// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s void clang_analyzer_eval(bool); void usePointer(int * const *); void useReference(int * const &); void testPointer() { int x; int *p; p = &x; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} usePointer(&p); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} p = &x; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} useReference(p); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} int * const cp1 = &x; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} usePointer(&cp1); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} int * const cp2 = &x; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} useReference(cp2); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} } struct Wrapper { int *ptr; }; void useStruct(Wrapper &w); void useConstStruct(const Wrapper &w); void testPointerStruct() { int x; Wrapper w; w.ptr = &x; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} useStruct(w); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} w.ptr = &x; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} useConstStruct(w); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} } struct RefWrapper { int &ref; }; void useStruct(RefWrapper &w); void useConstStruct(const RefWrapper &w); void testReferenceStruct() { int x; RefWrapper w = { x }; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} useStruct(w); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} } // FIXME: This test is split into two functions because region invalidation // does not preserve reference bindings. void testConstReferenceStruct() { int x; RefWrapper w = { x }; x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} useConstStruct(w); clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}} }