[clang] [clang][bytecode] Reject invalid opaque pointer base conversions (PR #231366)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 12 21:54:09 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/231366
We can't reject them as they happen because that needs to work for other tests. So reject them when computing the layout offset.
>From 134538783d7492bd20a0d82b34ecfdd3f68ff852 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 13 Oct 2026 06:48:29 +0200
Subject: [PATCH] asdf
---
clang/lib/AST/ByteCode/Interp.h | 2 +-
clang/lib/AST/ByteCode/Pointer.cpp | 14 ++++++++------
clang/test/AST/ByteCode/invalid.cpp | 9 +++++++++
3 files changed, 18 insertions(+), 7 deletions(-)
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}}
+}
More information about the cfe-commits
mailing list