1a393e68bSGeorge Karpenkov // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s 24f770deeSDevin Coughlin 34f770deeSDevin Coughlin void clang_analyzer_eval(bool); 44f770deeSDevin Coughlin 54f770deeSDevin Coughlin struct A { 64f770deeSDevin Coughlin int x; 74f770deeSDevin Coughlin void foo() const; 84f770deeSDevin Coughlin void bar(); 9f74ef4b1SArtem Dergachev testImplicitThisSyntaxA10f74ef4b1SArtem Dergachev void testImplicitThisSyntax() { 11f74ef4b1SArtem Dergachev x = 3; 12f74ef4b1SArtem Dergachev foo(); 13f74ef4b1SArtem Dergachev clang_analyzer_eval(x == 3); // expected-warning{{TRUE}} 14f74ef4b1SArtem Dergachev bar(); 15f74ef4b1SArtem Dergachev clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}} 16f74ef4b1SArtem Dergachev } 174f770deeSDevin Coughlin }; 184f770deeSDevin Coughlin 194f770deeSDevin Coughlin struct B { 204f770deeSDevin Coughlin mutable int mut; 214f770deeSDevin Coughlin void foo() const; 224f770deeSDevin Coughlin }; 234f770deeSDevin Coughlin 244f770deeSDevin Coughlin struct C { 254f770deeSDevin Coughlin int *p; 264f770deeSDevin Coughlin void foo() const; 274f770deeSDevin Coughlin }; 284f770deeSDevin Coughlin 294f770deeSDevin Coughlin struct MutBase { 304f770deeSDevin Coughlin mutable int b_mut; 314f770deeSDevin Coughlin }; 324f770deeSDevin Coughlin 334f770deeSDevin Coughlin struct MutDerived : MutBase { 344f770deeSDevin Coughlin void foo() const; 354f770deeSDevin Coughlin }; 364f770deeSDevin Coughlin 374f770deeSDevin Coughlin struct PBase { 384f770deeSDevin Coughlin int *p; 394f770deeSDevin Coughlin }; 404f770deeSDevin Coughlin 414f770deeSDevin Coughlin struct PDerived : PBase { 424f770deeSDevin Coughlin void foo() const; 434f770deeSDevin Coughlin }; 444f770deeSDevin Coughlin 454f770deeSDevin Coughlin struct Inner { 464f770deeSDevin Coughlin int x; 474f770deeSDevin Coughlin int *p; 484f770deeSDevin Coughlin void bar() const; 494f770deeSDevin Coughlin }; 504f770deeSDevin Coughlin 514f770deeSDevin Coughlin struct Outer { 524f770deeSDevin Coughlin int x; 534f770deeSDevin Coughlin Inner in; 544f770deeSDevin Coughlin void foo() const; 554f770deeSDevin Coughlin }; 564f770deeSDevin Coughlin checkThatConstMethodWithoutDefinitionDoesNotInvalidateObject()574f770deeSDevin Coughlinvoid checkThatConstMethodWithoutDefinitionDoesNotInvalidateObject() { 584f770deeSDevin Coughlin A t; 594f770deeSDevin Coughlin t.x = 3; 604f770deeSDevin Coughlin t.foo(); 614f770deeSDevin Coughlin clang_analyzer_eval(t.x == 3); // expected-warning{{TRUE}} 624f770deeSDevin Coughlin // Test non-const does invalidate 634f770deeSDevin Coughlin t.bar(); 644f770deeSDevin Coughlin clang_analyzer_eval(t.x); // expected-warning{{UNKNOWN}} 654f770deeSDevin Coughlin } 664f770deeSDevin Coughlin checkThatConstMethodDoesInvalidateMutableFields()674f770deeSDevin Coughlinvoid checkThatConstMethodDoesInvalidateMutableFields() { 684f770deeSDevin Coughlin B t; 694f770deeSDevin Coughlin t.mut = 4; 704f770deeSDevin Coughlin t.foo(); 714f770deeSDevin Coughlin clang_analyzer_eval(t.mut); // expected-warning{{UNKNOWN}} 724f770deeSDevin Coughlin } 734f770deeSDevin Coughlin checkThatConstMethodDoesInvalidatePointedAtMemory()744f770deeSDevin Coughlinvoid checkThatConstMethodDoesInvalidatePointedAtMemory() { 754f770deeSDevin Coughlin int x = 1; 764f770deeSDevin Coughlin C t; 774f770deeSDevin Coughlin t.p = &x; 784f770deeSDevin Coughlin t.foo(); 794f770deeSDevin Coughlin clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 804f770deeSDevin Coughlin clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}} 814f770deeSDevin Coughlin } 824f770deeSDevin Coughlin checkThatConstMethodDoesInvalidateInheritedMutableFields()834f770deeSDevin Coughlinvoid checkThatConstMethodDoesInvalidateInheritedMutableFields() { 844f770deeSDevin Coughlin MutDerived t; 854f770deeSDevin Coughlin t.b_mut = 4; 864f770deeSDevin Coughlin t.foo(); 874f770deeSDevin Coughlin clang_analyzer_eval(t.b_mut); // expected-warning{{UNKNOWN}} 884f770deeSDevin Coughlin } 894f770deeSDevin Coughlin checkThatConstMethodDoesInvalidateInheritedPointedAtMemory()904f770deeSDevin Coughlinvoid checkThatConstMethodDoesInvalidateInheritedPointedAtMemory() { 914f770deeSDevin Coughlin int x = 1; 924f770deeSDevin Coughlin PDerived t; 934f770deeSDevin Coughlin t.p = &x; 944f770deeSDevin Coughlin t.foo(); 954f770deeSDevin Coughlin clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 964f770deeSDevin Coughlin clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}} 974f770deeSDevin Coughlin } 984f770deeSDevin Coughlin checkThatConstMethodDoesInvalidateContainedPointedAtMemory()994f770deeSDevin Coughlinvoid checkThatConstMethodDoesInvalidateContainedPointedAtMemory() { 1004f770deeSDevin Coughlin int x = 1; 1014f770deeSDevin Coughlin Outer t; 1024f770deeSDevin Coughlin t.x = 2; 1034f770deeSDevin Coughlin t.in.p = &x; 1044f770deeSDevin Coughlin t.foo(); 1054f770deeSDevin Coughlin clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 1064f770deeSDevin Coughlin clang_analyzer_eval(t.x == 2); // expected-warning{{TRUE}} 1074f770deeSDevin Coughlin clang_analyzer_eval(t.in.p == &x); // expected-warning{{TRUE}} 1084f770deeSDevin Coughlin } 1094f770deeSDevin Coughlin checkThatContainedConstMethodDoesNotInvalidateObjects()1104f770deeSDevin Coughlinvoid checkThatContainedConstMethodDoesNotInvalidateObjects() { 1114f770deeSDevin Coughlin Outer t; 1124f770deeSDevin Coughlin t.x = 1; 1134f770deeSDevin Coughlin t.in.x = 2; 1144f770deeSDevin Coughlin t.in.bar(); 1154f770deeSDevin Coughlin clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}} 1164f770deeSDevin Coughlin clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}} 1174f770deeSDevin Coughlin } 1184f770deeSDevin Coughlin checkPointerTypedThisExpression(A * a)119f74ef4b1SArtem Dergachevvoid checkPointerTypedThisExpression(A *a) { 120f74ef4b1SArtem Dergachev a->x = 3; 121f74ef4b1SArtem Dergachev a->foo(); 122f74ef4b1SArtem Dergachev clang_analyzer_eval(a->x == 3); // expected-warning{{TRUE}} 123f74ef4b1SArtem Dergachev a->bar(); 124f74ef4b1SArtem Dergachev clang_analyzer_eval(a->x == 3); // expected-warning{{UNKNOWN}} 125f74ef4b1SArtem Dergachev } 126f74ef4b1SArtem Dergachev checkReferenceTypedThisExpression(A & a)127f74ef4b1SArtem Dergachevvoid checkReferenceTypedThisExpression(A &a) { 128f74ef4b1SArtem Dergachev a.x = 3; 129f74ef4b1SArtem Dergachev a.foo(); 130f74ef4b1SArtem Dergachev clang_analyzer_eval(a.x == 3); // expected-warning{{TRUE}} 131f74ef4b1SArtem Dergachev a.bar(); 132f74ef4b1SArtem Dergachev clang_analyzer_eval(a.x == 3); // expected-warning{{UNKNOWN}} 133f74ef4b1SArtem Dergachev } 134f74ef4b1SArtem Dergachev 1354f770deeSDevin Coughlin // --- Versions of the above tests where the const method is inherited --- // 1364f770deeSDevin Coughlin 1374f770deeSDevin Coughlin struct B1 { 1384f770deeSDevin Coughlin void foo() const; 1394f770deeSDevin Coughlin }; 1404f770deeSDevin Coughlin 1414f770deeSDevin Coughlin struct D1 : public B1 { 1424f770deeSDevin Coughlin int x; 1434f770deeSDevin Coughlin }; 1444f770deeSDevin Coughlin 1454f770deeSDevin Coughlin struct D2 : public B1 { 1464f770deeSDevin Coughlin mutable int mut; 1474f770deeSDevin Coughlin }; 1484f770deeSDevin Coughlin 1494f770deeSDevin Coughlin struct D3 : public B1 { 1504f770deeSDevin Coughlin int *p; 1514f770deeSDevin Coughlin }; 1524f770deeSDevin Coughlin 1534f770deeSDevin Coughlin struct DInner : public B1 { 1544f770deeSDevin Coughlin int x; 1554f770deeSDevin Coughlin int *p; 1564f770deeSDevin Coughlin }; 1574f770deeSDevin Coughlin 1584f770deeSDevin Coughlin struct DOuter : public B1 { 1594f770deeSDevin Coughlin int x; 1604f770deeSDevin Coughlin DInner in; 1614f770deeSDevin Coughlin }; 1624f770deeSDevin Coughlin checkThatInheritedConstMethodDoesNotInvalidateObject()1634f770deeSDevin Coughlinvoid checkThatInheritedConstMethodDoesNotInvalidateObject() { 1644f770deeSDevin Coughlin D1 t; 1654f770deeSDevin Coughlin t.x = 1; 1664f770deeSDevin Coughlin t.foo(); 1674f770deeSDevin Coughlin clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}} 1684f770deeSDevin Coughlin } 1694f770deeSDevin Coughlin checkThatInheritedConstMethodDoesInvalidateMutableFields()1704f770deeSDevin Coughlinvoid checkThatInheritedConstMethodDoesInvalidateMutableFields() { 1714f770deeSDevin Coughlin D2 t; 1724f770deeSDevin Coughlin t.mut = 1; 1734f770deeSDevin Coughlin t.foo(); 1744f770deeSDevin Coughlin clang_analyzer_eval(t.mut); // expected-warning{{UNKNOWN}} 1754f770deeSDevin Coughlin } 1764f770deeSDevin Coughlin checkThatInheritedConstMethodDoesInvalidatePointedAtMemory()1774f770deeSDevin Coughlinvoid checkThatInheritedConstMethodDoesInvalidatePointedAtMemory() { 1784f770deeSDevin Coughlin int x = 1; 1794f770deeSDevin Coughlin D3 t; 1804f770deeSDevin Coughlin t.p = &x; 1814f770deeSDevin Coughlin t.foo(); 1824f770deeSDevin Coughlin clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 1834f770deeSDevin Coughlin clang_analyzer_eval(t.p == &x); // expected-warning{{TRUE}} 1844f770deeSDevin Coughlin } 1854f770deeSDevin Coughlin checkThatInheritedConstMethodDoesInvalidateContainedPointedAtMemory()1864f770deeSDevin Coughlinvoid checkThatInheritedConstMethodDoesInvalidateContainedPointedAtMemory() { 1874f770deeSDevin Coughlin int x = 1; 1884f770deeSDevin Coughlin DOuter t; 1894f770deeSDevin Coughlin t.x = 2; 1904f770deeSDevin Coughlin t.in.x = 3; 1914f770deeSDevin Coughlin t.in.p = &x; 1924f770deeSDevin Coughlin t.foo(); 1934f770deeSDevin Coughlin clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} 1944f770deeSDevin Coughlin clang_analyzer_eval(t.x == 2); // expected-warning{{TRUE}} 1954f770deeSDevin Coughlin clang_analyzer_eval(t.in.x == 3); // expected-warning{{TRUE}} 1964f770deeSDevin Coughlin clang_analyzer_eval(t.in.p == &x); // expected-warning{{TRUE}} 1974f770deeSDevin Coughlin } 1984f770deeSDevin Coughlin checkThatInheritedContainedConstMethodDoesNotInvalidateObjects()1994f770deeSDevin Coughlinvoid checkThatInheritedContainedConstMethodDoesNotInvalidateObjects() { 2004f770deeSDevin Coughlin DOuter t; 2014f770deeSDevin Coughlin t.x = 1; 2024f770deeSDevin Coughlin t.in.x = 2; 2034f770deeSDevin Coughlin t.in.foo(); 2044f770deeSDevin Coughlin clang_analyzer_eval(t.x == 1); // expected-warning{{TRUE}} 2054f770deeSDevin Coughlin clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}} 2064f770deeSDevin Coughlin } 2074f770deeSDevin Coughlin 2084f770deeSDevin Coughlin // --- PR21606 --- // 2094f770deeSDevin Coughlin 2104f770deeSDevin Coughlin struct s1 { 2114f770deeSDevin Coughlin void g(const int *i) const; 2124f770deeSDevin Coughlin }; 2134f770deeSDevin Coughlin 2144f770deeSDevin Coughlin struct s2 { fs22154f770deeSDevin Coughlin void f(int *i) { 2164f770deeSDevin Coughlin m_i = i; 2174f770deeSDevin Coughlin m_s.g(m_i); 2184f770deeSDevin Coughlin if (m_i) 2194f770deeSDevin Coughlin *i = 42; // no-warning 2204f770deeSDevin Coughlin } 2214f770deeSDevin Coughlin 2224f770deeSDevin Coughlin int *m_i; 2234f770deeSDevin Coughlin s1 m_s; 2244f770deeSDevin Coughlin }; 2254f770deeSDevin Coughlin PR21606()2264f770deeSDevin Coughlinvoid PR21606() 2274f770deeSDevin Coughlin { 2284f770deeSDevin Coughlin s2().f(0); 2294f770deeSDevin Coughlin } 2304f770deeSDevin Coughlin 2319c76869bSDevin Coughlin // --- PR25392 --- // 2329c76869bSDevin Coughlin 2339c76869bSDevin Coughlin struct HasConstMemberFunction { 2349c76869bSDevin Coughlin public: 2359c76869bSDevin Coughlin void constMemberFunction() const; 2369c76869bSDevin Coughlin }; 2379c76869bSDevin Coughlin hasNoReturn()238*1da13237SDávid BolvanskýHasConstMemberFunction hasNoReturn() { } // expected-warning {{non-void function does not return a value}} 2399c76869bSDevin Coughlin testUnknownWithConstMemberFunction()2409c76869bSDevin Coughlinvoid testUnknownWithConstMemberFunction() { 2419c76869bSDevin Coughlin hasNoReturn().constMemberFunction(); 2429c76869bSDevin Coughlin } 2439c76869bSDevin Coughlin testNonRegionLocWithConstMemberFunction()2449c76869bSDevin Coughlinvoid testNonRegionLocWithConstMemberFunction() { 2459c76869bSDevin Coughlin (*((HasConstMemberFunction *)(&&label))).constMemberFunction(); 2469c76869bSDevin Coughlin 2479c76869bSDevin Coughlin label: return; 2489c76869bSDevin Coughlin } 2499c76869bSDevin Coughlin 2504f770deeSDevin Coughlin // FIXME 2514f770deeSDevin Coughlin // When there is a circular reference to an object and a const method is called 2524f770deeSDevin Coughlin // the object is not invalidated because TK_PreserveContents has already been 2534f770deeSDevin Coughlin // set. 2544f770deeSDevin Coughlin struct Outer2; 2554f770deeSDevin Coughlin 2564f770deeSDevin Coughlin struct InnerWithRef { 2574f770deeSDevin Coughlin Outer2 *ref; 2584f770deeSDevin Coughlin }; 2594f770deeSDevin Coughlin 2604f770deeSDevin Coughlin struct Outer2 { 2614f770deeSDevin Coughlin int x; 2624f770deeSDevin Coughlin InnerWithRef in; 2634f770deeSDevin Coughlin void foo() const; 2644f770deeSDevin Coughlin }; 2654f770deeSDevin Coughlin checkThatConstMethodCallDoesInvalidateObjectForCircularReferences()2664f770deeSDevin Coughlinvoid checkThatConstMethodCallDoesInvalidateObjectForCircularReferences() { 2674f770deeSDevin Coughlin Outer2 t; 2684f770deeSDevin Coughlin t.x = 1; 2694f770deeSDevin Coughlin t.in.ref = &t; 2704f770deeSDevin Coughlin t.foo(); 2714f770deeSDevin Coughlin // FIXME: Should be UNKNOWN. 2724f770deeSDevin Coughlin clang_analyzer_eval(t.x); // expected-warning{{TRUE}} 2734f770deeSDevin Coughlin } 274