mirror of https://github.com/microsoft/clang.git
[Sema] Don't crash when friending an unqualified templated constructor
Unqualified templated constructors cannot be friended and our lack of a diagnostic led to violated invariants. Instead, raise a diagnostic when processing the friend declaration. This fixes PR20251. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248953 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cb96b824e6
commit
20061ec162
|
@ -12689,15 +12689,31 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
|
|||
DC = CurContext;
|
||||
assert(isa<CXXRecordDecl>(DC) && "friend declaration not in class?");
|
||||
}
|
||||
|
||||
|
||||
if (!DC->isRecord()) {
|
||||
int DiagArg = -1;
|
||||
switch (D.getName().getKind()) {
|
||||
case UnqualifiedId::IK_ConstructorTemplateId:
|
||||
case UnqualifiedId::IK_ConstructorName:
|
||||
DiagArg = 0;
|
||||
break;
|
||||
case UnqualifiedId::IK_DestructorName:
|
||||
DiagArg = 1;
|
||||
break;
|
||||
case UnqualifiedId::IK_ConversionFunctionId:
|
||||
DiagArg = 2;
|
||||
break;
|
||||
case UnqualifiedId::IK_Identifier:
|
||||
case UnqualifiedId::IK_ImplicitSelfParam:
|
||||
case UnqualifiedId::IK_LiteralOperatorId:
|
||||
case UnqualifiedId::IK_OperatorFunctionId:
|
||||
case UnqualifiedId::IK_TemplateId:
|
||||
break;
|
||||
llvm_unreachable("Didn't expect this kind of unqualified-id!");
|
||||
}
|
||||
// This implies that it has to be an operator or function.
|
||||
if (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ||
|
||||
D.getName().getKind() == UnqualifiedId::IK_DestructorName ||
|
||||
D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) {
|
||||
Diag(Loc, diag::err_introducing_special_friend) <<
|
||||
(D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
|
||||
D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
|
||||
if (DiagArg >= 0) {
|
||||
Diag(Loc, diag::err_introducing_special_friend) << DiagArg;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,3 +79,9 @@ class PreDeclared;
|
|||
int myoperation(float f) {
|
||||
return (int) f;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class B {
|
||||
template <typename U>
|
||||
friend B<U>() {} // expected-error {{must use a qualified name when declaring a constructor as a friend}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue