================
@@ -0,0 +1,131 @@
+// RUN: %clang_analyze_cc1
-analyzer-checker=alpha.cplusplus.LifetimeAnnotations \
+// RUN: -verify %s
+// RUN: %clang_analyze_cc1
-analyzer-checker=alpha.cplusplus.LifetimeAnnotations \
+// RUN: -analyzer-config c++-container-inlining=false -verify %s
+
+struct A {};
+
+void clang_analyzer_lifetime_bound(int*);
+void clang_analyzer_lifetime_bound(int&);
+void clang_analyzer_lifetime_bound(A*);
+void clang_analyzer_lifetime_bound(A&);
+
+// These are the cases when the result of function calls are MemRegions.
+
+// Ref type parameter annotated case
+struct X {
+ int& choose(int& a [[clang::lifetimebound]]) { return a; }
+};
+
+void caller() {
+ int v = 0;
+ X obj;
+ int& r = obj.choose(v);
+ clang_analyzer_lifetime_bound(r); // expected-warning {{bound to v}}
+}
+
+// Obj ref type function return annotated case
+struct Y {
+ A a;
+ A& getA() [[clang::lifetimebound]] { return a; }
+};
+
+void caller_two() {
+ // Return statement is annotated case.
+ Y y;
+ A& f = y.getA();
+ clang_analyzer_lifetime_bound(f); // expected-warning {{bound to y}}
+}
+
+// Obj ptr type function return annotated case
+struct Z {
+ A a;
+ A* getA() [[clang::lifetimebound]] { return &a; }
+};
+
+void caller_three() {
+ Z z;
+ A* func = z.getA();
+ clang_analyzer_lifetime_bound(func); // expected-warning {{bound to z}}
+}
+
+// Free function with annotated param and ref return
+int& foo(int& num [[clang::lifetimebound]]) { return num; }
+
+void caller_four() {
+ int num = 5;
+ int& s = foo(num);
+ clang_analyzer_lifetime_bound(s); // expected-warning {{bound to num}}
+}
+
+// Free function with annotated param and ptr return
+int* boo(int* num [[clang::lifetimebound]]) { return num; }
+
+void caller_five() {
+ int n = 55;
+ int* n_ptr = &n;
+ int* s = boo(n_ptr);
+
+ clang_analyzer_lifetime_bound(s); // expected-warning {{bound to n}}
+}
+
+// Free function with both annotated and non-annotated parameters.
+int& fn(int& f, int& s [[clang::lifetimebound]]) { return s; }
+
+void caller_six() {
+ int even = 50;
+ int odd = 55;
+ int& s = fn(even, odd);
+
+ clang_analyzer_lifetime_bound(s); // expected-warning {{bound to odd}}
+}
+
+
+
+// These are the cases when the result of function calls are SymbolRefs.
+
+// Function returns ptr and has an annotated parameter
+int* foo(int* n [[clang::lifetimebound]]);
+
+void caller_seven() {
+ int y = 15;
+ int* y_ptr = &y;
+ auto* bind = foo(y_ptr);
+
+ clang_analyzer_lifetime_bound(bind); // expected-warning {{bound to y}}
+ // expected-warning@-1 {{contains loan
y}}
+// FIXME: The full warning does look like this:
+// Origin SymRegion{conj_$5{int *, LC1, S847, #1}} bound to n
+// Origin conj_$5{int *, LC1, S847, #1} contains loan n
+// Since the conj sym number and the ID can change across runs I have decided
to just include
+// string parts of the error message since that is the only consistent part of
the emitted report.
+// This does not apply to the test cases above this test case.
+}
+
+// Function returns a reference and has an annotated parameter
+int& func(int& some_number [[clang::lifetimebound]]);
+
+void caller_eight() {
+ int f = 15;
+ auto& bind = func(f);
+
+ clang_analyzer_lifetime_bound(bind); // expected-warning {{bound to f}}
+ // expected-warning@-1 {{contains loan
f}}
----------------
steakhal wrote:
Usually, it formats much nicer if you would:
```suggestion
clang_analyzer_lifetime_bound(bind);
// expected-warning@-1 {{bound to f}}
// expected-warning@-2 {{contains loan f}}
```
https://github.com/llvm/llvm-project/pull/200145
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits