================
@@ -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

Reply via email to