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