Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -Wno-null-dereference -verify %s
      2 
      3 void clang_analyzer_eval(bool);
      4 void clang_analyzer_checkInlined(bool);
      5 
      6 struct Wrapper {
      7   __strong id obj;
      8 };
      9 
     10 void test() {
     11   Wrapper w;
     12   // force a diagnostic
     13   *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
     14 }
     15 
     16 
     17 struct IntWrapper {
     18   int x;
     19 };
     20 
     21 void testCopyConstructor() {
     22   IntWrapper a;
     23   a.x = 42;
     24 
     25   IntWrapper b(a);
     26   clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
     27 }
     28 
     29 struct NonPODIntWrapper {
     30   int x;
     31 
     32   virtual int get();
     33 };
     34 
     35 void testNonPODCopyConstructor() {
     36   NonPODIntWrapper a;
     37   a.x = 42;
     38 
     39   NonPODIntWrapper b(a);
     40   clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
     41 }
     42 
     43 
     44 namespace ConstructorVirtualCalls {
     45   class A {
     46   public:
     47     int *out1, *out2, *out3;
     48 
     49     virtual int get() { return 1; }
     50 
     51     A(int *out1) {
     52       *out1 = get();
     53     }
     54   };
     55 
     56   class B : public A {
     57   public:
     58     virtual int get() { return 2; }
     59 
     60     B(int *out1, int *out2) : A(out1) {
     61       *out2 = get();
     62     }
     63   };
     64 
     65   class C : public B {
     66   public:
     67     virtual int get() { return 3; }
     68 
     69     C(int *out1, int *out2, int *out3) : B(out1, out2) {
     70       *out3 = get();
     71     }
     72   };
     73 
     74   void test() {
     75     int a, b, c;
     76 
     77     C obj(&a, &b, &c);
     78     clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
     79     clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
     80     clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
     81 
     82     clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
     83 
     84     // Sanity check for devirtualization.
     85     A *base = &obj;
     86     clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
     87   }
     88 }
     89 
     90 namespace TemporaryConstructor {
     91   class BoolWrapper {
     92   public:
     93     BoolWrapper() {
     94       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
     95       value = true;
     96     }
     97     bool value;
     98   };
     99 
    100   void test() {
    101     // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined.
    102     if (BoolWrapper().value)
    103       return;
    104   }
    105 }
    106