1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s 24920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s 34920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 44920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorvoid clang_analyzer_eval(int); 54920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 64920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorstruct S { 74920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor int field; 84920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 94920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#if __cplusplus 104920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor const struct S *getThis() const { return this; } 114920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#endif 124920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor}; 134920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 144920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorstruct S getS(); 154920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 164920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 174920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorvoid testAssignment() { 184920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor struct S s = getS(); 194920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 204920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor if (s.field != 42) return; 214920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 224920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 234920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor s.field = 0; 244920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}} 254920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 264920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#if __cplusplus 274920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}} 284920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#endif 294920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor} 304920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 314920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 324920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorvoid testImmediateUse() { 334920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor int x = getS().field; 344920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 354920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor if (x != 42) return; 364920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} 374920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 384920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#if __cplusplus 394920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}} 404920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#endif 414920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor} 424920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 434920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorint getConstrainedField(struct S s) { 444920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor if (s.field != 42) return 42; 454920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor return s.field; 464920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor} 474920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 484920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorint getAssignedField(struct S s) { 494920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor s.field = 42; 501829a6db2ec19e08061f0bb2f4c52a8e5e4efaf0Chris Lattner return s.field; 514920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor} 524920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 53cb821d045f5e445384f34d05a526955036073c4aDouglas Gregorvoid testArgument() { 544920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}} 554920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#if __cplusplus 564920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor // FIXME: Passing the struct by value seems to be confusing C++. 574920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor // Possibly related to <rdar://problem/12137950>. 58cb821d045f5e445384f34d05a526955036073c4aDouglas Gregor // expected-warning@-4{{UNKNOWN}} 594920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor#endif 604920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 614920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}} 624920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor} 634920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 644920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 654920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor//-------------------- 664920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor// C++-only tests 674920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor//-------------------- 684920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 69cb821d045f5e445384f34d05a526955036073c4aDouglas Gregor#if __cplusplus 704920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorvoid testReferenceAssignment() { 714920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor const S &s = getS(); 724920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 734920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor if (s.field != 42) return; 744920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}} 754920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 764920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}} 774920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor} 784920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 794920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregor 804920f1ffb62b13b88e579476803c093f97f3e17fDouglas Gregorint getConstrainedFieldRef(const S &s) { 81cb821d045f5e445384f34d05a526955036073c4aDouglas Gregor if (s.field != 42) return 42; 82c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbar return s.field; 83c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbar} 84c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbar 85c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbarbool checkThis(const S &s) { 86c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbar return s.getThis() == &s; 87c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbar} 88c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbar 89c8d8fa965e3d34335959923b0079f1d23ca5767dDaniel Dunbarvoid testReferenceArgument() { 90a71c129fb8052a143cbf548963a8db2150b0078eDouglas Gregor clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}} 91e950d4bbb7c785c7a7abdd0ad98f372b8c7980b8Douglas Gregor clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}} 92cb821d045f5e445384f34d05a526955036073c4aDouglas Gregor} 93e950d4bbb7c785c7a7abdd0ad98f372b8c7980b8Douglas Gregor#endif 94e950d4bbb7c785c7a7abdd0ad98f372b8c7980b8Douglas Gregor