[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