Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
      2 
      3 void clang_analyzer_eval(bool);
      4 
      5 class A {
      6   int x;
      7 public:
      8   A();
      9 };
     10 
     11 A::A() : x(0) {
     12   clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
     13 }
     14 
     15 
     16 class DirectMember {
     17   int x;
     18 public:
     19   DirectMember(int value) : x(value) {}
     20 
     21   int getX() { return x; }
     22 };
     23 
     24 void testDirectMember() {
     25   DirectMember obj(3);
     26   clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
     27 }
     28 
     29 
     30 class IndirectMember {
     31   struct {
     32     int x;
     33   };
     34 public:
     35   IndirectMember(int value) : x(value) {}
     36 
     37   int getX() { return x; }
     38 };
     39 
     40 void testIndirectMember() {
     41   IndirectMember obj(3);
     42   clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
     43 }
     44 
     45 
     46 struct DelegatingConstructor {
     47   int x;
     48   DelegatingConstructor(int y) { x = y; }
     49   DelegatingConstructor() : DelegatingConstructor(42) {}
     50 };
     51 
     52 void testDelegatingConstructor() {
     53   DelegatingConstructor obj;
     54   clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
     55 }
     56 
     57 
     58 struct RefWrapper {
     59   RefWrapper(int *p) : x(*p) {}
     60   RefWrapper(int &r) : x(r) {}
     61   int &x;
     62 };
     63 
     64 void testReferenceMember() {
     65   int *p = 0;
     66   RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}}
     67 }
     68 
     69 void testReferenceMember2() {
     70   int *p = 0;
     71   RefWrapper X(*p); // expected-warning {{Forming reference to null pointer}}
     72 }
     73 
     74 
     75 extern "C" char *strdup(const char *);
     76 
     77 class StringWrapper {
     78   char *str;
     79 public:
     80   StringWrapper(const char *input) : str(strdup(input)) {} // no-warning
     81 };
     82 
     83 
     84 // PR15070 - Constructing a type containing a non-POD array mistakenly
     85 // tried to perform a bind instead of relying on the CXXConstructExpr,
     86 // which caused a cast<> failure in RegionStore.
     87 namespace DefaultConstructorWithCleanups {
     88   class Element {
     89   public:
     90     int value;
     91 
     92     class Helper {
     93     public:
     94       ~Helper();
     95     };
     96     Element(Helper h = Helper());
     97   };
     98   class Wrapper {
     99   public:
    100     Element arr[2];
    101 
    102     Wrapper();
    103   };
    104 
    105   Wrapper::Wrapper() /* initializers synthesized */ {}
    106 
    107   int test() {
    108     Wrapper w;
    109     return w.arr[0].value; // no-warning
    110   }
    111 }
    112 
    113 namespace DefaultMemberInitializers {
    114   struct Wrapper {
    115     int value = 42;
    116 
    117     Wrapper() {}
    118     Wrapper(int x) : value(x) {}
    119     Wrapper(bool) {}
    120   };
    121 
    122   void test() {
    123     Wrapper w1;
    124     clang_analyzer_eval(w1.value == 42); // expected-warning{{TRUE}}
    125 
    126     Wrapper w2(50);
    127     clang_analyzer_eval(w2.value == 50); // expected-warning{{TRUE}}
    128 
    129     Wrapper w3(false);
    130     clang_analyzer_eval(w3.value == 42); // expected-warning{{TRUE}}
    131   }
    132 
    133   struct StringWrapper {
    134     const char s[4] = "abc";
    135     const char *p = "xyz";
    136 
    137     StringWrapper(bool) {}
    138   };
    139 
    140   void testString() {
    141     StringWrapper w(true);
    142     clang_analyzer_eval(w.s[1] == 'b'); // expected-warning{{TRUE}}
    143     clang_analyzer_eval(w.p[1] == 'y'); // expected-warning{{TRUE}}
    144   }
    145 }
    146 
    147 namespace ReferenceInitialization {
    148   struct OtherStruct {
    149     OtherStruct(int i);
    150     ~OtherStruct();
    151   };
    152 
    153   struct MyStruct {
    154     MyStruct(int i);
    155     MyStruct(OtherStruct os);
    156 
    157     void method() const;
    158   };
    159 
    160   void referenceInitializeLocal() {
    161     const MyStruct &myStruct(5);
    162     myStruct.method(); // no-warning
    163   }
    164 
    165   void referenceInitializeMultipleLocals() {
    166     const MyStruct &myStruct1(5), myStruct2(5), &myStruct3(5);
    167     myStruct1.method(); // no-warning
    168     myStruct2.method(); // no-warning
    169     myStruct3.method(); // no-warning
    170   }
    171 
    172   void referenceInitializeLocalWithCleanup() {
    173     const MyStruct &myStruct(OtherStruct(5));
    174     myStruct.method(); // no-warning
    175   }
    176 
    177   struct HasMyStruct {
    178     const MyStruct &ms; // expected-note {{reference member declared here}}
    179     const MyStruct &msWithCleanups; // expected-note {{reference member declared here}}
    180 
    181     // clang's Sema issues a warning when binding a reference member to a
    182     // temporary value.
    183     HasMyStruct() : ms(5), msWithCleanups(OtherStruct(5)) {
    184         // expected-warning@-1 {{binding reference member 'ms' to a temporary value}}
    185         // expected-warning@-2 {{binding reference member 'msWithCleanups' to a temporary value}}
    186 
    187       // At this point the members are not garbage so we should not expect an
    188       // analyzer warning here even though binding a reference member
    189       // to a member is a terrible idea.
    190       ms.method(); // no-warning
    191       msWithCleanups.method(); // no-warning
    192     }
    193   };
    194 
    195   void referenceInitializeField() {
    196     HasMyStruct hms;
    197   }
    198 
    199 };
    200