================
@@ -552,6 +608,71 @@ const int& get_ref_to_local() {
// expected-note@-1 {{returned here}}
}
+void test_view_pointer() {
+ View* vp;
+ {
+ View v;
+ vp = &v; // expected-warning {{object whose reference is captured does
not live long enough}}
+ } // expected-note {{destroyed here}}
+ vp->use(); // expected-note {{later used here}}
+}
+
+void test_view_double_pointer() {
+ View** vpp;
+ {
+ View* vp = nullptr;
+ vpp = &vp; // expected-warning {{object whose reference is captured does
not live long enough}}
+ } // expected-note {{destroyed here}}
+ (**vpp).use(); // expected-note {{later used here}}
+}
+
+struct PtrHolder {
+ int* ptr;
+ int* const& getRef() const [[clang::lifetimebound]] { return ptr; }
+};
+
+int* const& test_ref_to_ptr() {
+ PtrHolder a;
+ int *const &ref = a.getRef(); // expected-warning {{address of stack memory
is returned later}}
+ return ref; // expected-note {{returned here}}
+}
+int* const test_ref_to_ptr_no_error() {
+ PtrHolder a;
+ int *const &ref = a.getRef();
+ return ref;
+}
+
+int** return_inner_ptr_addr(int*** ppp [[clang::lifetimebound]]);
+void test_lifetimebound_multi_level() {
+ int** result;
+ {
+ int* p = nullptr;
+ int** pp = &p;
+ int*** ppp = &pp; // expected-warning {{object whose reference is captured
does not live long enough}}
+ result = return_inner_ptr_addr(ppp);
+ } // expected-note {{destroyed here}}
+ (void)**result; // expected-note {{used here}}
+}
+
+// FIXME: Assignment does not track the dereference of a pointer.
+void test_assign_through_double_ptr() {
+ int a = 1, b = 2;
+ int* p = &a;
+ int** pp = &p;
+ {
+ int c = 3;
+ *pp = &c;
+ }
+ (void)**pp;
+}
+
+int** test_ternary_double_ptr(bool cond) {
----------------
usx95 wrote:
None of the above works at this point.
The plan is to handle this using **flow-sensitive alias tracking** (similar to
Polonius in Rust). This should be handled once we start creating aliases among
origins due to cycles in subtype-relations.
### Alias Creation via Multilevel Origins
```cpp
int* pa = &a;
// Opa <- loan to 'a'
int** result = &pa;
// [Or1, Or2] <- [Opa_outer, Opa]
// Or1 <- loan to 'pa' (the storage of pa)
// Or2 <- Opa (what pa points to)
```
The missing piece is creating a **bidirectional alias relationship**: `Or2` and
`Opa` should be treated as aliases/subtype of each other, forming an SCC in the
origin-flow graph. This should for all inner origins at all levels. For
example, here we should have `// Opa <- Or2`flow fact but not for `Or1` and
`Opa_outer`.
(Thinking about the case 3 to not make `Opa` and `Opb` alias of each other. I
think it involves something on the lines of dropping flow facts which involve
dead origins)
https://github.com/llvm/llvm-project/pull/168344
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits