1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s 2*67e74705SXin Li 3*67e74705SXin Li void clang_analyzer_eval(bool); 4*67e74705SXin Li 5*67e74705SXin Li struct A { 6*67e74705SXin Li int x; 7*67e74705SXin Li void foo() const; 8*67e74705SXin Li void bar(); 9*67e74705SXin Li }; 10*67e74705SXin Li 11*67e74705SXin Li struct B { 12*67e74705SXin Li mutable int mut; 13*67e74705SXin Li void foo() const; 14*67e74705SXin Li }; 15*67e74705SXin Li 16*67e74705SXin Li struct C { 17*67e74705SXin Li int *p; 18*67e74705SXin Li void foo() const; 19*67e74705SXin Li }; 20*67e74705SXin Li 21*67e74705SXin Li struct MutBase { 22*67e74705SXin Li mutable int b_mut; 23*67e74705SXin Li }; 24*67e74705SXin Li 25*67e74705SXin Li struct MutDerived : MutBase { 26*67e74705SXin Li void foo() const; 27*67e74705SXin Li }; 28*67e74705SXin Li 29*67e74705SXin Li struct PBase { 30*67e74705SXin Li int *p; 31*67e74705SXin Li }; 32*67e74705SXin Li 33*67e74705SXin Li struct PDerived : PBase { 34*67e74705SXin Li void foo() const; 35*67e74705SXin Li }; 36*67e74705SXin Li 37*67e74705SXin Li struct Inner { 38*67e74705SXin Li int x; 39*67e74705SXin Li int *p; 40*67e74705SXin Li void bar() const; 41*67e74705SXin Li }; 42*67e74705SXin Li 43*67e74705SXin Li struct Outer { 44*67e74705SXin Li int x; 45*67e74705SXin Li Inner in; 46*67e74705SXin Li void foo() const; 47*67e74705SXin Li }; 48*67e74705SXin Li checkThatConstMethodWithoutDefinitionDoesNotInvalidateObject()49*67e74705SXin Livoid checkThatConstMethodWithoutDefinitionDoesNotInvalidateObject() { 50*67e74705SXin Li A t; 51*67e74705SXin Li t.x = 3; 52*67e74705SXin Li t.foo(); 53*67e74705SXin Li clang_analyzer_eval(t.x == 3); // expected-warning{{TRUE}} 54*67e74705SXin Li // Test non-const does invalidate 55*67e74705SXin Li t.bar(); 56*67e74705SXin Li clang_analyzer_eval(t.x); // expected-warning{{UNKNOWN}} 57*67e74705SXin Li } 58*67e74705SXin Li checkThatConstMethodDoesInvalidateMutableFields()59*67e74705SXin Livoid checkThatConstMethodDoesInvalidateMutableFields() { 60*67e74705SXin Li B t; 61*67e74705SXin Li t.mut = 4; 62*67e74705SXin Li t.foo(); 63*67e74705SXin Li clang_analyzer_eval(t.mut); // expected-warning{{UNKNOWN}} 64*67e74705SXin Li } 65*67e74705SXin Li checkThatConstMethodDoesInvalidatePointedAtMemory()66*67e74705SXin Livoid checkThatConstMethodDoesInvalidatePointedAtMemory() { 67*67e74705SXin Li int x = 1; 68*67e74705SXin Li C t; 69*67e74705SXin Li t.p = &x; 70*67e74705SXin Li t.foo(); 71*67e74705SXin Li clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 72*67e74705SXin Li clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}} 73*67e74705SXin Li } 74*67e74705SXin Li checkThatConstMethodDoesInvalidateInheritedMutableFields()75*67e74705SXin Livoid checkThatConstMethodDoesInvalidateInheritedMutableFields() { 76*67e74705SXin Li MutDerived t; 77*67e74705SXin Li t.b_mut = 4; 78*67e74705SXin Li t.foo(); 79*67e74705SXin Li clang_analyzer_eval(t.b_mut); // expected-warning{{UNKNOWN}} 80*67e74705SXin Li } 81*67e74705SXin Li checkThatConstMethodDoesInvalidateInheritedPointedAtMemory()82*67e74705SXin Livoid checkThatConstMethodDoesInvalidateInheritedPointedAtMemory() { 83*67e74705SXin Li int x = 1; 84*67e74705SXin Li PDerived t; 85*67e74705SXin Li t.p = &x; 86*67e74705SXin Li t.foo(); 87*67e74705SXin Li clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 88*67e74705SXin Li clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}} 89*67e74705SXin Li } 90*67e74705SXin Li checkThatConstMethodDoesInvalidateContainedPointedAtMemory()91*67e74705SXin Livoid checkThatConstMethodDoesInvalidateContainedPointedAtMemory() { 92*67e74705SXin Li int x = 1; 93*67e74705SXin Li Outer t; 94*67e74705SXin Li t.x = 2; 95*67e74705SXin Li t.in.p = &x; 96*67e74705SXin Li t.foo(); 97*67e74705SXin Li clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 98*67e74705SXin Li clang_analyzer_eval(t.x == 2); // expected-warning{{TRUE}} 99*67e74705SXin Li clang_analyzer_eval(t.in.p == &x); // expected-warning{{TRUE}} 100*67e74705SXin Li } 101*67e74705SXin Li checkThatContainedConstMethodDoesNotInvalidateObjects()102*67e74705SXin Livoid checkThatContainedConstMethodDoesNotInvalidateObjects() { 103*67e74705SXin Li Outer t; 104*67e74705SXin Li t.x = 1; 105*67e74705SXin Li t.in.x = 2; 106*67e74705SXin Li t.in.bar(); 107*67e74705SXin Li clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}} 108*67e74705SXin Li clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}} 109*67e74705SXin Li } 110*67e74705SXin Li 111*67e74705SXin Li // --- Versions of the above tests where the const method is inherited --- // 112*67e74705SXin Li 113*67e74705SXin Li struct B1 { 114*67e74705SXin Li void foo() const; 115*67e74705SXin Li }; 116*67e74705SXin Li 117*67e74705SXin Li struct D1 : public B1 { 118*67e74705SXin Li int x; 119*67e74705SXin Li }; 120*67e74705SXin Li 121*67e74705SXin Li struct D2 : public B1 { 122*67e74705SXin Li mutable int mut; 123*67e74705SXin Li }; 124*67e74705SXin Li 125*67e74705SXin Li struct D3 : public B1 { 126*67e74705SXin Li int *p; 127*67e74705SXin Li }; 128*67e74705SXin Li 129*67e74705SXin Li struct DInner : public B1 { 130*67e74705SXin Li int x; 131*67e74705SXin Li int *p; 132*67e74705SXin Li }; 133*67e74705SXin Li 134*67e74705SXin Li struct DOuter : public B1 { 135*67e74705SXin Li int x; 136*67e74705SXin Li DInner in; 137*67e74705SXin Li }; 138*67e74705SXin Li checkThatInheritedConstMethodDoesNotInvalidateObject()139*67e74705SXin Livoid checkThatInheritedConstMethodDoesNotInvalidateObject() { 140*67e74705SXin Li D1 t; 141*67e74705SXin Li t.x = 1; 142*67e74705SXin Li t.foo(); 143*67e74705SXin Li clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}} 144*67e74705SXin Li } 145*67e74705SXin Li checkThatInheritedConstMethodDoesInvalidateMutableFields()146*67e74705SXin Livoid checkThatInheritedConstMethodDoesInvalidateMutableFields() { 147*67e74705SXin Li D2 t; 148*67e74705SXin Li t.mut = 1; 149*67e74705SXin Li t.foo(); 150*67e74705SXin Li clang_analyzer_eval(t.mut); // expected-warning{{UNKNOWN}} 151*67e74705SXin Li } 152*67e74705SXin Li checkThatInheritedConstMethodDoesInvalidatePointedAtMemory()153*67e74705SXin Livoid checkThatInheritedConstMethodDoesInvalidatePointedAtMemory() { 154*67e74705SXin Li int x = 1; 155*67e74705SXin Li D3 t; 156*67e74705SXin Li t.p = &x; 157*67e74705SXin Li t.foo(); 158*67e74705SXin Li clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 159*67e74705SXin Li clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}} 160*67e74705SXin Li } 161*67e74705SXin Li checkThatInheritedConstMethodDoesInvalidateContainedPointedAtMemory()162*67e74705SXin Livoid checkThatInheritedConstMethodDoesInvalidateContainedPointedAtMemory() { 163*67e74705SXin Li int x = 1; 164*67e74705SXin Li DOuter t; 165*67e74705SXin Li t.x = 2; 166*67e74705SXin Li t.in.x = 3; 167*67e74705SXin Li t.in.p = &x; 168*67e74705SXin Li t.foo(); 169*67e74705SXin Li clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 170*67e74705SXin Li clang_analyzer_eval(t.x == 2); // expected-warning{{TRUE}} 171*67e74705SXin Li clang_analyzer_eval(t.in.x == 3); // expected-warning{{TRUE}} 172*67e74705SXin Li clang_analyzer_eval(t.in.p == &x); // expected-warning{{TRUE}} 173*67e74705SXin Li } 174*67e74705SXin Li checkThatInheritedContainedConstMethodDoesNotInvalidateObjects()175*67e74705SXin Livoid checkThatInheritedContainedConstMethodDoesNotInvalidateObjects() { 176*67e74705SXin Li DOuter t; 177*67e74705SXin Li t.x = 1; 178*67e74705SXin Li t.in.x = 2; 179*67e74705SXin Li t.in.foo(); 180*67e74705SXin Li clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}} 181*67e74705SXin Li clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}} 182*67e74705SXin Li } 183*67e74705SXin Li 184*67e74705SXin Li // --- PR21606 --- // 185*67e74705SXin Li 186*67e74705SXin Li struct s1 { 187*67e74705SXin Li void g(const int *i) const; 188*67e74705SXin Li }; 189*67e74705SXin Li 190*67e74705SXin Li struct s2 { fs2191*67e74705SXin Li void f(int *i) { 192*67e74705SXin Li m_i = i; 193*67e74705SXin Li m_s.g(m_i); 194*67e74705SXin Li if (m_i) 195*67e74705SXin Li *i = 42; // no-warning 196*67e74705SXin Li } 197*67e74705SXin Li 198*67e74705SXin Li int *m_i; 199*67e74705SXin Li s1 m_s; 200*67e74705SXin Li }; 201*67e74705SXin Li PR21606()202*67e74705SXin Livoid PR21606() 203*67e74705SXin Li { 204*67e74705SXin Li s2().f(0); 205*67e74705SXin Li } 206*67e74705SXin Li 207*67e74705SXin Li // --- PR25392 --- // 208*67e74705SXin Li 209*67e74705SXin Li struct HasConstMemberFunction { 210*67e74705SXin Li public: 211*67e74705SXin Li void constMemberFunction() const; 212*67e74705SXin Li }; 213*67e74705SXin Li hasNoReturn()214*67e74705SXin LiHasConstMemberFunction hasNoReturn() { } // expected-warning {{control reaches end of non-void function}} 215*67e74705SXin Li testUnknownWithConstMemberFunction()216*67e74705SXin Livoid testUnknownWithConstMemberFunction() { 217*67e74705SXin Li hasNoReturn().constMemberFunction(); 218*67e74705SXin Li } 219*67e74705SXin Li testNonRegionLocWithConstMemberFunction()220*67e74705SXin Livoid testNonRegionLocWithConstMemberFunction() { 221*67e74705SXin Li (*((HasConstMemberFunction *)(&&label))).constMemberFunction(); 222*67e74705SXin Li 223*67e74705SXin Li label: return; 224*67e74705SXin Li } 225*67e74705SXin Li 226*67e74705SXin Li // FIXME 227*67e74705SXin Li // When there is a circular reference to an object and a const method is called 228*67e74705SXin Li // the object is not invalidated because TK_PreserveContents has already been 229*67e74705SXin Li // set. 230*67e74705SXin Li struct Outer2; 231*67e74705SXin Li 232*67e74705SXin Li struct InnerWithRef { 233*67e74705SXin Li Outer2 *ref; 234*67e74705SXin Li }; 235*67e74705SXin Li 236*67e74705SXin Li struct Outer2 { 237*67e74705SXin Li int x; 238*67e74705SXin Li InnerWithRef in; 239*67e74705SXin Li void foo() const; 240*67e74705SXin Li }; 241*67e74705SXin Li checkThatConstMethodCallDoesInvalidateObjectForCircularReferences()242*67e74705SXin Livoid checkThatConstMethodCallDoesInvalidateObjectForCircularReferences() { 243*67e74705SXin Li Outer2 t; 244*67e74705SXin Li t.x = 1; 245*67e74705SXin Li t.in.ref = &t; 246*67e74705SXin Li t.foo(); 247*67e74705SXin Li // FIXME: Should be UNKNOWN. 248*67e74705SXin Li clang_analyzer_eval(t.x); // expected-warning{{TRUE}} 249*67e74705SXin Li } 250