brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · cb50302 Raw
283 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s2 3template <class T> void clang_analyzer_dump(T);4void clang_analyzer_eval(bool);5 6void usePointer(int * const *);7void useReference(int * const &);8 9void testPointer() {10  int x;11  int *p;12 13  p = &x;14  x = 42;15  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}16  usePointer(&p);17  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}18 19  p = &x;20  x = 42;21  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}22  useReference(p);23  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}24 25  int * const cp1 = &x;26  x = 42;27  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}28  usePointer(&cp1);29  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}30 31  int * const cp2 = &x;32  x = 42;33  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}34  useReference(cp2);35  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}36}37 38 39struct Wrapper {40  int *ptr;41};42 43void useStruct(Wrapper &w);44void useConstStruct(const Wrapper &w);45 46void testPointerStruct() {47  int x;48  Wrapper w;49 50  w.ptr = &x;51  x = 42;52  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}53  useStruct(w);54  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}55 56  w.ptr = &x;57  x = 42;58  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}59  useConstStruct(w);60  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}61}62 63 64struct RefWrapper {65  int &ref;66};67 68void useStruct(RefWrapper &w);69void useConstStruct(const RefWrapper &w);70 71void testReferenceStruct() {72  int x;73  RefWrapper w = { x };74 75  x = 42;76  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}77  useStruct(w);78  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}79}80 81// FIXME: This test is split into two functions because region invalidation82// does not preserve reference bindings.83void testConstReferenceStruct() {84  int x;85  RefWrapper w = { x };86 87  x = 42;88  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}89  useConstStruct(w);90  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}91}92 93 94int usePointerPure(int * const *) __attribute__((pure));95int usePointerConst(int * const *) __attribute__((const));96 97void testPureConst() {98  extern int global;99  int x;100  int *p;101 102  p = &x;103  x = 42;104  global = -5;105  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}106  clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}107 108  (void)usePointerPure(&p);109  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}110  clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}111 112  (void)usePointerConst(&p);113  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}114  clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}115 116  usePointer(&p);117  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}118  clang_analyzer_eval(global == -5); // expected-warning{{UNKNOWN}}119}120 121 122struct PlainStruct {123  int x, y;124  mutable int z;125};126 127PlainStruct glob;128 129void useAnything(void *);130void useAnythingConst(const void *);131 132void testInvalidationThroughBaseRegionPointer() {133  PlainStruct s1;134  s1.x = 1;135  s1.z = 1;136  clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}}137  clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}}138  // Not only passing a structure pointer through const pointer parameter,139  // but also passing a field pointer through const pointer parameter140  // should preserve the contents of the structure.141  useAnythingConst(&(s1.y));142  clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}}143  // FIXME: Should say "UNKNOWN", because it is not uncommon to144  // modify a mutable member variable through const pointer.145  clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}}146  useAnything(&(s1.y));147  clang_analyzer_eval(s1.x == 1); // expected-warning{{UNKNOWN}}148}149 150 151void useFirstConstSecondNonConst(const void *x, void *y);152void useFirstNonConstSecondConst(void *x, const void *y);153 154void testMixedConstNonConstCalls() {155  PlainStruct s2;156  s2.x = 1;157  useFirstConstSecondNonConst(&(s2.x), &(s2.y));158  clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}}159  s2.x = 1;160  useFirstNonConstSecondConst(&(s2.x), &(s2.y));161  clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}}162  s2.y = 1;163  useFirstConstSecondNonConst(&(s2.x), &(s2.y));164  clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}165  s2.y = 1;166  useFirstNonConstSecondConst(&(s2.x), &(s2.y));167  clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}}168}169 170namespace std {171class Opaque {172public:173  Opaque();174  int nested_member;175};176} // namespace std177 178struct StdWrappingOpaque {179  std::Opaque o; // first member180  int uninit;181};182struct StdWrappingOpaqueSwapped {183  int uninit; // first member184  std::Opaque o;185};186 187int testStdCtorDoesNotInvalidateParentObject() {188  StdWrappingOpaque obj;189  int x = obj.o.nested_member; // no-garbage: std::Opaque::ctor might initialized this190  int y = obj.uninit; // FIXME: We should have a garbage read here. Read the details.191  // As the first member ("obj.o") is invalidated, a conjured default binding is bound192  // to the offset 0 within cluster "obj", and this masks every uninitialized fields193  // that follows. We need a better store with extents to fix this.194  return x + y;195}196 197int testStdCtorDoesNotInvalidateParentObjectSwapped() {198  StdWrappingOpaqueSwapped obj;199  int x = obj.o.nested_member; // no-garbage: std::Opaque::ctor might initialized this200  int y = obj.uninit; // expected-warning {{Assigned value is uninitialized}}201  return x + y;202}203 204class UserProvidedOpaque {205public:206  UserProvidedOpaque(); // might reinterpret_cast(this)207  int nested_member;208};209 210struct WrappingUserProvidedOpaque {211  UserProvidedOpaque o; // first member212  int uninit;213};214struct WrappingUserProvidedOpaqueSwapped {215  int uninit; // first member216  UserProvidedOpaque o;217};218 219int testUserProvidedCtorInvalidatesParentObject() {220  WrappingUserProvidedOpaque obj;221  int x = obj.o.nested_member; // no-garbage: UserProvidedOpaque::ctor might initialized this222  int y = obj.uninit; // no-garbage: UserProvidedOpaque::ctor might reinterpret_cast(this) and write to the "uninit" member.223  return x + y;224}225 226int testUserProvidedCtorInvalidatesParentObjectSwapped() {227  WrappingUserProvidedOpaqueSwapped obj;228  int x = obj.o.nested_member; // no-garbage: same as above229  int y = obj.uninit; // no-garbage: same as above230  return x + y;231}232 233struct WrappingStdWrappingOpaqueOuterInits {234  int first = 1;235  std::Opaque second;236  int third = 3;237  WrappingStdWrappingOpaqueOuterInits() {238    clang_analyzer_dump(first); // expected-warning {{1 S32b}}239    clang_analyzer_dump(second.nested_member); // expected-warning {{derived_}}240    clang_analyzer_dump(third); // expected-warning {{3 S32b}}241  }242};243 244struct WrappingUserProvidedOpaqueOuterInits {245  int first = 1; // Potentially overwritten by UserProvidedOpaque::ctor246  UserProvidedOpaque second; // Invalidates the object so far.247  int third = 3; // Happens after UserProvidedOpaque::ctor, thus preserved!248  WrappingUserProvidedOpaqueOuterInits() {249    clang_analyzer_dump(first); // expected-warning {{derived_}}250    clang_analyzer_dump(second.nested_member); // expected-warning {{derived_}}251    clang_analyzer_dump(third); // expected-warning {{3 S32b}}252  }253};254 255extern "C++" {256namespace std {257inline namespace v1 {258namespace custom_ranges {259struct Fancy {260struct iterator {261struct Opaque {262  Opaque();263  int nested_member;264}; // struct Opaque265}; // struct iterator266}; // struct Fancy267} // namespace custom_ranges268} // namespace v1269} // namespace std270} // extern "C++"271 272struct StdWrappingFancyOpaque {273  int uninit;274  std::custom_ranges::Fancy::iterator::Opaque o;275};276 277int testNestedStdNamespacesAndRecords() {278  StdWrappingFancyOpaque obj;279  int x = obj.o.nested_member; // no-garbage: ctor280  int y = obj.uninit; // expected-warning {{Assigned value is uninitialized}}281  return x + y;282}283