================
@@ -642,6 +646,48 @@ 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`), but only when that access reaches through value
+// semantics: mutating `a.b` mutates `a`'s own storage, so we keep chaining.
+// We deliberately stop at a pointer-typed base (e.g. `p->b`, `p[i]`,
+// `p->*pmf`): that only mutates `*p`, never `p`'s own binding, so chaining
+// through it would incorrectly require `p` to stay non-const. For the same
+// reason, a dereference (`*p = 1`) is intentionally not handled at all: it
+// only ever mutates the pointee, never the pointer itself.
+//
+// A genuine array subscript (`arr[i]` where `arr` is an array, not a
+// pointer) also stops here: the base is always wrapped in an
+// ArrayToPointerDecay cast, indistinguishable at this point from
+// subscripting a real pointer. That's fine because createParameters()
+// never makes an array-typed capture const in the first place, regardless
+// of what we compute here.
+//
+// Returns null if E isn't ultimately grounded in a variable this way (e.g.
+// it's a temporary, a call result, or reached through a pointer).
+const Decl *underlyingDecl(const Expr *E) {
+ if (!E)
+ return nullptr;
+ E = E->IgnoreParenCasts();
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+ return DRE->getDecl();
+ if (const auto *ME = dyn_cast<MemberExpr>(E)) {
+ if (ME->getBase()->getType()->isPointerType())
+ return nullptr;
+ return underlyingDecl(ME->getBase());
+ }
+ if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
+ if (ASE->getBase()->getType()->isPointerType())
+ return nullptr;
+ return underlyingDecl(ASE->getBase());
+ }
+ if (const auto *BO = dyn_cast<BinaryOperator>(E))
+ if ((BO->getOpcode() == BO_PtrMemD || BO->getOpcode() == BO_PtrMemI) &&
+ !BO->getLHS()->getType()->isPointerType())
----------------
ArcsinX wrote:
`BO_PtrMemI` is `Pointer-to-member` operator, so if `BO->getOpcode() ==
BO_PtrMemI` then `BO->getLHS()->getType()->isPointerType()` is always true.
Maybe we can remove `BO->getOpcode() == BO_PtrMemI` check?
https://github.com/llvm/llvm-project/pull/225666
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits