Correct handling of pointers into anonymous unions.

This commit is contained in:
Dan Katz
2025-06-03 13:59:02 -04:00
parent 7729ff85f9
commit 19eb496954
3 changed files with 28 additions and 3 deletions

View File

@@ -7061,6 +7061,8 @@ def err_illegal_decl_mempointer_to_reference : Error<
"'%0' declared as a member pointer to a reference of type %1">;
def err_illegal_decl_mempointer_to_void : Error<
"'%0' declared as a member pointer to void">;
def err_illegal_decl_mempointer_into_anon_union : Error<
"'%0' declared as a member pointer into an anonymous union">;
def err_illegal_decl_mempointer_in_nonclass
: Error<"%0 does not point into a class">;
def err_reference_to_void : Error<"cannot form a reference to 'void'">;

View File

@@ -3165,9 +3165,23 @@ bool extract(APValue &Result, ASTContext &C, MetaActions &Meta,
return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) << 2
<< DescriptionOf(RV) << Range;
QualType MemPtrTy = C.getMemberPointerType(
Decl->getType(), nullptr,
cast<CXXRecordDecl>(Decl->getDeclContext()));
DeclContext *ObjDC = Decl->getDeclContext();
while (ObjDC &&
[](DeclContext *DC) {
if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
return RD->isAnonymousStructOrUnion();
else return DC->isTransparentContext();
}(ObjDC))
if (isa<TranslationUnitDecl>(ObjDC))
// Can happen if Target was a member of a static anonymous union at
// namespace scope.
return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) << 2
<< "a field that is not a member of a class";
else
ObjDC = ObjDC->getParent();
QualType MemPtrTy = C.getMemberPointerType(Decl->getType(), nullptr,
cast<CXXRecordDecl>(ObjDC));
if (MemPtrTy.getCanonicalType().getTypePtr() !=
ResultTy.getCanonicalType().getTypePtr())
return Diagnoser(Range.getBegin(),

View File

@@ -2718,6 +2718,15 @@ QualType Sema::BuildMemberPointerType(QualType T, const CXXScopeSpec &SS,
}
}
if (Cls && Cls->isAnonymousStructOrUnion()) {
auto D = Diag(Loc, diag::err_illegal_decl_mempointer_into_anon_union);
if (const IdentifierInfo *II = Entity.getAsIdentifierInfo())
D << II;
else
D << "member pointer";
return QualType();
}
// Verify that we're not building a pointer to pointer to function with
// exception specification.
if (CheckDistantExceptionSpec(T)) {