[clang] [clang][bytecode] Reject invalid opaque pointer base conversions (PR #231366)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 12 21:54:48 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
We can't reject them as they happen because that needs to work for other tests. So reject them when computing the layout offset.
---
Full diff: https://github.com/llvm/llvm-project/pull/231366.diff
3 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.h (+1-1)
- (modified) clang/lib/AST/ByteCode/Pointer.cpp (+8-6)
- (modified) clang/test/AST/ByteCode/invalid.cpp (+9)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index ea115b6fef7e3..73f2d415cf56e 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1343,7 +1343,7 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
std::optional<size_t> A = LHS.computeOffsetForComparison(S.getASTContext());
std::optional<size_t> B = RHS.computeOffsetForComparison(S.getASTContext());
if (!A || !B)
- return Invalid(S, OpPC);
+ return false;
S.Stk.push<BoolT>(BoolT::from(Fn(Compare(*A, *B))));
return true;
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 6ea2cae2a02ca..839a0929d1852 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -1415,19 +1415,21 @@ OpaquePointer::computeLayoutOffset(const ASTContext &ASTCtx) const {
for (const PointerPathEntry &Entry : path()) {
switch (Entry.Kind) {
case PointerPathEntry::Base: {
- const RecordDecl *RD = CurType->getAsRecordDecl();
+ const CXXRecordDecl *RD = CurType->getAsCXXRecordDecl();
if (!ASTContext::hasLayout(RD))
return std::nullopt;
+ const CXXRecordDecl *BaseDecl = Entry.RD.getPointer();
+ if (!RD->isDerivedFrom(BaseDecl))
+ return std::nullopt;
+
const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
if (Entry.RD.getInt())
- Offset +=
- Layout.getVBaseClassOffset(Entry.RD.getPointer()).getQuantity();
+ Offset += Layout.getVBaseClassOffset(BaseDecl).getQuantity();
else
- Offset +=
- Layout.getBaseClassOffset(Entry.RD.getPointer()).getQuantity();
+ Offset += Layout.getBaseClassOffset(BaseDecl).getQuantity();
- CurType = ASTCtx.getCanonicalTagType(Entry.RD.getPointer());
+ CurType = ASTCtx.getCanonicalTagType(BaseDecl);
} break;
case PointerPathEntry::Field: {
diff --git a/clang/test/AST/ByteCode/invalid.cpp b/clang/test/AST/ByteCode/invalid.cpp
index a160c29169bc5..784fd95baf1dd 100644
--- a/clang/test/AST/ByteCode/invalid.cpp
+++ b/clang/test/AST/ByteCode/invalid.cpp
@@ -338,3 +338,12 @@ namespace PointerIntoInvalidRecord {
} u;
template int *foo<&u.baz>; // both-error {{non-type template argument is not a constant expression}}
}
+
+namespace OpaquePtrPtrCast {
+ struct X {};
+ struct Y : X {};
+
+ constexpr struct Z {} z;
+ static_assert((X *)(Y *)&z != (X *)(Y *)&z, ""); // both-error {{not an integral constant expression}} \
+ // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/231366
More information about the cfe-commits
mailing list