Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
      2 
      3 void clang_analyzer_eval(bool);
      4 
      5 class A {
      6 protected:
      7   int x;
      8 };
      9 
     10 class B : public A {
     11 public:
     12   void f();
     13 };
     14 
     15 void B::f() {
     16   x = 3;
     17 }
     18 
     19 
     20 class C : public B {
     21 public:
     22   void g() {
     23     // This used to crash because we are upcasting through two bases.
     24     x = 5;
     25   }
     26 };
     27 
     28 
     29 namespace VirtualBaseClasses {
     30   class A {
     31   protected:
     32     int x;
     33   };
     34 
     35   class B : public virtual A {
     36   public:
     37     int getX() { return x; }
     38   };
     39 
     40   class C : public virtual A {
     41   public:
     42     void setX() { x = 42; }
     43   };
     44 
     45   class D : public B, public C {};
     46   class DV : virtual public B, public C {};
     47   class DV2 : public B, virtual public C {};
     48 
     49   void test() {
     50     D d;
     51     d.setX();
     52     clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
     53 
     54     DV dv;
     55     dv.setX();
     56     clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
     57 
     58     DV2 dv2;
     59     dv2.setX();
     60     clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
     61   }
     62 
     63 
     64   // Make sure we're consistent about the offset of the A subobject within an
     65   // Intermediate virtual base class.
     66   class Padding1 { int unused; };
     67   class Padding2 { int unused; };
     68   class Intermediate : public Padding1, public A, public Padding2 {};
     69 
     70   class BI : public virtual Intermediate {
     71   public:
     72     int getX() { return x; }
     73   };
     74 
     75   class CI : public virtual Intermediate {
     76   public:
     77     void setX() { x = 42; }
     78   };
     79 
     80   class DI : public BI, public CI {};
     81 
     82   void testIntermediate() {
     83     DI d;
     84     d.setX();
     85     clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
     86   }
     87 }
     88 
     89 
     90 namespace DynamicVirtualUpcast {
     91   class A {
     92   public:
     93     virtual ~A();
     94   };
     95 
     96   class B : virtual public A {};
     97   class C : virtual public B {};
     98   class D : virtual public C {};
     99 
    100   bool testCast(A *a) {
    101     return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);
    102   }
    103 
    104   void test() {
    105     D d;
    106     clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
    107   }
    108 }
    109 
    110 namespace DynamicMultipleInheritanceUpcast {
    111   class B {
    112   public:
    113     virtual ~B();
    114   };
    115   class C {
    116   public:
    117     virtual ~C();
    118   };
    119   class D : public B, public C {};
    120 
    121   bool testCast(B *a) {
    122     return dynamic_cast<C*>(a);
    123   }
    124 
    125   void test() {
    126     D d;
    127     clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
    128   }
    129 
    130 
    131   class DV : virtual public B, virtual public C {};
    132 
    133   void testVirtual() {
    134     DV d;
    135     clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
    136   }
    137 }
    138