aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-04-25 11:23:34 +0200
committerGitHub <noreply@github.com>2025-04-25 11:23:34 +0200
commit211b51e4713d814d6fa894f4fc309a364c5642ce (patch)
treec45da24e48f2aa59235f8b30bd280e2e999dd8f0 /clang/lib/AST/ByteCode/Interp.cpp
parent5a645109c3a965dcaab08e3485f2fa505e44cde3 (diff)
downloadllvm-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.cpp23
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();
}