[clang] Add fix-it note to defaulted-function-deleted warning

Adds a fix to the diagnostic of replacing the `= default` to `= delete`

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D134549
This commit is contained in:
Nathan James 2022-10-04 19:38:09 +01:00
parent 266ec801fb
commit 1376c73927
No known key found for this signature in database
GPG Key ID: CC007AFCDA90AA5F
22 changed files with 139 additions and 67 deletions

View File

@ -229,6 +229,8 @@ Improvements to Clang's diagnostics
doesn't generate strange cascading errors, particularly in cases where a
subsuming constraint fails, which would result in a less-specific overload to
be selected.
- Add a fix-it hint for the ``-Wdefaulted-function-deleted`` warning to
explicitly delete the function.
Non-comprehensive list of changes in this release
-------------------------------------------------

View File

@ -1944,6 +1944,8 @@ private:
/// EndRangeLoc.
SourceLocation EndRangeLoc;
SourceLocation DefaultKWLoc;
/// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
@ -2250,6 +2252,17 @@ public:
FunctionDeclBits.IsExplicitlyDefaulted = ED;
}
SourceLocation getDefaultLoc() const {
return isExplicitlyDefaulted() ? DefaultKWLoc : SourceLocation();
}
void setDefaultLoc(SourceLocation NewLoc) {
assert(NewLoc.isInvalid() ||
isExplicitlyDefaulted() &&
"Can't set default loc is function isn't explicitly defaulted");
DefaultKWLoc = NewLoc;
}
/// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {

View File

@ -9261,6 +9261,8 @@ def err_incorrect_defaulted_consteval : Error<
def warn_defaulted_method_deleted : Warning<
"explicitly defaulted %sub{select_special_member_kind}0 is implicitly "
"deleted">, InGroup<DefaultedFunctionDeleted>;
def note_replace_equals_default_to_delete : Note<
"replace 'default' with 'delete'">;
def err_out_of_line_default_deletes : Error<
"defaulting this %sub{select_special_member_kind}0 "
"would delete it after its first declaration">;

View File

@ -7631,7 +7631,8 @@ public:
void CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *MD);
bool CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
CXXSpecialMember CSM);
CXXSpecialMember CSM,
SourceLocation DefaultLoc);
void CheckDelayedMemberExceptionSpecs();
bool CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *MD,

View File

@ -3587,6 +3587,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
auto TInfo = importChecked(Err, FromTSI);
auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
auto ToEndLoc = importChecked(Err, D->getEndLoc());
auto ToDefaultLoc = importChecked(Err, D->getDefaultLoc());
auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
auto TrailingRequiresClause =
importChecked(Err, D->getTrailingRequiresClause());
@ -3707,6 +3708,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ToFunction->setFriendConstraintRefersToEnclosingTemplate(
D->FriendConstraintRefersToEnclosingTemplate());
ToFunction->setRangeEnd(ToEndLoc);
ToFunction->setDefaultLoc(ToDefaultLoc);
// Set the parameters.
for (auto *Param : Parameters) {

View File

@ -7410,13 +7410,15 @@ void Sema::CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *FD) {
if (DefKind.isSpecialMember()
? CheckExplicitlyDefaultedSpecialMember(cast<CXXMethodDecl>(FD),
DefKind.asSpecialMember())
DefKind.asSpecialMember(),
FD->getDefaultLoc())
: CheckExplicitlyDefaultedComparison(S, FD, DefKind.asComparison()))
FD->setInvalidDecl();
}
bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
CXXSpecialMember CSM) {
CXXSpecialMember CSM,
SourceLocation DefaultLoc) {
CXXRecordDecl *RD = MD->getParent();
assert(MD->isExplicitlyDefaulted() && CSM != CXXInvalid &&
@ -7608,8 +7610,11 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
Diag(MD->getLocation(), diag::warn_defaulted_method_deleted) << CSM;
if (ShouldDeleteForTypeMismatch) {
Diag(MD->getLocation(), diag::note_deleted_type_mismatch) << CSM;
} else {
ShouldDeleteSpecialMember(MD, CSM, nullptr, /*Diagnose*/true);
} else if (ShouldDeleteSpecialMember(MD, CSM, nullptr,
/*Diagnose*/ true) &&
DefaultLoc.isValid()) {
Diag(DefaultLoc, diag::note_replace_equals_default_to_delete)
<< FixItHint::CreateReplacement(DefaultLoc, "delete");
}
}
if (ShouldDeleteForTypeMismatch && !HadError) {
@ -8708,6 +8713,9 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
DefaultedComparisonAnalyzer(*this, RD, FD, DCK,
DefaultedComparisonAnalyzer::ExplainDeleted)
.visit();
if (FD->getDefaultLoc().isValid())
Diag(FD->getDefaultLoc(), diag::note_replace_equals_default_to_delete)
<< FixItHint::CreateReplacement(FD->getDefaultLoc(), "delete");
}
return false;
}
@ -17530,6 +17538,7 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
FD->setDefaulted();
FD->setExplicitlyDefaulted();
FD->setDefaultLoc(DefaultLoc);
// Defer checking functions that are defaulted in a dependent context.
if (FD->isDependentContext())
@ -17569,7 +17578,8 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
} else {
auto *MD = cast<CXXMethodDecl>(FD);
if (CheckExplicitlyDefaultedSpecialMember(MD, DefKind.asSpecialMember()))
if (CheckExplicitlyDefaultedSpecialMember(MD, DefKind.asSpecialMember(),
DefaultLoc))
MD->setInvalidDecl();
else
DefineDefaultedFunction(*this, MD, DefaultLoc);

View File

@ -934,6 +934,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
FD->EndRangeLoc = readSourceLocation();
FD->setDefaultLoc(readSourceLocation());
FD->ODRHash = Record.readInt();
FD->setHasODRHash(true);

View File

@ -566,6 +566,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->FriendConstraintRefersToEnclosingTemplate());
Record.push_back(D->getLinkageInternal());
Record.AddSourceLocation(D->getEndLoc());
Record.AddSourceLocation(D->getDefaultLoc());
Record.push_back(D->getODRHash());
@ -2289,6 +2290,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FriendConstraintRefersToEnclosingTemplate
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Default
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
// This Array slurps the rest of the record. Fortunately we want to encode

View File

@ -43,7 +43,7 @@ struct G : D {};
// expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}}
// expected-note@-4 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
struct H : D { // expected-note {{deleted because base class 'D' has an inaccessible move assignment}}
H &operator=(H&&) = default; // expected-warning {{implicitly deleted}}
H &operator=(H&&) = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
// expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}}
// expected-note@-3 {{move assignment operator of 'H' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
~H();

View File

@ -11,7 +11,7 @@ struct A {
friend bool operator!=(const B&, const B&) = default; // expected-error {{invalid parameter type for defaulted equality comparison}}
friend bool operator<(const A&, const A&);
friend bool operator<(const B&, const B&) = default; // expected-error {{invalid parameter type for defaulted relational comparison}}
friend bool operator>(A, A) = default; // expected-warning {{implicitly deleted}}
friend bool operator>(A, A) = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
bool operator<(const A&) const;
bool operator<=(const A&) const = default;
@ -87,11 +87,11 @@ namespace LookupContext {
bool operator>=(const B&, const B&); // expected-note 2{{best match}}
struct B {
bool operator!=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}}
bool operator<(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}}
bool operator<=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}}
bool operator>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}}
bool operator>=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}}
bool operator!=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
bool operator<(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
bool operator<=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
bool operator>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
bool operator>=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
};
return B();
}
@ -144,7 +144,7 @@ namespace P1946 {
struct B {
A a; // expected-note {{no viable three-way comparison}}
friend bool operator==(B, B) = default; // ok
friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}}
friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
}

View File

@ -4,8 +4,8 @@ struct A1 {
int x;
int &y; // expected-note 9{{because class 'A1' has a reference member}}
bool operator==(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 2{{deleted here}}
bool operator<=>(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 5{{deleted here}}
bool operator==(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 2{{deleted here}} expected-note{{replace 'default'}}
bool operator<=>(const A1&) const = default; // expected-warning {{implicitly deleted}} expected-note 5{{deleted here}} expected-note{{replace 'default'}}
};
struct A2 {
int x;
@ -42,8 +42,8 @@ void f(A2 a) {
struct A3 {
int &x; // expected-note {{because class 'A3' has a reference member}}
bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}}
bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}}
bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'A3'}}
};
@ -53,8 +53,8 @@ struct B1 {
int &y; // expected-note 2{{because class 'B1' has a reference member}}
};
bool operator==(const B1&) const = default; // expected-warning {{implicitly deleted}}
bool operator<=>(const B1&) const = default; // expected-warning {{implicitly deleted}}
bool operator==(const B1&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
bool operator<=>(const B1&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
};
struct B2 {
@ -76,8 +76,8 @@ struct B2 {
union C1 {
int a;
bool operator==(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }}
bool operator<=>(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }}
bool operator==(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} expected-note{{replace 'default'}}
bool operator<=>(const C1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'C1' is a union }} expected-note{{replace 'default'}}
};
union C2 {
@ -98,8 +98,8 @@ struct D1 {
int a;
};
bool operator==(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}}
bool operator<=>(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}}
bool operator==(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} expected-note{{replace 'default'}}
bool operator<=>(const D1&) const = default; // expected-warning {{implicitly deleted}} expected-note {{because 'D1' is a union-like class}} expected-note{{replace 'default'}}
};
struct D2 {
union {

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -std=c++20 -verify %s
struct A {
bool operator!=(const A&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}}
bool operator!=(const A&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{defaulted 'operator!=' is implicitly deleted because there is no viable 'operator==' for 'A'}}
};
@ -9,7 +9,7 @@ struct Q {};
bool operator!=(Q, Q); // expected-note {{defaulted 'operator!=' is implicitly deleted because this non-rewritten comparison function would be the best match for the comparison}}
struct B {
operator Q() const;
bool operator!=(const B&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}}
bool operator!=(const B&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
};
struct R {};
@ -21,18 +21,18 @@ struct B2 {
struct C {
operator int() const; // expected-note {{defaulted 'operator!=' is implicitly deleted because a builtin comparison function using this conversion would be the best match for the comparison}}
bool operator!=(const C&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}}
bool operator!=(const C&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
};
struct D {
bool operator<(const D&) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
bool operator<(const D&) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{defaulted 'operator<' is implicitly deleted because there is no viable three-way comparison function for 'D'}}
};
bool operator<(Q, Q); // expected-note {{defaulted 'operator<' is implicitly deleted because this non-rewritten comparison function would be the best match for the comparison}}
struct E {
operator Q() const;
bool operator<(const E&) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
bool operator<(const E&) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
};
int operator<=>(R, R);
@ -43,5 +43,5 @@ struct E2 {
struct F {
operator int() const; // expected-note {{defaulted 'operator<' is implicitly deleted because a builtin comparison function using this conversion would be the best match for the comparison}}
bool operator<(const F&) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}}
bool operator<(const F&) const = default; // expected-warning {{explicitly defaulted relational comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
};

View File

@ -17,19 +17,19 @@ struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here
struct H1 {
bool operator==(const H1 &) const = default;
bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}}
bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'H1'}}
void (*x)();
};
struct H2 {
bool operator==(const H2 &) const = default;
bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}}
bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'H2'}}
void (H2::*x)();
};
struct H3 {
bool operator==(const H3 &) const = default;
bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}}
bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'H3'}}
int H3::*x;
};
@ -72,8 +72,8 @@ namespace Access {
bool operator==(const A &) const; // expected-note 2{{implicitly declared private here}}
};
struct B : A { // expected-note 2{{because it would invoke a private 'operator==' to compare base class 'A'}}
bool operator==(const B &) const = default; // expected-warning {{deleted}}
friend bool operator==(const B &, const B &) = default; // expected-warning {{deleted}}
bool operator==(const B &) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
friend bool operator==(const B &, const B &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
class C {
@ -86,8 +86,8 @@ namespace Access {
};
struct E {
C c; // expected-note 2{{because it would invoke a protected 'operator==' member of 'Access::C' to compare member 'c'}}
bool operator==(const E &) const = default; // expected-warning {{deleted}}
friend bool operator==(const E &, const E &) = default; // expected-warning {{deleted}}
bool operator==(const E &) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
friend bool operator==(const E &, const E &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
struct F : C {
@ -103,8 +103,8 @@ namespace Access {
using C::operator==; // expected-note 2{{declared private here}}
};
struct I : H { // expected-note 2{{private 'operator==' to compare base class 'H'}}
bool operator==(const I&) const = default; // expected-warning {{deleted}}
friend bool operator==(const I&, const I&) = default; // expected-warning {{deleted}}
bool operator==(const I&) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
friend bool operator==(const I&, const I&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
class J {

View File

@ -22,10 +22,10 @@ namespace Rel {
struct B {
bool operator<=>(B) const = delete; // expected-note 4{{deleted here}} expected-note-re 8{{candidate {{.*}} deleted}}
friend bool operator<(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}}
friend bool operator<=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}}
friend bool operator>(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}}
friend bool operator>=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}}
friend bool operator<(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}
friend bool operator<=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}
friend bool operator>(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}
friend bool operator>=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}
};
bool b1 = B() < B(); // expected-error {{deleted}}
bool b2 = B() <= B(); // expected-error {{deleted}}
@ -36,7 +36,7 @@ namespace Rel {
friend bool operator<=>(const C&, const C&);
friend bool operator<(const C&, const C&); // expected-note {{because this non-rewritten comparison function would be the best match}}
bool operator<(const C&) const = default; // expected-warning {{implicitly deleted}}
bool operator<(const C&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
bool operator>(const C&) const = default; // OK
};
}
@ -53,7 +53,7 @@ namespace NotEqual {
struct B {
bool operator==(B) const = delete; // expected-note {{deleted here}} expected-note-re 2{{candidate {{.*}} deleted}}
friend bool operator!=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}}
friend bool operator!=(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note {{because it would invoke a deleted comparison}} expected-note-re {{candidate {{.*}} deleted}} expected-note{{replace 'default'}}
};
bool b = B() != B(); // expected-error {{deleted}}
@ -61,15 +61,15 @@ namespace NotEqual {
friend bool operator==(const C&, const C&);
friend bool operator!=(const C&, const C&); // expected-note {{because this non-rewritten comparison function would be the best match}}
bool operator!=(const C&) const = default; // expected-warning {{implicitly deleted}}
bool operator!=(const C&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
};
// Ensure we don't go into an infinite loop diagnosing this: the first function
// is deleted because it calls the second function, which is deleted because it
// calls the first.
struct Evil {
friend bool operator!=(const Evil&, const Evil&) = default; // expected-warning {{implicitly deleted}} expected-note {{would be the best match}}
bool operator!=(const Evil&) const = default; // expected-warning {{implicitly deleted}} expected-note {{would be the best match}}
friend bool operator!=(const Evil&, const Evil&) = default; // expected-warning {{implicitly deleted}} expected-note {{would be the best match}} expected-note{{replace 'default'}}
bool operator!=(const Evil&) const = default; // expected-warning {{implicitly deleted}} expected-note {{would be the best match}} expected-note{{replace 'default'}}
};
}
@ -78,7 +78,7 @@ namespace Access {
int operator<=>(A) const; // expected-note {{private}}
};
struct B : A {
friend bool operator<(const B&, const B&) = default; // expected-warning {{implicitly deleted}}
friend bool operator<(const B&, const B&) = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-1 {{defaulted 'operator<' is implicitly deleted because it would invoke a private 'operator<=>' member of 'Access::A'}}
};
}

View File

@ -150,7 +150,7 @@ namespace Access {
};
struct B {
A a; // expected-note {{would invoke a private 'operator<=>'}}
friend std::strong_ordering operator<=>(const B &, const B &) = default; // expected-warning {{deleted}}
friend std::strong_ordering operator<=>(const B &, const B &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
class C {
@ -160,7 +160,7 @@ namespace Access {
};
struct D {
C c; // expected-note {{would invoke a private 'operator=='}}
friend std::strong_ordering operator<=>(const D &, const D &) = default; // expected-warning {{deleted}}
friend std::strong_ordering operator<=>(const D &, const D &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
}

View File

@ -42,7 +42,7 @@ namespace DeducedNotCat {
};
struct B {
A a; // expected-note {{return type 'A' of three-way comparison for member 'a' is not a standard comparison category type}}
auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}}
auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
};
}
@ -53,7 +53,7 @@ namespace DeducedVsSynthesized {
};
struct B {
A a; // expected-note {{no viable three-way comparison function for member 'a'}}
auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}}
auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
};
}
@ -122,6 +122,7 @@ namespace PR44723 {
friend auto operator<=>(const d&, const d&) = default; // #d
// expected-error@#d {{return type of defaulted 'operator<=>' cannot be deduced because three-way comparison for base class 'c' has a deduced return type and is not yet defined}}
// expected-warning@#d {{implicitly deleted}}
// expected-note@#d {{replace 'default'}}
};
auto c::operator<=>(const c&) const& { // #c
return std::strong_ordering::equal;
@ -158,17 +159,17 @@ namespace BadDeducedType {
namespace PR48856 {
struct A {
auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}}
auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
void (*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}}
};
struct B {
auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}}
auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
void (B::*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}}
};
struct C {
auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}}
auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
int C::*x; // expected-note {{because there is no viable three-way comparison function for member 'x'}}
};
}
@ -198,7 +199,7 @@ namespace PR50591 {
operator fp() const;
};
struct b3 {
auto operator<=>(b3 const &) const = default; // expected-warning {{implicitly deleted}}
auto operator<=>(b3 const &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
a3 f; // expected-note {{because there is no viable three-way comparison function}}
};

View File

@ -776,7 +776,7 @@ namespace dr666 { // dr666: yes
#if __cplusplus >= 201103L
namespace dr667 { // dr667: yes
struct A {
A() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}}
A() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note{{replace 'default'}}
int &r; // expected-note {{because field 'r' of reference type 'int &' would not be initialized}}
};
static_assert(!__is_trivially_constructible(A), "");

View File

@ -113,7 +113,7 @@ has_friend hf;
struct defaulted_delete {
no_default nd; // expected-note 2{{because field 'nd' has a deleted default constructor}}
defaulted_delete() = default; // expected-note{{implicitly deleted here}} expected-warning {{implicitly deleted}}
defaulted_delete() = default; // expected-note{{implicitly deleted here}} expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
};
defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}

View File

@ -17,7 +17,7 @@ struct C {
int c = C().b.n; // expected-error {{call to implicitly-deleted default}}
struct D {
D() = default; // expected-note {{here}} expected-warning {{implicitly deleted}}
D() = default; // expected-note {{here}} expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
B b; // expected-note 2{{'b' has a deleted default constructor}}
};
int d = D().b.n; // expected-error {{call to implicitly-deleted default}}

View File

@ -0,0 +1,38 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
struct Deleted {
Deleted() = delete; // expected-note 3{{marked deleted here}}
Deleted(const Deleted &) = delete; // expected-note 2{{marked deleted here}}
Deleted(Deleted &&) = delete; // expected-note 2{{marked deleted here}}
Deleted &operator=(const Deleted &) = delete; // expected-note 2{{marked deleted here}}
Deleted &operator=(Deleted &&) = delete; // expected-note 2{{marked deleted here}}
~Deleted() = delete; // expected-note 2{{marked deleted here}}
};
struct Derive : Deleted { // expected-note 6{{because base class}}
Derive() = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Derive(const Derive &) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Derive(Derive &&) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Derive &operator=(const Derive &) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Derive &operator=(Derive &&) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
~Derive() = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
};
struct Member {
Deleted A; // expected-note 6{{because field 'A'}}
Member() = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Member(const Member &) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Member(Member &&) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Member &operator=(const Member &) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
Member &operator=(Member &&) = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
~Member() = default; // expected-warning{{explicitly defaulted}} expected-note{{replace 'default' with 'delete'}}
};
template<typename T>
struct TDerive : T { // expected-note {{because base class}}
TDerive() = default; //expected-note {{explicitly defaulted}} // Don't expect a fix note to be emitted
};
using ShouldDelete = TDerive<Deleted>;
ShouldDelete A; // expected-error{{call to implicitly-deleted}}

View File

@ -7,7 +7,7 @@ struct S {
} s; // expected-error {{attempt to use a deleted function}}
struct T { // expected-note 2{{virtual destructor requires an unambiguous, accessible 'operator delete'}}
virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}} expected-warning {{implicitly deleted}}
virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}} expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
void operator delete(void*, int);
void operator delete(void*, double);
} t; // expected-error {{attempt to use a deleted function}}

View File

@ -121,12 +121,12 @@ namespace test_union {
union U1 {
__weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}}
~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}}
U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}}
U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}}
U1 & operator=(const U1 &) = default; // expected-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}}
U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}}
U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}} expected-note{{replace 'default'}}
U1 & operator=(const U1 &) = default; // expected-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}} expected-note{{replace 'default'}}
};
id getStrong();