brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 44990fc Raw
148 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s \2// RUN:   2>&1 | FileCheck %s3 4 5void clang_analyzer_printState();6template <typename T> void clang_analyzer_dump_lref(T& param);7template <typename T> void clang_analyzer_dump_val(T param);8template <typename T> T conjure();9template <typename... Ts> void nop(const Ts &... args) {}10 11struct aggr {12  int x;13  int y;14};15 16struct empty {17};18 19void test_copy_return() {20  aggr s1 = {1, 2};21  aggr const& cr1 = aggr(s1);22  clang_analyzer_dump_lref(cr1); // expected-warning-re {{&lifetime_extended_object{aggr, cr1, S{{[0-9]+}}} }}23 24  empty s2;25  empty const& cr2 = empty{s2};26  clang_analyzer_dump_lref(cr2); // expected-warning-re {{&lifetime_extended_object{empty, cr2, S{{[0-9]+}}} }}27}28 29void test_assign_return() {30  aggr s1 = {1, 2};31  aggr d1;32  clang_analyzer_dump_lref(d1 = s1); // expected-warning {{&d1 }}33 34  empty s2;35  empty d2;36  clang_analyzer_dump_lref(d2 = s2); // expected-warning {{&d2 }} was Unknown37}38 39 40namespace trivial_struct_copy {41 42void _01_empty_structs() {43  clang_analyzer_dump_val(conjure<empty>()); // expected-warning {{lazyCompoundVal}}44  empty Empty = conjure<empty>();45  empty Empty2 = Empty;46  empty Empty3 = Empty2;47  // All of these should refer to the exact same LCV, because all of48  // these trivial copies refer to the original conjured value.49  // There were Unknown before:50  clang_analyzer_dump_val(Empty);  // expected-warning {{lazyCompoundVal}}51  clang_analyzer_dump_val(Empty2); // expected-warning {{lazyCompoundVal}}52  clang_analyzer_dump_val(Empty3); // expected-warning {{lazyCompoundVal}}53 54  // We only have binding for the original Empty object, because copying empty55  // objects is a no-op in the performTrivialCopy. This is fine, because empty56  // objects don't have any data members that could be accessed anyway.57  clang_analyzer_printState();58  // CHECK:       "store": { "pointer": "0x{{[0-9a-f]+}}", "items": [59  // CHECK-NEXT:    { "cluster": "GlobalInternalSpaceRegion", "pointer": "0x{{[0-9a-f]+}}", "items": [60  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "conj_$61  // CHECK-NEXT:    ]},62  // CHECK-NEXT:    { "cluster": "GlobalSystemSpaceRegion", "pointer": "0x{{[0-9a-f]+}}", "items": [63  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "conj_$64  // CHECK-NEXT:    ]},65  // CHECK-NEXT:    { "cluster": "Empty", "pointer": "0x{{[0-9a-f]+}}", "items": [66  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "[[EMPTY_CONJ:conj_\$[0-9]+{int, LC[0-9]+, S[0-9]+, #[0-9]+}]]" }67  // CHECK-NEXT:    ]}68  // CHECK-NEXT:  ]},69 70  nop(Empty, Empty2, Empty3);71}72 73void _02_structs_with_members() {74  clang_analyzer_dump_val(conjure<aggr>()); // expected-warning {{lazyCompoundVal}}75  aggr Aggr = conjure<aggr>();76  aggr Aggr2 = Aggr;77  aggr Aggr3 = Aggr2;78  // All of these should refer to the exact same LCV, because all of79  // these trivial copies refer to the original conjured value.80  clang_analyzer_dump_val(Aggr);  // expected-warning {{lazyCompoundVal}}81  clang_analyzer_dump_val(Aggr2); // expected-warning {{lazyCompoundVal}}82  clang_analyzer_dump_val(Aggr3); // expected-warning {{lazyCompoundVal}}83 84  // We have fields in the struct we copy, thus we also have the entries for the copies85  // (and for all of their fields).86  clang_analyzer_printState();87  // CHECK:       "store": { "pointer": "0x{{[0-9a-f]+}}", "items": [88  // CHECK-NEXT:    { "cluster": "GlobalInternalSpaceRegion", "pointer": "0x{{[0-9a-f]+}}", "items": [89  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "conj_$90  // CHECK-NEXT:    ]},91  // CHECK-NEXT:    { "cluster": "GlobalSystemSpaceRegion", "pointer": "0x{{[0-9a-f]+}}", "items": [92  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "conj_$93  // CHECK-NEXT:    ]},94  // CHECK-NEXT:    { "cluster": "Aggr", "pointer": "0x{{[0-9a-f]+}}", "items": [95  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "[[AGGR_CONJ:conj_\$[0-9]+{int, LC[0-9]+, S[0-9]+, #[0-9]+}]]" }96  // CHECK-NEXT:    ]},97  // CHECK-NEXT:    { "cluster": "Aggr2", "pointer": "0x{{[0-9a-f]+}}", "items": [98  // CHECK-NEXT:      { "kind": "Direct", "offset": 0, "value": "derived_${{[0-9]+}}{[[AGGR_CONJ]],Aggr.x}" },99  // CHECK-NEXT:      { "kind": "Direct", "offset": 32, "value": "derived_${{[0-9]+}}{[[AGGR_CONJ]],Aggr.y}" }100  // CHECK-NEXT:    ]},101  // CHECK-NEXT:    { "cluster": "Aggr3", "pointer": "0x{{[0-9a-f]+}}", "items": [102  // CHECK-NEXT:      { "kind": "Direct", "offset": 0, "value": "derived_${{[0-9]+}}{[[AGGR_CONJ]],Aggr.x}" },103  // CHECK-NEXT:      { "kind": "Direct", "offset": 32, "value": "derived_${{[0-9]+}}{[[AGGR_CONJ]],Aggr.y}" }104  // CHECK-NEXT:    ]}105  // CHECK-NEXT:  ]},106 107  nop(Aggr, Aggr2, Aggr3);108}109 110// Tests that use `clang_analyzer_printState()` must share the analysis entry111// point, and have a strict ordering between. This is to meet the different112// `clang_analyzer_printState()` calls in a fixed relative ordering, thus113// FileCheck could check the stdouts.114void entrypoint() {115  _01_empty_structs();116  _02_structs_with_members();117}118 119} // namespace trivial_struct_copy120 121namespace gh153782 {122 123// Ensure we do not regress on the following use cases.124// The assumption made on a field in `setPtr` should apply to the returned copy in `func`.125struct Status { int error; };126Status getError();127 128Status setPtr(int **outptr, int* ptr) {129  Status e = getError();130  if (e.error != 0) return e; // When assuming the error field is non-zero,131  *outptr = ptr;              // this is not executed132  return e;133}134 135int func() {136  int *ptr = nullptr;137  int x = 42;138  if (setPtr(&ptr, &x).error == 0) {139    // The assumption made in get() SHOULD match the assumption about140    // the returned value, hence the engine SHOULD NOT assume ptr is null.141    clang_analyzer_dump_val(ptr); // expected-warning {{&x}}142    return *ptr;143  }144  return 0;145}146 147} // namespace gh153782148