Correct handling of pointers into anonymous unions.
This commit is contained in:
@@ -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'">;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user