diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-04-25 11:23:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-25 11:23:34 +0200 |
commit | 211b51e4713d814d6fa894f4fc309a364c5642ce (patch) | |
tree | c45da24e48f2aa59235f8b30bd280e2e999dd8f0 /clang/lib/AST/ByteCode/Interp.cpp | |
parent | 5a645109c3a965dcaab08e3485f2fa505e44cde3 (diff) | |
download | llvm-211b51e4713d814d6fa894f4fc309a364c5642ce.zip llvm-211b51e4713d814d6fa894f4fc309a364c5642ce.tar.gz llvm-211b51e4713d814d6fa894f4fc309a364c5642ce.tar.bz2 |
[clang][bytecode] Propagate IsVolatile bit to subobjects (#137293)
For
```c++
struct S {
constexpr S(int=0) : i(1) {}
int i;
};
constexpr volatile S vs;
```
reading from `vs.i` is not allowed, even though `i` is not volatile
qualified. Propagate the IsVolatile bit down the hierarchy, so we know
reading from `vs.i` is a volatile read.
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.cpp | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 9d7cea0..0cb6d87 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -634,32 +634,35 @@ static bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { assert(Ptr.isLive()); - // FIXME: This check here might be kinda expensive. Maybe it would be better - // to have another field in InlineDescriptor for this? - if (!Ptr.isBlockPointer()) - return true; - - QualType PtrType = Ptr.getType(); - if (!PtrType.isVolatileQualified()) + if (!Ptr.isVolatile()) return true; if (!S.getLangOpts().CPlusPlus) return Invalid(S, OpPC); + // The reason why Ptr is volatile might be further up the hierarchy. + // Find that pointer. + Pointer P = Ptr; + while (!P.isRoot()) { + if (P.getType().isVolatileQualified()) + break; + P = P.getBase(); + } + const NamedDecl *ND = nullptr; int DiagKind; SourceLocation Loc; - if (const auto *F = Ptr.getField()) { + if (const auto *F = P.getField()) { DiagKind = 2; Loc = F->getLocation(); ND = F; - } else if (auto *VD = Ptr.getFieldDesc()->asValueDecl()) { + } else if (auto *VD = P.getFieldDesc()->asValueDecl()) { DiagKind = 1; Loc = VD->getLocation(); ND = VD; } else { DiagKind = 0; - if (const auto *E = Ptr.getFieldDesc()->asExpr()) + if (const auto *E = P.getFieldDesc()->asExpr()) Loc = E->getExprLoc(); } |