================
@@ -642,6 +645,30 @@ bool isLoop(const Stmt *S) {
          isa<CXXForRangeStmt>(S);
 }
 
+// Strips E down to the Decl whose storage it ultimately refers to, chaining
+// through parens, casts, and member/array-element access (e.g. `a.b[i]`
+// resolves to `a`). Mutating any part of such a chain requires the base
+// Decl itself to be non-const if the chain is through value members/
+// elements (e.g. `a.b = 1` mutates `a`'s own storage); for a chain through a
+// pointer or reference, the base Decl's own binding usually isn't actually
+// touched (e.g. `p->b = 1` only mutates `*p`, not `p` itself), but treating
+// it as if it were is conservative and safe, just occasionally overcautious.
+// Returns null if E isn't ultimately grounded in a variable this way (e.g.
+// it's a temporary or a call result).
+const Decl *underlyingDecl(const Expr *E) {
+  E = E->IgnoreParenCasts();
----------------
ArcsinX wrote:

Do we need to check `E` for nullptr?

https://github.com/llvm/llvm-project/pull/225666
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to