"%select{unavailable|deleted|deprecated}1 here">;
def note_implicitly_deleted : Note<
"explicitly defaulted function was implicitly deleted here">;
+def note_inherited_deleted_here : Note<
+ "deleted constructor was inherited here">;
+def note_cannot_inherit : Note<
+ "constructor cannot be inherited">;
def warn_not_enough_argument : Warning<
"not enough variable arguments in %0 declaration to fit a sentinel">,
InGroup<Sentinel>;
}
bool Sema::isImplicitlyDeleted(FunctionDecl *FD) {
- return FD->isDeleted() &&
- (FD->isDefaulted() || FD->isImplicit()) &&
- isa<CXXMethodDecl>(FD);
+ return FD->isDeleted() && FD->isDefaulted() && isa<CXXMethodDecl>(FD);
}
/// \brief Mark the call operator of the given lambda closure type as "used".
return Result;
}
-/// \brief Emit a note explaining that this function is deleted or unavailable.
+/// \brief Emit a note explaining that this function is deleted.
void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
+ assert(Decl->isDeleted());
+
CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Decl);
- if (Method && Method->isDeleted() && !Method->isDeletedAsWritten()) {
+ if (Method && Method->isDeleted() && Method->isDefaulted()) {
// If the method was explicitly defaulted, point at that declaration.
if (!Method->isImplicit())
Diag(Decl->getLocation(), diag::note_implicitly_deleted);
return;
}
+ if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Decl)) {
+ if (CXXConstructorDecl *BaseCD =
+ const_cast<CXXConstructorDecl*>(CD->getInheritedConstructor())) {
+ Diag(Decl->getLocation(), diag::note_inherited_deleted_here);
+ if (BaseCD->isDeleted()) {
+ NoteDeletedFunction(BaseCD);
+ } else {
+ // FIXME: An explanation of why exactly it can't be inherited
+ // would be nice.
+ Diag(BaseCD->getLocation(), diag::note_cannot_inherit);
+ }
+ return;
+ }
+ }
+
Diag(Decl->getLocation(), diag::note_unavailable_here)
- << 1 << Decl->isDeleted();
+ << 1 << true;
}
/// \brief Determine whether a FunctionDecl was ever declared with an
// Per a core issue (no number yet), an ellipsis is always dropped.
struct A {
A(...); // expected-note {{here}}
- A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 9{{here}}
+ A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 9{{here}} expected-note 2{{constructor cannot be inherited}}
A(int = 0, int = 0, ...); // expected-note {{here}}
template<typename T> A(T, int = 0, ...); // expected-note 5{{here}}
- template<typename T, int N> A(const T (&)[N]); // expected-note 2{{here}}
+ template<typename T, int N> A(const T (&)[N]); // expected-note 2{{here}} expected-note {{constructor cannot be inherited}}
template<typename T, int N> A(const T (&)[N], int = 0); // expected-note 2{{here}}
};
struct B : A { // expected-note 6{{candidate}}
- using A::A; // expected-warning 4{{inheriting constructor does not inherit ellipsis}} expected-note 16{{candidate}} expected-note 3{{deleted}}
+ using A::A; // expected-warning 4{{inheriting constructor does not inherit ellipsis}} expected-note 16{{candidate}} expected-note 3{{deleted constructor was inherited here}}
};
struct C {} c;
B b0{};
-// expected-error@-1 {{call to implicitly-deleted default constructor}}
+// expected-error@-1 {{call to implicitly-deleted default constructor of 'B'}}
// expected-note@-8 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}}
B b1{1};
-// FIXME: explain why the inheriting constructor was deleted
-// expected-error@-2 {{call to implicitly-deleted function of 'B'}}
+// expected-error@-1 {{call to deleted constructor of 'B'}}
B b2{1,2};
-// expected-error@-1 {{call to implicitly-deleted function of 'B'}}
+// expected-error@-1 {{call to deleted constructor of 'B'}}
B b3{1,2,3};
// ok
// It is deleted if the corresponding constructor [...] is deleted.
struct G {
- G(int) = delete;
- template<typename T> G(T*) = delete;
+ G(int) = delete; // expected-note {{function has been explicitly marked deleted here}}
+ template<typename T> G(T*) = delete; // expected-note {{function has been explicitly marked deleted here}}
};
struct H : G {
- using G::G; // expected-note 2{{marked deleted here}}
+ using G::G; // expected-note 2{{deleted constructor was inherited here}}
};
-H h1(5); // expected-error {{call to implicitly-deleted function of 'H'}}
+H h1(5); // expected-error {{call to deleted constructor of 'H'}}
H h2("foo"); // expected-error {{call to deleted constructor of 'H'}}
namespace DRnnnn {
struct A {
constexpr A(int, float = 0) {}
- explicit A(int, int = 0) {}
+ explicit A(int, int = 0) {} // expected-note {{constructor cannot be inherited}}
A(int, int, int = 0) = delete;
};
struct B : A {
- // FIXME: produce notes indicating why it was deleted
using A::A; // expected-note {{here}}
};
constexpr B b0(0, 0.0f); // ok, constexpr
- B b1(0, 1); // expected-error {{call to implicitly-deleted}}
+ B b1(0, 1); // expected-error {{call to deleted constructor of 'DRnnnn::B'}}
}