forked from OSchip/llvm-project
PR10217: Provide diagnostics explaining why an implicitly-deleted special
member function is deleted. llvm-svn: 153773
This commit is contained in:
parent
066aba5fe9
commit
852265ff1c
|
@ -2821,6 +2821,37 @@ def warn_cxx98_compat_friend_redefinition : Warning<
|
||||||
"friend function %0 would be implicitly redefined in C++98">,
|
"friend function %0 would be implicitly redefined in C++98">,
|
||||||
InGroup<CXX98Compat>, DefaultIgnore;
|
InGroup<CXX98Compat>, DefaultIgnore;
|
||||||
|
|
||||||
|
def note_deleted_dtor_no_operator_delete : Note<
|
||||||
|
"virtual destructor requires an unambiguous, accessible 'operator delete'">;
|
||||||
|
def note_deleted_special_member_class_subobject : Note<
|
||||||
|
"%select{default constructor|copy constructor|move constructor|"
|
||||||
|
"copy assignment operator|move assignment operator|destructor}0 of "
|
||||||
|
"%select{||||union }4%1 is implicitly deleted because "
|
||||||
|
"%select{base class %3|field %3}2 has "
|
||||||
|
"%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 "
|
||||||
|
"%select{%select{default constructor|copy constructor|move constructor|copy "
|
||||||
|
"assignment operator|move assignment operator|destructor}0|destructor}5"
|
||||||
|
"%select{||s||}4">;
|
||||||
|
def note_deleted_default_ctor_uninit_field : Note<
|
||||||
|
"default constructor of %0 is implicitly deleted because field %1 of "
|
||||||
|
"%select{reference|const-qualified}3 type %2 would not be initialized">;
|
||||||
|
def note_deleted_default_ctor_all_const : Note<
|
||||||
|
"default constructor of %0 is implicitly deleted because all "
|
||||||
|
"%select{data members|data members of an anonymous union member}1"
|
||||||
|
" are const-qualified">;
|
||||||
|
def note_deleted_copy_ctor_rvalue_reference : Note<
|
||||||
|
"copy constructor of %0 is implicitly deleted because field %1 is of "
|
||||||
|
"rvalue reference type %2">;
|
||||||
|
def note_deleted_copy_user_declared_move : Note<
|
||||||
|
"copy %select{constructor|assignment operator}0 is implicitly deleted because"
|
||||||
|
" %1 has a user-declared move %select{constructor|assignment operator}2">;
|
||||||
|
def note_deleted_assign_field : Note<
|
||||||
|
"%select{copy|move}0 assignment operator of %0 is implicitly deleted "
|
||||||
|
"because field %1 is of %select{reference|const-qualified}3 type %2">;
|
||||||
|
def note_deleted_move_assign_virtual_base : Note<
|
||||||
|
"move assignment operator of %0 is implicitly deleted because it has a "
|
||||||
|
"virtual base class %1">;
|
||||||
|
|
||||||
// This should eventually be an error.
|
// This should eventually be an error.
|
||||||
def warn_undefined_internal : Warning<
|
def warn_undefined_internal : Warning<
|
||||||
"%select{function|variable}0 %q1 has internal linkage but is not defined">,
|
"%select{function|variable}0 %q1 has internal linkage but is not defined">,
|
||||||
|
|
|
@ -660,7 +660,17 @@ public:
|
||||||
/// This is used for determining parameter types of other objects and is
|
/// This is used for determining parameter types of other objects and is
|
||||||
/// utterly meaningless on other types of special members.
|
/// utterly meaningless on other types of special members.
|
||||||
class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
|
class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
|
||||||
|
public:
|
||||||
|
enum Kind {
|
||||||
|
NoMemberOrDeleted,
|
||||||
|
Ambiguous,
|
||||||
|
SuccessNonConst,
|
||||||
|
SuccessConst
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
|
llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
|
SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
|
||||||
: FastFoldingSetNode(ID)
|
: FastFoldingSetNode(ID)
|
||||||
|
@ -669,15 +679,11 @@ public:
|
||||||
CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
|
CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
|
||||||
void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
|
void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
|
||||||
|
|
||||||
bool hasSuccess() const { return Pair.getInt() & 0x1; }
|
Kind getKind() const { return static_cast<Kind>(Pair.getInt()); }
|
||||||
void setSuccess(bool B) {
|
void setKind(Kind K) { Pair.setInt(K); }
|
||||||
Pair.setInt(unsigned(B) | hasConstParamMatch() << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasConstParamMatch() const { return Pair.getInt() & 0x2; }
|
bool hasSuccess() const { return getKind() >= SuccessNonConst; }
|
||||||
void setConstParamMatch(bool B) {
|
bool hasConstParamMatch() const { return getKind() == SuccessConst; }
|
||||||
Pair.setInt(B << 1 | unsigned(hasSuccess()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A cache of special member function overload resolution results
|
/// \brief A cache of special member function overload resolution results
|
||||||
|
@ -2421,6 +2427,7 @@ public:
|
||||||
bool CanUseDecl(NamedDecl *D);
|
bool CanUseDecl(NamedDecl *D);
|
||||||
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
|
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
|
||||||
const ObjCInterfaceDecl *UnknownObjCClass=0);
|
const ObjCInterfaceDecl *UnknownObjCClass=0);
|
||||||
|
void NoteDeletedFunction(FunctionDecl *FD);
|
||||||
std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
|
std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
|
||||||
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
|
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
|
||||||
ObjCMethodDecl *Getter,
|
ObjCMethodDecl *Getter,
|
||||||
|
@ -3127,7 +3134,8 @@ public:
|
||||||
|
|
||||||
/// \brief Determine if a special member function should have a deleted
|
/// \brief Determine if a special member function should have a deleted
|
||||||
/// definition when it is defaulted.
|
/// definition when it is defaulted.
|
||||||
bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM);
|
bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
|
||||||
|
bool Diagnose = false);
|
||||||
|
|
||||||
/// \brief Declare the implicit default constructor for the given class.
|
/// \brief Declare the implicit default constructor for the given class.
|
||||||
///
|
///
|
||||||
|
|
|
@ -4333,6 +4333,7 @@ struct SpecialMemberDeletionInfo {
|
||||||
Sema &S;
|
Sema &S;
|
||||||
CXXMethodDecl *MD;
|
CXXMethodDecl *MD;
|
||||||
Sema::CXXSpecialMember CSM;
|
Sema::CXXSpecialMember CSM;
|
||||||
|
bool Diagnose;
|
||||||
|
|
||||||
// Properties of the special member, computed for convenience.
|
// Properties of the special member, computed for convenience.
|
||||||
bool IsConstructor, IsAssignment, IsMove, ConstArg, VolatileArg;
|
bool IsConstructor, IsAssignment, IsMove, ConstArg, VolatileArg;
|
||||||
|
@ -4341,8 +4342,8 @@ struct SpecialMemberDeletionInfo {
|
||||||
bool AllFieldsAreConst;
|
bool AllFieldsAreConst;
|
||||||
|
|
||||||
SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
|
SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
|
||||||
Sema::CXXSpecialMember CSM)
|
Sema::CXXSpecialMember CSM, bool Diagnose)
|
||||||
: S(S), MD(MD), CSM(CSM),
|
: S(S), MD(MD), CSM(CSM), Diagnose(Diagnose),
|
||||||
IsConstructor(false), IsAssignment(false), IsMove(false),
|
IsConstructor(false), IsAssignment(false), IsMove(false),
|
||||||
ConstArg(false), VolatileArg(false), Loc(MD->getLocation()),
|
ConstArg(false), VolatileArg(false), Loc(MD->getLocation()),
|
||||||
AllFieldsAreConst(true) {
|
AllFieldsAreConst(true) {
|
||||||
|
@ -4385,35 +4386,76 @@ struct SpecialMemberDeletionInfo {
|
||||||
TQ & Qualifiers::Volatile);
|
TQ & Qualifiers::Volatile);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldDeleteForClassSubobject(CXXRecordDecl *Class, FieldDecl *Field);
|
typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject;
|
||||||
|
|
||||||
bool shouldDeleteForBase(CXXRecordDecl *BaseDecl, bool IsVirtualBase);
|
bool shouldDeleteForBase(CXXBaseSpecifier *Base);
|
||||||
bool shouldDeleteForField(FieldDecl *FD);
|
bool shouldDeleteForField(FieldDecl *FD);
|
||||||
bool shouldDeleteForAllConstMembers();
|
bool shouldDeleteForAllConstMembers();
|
||||||
|
|
||||||
|
bool shouldDeleteForClassSubobject(CXXRecordDecl *Class, Subobject Subobj);
|
||||||
|
bool shouldDeleteForSubobjectCall(Subobject Subobj,
|
||||||
|
Sema::SpecialMemberOverloadResult *SMOR,
|
||||||
|
bool IsDtorCallInCtor);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether we should delete a special member due to the implicit
|
||||||
|
/// definition containing a call to a special member of a subobject.
|
||||||
|
bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
|
||||||
|
Subobject Subobj, Sema::SpecialMemberOverloadResult *SMOR,
|
||||||
|
bool IsDtorCallInCtor) {
|
||||||
|
CXXMethodDecl *Decl = SMOR->getMethod();
|
||||||
|
FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
|
||||||
|
|
||||||
|
int DiagKind = -1;
|
||||||
|
|
||||||
|
if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
|
||||||
|
DiagKind = !Decl ? 0 : 1;
|
||||||
|
else if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
|
||||||
|
DiagKind = 2;
|
||||||
|
else if (S.CheckDirectMemberAccess(Loc, Decl, S.PDiag())
|
||||||
|
!= Sema::AR_accessible)
|
||||||
|
DiagKind = 3;
|
||||||
|
else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() &&
|
||||||
|
!Decl->isTrivial()) {
|
||||||
|
// A member of a union must have a trivial corresponding special member.
|
||||||
|
// As a weird special case, a destructor call from a union's constructor
|
||||||
|
// must be accessible and non-deleted, but need not be trivial. Such a
|
||||||
|
// destructor is never actually called, but is semantically checked as
|
||||||
|
// if it were.
|
||||||
|
DiagKind = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DiagKind == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Diagnose) {
|
||||||
|
if (Field) {
|
||||||
|
S.Diag(Field->getLocation(),
|
||||||
|
diag::note_deleted_special_member_class_subobject)
|
||||||
|
<< CSM << MD->getParent() << /*IsField*/true
|
||||||
|
<< Field << DiagKind << IsDtorCallInCtor;
|
||||||
|
} else {
|
||||||
|
CXXBaseSpecifier *Base = Subobj.get<CXXBaseSpecifier*>();
|
||||||
|
S.Diag(Base->getLocStart(),
|
||||||
|
diag::note_deleted_special_member_class_subobject)
|
||||||
|
<< CSM << MD->getParent() << /*IsField*/false
|
||||||
|
<< Base->getType() << DiagKind << IsDtorCallInCtor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DiagKind == 1)
|
||||||
|
S.NoteDeletedFunction(Decl);
|
||||||
|
// FIXME: Explain inaccessibility if DiagKind == 3.
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Check whether we should delete a special member function due to having a
|
/// Check whether we should delete a special member function due to having a
|
||||||
/// direct or virtual base class or static data member of class type M.
|
/// direct or virtual base class or static data member of class type M.
|
||||||
bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
|
bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
|
||||||
CXXRecordDecl *Class, FieldDecl *Field) {
|
CXXRecordDecl *Class, Subobject Subobj) {
|
||||||
// C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5:
|
FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
|
||||||
// -- any direct or virtual base class [...] has a type with a destructor
|
|
||||||
// that is deleted or inaccessible
|
|
||||||
if (!IsAssignment) {
|
|
||||||
CXXDestructorDecl *Dtor = S.LookupDestructor(Class);
|
|
||||||
if (Dtor->isDeleted())
|
|
||||||
return true;
|
|
||||||
if (S.CheckDestructorAccess(Loc, Dtor, S.PDiag()) != Sema::AR_accessible)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// C++11 [class.dtor]p5:
|
|
||||||
// -- X is a union-like class that has a variant member with a non-trivial
|
|
||||||
// destructor
|
|
||||||
if (CSM == Sema::CXXDestructor && Field && Field->getParent()->isUnion() &&
|
|
||||||
!Dtor->isTrivial())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// C++11 [class.ctor]p5:
|
// C++11 [class.ctor]p5:
|
||||||
// -- any direct or virtual base class, or non-static data member with no
|
// -- any direct or virtual base class, or non-static data member with no
|
||||||
|
@ -4426,58 +4468,62 @@ bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
|
||||||
// overload resolution, as applied to B's corresponding special member,
|
// overload resolution, as applied to B's corresponding special member,
|
||||||
// results in an ambiguity or a function that is deleted or inaccessible
|
// results in an ambiguity or a function that is deleted or inaccessible
|
||||||
// from the defaulted special member
|
// from the defaulted special member
|
||||||
if (CSM != Sema::CXXDestructor &&
|
// C++11 [class.dtor]p5:
|
||||||
!(CSM == Sema::CXXDefaultConstructor &&
|
// -- any direct or virtual base class [...] has a type with a destructor
|
||||||
|
// that is deleted or inaccessible
|
||||||
|
if (!(CSM == Sema::CXXDefaultConstructor &&
|
||||||
Field && Field->hasInClassInitializer())) {
|
Field && Field->hasInClassInitializer())) {
|
||||||
Sema::SpecialMemberOverloadResult *SMOR = lookupIn(Class);
|
Sema::SpecialMemberOverloadResult *SMOR = lookupIn(Class);
|
||||||
if (!SMOR->hasSuccess())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
CXXMethodDecl *Member = SMOR->getMethod();
|
CXXMethodDecl *Member = SMOR->getMethod();
|
||||||
// A member of a union must have a trivial corresponding special member.
|
if (shouldDeleteForSubobjectCall(Subobj, SMOR, false))
|
||||||
if (Field && Field->getParent()->isUnion() && !Member->isTrivial())
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (IsConstructor) {
|
// FIXME: CWG 1402 moves these bullets elsewhere.
|
||||||
|
if (CSM == Sema::CXXMoveConstructor) {
|
||||||
CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(Member);
|
CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(Member);
|
||||||
if (S.CheckConstructorAccess(Loc, Ctor, Ctor->getAccess(), S.PDiag())
|
|
||||||
!= Sema::AR_accessible)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// -- for the move constructor, a [...] direct or virtual base class with
|
// -- for the move constructor, a [...] direct or virtual base class with
|
||||||
// a type that does not have a move constructor and is not trivially
|
// a type that does not have a move constructor and is not trivially
|
||||||
// copyable.
|
// copyable.
|
||||||
if (IsMove && !Ctor->isMoveConstructor() && !Class->isTriviallyCopyable())
|
if (!Ctor->isMoveConstructor() && !Class->isTriviallyCopyable())
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else if (CSM == Sema::CXXMoveAssignment) {
|
||||||
assert(IsAssignment && "unexpected kind of special member");
|
|
||||||
if (S.CheckDirectMemberAccess(Loc, Member, S.PDiag())
|
|
||||||
!= Sema::AR_accessible)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// -- for the move assignment operator, a direct base class with a type
|
// -- for the move assignment operator, a direct base class with a type
|
||||||
// that does not have a move assignment operator and is not trivially
|
// that does not have a move assignment operator and is not trivially
|
||||||
// copyable.
|
// copyable.
|
||||||
if (IsMove && !Member->isMoveAssignmentOperator() &&
|
if (!Member->isMoveAssignmentOperator() && !Class->isTriviallyCopyable())
|
||||||
!Class->isTriviallyCopyable())
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// C++11 [class.ctor]p5, C++11 [class.copy]p11:
|
||||||
|
// -- any direct or virtual base class or non-static data member has a
|
||||||
|
// type with a destructor that is deleted or inaccessible
|
||||||
|
if (IsConstructor) {
|
||||||
|
Sema::SpecialMemberOverloadResult *SMOR =
|
||||||
|
S.LookupSpecialMember(Class, Sema::CXXDestructor,
|
||||||
|
false, false, false, false, false);
|
||||||
|
if (shouldDeleteForSubobjectCall(Subobj, SMOR, true))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether we should delete a special member function due to the class
|
/// Check whether we should delete a special member function due to the class
|
||||||
/// having a particular direct or virtual base class.
|
/// having a particular direct or virtual base class.
|
||||||
bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXRecordDecl *BaseDecl,
|
bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) {
|
||||||
bool IsVirtualBase) {
|
|
||||||
// C++11 [class.copy]p23:
|
// C++11 [class.copy]p23:
|
||||||
// -- for the move assignment operator, any direct or indirect virtual
|
// -- for the move assignment operator, any direct or indirect virtual
|
||||||
// base class.
|
// base class.
|
||||||
if (CSM == Sema::CXXMoveAssignment && IsVirtualBase)
|
if (CSM == Sema::CXXMoveAssignment && Base->isVirtual()) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(Base->getLocStart(), diag::note_deleted_move_assign_virtual_base)
|
||||||
|
<< MD->getParent() << Base->getType();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldDeleteForClassSubobject(BaseDecl, 0))
|
if (shouldDeleteForClassSubobject(Base->getType()->getAsCXXRecordDecl(),
|
||||||
|
Base))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -4492,29 +4538,52 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
|
||||||
if (CSM == Sema::CXXDefaultConstructor) {
|
if (CSM == Sema::CXXDefaultConstructor) {
|
||||||
// For a default constructor, all references must be initialized in-class
|
// For a default constructor, all references must be initialized in-class
|
||||||
// and, if a union, it must have a non-const member.
|
// and, if a union, it must have a non-const member.
|
||||||
if (FieldType->isReferenceType() && !FD->hasInClassInitializer())
|
if (FieldType->isReferenceType() && !FD->hasInClassInitializer()) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field)
|
||||||
|
<< MD->getParent() << FD << FieldType << /*Reference*/0;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (inUnion() && !FieldType.isConstQualified())
|
|
||||||
AllFieldsAreConst = false;
|
|
||||||
|
|
||||||
// C++11 [class.ctor]p5: any non-variant non-static data member of
|
// C++11 [class.ctor]p5: any non-variant non-static data member of
|
||||||
// const-qualified type (or array thereof) with no
|
// const-qualified type (or array thereof) with no
|
||||||
// brace-or-equal-initializer does not have a user-provided default
|
// brace-or-equal-initializer does not have a user-provided default
|
||||||
// constructor.
|
// constructor.
|
||||||
if (!inUnion() && FieldType.isConstQualified() &&
|
if (!inUnion() && FieldType.isConstQualified() &&
|
||||||
!FD->hasInClassInitializer() &&
|
!FD->hasInClassInitializer() &&
|
||||||
(!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor()))
|
(!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor())) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field)
|
||||||
|
<< MD->getParent() << FD << FieldType << /*Const*/1;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inUnion() && !FieldType.isConstQualified())
|
||||||
|
AllFieldsAreConst = false;
|
||||||
} else if (CSM == Sema::CXXCopyConstructor) {
|
} else if (CSM == Sema::CXXCopyConstructor) {
|
||||||
// For a copy constructor, data members must not be of rvalue reference
|
// For a copy constructor, data members must not be of rvalue reference
|
||||||
// type.
|
// type.
|
||||||
if (FieldType->isRValueReferenceType())
|
if (FieldType->isRValueReferenceType()) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(FD->getLocation(), diag::note_deleted_copy_ctor_rvalue_reference)
|
||||||
|
<< MD->getParent() << FD << FieldType;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
} else if (IsAssignment) {
|
} else if (IsAssignment) {
|
||||||
// For an assignment operator, data members must not be of reference type.
|
// For an assignment operator, data members must not be of reference type.
|
||||||
if (FieldType->isReferenceType())
|
if (FieldType->isReferenceType()) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
|
||||||
|
<< IsMove << MD->getParent() << FD << FieldType << /*Reference*/0;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
if (!FieldRecord && FieldType.isConstQualified()) {
|
||||||
|
// C++11 [class.copy]p23:
|
||||||
|
// -- a non-static data member of const non-class type (or array thereof)
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
|
||||||
|
<< IsMove << MD->getParent() << FD << FieldType << /*Const*/1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FieldRecord) {
|
if (FieldRecord) {
|
||||||
|
@ -4540,8 +4609,13 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
|
||||||
|
|
||||||
// At least one member in each anonymous union must be non-const
|
// At least one member in each anonymous union must be non-const
|
||||||
if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst &&
|
if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst &&
|
||||||
FieldRecord->field_begin() != FieldRecord->field_end())
|
FieldRecord->field_begin() != FieldRecord->field_end()) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(FieldRecord->getLocation(),
|
||||||
|
diag::note_deleted_default_ctor_all_const)
|
||||||
|
<< MD->getParent() << /*anonymous union*/1;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't check the implicit member of the anonymous union type.
|
// Don't check the implicit member of the anonymous union type.
|
||||||
// This is technically non-conformant, but sanity demands it.
|
// This is technically non-conformant, but sanity demands it.
|
||||||
|
@ -4550,10 +4624,6 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
|
||||||
|
|
||||||
if (shouldDeleteForClassSubobject(FieldRecord, FD))
|
if (shouldDeleteForClassSubobject(FieldRecord, FD))
|
||||||
return true;
|
return true;
|
||||||
} else if (IsAssignment && FieldType.isConstQualified()) {
|
|
||||||
// C++11 [class.copy]p23:
|
|
||||||
// -- a non-static data member of const non-class type (or array thereof)
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -4565,40 +4635,81 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
|
||||||
bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
|
bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
|
||||||
// This is a silly definition, because it gives an empty union a deleted
|
// This is a silly definition, because it gives an empty union a deleted
|
||||||
// default constructor. Don't do that.
|
// default constructor. Don't do that.
|
||||||
return CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst &&
|
if (CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst &&
|
||||||
(MD->getParent()->field_begin() != MD->getParent()->field_end());
|
(MD->getParent()->field_begin() != MD->getParent()->field_end())) {
|
||||||
|
if (Diagnose)
|
||||||
|
S.Diag(MD->getParent()->getLocation(),
|
||||||
|
diag::note_deleted_default_ctor_all_const)
|
||||||
|
<< MD->getParent() << /*not anonymous union*/0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine whether a defaulted special member function should be defined as
|
/// Determine whether a defaulted special member function should be defined as
|
||||||
/// deleted, as specified in C++11 [class.ctor]p5, C++11 [class.copy]p11,
|
/// deleted, as specified in C++11 [class.ctor]p5, C++11 [class.copy]p11,
|
||||||
/// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
|
/// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
|
||||||
bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM) {
|
bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
|
||||||
|
bool Diagnose) {
|
||||||
assert(!MD->isInvalidDecl());
|
assert(!MD->isInvalidDecl());
|
||||||
CXXRecordDecl *RD = MD->getParent();
|
CXXRecordDecl *RD = MD->getParent();
|
||||||
assert(!RD->isDependentType() && "do deletion after instantiation");
|
assert(!RD->isDependentType() && "do deletion after instantiation");
|
||||||
if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
|
if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// FIXME: Provide the ability to diagnose why a special member was deleted.
|
|
||||||
|
|
||||||
// C++11 [expr.lambda.prim]p19:
|
// C++11 [expr.lambda.prim]p19:
|
||||||
// The closure type associated with a lambda-expression has a
|
// The closure type associated with a lambda-expression has a
|
||||||
// deleted (8.4.3) default constructor and a deleted copy
|
// deleted (8.4.3) default constructor and a deleted copy
|
||||||
// assignment operator.
|
// assignment operator.
|
||||||
if (RD->isLambda() &&
|
if (RD->isLambda() &&
|
||||||
(CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment))
|
(CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment)) {
|
||||||
|
if (Diagnose)
|
||||||
|
Diag(RD->getLocation(), diag::note_lambda_decl);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// C++11 [class.copy]p7, p18:
|
||||||
|
// If the class definition declares a move constructor or move assignment
|
||||||
|
// operator, an implicitly declared copy constructor or copy assignment
|
||||||
|
// operator is defined as deleted.
|
||||||
|
if (MD->isImplicit() &&
|
||||||
|
(CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)) {
|
||||||
|
CXXMethodDecl *UserDeclaredMove = 0;
|
||||||
|
|
||||||
|
// In Microsoft mode, a user-declared move only causes the deletion of the
|
||||||
|
// corresponding copy operation, not both copy operations.
|
||||||
|
if (RD->hasUserDeclaredMoveConstructor() &&
|
||||||
|
(!getLangOpts().MicrosoftMode || CSM == CXXCopyConstructor)) {
|
||||||
|
if (!Diagnose) return true;
|
||||||
|
UserDeclaredMove = RD->getMoveConstructor();
|
||||||
|
} else if (RD->hasUserDeclaredMoveAssignment() &&
|
||||||
|
(!getLangOpts().MicrosoftMode || CSM == CXXCopyAssignment)) {
|
||||||
|
if (!Diagnose) return true;
|
||||||
|
UserDeclaredMove = RD->getMoveAssignmentOperator();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserDeclaredMove) {
|
||||||
|
Diag(UserDeclaredMove->getLocation(),
|
||||||
|
diag::note_deleted_copy_user_declared_move)
|
||||||
|
<< (CSM == CXXMoveAssignment) << RD
|
||||||
|
<< UserDeclaredMove->isMoveAssignmentOperator();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// C++11 [class.dtor]p5:
|
// C++11 [class.dtor]p5:
|
||||||
// -- for a virtual destructor, lookup of the non-array deallocation function
|
// -- for a virtual destructor, lookup of the non-array deallocation function
|
||||||
// results in an ambiguity or in a function that is deleted or inaccessible
|
// results in an ambiguity or in a function that is deleted or inaccessible
|
||||||
if (CSM == Sema::CXXDestructor && MD->isVirtual()) {
|
if (CSM == CXXDestructor && MD->isVirtual()) {
|
||||||
FunctionDecl *OperatorDelete = 0;
|
FunctionDecl *OperatorDelete = 0;
|
||||||
DeclarationName Name =
|
DeclarationName Name =
|
||||||
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
|
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
|
||||||
if (FindDeallocationFunction(MD->getLocation(), MD->getParent(), Name,
|
if (FindDeallocationFunction(MD->getLocation(), MD->getParent(), Name,
|
||||||
OperatorDelete, false))
|
OperatorDelete, false)) {
|
||||||
|
if (Diagnose)
|
||||||
|
Diag(RD->getLocation(), diag::note_deleted_dtor_no_operator_delete);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For an anonymous struct or union, the copy and assignment special members
|
// For an anonymous struct or union, the copy and assignment special members
|
||||||
|
@ -4611,17 +4722,17 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM) {
|
||||||
// Do access control from the special member function
|
// Do access control from the special member function
|
||||||
ContextRAII MethodContext(*this, MD);
|
ContextRAII MethodContext(*this, MD);
|
||||||
|
|
||||||
SpecialMemberDeletionInfo SMI(*this, MD, CSM);
|
SpecialMemberDeletionInfo SMI(*this, MD, CSM, Diagnose);
|
||||||
|
|
||||||
for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
|
for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
|
||||||
BE = RD->bases_end(); BI != BE; ++BI)
|
BE = RD->bases_end(); BI != BE; ++BI)
|
||||||
if (!BI->isVirtual() &&
|
if (!BI->isVirtual() &&
|
||||||
SMI.shouldDeleteForBase(BI->getType()->getAsCXXRecordDecl(), false))
|
SMI.shouldDeleteForBase(BI))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
|
for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
|
||||||
BE = RD->vbases_end(); BI != BE; ++BI)
|
BE = RD->vbases_end(); BI != BE; ++BI)
|
||||||
if (SMI.shouldDeleteForBase(BI->getType()->getAsCXXRecordDecl(), true))
|
if (SMI.shouldDeleteForBase(BI))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
|
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
|
||||||
|
@ -7603,12 +7714,9 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
|
||||||
// assignment operator, there is no user-declared move constructor, and
|
// assignment operator, there is no user-declared move constructor, and
|
||||||
// there is no user-declared move assignment operator, a copy assignment
|
// there is no user-declared move assignment operator, a copy assignment
|
||||||
// operator is implicitly declared as defaulted.
|
// operator is implicitly declared as defaulted.
|
||||||
if ((ClassDecl->hasUserDeclaredMoveConstructor() &&
|
if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment))
|
||||||
!getLangOpts().MicrosoftMode) ||
|
|
||||||
ClassDecl->hasUserDeclaredMoveAssignment() ||
|
|
||||||
ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment))
|
|
||||||
CopyAssignment->setDeletedAsWritten();
|
CopyAssignment->setDeletedAsWritten();
|
||||||
|
|
||||||
AddOverriddenMethods(ClassDecl, CopyAssignment);
|
AddOverriddenMethods(ClassDecl, CopyAssignment);
|
||||||
return CopyAssignment;
|
return CopyAssignment;
|
||||||
}
|
}
|
||||||
|
@ -8522,12 +8630,9 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
|
||||||
// constructor, there is no user-declared move constructor, and there is no
|
// constructor, there is no user-declared move constructor, and there is no
|
||||||
// user-declared move assignment operator, a copy constructor is implicitly
|
// user-declared move assignment operator, a copy constructor is implicitly
|
||||||
// declared as defaulted.
|
// declared as defaulted.
|
||||||
if (ClassDecl->hasUserDeclaredMoveConstructor() ||
|
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
|
||||||
(ClassDecl->hasUserDeclaredMoveAssignment() &&
|
|
||||||
!getLangOpts().MicrosoftMode) ||
|
|
||||||
ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
|
|
||||||
CopyConstructor->setDeletedAsWritten();
|
CopyConstructor->setDeletedAsWritten();
|
||||||
|
|
||||||
return CopyConstructor;
|
return CopyConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,25 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Emit a note explaining that this function is deleted or unavailable.
|
||||||
|
void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
|
||||||
|
CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Decl);
|
||||||
|
|
||||||
|
if (Method && Method->isImplicit()) {
|
||||||
|
CXXSpecialMember CSM = getSpecialMember(Method);
|
||||||
|
// It is possible for us to no longer be able to determine why the special
|
||||||
|
// member function was deleted, due to a field or base class having acquired
|
||||||
|
// a new special member function by the addition of a default argument.
|
||||||
|
// FIXME: Add a test and a special-case diagnostic for this.
|
||||||
|
if (CSM != CXXInvalid &&
|
||||||
|
ShouldDeleteSpecialMember(Method, CSM, /*Diagnose=*/true))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Diag(Decl->getLocation(), diag::note_unavailable_here)
|
||||||
|
<< 1 << Decl->isDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Determine whether the use of this declaration is valid, and
|
/// \brief Determine whether the use of this declaration is valid, and
|
||||||
/// emit any corresponding diagnostics.
|
/// emit any corresponding diagnostics.
|
||||||
///
|
///
|
||||||
|
@ -151,7 +170,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
|
||||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||||
if (FD->isDeleted()) {
|
if (FD->isDeleted()) {
|
||||||
Diag(Loc, diag::err_deleted_function_use);
|
Diag(Loc, diag::err_deleted_function_use);
|
||||||
Diag(D->getLocation(), diag::note_unavailable_here) << 1 << true;
|
NoteDeletedFunction(FD);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1899,8 +1899,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||||
if (Operator->isDeleted()) {
|
if (Operator->isDeleted()) {
|
||||||
if (Diagnose) {
|
if (Diagnose) {
|
||||||
Diag(StartLoc, diag::err_deleted_function_use);
|
Diag(StartLoc, diag::err_deleted_function_use);
|
||||||
Diag(Operator->getLocation(), diag::note_unavailable_here)
|
NoteDeletedFunction(Operator);
|
||||||
<< /*function*/ 1 << /*deleted*/ 1;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4482,8 +4482,7 @@ static ExprResult CopyObject(Sema &S,
|
||||||
S.Diag(Loc, diag::err_temp_copy_deleted)
|
S.Diag(Loc, diag::err_temp_copy_deleted)
|
||||||
<< (int)Entity.getKind() << CurInitExpr->getType()
|
<< (int)Entity.getKind() << CurInitExpr->getType()
|
||||||
<< CurInitExpr->getSourceRange();
|
<< CurInitExpr->getSourceRange();
|
||||||
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
|
S.NoteDeletedFunction(Best->Function);
|
||||||
<< 1 << Best->Function->isDeleted();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4592,8 +4591,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
|
||||||
|
|
||||||
case OR_Deleted:
|
case OR_Deleted:
|
||||||
S.Diag(Loc, Diag);
|
S.Diag(Loc, Diag);
|
||||||
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
|
S.NoteDeletedFunction(Best->Function);
|
||||||
<< 1 << Best->Function->isDeleted();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5362,26 +5360,6 @@ InitializationSequence::Perform(Sema &S,
|
||||||
return move(CurInit);
|
return move(CurInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Provide some notes that detail why a function was implicitly
|
|
||||||
/// deleted.
|
|
||||||
static void diagnoseImplicitlyDeletedFunction(Sema &S, CXXMethodDecl *Method) {
|
|
||||||
// FIXME: This is a work in progress. It should dig deeper to figure out
|
|
||||||
// why the function was deleted (e.g., because one of its members doesn't
|
|
||||||
// have a copy constructor, for the copy-constructor case).
|
|
||||||
if (!Method->isImplicit()) {
|
|
||||||
S.Diag(Method->getLocation(), diag::note_callee_decl)
|
|
||||||
<< Method->getDeclName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Method->getParent()->isLambda()) {
|
|
||||||
S.Diag(Method->getParent()->getLocation(), diag::note_lambda_decl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
S.Diag(Method->getParent()->getLocation(), diag::note_defined_here)
|
|
||||||
<< Method->getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Diagnose initialization failures
|
// Diagnose initialization failures
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -5469,8 +5447,7 @@ bool InitializationSequence::Diagnose(Sema &S,
|
||||||
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best,
|
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best,
|
||||||
true);
|
true);
|
||||||
if (Ovl == OR_Deleted) {
|
if (Ovl == OR_Deleted) {
|
||||||
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
|
S.NoteDeletedFunction(Best->Function);
|
||||||
<< 1 << Best->Function->isDeleted();
|
|
||||||
} else {
|
} else {
|
||||||
llvm_unreachable("Inconsistent overload resolution?");
|
llvm_unreachable("Inconsistent overload resolution?");
|
||||||
}
|
}
|
||||||
|
@ -5661,20 +5638,15 @@ bool InitializationSequence::Diagnose(Sema &S,
|
||||||
// If this is a defaulted or implicitly-declared function, then
|
// If this is a defaulted or implicitly-declared function, then
|
||||||
// it was implicitly deleted. Make it clear that the deletion was
|
// it was implicitly deleted. Make it clear that the deletion was
|
||||||
// implicit.
|
// implicit.
|
||||||
if (S.isImplicitlyDeleted(Best->Function)) {
|
if (S.isImplicitlyDeleted(Best->Function))
|
||||||
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
|
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
|
||||||
<< S.getSpecialMember(cast<CXXMethodDecl>(Best->Function))
|
<< S.getSpecialMember(cast<CXXMethodDecl>(Best->Function))
|
||||||
<< DestType << ArgsRange;
|
<< DestType << ArgsRange;
|
||||||
|
else
|
||||||
diagnoseImplicitlyDeletedFunction(S,
|
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
|
||||||
cast<CXXMethodDecl>(Best->Function));
|
<< true << DestType << ArgsRange;
|
||||||
break;
|
|
||||||
}
|
S.NoteDeletedFunction(Best->Function);
|
||||||
|
|
||||||
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
|
|
||||||
<< true << DestType << ArgsRange;
|
|
||||||
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
|
|
||||||
<< 1 << Best->Function->isDeleted();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2274,8 +2274,9 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
|
||||||
CXXDestructorDecl *DD = RD->getDestructor();
|
CXXDestructorDecl *DD = RD->getDestructor();
|
||||||
assert(DD && "record without a destructor");
|
assert(DD && "record without a destructor");
|
||||||
Result->setMethod(DD);
|
Result->setMethod(DD);
|
||||||
Result->setSuccess(!DD->isDeleted());
|
Result->setKind(DD->isDeleted() ?
|
||||||
Result->setConstParamMatch(false);
|
SpecialMemberOverloadResult::NoMemberOrDeleted :
|
||||||
|
SpecialMemberOverloadResult::SuccessNonConst);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2345,7 +2346,8 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
|
||||||
// will always be a (possibly implicit) declaration to shadow any others.
|
// will always be a (possibly implicit) declaration to shadow any others.
|
||||||
OverloadCandidateSet OCS((SourceLocation()));
|
OverloadCandidateSet OCS((SourceLocation()));
|
||||||
DeclContext::lookup_iterator I, E;
|
DeclContext::lookup_iterator I, E;
|
||||||
Result->setConstParamMatch(false);
|
SpecialMemberOverloadResult::Kind SuccessKind =
|
||||||
|
SpecialMemberOverloadResult::SuccessNonConst;
|
||||||
|
|
||||||
llvm::tie(I, E) = RD->lookup(Name);
|
llvm::tie(I, E) = RD->lookup(Name);
|
||||||
assert((I != E) &&
|
assert((I != E) &&
|
||||||
|
@ -2384,7 +2386,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
|
||||||
QualType ArgType = M->getType()->getAs<FunctionProtoType>()->getArgType(0);
|
QualType ArgType = M->getType()->getAs<FunctionProtoType>()->getArgType(0);
|
||||||
if (!ArgType->isReferenceType() ||
|
if (!ArgType->isReferenceType() ||
|
||||||
ArgType->getPointeeType().isConstQualified())
|
ArgType->getPointeeType().isConstQualified())
|
||||||
Result->setConstParamMatch(true);
|
SuccessKind = SpecialMemberOverloadResult::SuccessConst;
|
||||||
}
|
}
|
||||||
} else if (FunctionTemplateDecl *Tmpl =
|
} else if (FunctionTemplateDecl *Tmpl =
|
||||||
dyn_cast<FunctionTemplateDecl>(Cand)) {
|
dyn_cast<FunctionTemplateDecl>(Cand)) {
|
||||||
|
@ -2406,18 +2408,22 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
|
||||||
switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
|
switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
|
||||||
case OR_Success:
|
case OR_Success:
|
||||||
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
|
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
|
||||||
Result->setSuccess(true);
|
Result->setKind(SuccessKind);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OR_Deleted:
|
case OR_Deleted:
|
||||||
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
|
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
|
||||||
Result->setSuccess(false);
|
Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OR_Ambiguous:
|
case OR_Ambiguous:
|
||||||
|
Result->setMethod(0);
|
||||||
|
Result->setKind(SpecialMemberOverloadResult::Ambiguous);
|
||||||
|
break;
|
||||||
|
|
||||||
case OR_No_Viable_Function:
|
case OR_No_Viable_Function:
|
||||||
Result->setMethod(0);
|
Result->setMethod(0);
|
||||||
Result->setSuccess(false);
|
Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ private:
|
||||||
protected:
|
protected:
|
||||||
struct Inner { int m; };
|
struct Inner { int m; };
|
||||||
public:
|
public:
|
||||||
bool &br;
|
bool &br; // expected-note {{default constructor of 'Aggr' is implicitly deleted because field 'br' of reference type 'bool &' would not be initialized}}
|
||||||
};
|
};
|
||||||
bool b;
|
bool b;
|
||||||
Aggr ag = { b };
|
Aggr ag = { b };
|
||||||
|
@ -54,7 +54,7 @@ struct NonAggr5 : Aggr { // expected-note 3 {{candidate constructor}}
|
||||||
};
|
};
|
||||||
NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}}
|
NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}}
|
||||||
template<typename...BaseList>
|
template<typename...BaseList>
|
||||||
struct MaybeAggr5a : BaseList... {}; // expected-note {{defined here}}
|
struct MaybeAggr5a : BaseList... {}; // expected-note {{default constructor of 'MaybeAggr5a<Aggr>' is implicitly deleted because base class 'Aggr' has a deleted default constructor}}
|
||||||
MaybeAggr5a<> ma5a0 = {}; // ok
|
MaybeAggr5a<> ma5a0 = {}; // ok
|
||||||
MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a<Aggr>'}}
|
MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a<Aggr>'}}
|
||||||
|
|
||||||
|
|
|
@ -87,9 +87,9 @@ private:
|
||||||
~PrivateDestructor() noexcept;
|
~PrivateDestructor() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{defined here}}
|
struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
|
||||||
struct ContainsPrivateDestructor { // expected-note{{defined here}}
|
struct ContainsPrivateDestructor {
|
||||||
PrivateDestructor pd;
|
PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NonTrivialCopyOnly {
|
struct NonTrivialCopyOnly {
|
||||||
|
|
|
@ -7,16 +7,16 @@ struct NonTrivial {
|
||||||
// A defaulted copy constructor for a class X is defined as deleted if X has:
|
// A defaulted copy constructor for a class X is defined as deleted if X has:
|
||||||
|
|
||||||
// -- a variant member with a non-trivial corresponding constructor
|
// -- a variant member with a non-trivial corresponding constructor
|
||||||
union DeletedNTVariant { // expected-note{{here}}
|
union DeletedNTVariant {
|
||||||
NonTrivial NT;
|
NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
|
||||||
DeletedNTVariant();
|
DeletedNTVariant();
|
||||||
};
|
};
|
||||||
DeletedNTVariant DVa;
|
DeletedNTVariant DVa;
|
||||||
DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
|
DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
|
||||||
|
|
||||||
struct DeletedNTVariant2 { // expected-note{{here}}
|
struct DeletedNTVariant2 {
|
||||||
union {
|
union {
|
||||||
NonTrivial NT;
|
NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant2' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
|
||||||
};
|
};
|
||||||
DeletedNTVariant2();
|
DeletedNTVariant2();
|
||||||
};
|
};
|
||||||
|
@ -34,8 +34,8 @@ private:
|
||||||
friend struct HasAccess;
|
friend struct HasAccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HasNoAccess { // expected-note{{here}}
|
struct HasNoAccess {
|
||||||
NoAccess NA;
|
NoAccess NA; // expected-note{{copy constructor of 'HasNoAccess' is implicitly deleted because field 'NA' has an inaccessible copy constructor}}
|
||||||
};
|
};
|
||||||
HasNoAccess HNAa;
|
HasNoAccess HNAa;
|
||||||
HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}}
|
HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}}
|
||||||
|
@ -55,16 +55,16 @@ struct Ambiguity {
|
||||||
Ambiguity(volatile Ambiguity&);
|
Ambiguity(volatile Ambiguity&);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IsAmbiguous { // expected-note{{here}}
|
struct IsAmbiguous {
|
||||||
NonConst NC;
|
NonConst NC;
|
||||||
Ambiguity A;
|
Ambiguity A; // expected-note 2{{copy constructor of 'IsAmbiguous' is implicitly deleted because field 'A' has multiple copy constructors}}
|
||||||
IsAmbiguous();
|
IsAmbiguous();
|
||||||
};
|
};
|
||||||
IsAmbiguous IAa;
|
IsAmbiguous IAa;
|
||||||
IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}}
|
IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}}
|
||||||
|
|
||||||
struct Deleted { // expected-note{{here}}
|
struct Deleted {
|
||||||
IsAmbiguous IA;
|
IsAmbiguous IA; // expected-note{{copy constructor of 'Deleted' is implicitly deleted because field 'IA' has a deleted copy constructor}}
|
||||||
};
|
};
|
||||||
Deleted Da;
|
Deleted Da;
|
||||||
Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
|
Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
|
||||||
|
@ -72,17 +72,17 @@ Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
|
||||||
// -- a direct or virtual base class B that cannot be copied because overload
|
// -- a direct or virtual base class B that cannot be copied because overload
|
||||||
// resolution results in an ambiguity or a function that is deleted or
|
// resolution results in an ambiguity or a function that is deleted or
|
||||||
// inaccessible
|
// inaccessible
|
||||||
struct AmbiguousCopyBase : Ambiguity { // expected-note {{here}}
|
struct AmbiguousCopyBase : Ambiguity { // expected-note 2{{copy constructor of 'AmbiguousCopyBase' is implicitly deleted because base class 'Ambiguity' has multiple copy constructors}}
|
||||||
NonConst NC;
|
NonConst NC;
|
||||||
};
|
};
|
||||||
extern AmbiguousCopyBase ACBa;
|
extern AmbiguousCopyBase ACBa;
|
||||||
AmbiguousCopyBase ACBb(ACBa); // expected-error {{deleted copy constructor}}
|
AmbiguousCopyBase ACBb(ACBa); // expected-error {{deleted copy constructor}}
|
||||||
|
|
||||||
struct DeletedCopyBase : AmbiguousCopyBase {}; // expected-note {{here}}
|
struct DeletedCopyBase : AmbiguousCopyBase {}; // expected-note {{copy constructor of 'DeletedCopyBase' is implicitly deleted because base class 'AmbiguousCopyBase' has a deleted copy constructor}}
|
||||||
extern DeletedCopyBase DCBa;
|
extern DeletedCopyBase DCBa;
|
||||||
DeletedCopyBase DCBb(DCBa); // expected-error {{deleted copy constructor}}
|
DeletedCopyBase DCBb(DCBa); // expected-error {{deleted copy constructor}}
|
||||||
|
|
||||||
struct InaccessibleCopyBase : NoAccess {}; // expected-note {{here}}
|
struct InaccessibleCopyBase : NoAccess {}; // expected-note {{copy constructor of 'InaccessibleCopyBase' is implicitly deleted because base class 'NoAccess' has an inaccessible copy constructor}}
|
||||||
extern InaccessibleCopyBase ICBa;
|
extern InaccessibleCopyBase ICBa;
|
||||||
InaccessibleCopyBase ICBb(ICBa); // expected-error {{deleted copy constructor}}
|
InaccessibleCopyBase ICBb(ICBa); // expected-error {{deleted copy constructor}}
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ private:
|
||||||
friend struct HasAccessDtor;
|
friend struct HasAccessDtor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HasNoAccessDtor { // expected-note{{here}}
|
struct HasNoAccessDtor {
|
||||||
NoAccessDtor NAD;
|
NoAccessDtor NAD; // expected-note{{copy constructor of 'HasNoAccessDtor' is implicitly deleted because field 'NAD' has an inaccessible destructor}}
|
||||||
HasNoAccessDtor();
|
HasNoAccessDtor();
|
||||||
~HasNoAccessDtor();
|
~HasNoAccessDtor();
|
||||||
};
|
};
|
||||||
|
@ -108,14 +108,14 @@ struct HasAccessDtor {
|
||||||
HasAccessDtor HADa;
|
HasAccessDtor HADa;
|
||||||
HasAccessDtor HADb(HADa);
|
HasAccessDtor HADb(HADa);
|
||||||
|
|
||||||
struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{here}}
|
struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has an inaccessible destructor}}
|
||||||
};
|
};
|
||||||
extern HasNoAccessDtorBase HNADBa;
|
extern HasNoAccessDtorBase HNADBa;
|
||||||
HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
|
HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
|
||||||
|
|
||||||
// -- a non-static data member of rvalue reference type
|
// -- a non-static data member of rvalue reference type
|
||||||
struct RValue { // expected-note{{here}}
|
struct RValue {
|
||||||
int && ri = 1;
|
int && ri = 1; // expected-note{{copy constructor of 'RValue' is implicitly deleted because field 'ri' is of rvalue reference type 'int &&'}}
|
||||||
};
|
};
|
||||||
RValue RVa;
|
RValue RVa;
|
||||||
RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}}
|
RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}}
|
||||||
|
|
|
@ -82,7 +82,7 @@ InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; //
|
||||||
// -- any direct or virtual base class or non-static data member of a type with
|
// -- any direct or virtual base class or non-static data member of a type with
|
||||||
// a destructor that is deleted or inaccessible
|
// a destructor that is deleted or inaccessible
|
||||||
struct NoAccessDtor {
|
struct NoAccessDtor {
|
||||||
NoAccessDtor(NoAccessDtor&&);
|
NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
|
||||||
private:
|
private:
|
||||||
~NoAccessDtor();
|
~NoAccessDtor();
|
||||||
friend struct HasAccessDtor;
|
friend struct HasAccessDtor;
|
||||||
|
@ -100,7 +100,7 @@ struct HasAccessDtor {
|
||||||
};
|
};
|
||||||
HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
|
HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
|
||||||
|
|
||||||
struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{here}}
|
struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
|
||||||
};
|
};
|
||||||
extern HasNoAccessDtorBase HNADBa;
|
extern HasNoAccessDtorBase HNADBa;
|
||||||
HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
|
HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
struct DefaultedDefCtor1 {};
|
struct DefaultedDefCtor1 {};
|
||||||
struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; };
|
struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; };
|
||||||
struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); };
|
struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); }; // expected-note {{explicitly marked deleted here}}
|
||||||
class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); };
|
class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); };
|
||||||
struct DeletedDtor { ~DeletedDtor() = delete; };
|
struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note 4{{explicitly marked deleted here}}
|
||||||
class PrivateDtor { ~PrivateDtor() = default; };
|
class PrivateDtor { ~PrivateDtor() = default; };
|
||||||
class Friend {
|
class Friend {
|
||||||
Friend() = default; ~Friend() = default;
|
Friend() = default; ~Friend() = default;
|
||||||
|
@ -21,7 +21,7 @@ int n;
|
||||||
|
|
||||||
// - X is a union-like class that has a variant member with a non-trivial
|
// - X is a union-like class that has a variant member with a non-trivial
|
||||||
// default constructor,
|
// default constructor,
|
||||||
union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{defined here}}
|
union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of union 'Deleted1a' is implicitly deleted because field 'u' has a non-trivial default constructor}}
|
||||||
Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
union NotDeleted1a { DefaultedDefCtor1 nu; };
|
union NotDeleted1a { DefaultedDefCtor1 nu; };
|
||||||
NotDeleted1a nd1a;
|
NotDeleted1a nd1a;
|
||||||
|
@ -30,13 +30,15 @@ NotDeleted1b nd1b;
|
||||||
|
|
||||||
// - any non-static data member with no brace-or-equal-initializer is of
|
// - any non-static data member with no brace-or-equal-initializer is of
|
||||||
// reference type,
|
// reference type,
|
||||||
class Deleted2a { // expected-note {{defined here}}
|
class Deleted2a {
|
||||||
Deleted2a() = default; // expected-note {{declared here}}
|
// FIXME: We should explain that the function was implicitly deleted as a
|
||||||
|
// result of being defaulted, and why.
|
||||||
|
Deleted2a() = default; // expected-note 4{{explicitly marked deleted here}}
|
||||||
int &a;
|
int &a;
|
||||||
};
|
};
|
||||||
Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted2b { // expected-note {{here}}
|
struct Deleted2b {
|
||||||
int &&b;
|
int &&b; // expected-note {{default constructor of 'Deleted2b' is implicitly deleted because field 'b' of reference type 'int &&' would not be initialized}}
|
||||||
};
|
};
|
||||||
Deleted2b d2b; // expected-error {{deleted default constructor}}
|
Deleted2b d2b; // expected-error {{deleted default constructor}}
|
||||||
class NotDeleted2a { int &a = n; };
|
class NotDeleted2a { int &a = n; };
|
||||||
|
@ -49,13 +51,13 @@ NotDeleted2c nd2c;
|
||||||
// - any non-variant non-static data member of const qualified type (or array
|
// - any non-variant non-static data member of const qualified type (or array
|
||||||
// thereof) with no brace-or-equal-initializer does not have a user-provided
|
// thereof) with no brace-or-equal-initializer does not have a user-provided
|
||||||
// default constructor,
|
// default constructor,
|
||||||
class Deleted3a { const int a; }; // expected-note {{here}} \
|
class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-qualified type 'const int' would not be initialized}} \
|
||||||
expected-warning {{does not declare any constructor}} \
|
expected-warning {{does not declare any constructor}} \
|
||||||
expected-note {{will never be initialized}}
|
expected-note {{will never be initialized}}
|
||||||
Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{here}}
|
class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1' would not be initialized}}
|
||||||
Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
|
Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
|
||||||
class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{defined here}}
|
class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}}
|
||||||
Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
|
Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
|
||||||
class NotDeleted3a { const int a = 0; };
|
class NotDeleted3a { const int a = 0; };
|
||||||
NotDeleted3a nd3a;
|
NotDeleted3a nd3a;
|
||||||
|
@ -74,14 +76,21 @@ NotDeleted3g nd3g;
|
||||||
|
|
||||||
// - X is a union and all of its variant members are of const-qualified type (or
|
// - X is a union and all of its variant members are of const-qualified type (or
|
||||||
// array thereof),
|
// array thereof),
|
||||||
union Deleted4a { const int a; const int b; const UserProvidedDefCtor c; }; // expected-note {{here}}
|
union Deleted4a {
|
||||||
|
const int a;
|
||||||
|
const int b;
|
||||||
|
const UserProvidedDefCtor c; // expected-note {{because field 'c' has a non-trivial default constructor}}
|
||||||
|
};
|
||||||
Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
union NotDeleted4a { const int a; int b; };
|
union NotDeleted4a { const int a; int b; };
|
||||||
NotDeleted4a nd4a;
|
NotDeleted4a nd4a;
|
||||||
|
|
||||||
// - X is a non-union class and all members of any anonymous union member are of
|
// - X is a non-union class and all members of any anonymous union member are of
|
||||||
// const-qualified type (or array thereof),
|
// const-qualified type (or array thereof),
|
||||||
struct Deleted5a { union { const int a; }; union { int b; }; }; // expected-note {{here}}
|
struct Deleted5a {
|
||||||
|
union { const int a; }; // expected-note {{because all data members of an anonymous union member are const-qualified}}
|
||||||
|
union { int b; };
|
||||||
|
};
|
||||||
Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; };
|
struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; };
|
||||||
NotDeleted5a nd5a;
|
NotDeleted5a nd5a;
|
||||||
|
@ -91,17 +100,17 @@ NotDeleted5a nd5a;
|
||||||
// M has no default constructor or overload resolution as applied to M's default
|
// M has no default constructor or overload resolution as applied to M's default
|
||||||
// constructor results in an ambiguity or in a function that is deleted or
|
// constructor results in an ambiguity or in a function that is deleted or
|
||||||
// inaccessible from the defaulted default constructor, or
|
// inaccessible from the defaulted default constructor, or
|
||||||
struct Deleted6a : Deleted2a {}; // expected-note {{here}}
|
struct Deleted6a : Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}}
|
||||||
Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted6b : virtual Deleted2a {}; // expected-note {{here}}
|
struct Deleted6b : virtual Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}}
|
||||||
Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}}
|
Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted6c { Deleted2a a; }; // expected-note {{here}}
|
struct Deleted6c { Deleted2a a; }; // expected-note {{because field 'a' has a deleted default constructor}}
|
||||||
Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}}
|
Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted6d { DeletedDefCtor a; }; // expected-note {{here}}
|
struct Deleted6d { DeletedDefCtor a; }; // expected-note {{because field 'a' has a deleted default constructor}}
|
||||||
Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}}
|
Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct NotDeleted6a { DeletedDefCtor a = 0; };
|
struct NotDeleted6a { DeletedDefCtor a = 0; };
|
||||||
NotDeleted6a nd6a;
|
NotDeleted6a nd6a;
|
||||||
struct Deleted6e { PrivateDefCtor a; }; // expected-note {{here}}
|
struct Deleted6e { PrivateDefCtor a; }; // expected-note {{because field 'a' has an inaccessible default constructor}}
|
||||||
Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}}
|
Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct NotDeleted6b { PrivateDefCtor a = 0; };
|
struct NotDeleted6b { PrivateDefCtor a = 0; };
|
||||||
NotDeleted6b nd6b;
|
NotDeleted6b nd6b;
|
||||||
|
@ -111,21 +120,21 @@ NotDeleted6c nd6c;
|
||||||
// - any direct or virtual base class or non-static data member has a type with
|
// - any direct or virtual base class or non-static data member has a type with
|
||||||
// a destructor that is deleted or inaccessible from the defaulted default
|
// a destructor that is deleted or inaccessible from the defaulted default
|
||||||
// constructor.
|
// constructor.
|
||||||
struct Deleted7a : DeletedDtor {}; // expected-note {{here}}
|
struct Deleted7a : DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}}
|
||||||
Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7b : virtual DeletedDtor {}; // expected-note {{here}}
|
struct Deleted7b : virtual DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}}
|
||||||
Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7c { DeletedDtor a; }; // expected-note {{here}}
|
struct Deleted7c { DeletedDtor a; }; // expected-note {{because field 'a' has a deleted destructor}}
|
||||||
Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{here}}
|
struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{because field 'a' has a deleted destructor}}
|
||||||
Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7e : PrivateDtor {}; // expected-note {{here}}
|
struct Deleted7e : PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}}
|
||||||
Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7f : virtual PrivateDtor {}; // expected-note {{here}}
|
struct Deleted7f : virtual PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}}
|
||||||
Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7g { PrivateDtor a; }; // expected-note {{here}}
|
struct Deleted7g { PrivateDtor a; }; // expected-note {{field 'a' has an inaccessible destructor}}
|
||||||
Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{here}}
|
struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{field 'a' has an inaccessible destructor}}
|
||||||
Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}}
|
Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}}
|
||||||
struct NotDeleted7i : Friend {};
|
struct NotDeleted7i : Friend {};
|
||||||
NotDeleted7i d7i;
|
NotDeleted7i d7i;
|
||||||
|
|
|
@ -4,7 +4,7 @@ struct NonTrivDtor {
|
||||||
~NonTrivDtor();
|
~NonTrivDtor();
|
||||||
};
|
};
|
||||||
struct DeletedDtor {
|
struct DeletedDtor {
|
||||||
~DeletedDtor() = delete;
|
~DeletedDtor() = delete; // expected-note 5 {{deleted here}}
|
||||||
};
|
};
|
||||||
class InaccessibleDtor {
|
class InaccessibleDtor {
|
||||||
~InaccessibleDtor() = default;
|
~InaccessibleDtor() = default;
|
||||||
|
@ -14,73 +14,74 @@ class InaccessibleDtor {
|
||||||
|
|
||||||
// -- X is a union-like class that has a variant member with a non-trivial
|
// -- X is a union-like class that has a variant member with a non-trivial
|
||||||
// destructor.
|
// destructor.
|
||||||
union A1 { // expected-note {{here}}
|
union A1 {
|
||||||
A1();
|
A1();
|
||||||
NonTrivDtor n;
|
NonTrivDtor n; // expected-note {{destructor of union 'A1' is implicitly deleted because field 'n' has a non-trivial destructor}}
|
||||||
};
|
};
|
||||||
A1 a1; // expected-error {{deleted function}}
|
A1 a1; // expected-error {{deleted function}}
|
||||||
struct A2 { // expected-note {{here}}
|
struct A2 {
|
||||||
A2();
|
A2();
|
||||||
union {
|
union {
|
||||||
NonTrivDtor n;
|
NonTrivDtor n; // expected-note {{because field 'n' has a non-trivial destructor}}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
A2 a2; // expected-error {{deleted function}}
|
A2 a2; // expected-error {{deleted function}}
|
||||||
union A3 { // expected-note {{here}}
|
union A3 {
|
||||||
A3();
|
A3();
|
||||||
NonTrivDtor n[3];
|
NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
|
||||||
};
|
};
|
||||||
A3 a3; // expected-error {{deleted function}}
|
A3 a3; // expected-error {{deleted function}}
|
||||||
struct A4 { // expected-note {{here}}
|
struct A4 {
|
||||||
A4();
|
A4();
|
||||||
union {
|
union {
|
||||||
NonTrivDtor n[3];
|
NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
A4 a4; // expected-error {{deleted function}}
|
A4 a4; // expected-error {{deleted function}}
|
||||||
|
|
||||||
// -- any of the non-static data members has class type M (or array thereof) and
|
// -- any of the non-static data members has class type M (or array thereof) and
|
||||||
// M has a deleted or inaccessible destructor.
|
// M has a deleted or inaccessible destructor.
|
||||||
struct B1 { // expected-note {{here}}
|
struct B1 {
|
||||||
B1();
|
B1();
|
||||||
DeletedDtor a;
|
DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
|
||||||
};
|
};
|
||||||
B1 b1; // expected-error {{deleted function}}
|
B1 b1; // expected-error {{deleted function}}
|
||||||
struct B2 { // expected-note {{here}}
|
struct B2 {
|
||||||
B2();
|
B2();
|
||||||
InaccessibleDtor a;
|
InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
|
||||||
};
|
};
|
||||||
B2 b2; // expected-error {{deleted function}}
|
B2 b2; // expected-error {{deleted function}}
|
||||||
struct B3 { // expected-note {{here}}
|
struct B3 {
|
||||||
B3();
|
B3();
|
||||||
DeletedDtor a[4];
|
DeletedDtor a[4]; // expected-note {{because field 'a' has a deleted destructor}}
|
||||||
};
|
};
|
||||||
B3 b3; // expected-error {{deleted function}}
|
B3 b3; // expected-error {{deleted function}}
|
||||||
struct B4 { // expected-note {{here}}
|
struct B4 {
|
||||||
B4();
|
B4();
|
||||||
InaccessibleDtor a[4];
|
InaccessibleDtor a[4]; // expected-note {{because field 'a' has an inaccessible destructor}}
|
||||||
};
|
};
|
||||||
B4 b4; // expected-error {{deleted function}}
|
B4 b4; // expected-error {{deleted function}}
|
||||||
union B5 { // expected-note {{here}}
|
union B5 {
|
||||||
B5();
|
B5();
|
||||||
union {
|
// FIXME: Describe the anonymous union member better than ''.
|
||||||
DeletedDtor a;
|
union { // expected-note {{because field '' has a deleted destructor}}
|
||||||
|
DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
B5 b5; // expected-error {{deleted function}}
|
B5 b5; // expected-error {{deleted function}}
|
||||||
union B6 { // expected-note {{here}}
|
union B6 {
|
||||||
B6();
|
B6();
|
||||||
union {
|
union { // expected-note {{because field '' has a deleted destructor}}
|
||||||
InaccessibleDtor a;
|
InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
B6 b6; // expected-error {{deleted function}}
|
B6 b6; // expected-error {{deleted function}}
|
||||||
|
|
||||||
// -- any direct or virtual base class has a deleted or inaccessible destructor.
|
// -- any direct or virtual base class has a deleted or inaccessible destructor.
|
||||||
struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{here}}
|
struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
|
||||||
struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{here}}
|
struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
|
||||||
struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{here}}
|
struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
|
||||||
struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{here}}
|
struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
|
||||||
|
|
||||||
// -- for a virtual destructor, lookup of the non-array deallocation function
|
// -- for a virtual destructor, lookup of the non-array deallocation function
|
||||||
// results in an ambiguity or a function that is deleted or inaccessible.
|
// results in an ambiguity or a function that is deleted or inaccessible.
|
||||||
|
|
|
@ -7,23 +7,23 @@ struct non_trivial {
|
||||||
~non_trivial();
|
~non_trivial();
|
||||||
};
|
};
|
||||||
|
|
||||||
union bad_union { // expected-note {{defined here}}
|
union bad_union {
|
||||||
non_trivial nt;
|
non_trivial nt; // expected-note {{non-trivial default constructor}}
|
||||||
};
|
};
|
||||||
bad_union u; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_union u; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
union bad_union2 { // expected-note {{defined here}}
|
union bad_union2 { // expected-note {{all data members are const-qualified}}
|
||||||
const int i;
|
const int i;
|
||||||
};
|
};
|
||||||
bad_union2 u2; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_union2 u2; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
struct bad_anon { // expected-note {{defined here}}
|
struct bad_anon {
|
||||||
union {
|
union {
|
||||||
non_trivial nt;
|
non_trivial nt; // expected-note {{non-trivial default constructor}}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
bad_anon a; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_anon a; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
struct bad_anon2 { // expected-note {{defined here}}
|
struct bad_anon2 {
|
||||||
union {
|
union { // expected-note {{all data members of an anonymous union member are const-qualified}}
|
||||||
const int i;
|
const int i;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -48,8 +48,8 @@ struct good : non_trivial {
|
||||||
};
|
};
|
||||||
good g;
|
good g;
|
||||||
|
|
||||||
struct bad_const { // expected-note {{defined here}}
|
struct bad_const {
|
||||||
const good g;
|
const good g; // expected-note {{field 'g' of const-qualified type 'const good' would not be initialized}}
|
||||||
};
|
};
|
||||||
bad_const bc; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_const bc; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
|
@ -59,25 +59,25 @@ struct good_const {
|
||||||
good_const gc;
|
good_const gc;
|
||||||
|
|
||||||
struct no_default {
|
struct no_default {
|
||||||
no_default() = delete;
|
no_default() = delete; // expected-note 2{{deleted here}}
|
||||||
};
|
};
|
||||||
struct no_dtor {
|
struct no_dtor {
|
||||||
~no_dtor() = delete;
|
~no_dtor() = delete; // expected-note 2{{deleted here}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bad_field_default { // expected-note {{defined here}}
|
struct bad_field_default {
|
||||||
no_default nd;
|
no_default nd; // expected-note {{field 'nd' has a deleted default constructor}}
|
||||||
};
|
};
|
||||||
bad_field_default bfd; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_field_default bfd; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
struct bad_base_default : no_default { // expected-note {{defined here}}
|
struct bad_base_default : no_default { // expected-note {{base class 'no_default' has a deleted default constructor}}
|
||||||
};
|
};
|
||||||
bad_base_default bbd; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_base_default bbd; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
struct bad_field_dtor { // expected-note {{defined here}}
|
struct bad_field_dtor {
|
||||||
no_dtor nd;
|
no_dtor nd; // expected-note {{field 'nd' has a deleted destructor}}
|
||||||
};
|
};
|
||||||
bad_field_dtor bfx; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_field_dtor bfx; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
struct bad_base_dtor : no_dtor { // expected-note {{defined here}}
|
struct bad_base_dtor : no_dtor { // expected-note {{base class 'no_dtor' has a deleted destructor}}
|
||||||
};
|
};
|
||||||
bad_base_dtor bbx; // expected-error {{call to implicitly-deleted default constructor}}
|
bad_base_dtor bbx; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
|
@ -85,16 +85,16 @@ struct ambiguous_default {
|
||||||
ambiguous_default();
|
ambiguous_default();
|
||||||
ambiguous_default(int = 2);
|
ambiguous_default(int = 2);
|
||||||
};
|
};
|
||||||
struct has_amb_field { // expected-note {{defined here}}
|
struct has_amb_field {
|
||||||
ambiguous_default ad;
|
ambiguous_default ad; // expected-note {{field 'ad' has multiple default constructors}}
|
||||||
};
|
};
|
||||||
has_amb_field haf; // expected-error {{call to implicitly-deleted default constructor}}
|
has_amb_field haf; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
class inaccessible_default {
|
class inaccessible_default {
|
||||||
inaccessible_default();
|
inaccessible_default();
|
||||||
};
|
};
|
||||||
struct has_inacc_field { // expected-note {{defined here}}
|
struct has_inacc_field {
|
||||||
inaccessible_default id;
|
inaccessible_default id; // expected-note {{field 'id' has an inaccessible default constructor}}
|
||||||
};
|
};
|
||||||
has_inacc_field hif; // expected-error {{call to implicitly-deleted default constructor}}
|
has_inacc_field hif; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
|
@ -107,9 +107,9 @@ struct has_friend {
|
||||||
};
|
};
|
||||||
has_friend hf;
|
has_friend hf;
|
||||||
|
|
||||||
struct defaulted_delete { // expected-note {{defined here}}
|
struct defaulted_delete {
|
||||||
no_default nd;
|
no_default nd;
|
||||||
defaulted_delete() = default; // expected-note{{declared here}}
|
defaulted_delete() = default; // expected-note{{deleted here}}
|
||||||
};
|
};
|
||||||
defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
|
defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,8 @@ namespace CopyCtorIssues {
|
||||||
Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}}
|
Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}}
|
||||||
Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}}
|
Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}}
|
||||||
};
|
};
|
||||||
struct Deleted { // expected-note {{here}}
|
struct Deleted {
|
||||||
// Copy ctor implicitly defined as deleted because Private's copy ctor is
|
Private p; // expected-note {{copy constructor of 'Deleted' is implicitly deleted because field 'p' has an inaccessible copy constructor}}
|
||||||
// inaccessible.
|
|
||||||
Private p;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}
|
const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}
|
||||||
|
|
|
@ -214,10 +214,8 @@ namespace CopyCtorIssues {
|
||||||
Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}}
|
Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}}
|
||||||
Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}}
|
Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}}
|
||||||
};
|
};
|
||||||
struct Deleted { // expected-note {{here}}
|
struct Deleted {
|
||||||
// Copy ctor implicitly defined as deleted because Private's copy ctor is
|
Private p; // expected-note {{implicitly deleted}}
|
||||||
// inaccessible.
|
|
||||||
Private p;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}
|
const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}
|
||||||
|
|
|
@ -12,12 +12,12 @@ void f() {
|
||||||
BadDtor dd; // expected-error {{private destructor}}
|
BadDtor dd; // expected-error {{private destructor}}
|
||||||
throw dd; // expected-error {{private destructor}}
|
throw dd; // expected-error {{private destructor}}
|
||||||
}
|
}
|
||||||
struct V { // expected-note {{here}}
|
struct V {
|
||||||
V();
|
V();
|
||||||
BadDtor bd;
|
BadDtor bd; // expected-note {{inaccessible destructor}}
|
||||||
};
|
};
|
||||||
V v; // expected-error {{deleted function}}
|
V v; // expected-error {{deleted function}}
|
||||||
struct W : BadDtor { // expected-note {{here}}
|
struct W : BadDtor { // expected-note {{inaccessible destructor}}
|
||||||
W();
|
W();
|
||||||
};
|
};
|
||||||
W w; // expected-error {{deleted function}}
|
W w; // expected-error {{deleted function}}
|
||||||
|
|
|
@ -6,18 +6,18 @@ struct A { // expected-note 2{{candidate}}
|
||||||
int a = A().n; // expected-error {{no matching constructor}}
|
int a = A().n; // expected-error {{no matching constructor}}
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
B() = delete; // expected-note {{here}}
|
B() = delete; // expected-note 2{{here}}
|
||||||
int n;
|
int n;
|
||||||
};
|
};
|
||||||
int b = B().n; // expected-error {{call to deleted}}
|
int b = B().n; // expected-error {{call to deleted}}
|
||||||
|
|
||||||
struct C { // expected-note {{here}}
|
struct C {
|
||||||
B b;
|
B b; // expected-note {{deleted default constructor}}
|
||||||
};
|
};
|
||||||
int c = C().b.n; // expected-error {{call to implicitly-deleted default}}
|
int c = C().b.n; // expected-error {{call to implicitly-deleted default}}
|
||||||
|
|
||||||
struct D { // expected-note {{defined here}}
|
struct D {
|
||||||
D() = default; // expected-note {{declared here}}
|
D() = default; // expected-note {{here}}
|
||||||
B b;
|
B b;
|
||||||
};
|
};
|
||||||
int d = D().b.n; // expected-error {{call to implicitly-deleted default}}
|
int d = D().b.n; // expected-error {{call to implicitly-deleted default}}
|
||||||
|
@ -34,8 +34,8 @@ struct F {
|
||||||
};
|
};
|
||||||
int f = F().n; // ok
|
int f = F().n; // ok
|
||||||
|
|
||||||
union G { // expected-note {{here}}
|
union G {
|
||||||
F f;
|
F f; // expected-note {{non-trivial default constructor}}
|
||||||
};
|
};
|
||||||
int g = G().f.n; // expected-error {{call to implicitly-deleted default}}
|
int g = G().f.n; // expected-error {{call to implicitly-deleted default}}
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ private:
|
||||||
};
|
};
|
||||||
int h = H().n; // expected-error {{private constructor}}
|
int h = H().n; // expected-error {{private constructor}}
|
||||||
|
|
||||||
struct I { // expected-note {{here}}
|
struct I {
|
||||||
H h;
|
H h; // expected-note {{inaccessible default constructor}}
|
||||||
};
|
};
|
||||||
int i = I().h.n; // expected-error {{call to implicitly-deleted default}}
|
int i = I().h.n; // expected-error {{call to implicitly-deleted default}}
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ struct J {
|
||||||
int j1 = J().n; // ok
|
int j1 = J().n; // ok
|
||||||
int j2 = J().f(); // ok
|
int j2 = J().f(); // ok
|
||||||
|
|
||||||
union K { // expected-note 2{{here}}
|
union K {
|
||||||
J j;
|
J j; // expected-note 2{{non-trivial default constructor}}
|
||||||
int m;
|
int m;
|
||||||
};
|
};
|
||||||
int k1 = K().j.n; // expected-error {{call to implicitly-deleted default}}
|
int k1 = K().j.n; // expected-error {{call to implicitly-deleted default}}
|
||||||
|
|
|
@ -54,9 +54,9 @@ namespace ExceptionSpecification {
|
||||||
// The same problem arises in delayed parsing of default arguments,
|
// The same problem arises in delayed parsing of default arguments,
|
||||||
// which clang does not yet support.
|
// which clang does not yet support.
|
||||||
namespace DefaultArgument {
|
namespace DefaultArgument {
|
||||||
struct Default { // expected-note {{defined here}}
|
struct Default {
|
||||||
struct T {
|
struct T {
|
||||||
T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
|
T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
} t;
|
} t; // expected-note {{has no default constructor}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
|
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
|
||||||
|
|
||||||
struct A { //expected-note {{defined here}} \
|
struct A { // expected-warning {{does not declare any constructor to initialize}}
|
||||||
// expected-warning {{does not declare any constructor to initialize}}
|
const int i; // expected-note{{const member 'i' will never be initialized}} expected-note {{implicitly deleted}}
|
||||||
const int i; // expected-note{{const member 'i' will never be initialized}}
|
|
||||||
virtual void f() { }
|
virtual void f() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue