[clang] 8179829 - [clang][bytecode] Check method accessibility in `GetMemberPtrDecl` (#194560)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 04:29:55 PDT 2026
Author: Timm Baeder
Date: 2026-04-28T13:29:50+02:00
New Revision: 81798298624a61952a2428fc6036794fb2ffb913
URL: https://github.com/llvm/llvm-project/commit/81798298624a61952a2428fc6036794fb2ffb913
DIFF: https://github.com/llvm/llvm-project/commit/81798298624a61952a2428fc6036794fb2ffb913.diff
LOG: [clang][bytecode] Check method accessibility in `GetMemberPtrDecl` (#194560)
The decl saved in the `MemberPointer` needs to be accessible from its
Base.
Added:
Modified:
clang/lib/AST/ByteCode/Interp.cpp
clang/lib/AST/ByteCode/Interp.h
clang/lib/AST/ByteCode/MemberPointer.h
clang/test/AST/ByteCode/cxx11.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index cb51eb409e655..983cd391e202a 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2680,6 +2680,46 @@ bool CastMemberPtrDerivedPop(InterpState &S, CodePtr OpPC, int32_t Off,
return castBackMemberPointer(S, Ptr, Off, BaseDecl);
}
+bool GetMemberPtr(InterpState &S, CodePtr OpPC, const ValueDecl *D) {
+ S.Stk.push<MemberPointer>(D);
+ return true;
+}
+
+bool GetMemberPtrBase(InterpState &S, CodePtr OpPC) {
+ const auto &MP = S.Stk.pop<MemberPointer>();
+
+ if (!MP.isBaseCastPossible())
+ return false;
+
+ S.Stk.push<Pointer>(MP.getBase());
+ return true;
+}
+
+bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) {
+ const auto &MP = S.Stk.pop<MemberPointer>();
+
+ const ValueDecl *D = MP.getDecl();
+ const auto *FD = dyn_cast_if_present<FunctionDecl>(D);
+ if (!FD)
+ return false;
+
+ const auto *Method = dyn_cast<CXXMethodDecl>(FD);
+ if (!Method)
+ return false;
+
+ const Pointer &Base = MP.getBase();
+ // The method must be accessible via the base of the MemberPointer.
+ const CXXRecordDecl *MethodParent = Method->getParent();
+ if (!Base.getRecord() || Base.getRecord()->getDecl() != MethodParent)
+ return false;
+
+ const auto *Func = S.getContext().getOrCreateFunction(FD);
+ if (!Func)
+ return false;
+ S.Stk.push<Pointer>(Func);
+ return true;
+}
+
// FIXME: Would be nice to generate this instead of hardcoding it here.
constexpr bool OpReturns(Opcode Op) {
return Op == OP_RetVoid || Op == OP_RetValue || Op == OP_NoRet ||
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 0f1c81fe300e6..00ed86c4618dd 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3503,30 +3503,9 @@ inline bool GetIntPtr(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
return true;
}
-inline bool GetMemberPtr(InterpState &S, CodePtr OpPC, const ValueDecl *D) {
- S.Stk.push<MemberPointer>(D);
- return true;
-}
-
-inline bool GetMemberPtrBase(InterpState &S, CodePtr OpPC) {
- const auto &MP = S.Stk.pop<MemberPointer>();
-
- if (!MP.isBaseCastPossible())
- return false;
-
- S.Stk.push<Pointer>(MP.getBase());
- return true;
-}
-
-inline bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) {
- const auto &MP = S.Stk.pop<MemberPointer>();
-
- const auto *FD = cast<FunctionDecl>(MP.getDecl());
- const auto *Func = S.getContext().getOrCreateFunction(FD);
-
- S.Stk.push<Pointer>(Func);
- return true;
-}
+bool GetMemberPtr(InterpState &S, CodePtr OpPC, const ValueDecl *D);
+bool GetMemberPtrBase(InterpState &S, CodePtr OpPC);
+bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC);
/// Just emit a diagnostic. The expression that caused emission of this
/// op is not valid in a constant context.
diff --git a/clang/lib/AST/ByteCode/MemberPointer.h b/clang/lib/AST/ByteCode/MemberPointer.h
index 7bef2accd39e5..e5079653ffdcf 100644
--- a/clang/lib/AST/ByteCode/MemberPointer.h
+++ b/clang/lib/AST/ByteCode/MemberPointer.h
@@ -147,7 +147,8 @@ class MemberPointer final {
MemberPointer takeInstance(Pointer Instance) const {
assert(this->Base.isZero());
return MemberPointer(Instance, DeclAndIsDerivedMember.getPointer(),
- this->PtrOffset);
+ this->PtrOffset, PathLength, Path,
+ DeclAndIsDerivedMember.getInt());
}
APValue toAPValue(const ASTContext &) const;
diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp
index a4c4be14775b3..3acfe50627713 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -377,13 +377,13 @@ namespace GH150709 {
static_assert((c1.*mp)() == 1, ""); // both-error {{constant expression}}
static_assert((d1.*mp)() == 1, "");
static_assert((f.*mp)() == 1, "");
- static_assert((c2[0].*mp)() == 1, ""); // ref-error {{constant expression}}
+ static_assert((c2[0].*mp)() == 1, ""); // both-error {{constant expression}}
static_assert((d2[0].*mp)() == 1, "");
// incorrectly undiagnosed before fix of GH150709
- static_assert((e1.*mp)() == 1, ""); // ref-error {{constant expression}}
- static_assert((e2[0].*mp)() == 1, ""); // ref-error {{constant expression}}
- static_assert((g.*mp)() == 1, ""); // ref-error {{constant expression}}
+ static_assert((e1.*mp)() == 1, ""); // both-error {{constant expression}}
+ static_assert((e2[0].*mp)() == 1, ""); // both-error {{constant expression}}
+ static_assert((g.*mp)() == 1, ""); // both-error {{constant expression}}
}
namespace DiscardedAddrLabel {
More information about the cfe-commits
mailing list