When overload resolution picks an implicitly-deleted special member
function, provide a specialized diagnostic that indicates the kind of
special member function (default constructor, copy assignment
operator, etc.) and that it was implicitly deleted. Add a hook where
we can provide more detailed information later.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150611 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index d9dadce..8e502ed 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1157,8 +1157,8 @@
 def err_temp_copy_deleted : Error<
   "%select{copying variable|copying parameter|returning object|throwing "
   "object|copying member subobject|copying array element|allocating object|"
-  "copying temporary|initializing base subobject|initializing vector element}0 "
-  "of type %1 invokes deleted constructor|capturing value">;
+  "copying temporary|initializing base subobject|initializing vector element|"
+  "capturing value}0 of type %1 invokes deleted constructor">;
 def err_temp_copy_incomplete : Error<
   "copying a temporary object of incomplete type %0">;
 def warn_cxx98_compat_temp_copy : Warning<
@@ -2104,6 +2104,10 @@
   "reference initialization of type %0 with initializer of type %1 is ambiguous">;
 def err_ovl_deleted_init : Error<
   "call to %select{unavailable|deleted}0 constructor of %1">;
+def err_ovl_deleted_special_init : Error<
+  "call to implicitly-deleted %select{default constructor|copy constructor|"
+  "move constructor|copy assignment operator|move assignment operator|"
+  "destructor|function}0 of %1">;
 def err_ovl_ambiguous_oper_unary : Error<
   "use of overloaded operator '%0' is ambiguous (operand type %1)">;
 def err_ovl_ambiguous_oper_binary : Error<
@@ -2111,6 +2115,10 @@
 def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
 def err_ovl_deleted_oper : Error<
   "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
+def err_ovl_deleted_special_oper : Error<
+  "overload resolution selected implicitly-deleted %select{default constructor|"
+  "copy constructor|move constructor|copy assignment operator|move assignment "
+  "operator|destructor|'%1'}0%2">;
 def err_ovl_no_viable_subscript :
     Error<"no viable overloaded operator[] for type %0">;
 def err_ovl_no_oper :
@@ -4307,6 +4315,8 @@
   "expected at most %1, have %2">;
 def note_callee_decl : Note<
   "%0 declared here">;
+def note_defined_here : Note<"%0 defined here">;
+
 def warn_call_wrong_number_of_arguments : Warning<
   "too %select{few|many}0 arguments in call to %1">;
 def err_atomic_builtin_must_be_pointer : Error<
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 5ac2cd5..0fd4c9f 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3068,6 +3068,10 @@
   /// class.
   void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
 
+  /// \brief Determine whether the given function is an implicitly-deleted
+  /// special member function.
+  bool isImplicitlyDeleted(FunctionDecl *FD);
+  
   /// MaybeBindToTemporary - If the passed in expression has a record type with
   /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
   /// it simply returns the passed in expression.
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 7d30b7f..664a658 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -672,8 +672,14 @@
     // Make an unambiguous representation for anonymous types, e.g.
     //   <anonymous enum at /usr/include/string.h:120:9>
     llvm::raw_string_ostream OS(Buffer);
-    OS << "<anonymous";
-
+    
+    if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
+      OS << "<lambda";
+      HasKindDecoration = true;
+    } else {
+      OS << "<anonymous";
+    }
+    
     if (Policy.AnonymousTagLocations) {
       // Suppress the redundant tag keyword if we just printed one.
       // We don't have to worry about ElaboratedTypes here because you can't
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 2d60900..bcb1381 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -219,7 +219,6 @@
   unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
   unsigned diag_NeverFallThroughOrReturn;
   enum { Function, Block, Lambda } funMode;
-  bool IsLambda;
   SourceLocation FuncLoc;
 
   static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 624dc5d..447a4b4 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -9045,6 +9045,12 @@
   }
 }
 
+bool Sema::isImplicitlyDeleted(FunctionDecl *FD) {
+  return FD->isDeleted() && 
+         (FD->isDefaulted() || FD->isImplicit()) &&
+         isa<CXXMethodDecl>(FD);
+}
+    
 ExprResult
 Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                             CXXConstructorDecl *Constructor,
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 1638693..da6892e 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -5273,6 +5273,26 @@
   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
 //===----------------------------------------------------------------------===//
@@ -5536,17 +5556,33 @@
         break;
 
       case OR_Deleted: {
-        S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
-          << true << DestType << ArgsRange;
         OverloadCandidateSet::iterator Best;
         OverloadingResult Ovl
           = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
-        if (Ovl == OR_Deleted) {
-          S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
-            << 1 << Best->Function->isDeleted();
-        } else {
+        if (Ovl != OR_Deleted) {
+          S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
+            << true << DestType << ArgsRange;
           llvm_unreachable("Inconsistent overload resolution?");
+          break;
         }
+       
+        // If this is a defaulted or implicitly-declared function, then
+        // it was implicitly deleted. Make it clear that the deletion was
+        // implicit.
+        if (S.isImplicitlyDeleted(Best->Function)) {
+          S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
+            << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function)) 
+            << DestType << ArgsRange;
+        
+          diagnoseImplicitlyDeletedFunction(S, 
+            cast<CXXMethodDecl>(Best->Function));            
+          break;
+        }
+        
+        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;
       }
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index b20dc95..2b025da 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -9984,11 +9984,24 @@
       return ExprError();
 
     case OR_Deleted:
-      Diag(OpLoc, diag::err_ovl_deleted_oper)
-        << Best->Function->isDeleted()
-        << BinaryOperator::getOpcodeStr(Opc)
-        << getDeletedOrUnavailableSuffix(Best->Function)
-        << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      if (isImplicitlyDeleted(Best->Function)) {
+        CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
+        Diag(OpLoc, diag::err_ovl_deleted_special_oper)
+          << getSpecialMember(Method)
+          << BinaryOperator::getOpcodeStr(Opc)
+          << getDeletedOrUnavailableSuffix(Best->Function);
+        
+        if (Method->getParent()->isLambda()) {
+          Diag(Method->getParent()->getLocation(), diag::note_lambda_decl);
+          return ExprError();
+        }
+      } else {
+        Diag(OpLoc, diag::err_ovl_deleted_oper)
+          << Best->Function->isDeleted()
+          << BinaryOperator::getOpcodeStr(Opc)
+          << getDeletedOrUnavailableSuffix(Best->Function)
+          << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      }
       CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
                                   BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
index 03f25ba..47efde2 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
@@ -54,9 +54,9 @@
 };
 NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}}
 template<typename...BaseList>
-struct MaybeAggr5a : BaseList... {}; // expected-note {{explicitly marked deleted}}
+struct MaybeAggr5a : BaseList... {}; // expected-note {{defined here}}
 MaybeAggr5a<> ma5a0 = {}; // ok
-MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to deleted constructor of 'MaybeAggr5a<Aggr>'}}
+MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a<Aggr>'}}
 
 // and no virtual functions.
 struct NonAggr6 { // expected-note 3 {{candidate constructor}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
index b5a445c..6fe3b25 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -7,16 +7,13 @@
 
 template<typename T> T &&move(T&);
 void test_special_member_functions(MoveOnly mo, int i) {
-  // FIXME: terrible note
-  auto lambda1 = [i]() { }; // expected-note{{function has been explicitly marked deleted here}} \
-  // expected-note{{the implicit copy assignment operator}} \
-  // expected-note{{the implicit move assignment operator}} \
+  auto lambda1 = [i]() { }; // expected-note 2 {{lambda expression begins here}}
 
   // Default constructor
-  decltype(lambda1) lambda2; // expected-error{{call to deleted constructor}}
+  decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '<lambda}}
 
   // Copy assignment operator
-  lambda1 = lambda1; // expected-error{{overload resolution selected deleted operator '='}}
+  lambda1 = lambda1; // expected-error{{overload resolution selected implicitly-deleted copy assignment operator}}
 
   // Move assignment operator
   lambda1 = move(lambda1);
diff --git a/test/CXX/special/class.copy/implicit-move.cpp b/test/CXX/special/class.copy/implicit-move.cpp
index 74f7eee..cc39af9 100644
--- a/test/CXX/special/class.copy/implicit-move.cpp
+++ b/test/CXX/special/class.copy/implicit-move.cpp
@@ -54,7 +54,7 @@
 
   static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
   HasMoveConstructor hmc;
-  hmc = HasMoveConstructor(); // expected-error {{selected deleted operator}}
+  hmc = HasMoveConstructor(); // expected-error {{selected implicitly-deleted copy assignment}}
 
   (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
   HasMoveAssignment hma;
@@ -87,8 +87,8 @@
   ~PrivateDestructor() noexcept;
 };
 
-struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note {{explicitly marked deleted}}
-struct ContainsPrivateDestructor { // expected-note {{explicitly marked deleted}}
+struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{defined here}}
+struct ContainsPrivateDestructor { // expected-note{{defined here}}
   PrivateDestructor pd;
 };
 
@@ -131,8 +131,8 @@
   ContainsPrivateMove cpm;
   static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
 
-  (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to deleted constructor}}
-  (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to deleted constructor}}
+  (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
+  (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
 
   static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
   static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
diff --git a/test/CXX/special/class.copy/p11.0x.copy.cpp b/test/CXX/special/class.copy/p11.0x.copy.cpp
index 752872a..65fd985 100644
--- a/test/CXX/special/class.copy/p11.0x.copy.cpp
+++ b/test/CXX/special/class.copy/p11.0x.copy.cpp
@@ -9,7 +9,7 @@
   DeletedNTVariant();
 };
 DeletedNTVariant DVa;
-DeletedNTVariant DVb(DVa); // expected-error{{call to deleted constructor}}
+DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct DeletedNTVariant2 { // expected-note{{here}}
   union {
@@ -18,7 +18,7 @@
   DeletedNTVariant2();
 };
 DeletedNTVariant2 DV2a;
-DeletedNTVariant2 DV2b(DV2a); // expected-error{{call to deleted constructor}}
+DeletedNTVariant2 DV2b(DV2a); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct NoAccess {
   NoAccess() = default;
@@ -32,7 +32,7 @@
   NoAccess NA;
 };
 HasNoAccess HNAa;
-HasNoAccess HNAb(HNAa); // expected-error{{call to deleted constructor}}
+HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct HasAccess {
   NoAccess NA;
@@ -55,13 +55,13 @@
   IsAmbiguous();
 };
 IsAmbiguous IAa;
-IsAmbiguous IAb(IAa); // expected-error{{call to deleted constructor}}
+IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct Deleted { // expected-note{{here}}
   IsAmbiguous IA;
 };
 Deleted Da;
-Deleted Db(Da); // expected-error{{call to deleted constructor}}
+Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct NoAccessDtor {
 private:
@@ -75,7 +75,7 @@
   ~HasNoAccessDtor();
 };
 HasNoAccessDtor HNADa;
-HasNoAccessDtor HNADb(HNADa); // expected-error{{call to deleted constructor}}
+HasNoAccessDtor HNADb(HNADa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct HasAccessDtor {
   NoAccessDtor NAD;
@@ -87,4 +87,4 @@
   int && ri = 1;
 };
 RValue RVa;
-RValue RVb(RVa); // expected-error{{call to deleted constructor}}
+RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}}
diff --git a/test/CXX/special/class.ctor/p5-0x.cpp b/test/CXX/special/class.ctor/p5-0x.cpp
index 00c25e8..b2fa0cf 100644
--- a/test/CXX/special/class.ctor/p5-0x.cpp
+++ b/test/CXX/special/class.ctor/p5-0x.cpp
@@ -21,19 +21,22 @@
 
 // - X is a union-like class that has a variant member with a non-trivial
 // default constructor,
-union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{deleted here}}
-Deleted1a d1a; // expected-error {{deleted constructor}}
+union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{defined here}}
+Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
 union NotDeleted1a { DefaultedDefCtor1 nu; };
 NotDeleted1a nd1a;
 // FIXME: clang implements the pre-FDIS rule, under which DefaultedDefCtor2's
 // default constructor is non-trivial.
-union NotDeleted1b { DefaultedDefCtor2 nu; }; // unexpected-note {{deleted here}}
-NotDeleted1b nd1b; // unexpected-error {{deleted constructor}}
+union NotDeleted1b { DefaultedDefCtor2 nu; }; // unexpected-note {{defined here}}
+NotDeleted1b nd1b; // unexpected-error {{implicitly-deleted default constructor}}
 
 // - any non-static data member with no brace-or-equal-initializer is of
 // reference type,
-class Deleted2a { Deleted2a() = default; int &a; }; // expected-note {{deleted here}}
-Deleted2a d2a; // expected-error {{deleted constructor}}
+class Deleted2a {  // expected-note {{defined here}}
+  Deleted2a() = default;  // expected-note {{declared here}}
+  int &a; 
+}; 
+Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
 class NotDeleted2a { int &a = n; };
 NotDeleted2a nd2a;
 class NotDeleted2b { int &a = error; }; // expected-error {{undeclared identifier}}
@@ -45,11 +48,11 @@
 class Deleted3a { const int a; }; // expected-note {{here}} \
                                      expected-warning {{does not declare any constructor}} \
                                      expected-note {{will never be initialized}}
-Deleted3a d3a; // expected-error {{deleted constructor}}
+Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
 class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{here}}
-Deleted3b d3b; // expected-error {{deleted constructor}}
-class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{deleted}}
-Deleted3c d3c; // expected-error {{deleted constructor}}
+Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
+class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{defined here}}
+Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
 class NotDeleted3a { const int a = 0; };
 NotDeleted3a nd3a;
 class NotDeleted3b { const DefaultedDefCtor1 a[42] = {}; };
@@ -60,23 +63,23 @@
 NotDeleted3d nd3d;
 // FIXME: this class should not have a deleted default constructor.
 union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; }; // unexpected-note {{here}}
-NotDeleted3e nd3e; // unexpected-error {{deleted constructor}}
+NotDeleted3e nd3e; // unexpected-error {{implicitly-deleted default constructor}}
 // FIXME: clang implements the pre-FDIS rule, under which DefaultedDefCtor2 is
 // non-trivial.
 union NotDeleted3f { const DefaultedDefCtor2 a; int b; }; // unexpected-note {{here}}
-NotDeleted3f nd3f; // unexpected-error {{deleted constructor}}
+NotDeleted3f nd3f; // unexpected-error {{implicitly-deleted default constructor}}
 
 // - X is a union and all of its variant members are of const-qualified type (or
 // array thereof),
 union Deleted4a { const int a; const int b; const UserProvidedDefCtor c; }; // expected-note {{here}}
-Deleted4a d4a; // expected-error {{deleted constructor}}
+Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
 union Deleted4b { const int a; int b; };
 Deleted4b d4b;
 
 // - X is a non-union class and all members of any anonymous union member are of
 // const-qualified type (or array thereof),
 struct Deleted5a { union { const int a; }; union { int b; }; }; // expected-note {{here}}
-Deleted5a d5a; // expected-error {{deleted constructor}}
+Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted5b { union { const int a; int b; }; union { const int c; int d; }; };
 Deleted5b d5b;
 
@@ -86,17 +89,17 @@
 // constructor results in an ambiguity or in a function that is deleted or
 // inaccessible from the defaulted default constructor, or
 struct Deleted6a : Deleted2a {}; // expected-note {{here}}
-Deleted6a d6a; // expected-error {{deleted constructor}}
+Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted6b : virtual Deleted2a {}; // expected-note {{here}}
-Deleted6b d6b; // expected-error {{deleted constructor}}
+Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted6c { Deleted2a a; }; // expected-note {{here}}
-Deleted6c d6c; // expected-error {{deleted constructor}}
+Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted6d { DeletedDefCtor a; }; // expected-note {{here}}
-Deleted6d d6d; // expected-error {{deleted constructor}}
+Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted6a { DeletedDefCtor a = 0; };
 NotDeleted6a nd6a;
 struct Deleted6e { PrivateDefCtor a; }; // expected-note {{here}}
-Deleted6e d6e; // expected-error {{deleted constructor}}
+Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted6b { PrivateDefCtor a = 0; };
 NotDeleted6b nd6b;
 struct NotDeleted6c { Friend a; };
@@ -106,21 +109,21 @@
 // a destructor that is deleted or inaccessible from the defaulted default
 // constructor.
 struct Deleted7a : DeletedDtor {}; // expected-note {{here}}
-Deleted7a d7a; // expected-error {{deleted constructor}}
+Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7b : virtual DeletedDtor {}; // expected-note {{here}}
-Deleted7b d7b; // expected-error {{deleted constructor}}
+Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7c { DeletedDtor a; }; // expected-note {{here}}
-Deleted7c d7c; // expected-error {{deleted constructor}}
+Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{here}}
-Deleted7d d7d; // expected-error {{deleted constructor}}
+Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7e : PrivateDtor {}; // expected-note {{here}}
-Deleted7e d7e; // expected-error {{deleted constructor}}
+Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7f : virtual PrivateDtor {}; // expected-note {{here}}
-Deleted7f d7f; // expected-error {{deleted constructor}}
+Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7g { PrivateDtor a; }; // expected-note {{here}}
-Deleted7g d7g; // expected-error {{deleted constructor}}
+Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{here}}
-Deleted7h d7h; // expected-error {{deleted constructor}}
+Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted7i : Friend {};
 NotDeleted7i d7i;
 struct NotDeleted7j : virtual Friend {};
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index 16c5664..9df4199 100644
--- a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -7,27 +7,27 @@
   ~non_trivial();
 };
 
-union bad_union { // expected-note {{marked deleted here}}
+union bad_union { // expected-note {{defined here}}
   non_trivial nt;
 };
-bad_union u; // expected-error {{call to deleted constructor}}
-union bad_union2 { // expected-note {{marked deleted here}}
+bad_union u; // expected-error {{call to implicitly-deleted default constructor}}
+union bad_union2 { // expected-note {{defined here}}
   const int i;
 };
-bad_union2 u2; // expected-error {{call to deleted constructor}}
+bad_union2 u2; // expected-error {{call to implicitly-deleted default constructor}}
 
-struct bad_anon { // expected-note {{marked deleted here}}
+struct bad_anon { // expected-note {{defined here}}
   union {
     non_trivial nt;
   };
 };
-bad_anon a; // expected-error {{call to deleted constructor}}
-struct bad_anon2 { // expected-note {{marked deleted here}}
+bad_anon a; // expected-error {{call to implicitly-deleted default constructor}}
+struct bad_anon2 { // expected-note {{defined here}}
   union {
     const int i;
   };
 };
-bad_anon2 a2; // expected-error {{call to deleted constructor}}
+bad_anon2 a2; // expected-error {{call to implicitly-deleted default constructor}}
 
 // This would be great except that we implement
 union good_union {
@@ -48,10 +48,10 @@
 };
 good g;
 
-struct bad_const { // expected-note {{marked deleted here}}
+struct bad_const { // expected-note {{defined here}}
   const good g;
 };
-bad_const bc; // expected-error {{call to deleted constructor}}
+bad_const bc; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct good_const {
   const non_trivial nt;
@@ -65,38 +65,38 @@
   ~no_dtor() = delete;
 };
 
-struct bad_field_default { // expected-note {{marked deleted here}}
+struct bad_field_default { // expected-note {{defined here}}
   no_default nd;
 };
-bad_field_default bfd; // expected-error {{call to deleted constructor}}
-struct bad_base_default : no_default { // expected-note {{marked deleted here}}
+bad_field_default bfd; // expected-error {{call to implicitly-deleted default constructor}}
+struct bad_base_default : no_default { // expected-note {{defined here}}
 };
-bad_base_default bbd; // expected-error {{call to deleted constructor}}
+bad_base_default bbd; // expected-error {{call to implicitly-deleted default constructor}}
 
-struct bad_field_dtor { // expected-note {{marked deleted here}}
+struct bad_field_dtor { // expected-note {{defined here}}
   no_dtor nd;
 };
-bad_field_dtor bfx; // expected-error {{call to deleted constructor}}
-struct bad_base_dtor : no_dtor { // expected-note {{marked deleted here}}
+bad_field_dtor bfx; // expected-error {{call to implicitly-deleted default constructor}}
+struct bad_base_dtor : no_dtor { // expected-note {{defined here}}
 };
-bad_base_dtor bbx; // expected-error {{call to deleted constructor}}
+bad_base_dtor bbx; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct ambiguous_default {
   ambiguous_default();
   ambiguous_default(int = 2);
 };
-struct has_amb_field { // expected-note {{marked deleted here}}
+struct has_amb_field { // expected-note {{defined here}}
   ambiguous_default ad;
 };
-has_amb_field haf; // expected-error {{call to deleted constructor}}
+has_amb_field haf; // expected-error {{call to implicitly-deleted default constructor}}
 
 class inaccessible_default {
   inaccessible_default();
 };
-struct has_inacc_field { // expected-note {{marked deleted here}}
+struct has_inacc_field { // expected-note {{defined here}}
   inaccessible_default id;
 };
-has_inacc_field hif; // expected-error {{call to deleted constructor}}
+has_inacc_field hif; // expected-error {{call to implicitly-deleted default constructor}}
 
 class friend_default {
   friend struct has_friend;
@@ -107,11 +107,11 @@
 };
 has_friend hf;
 
-struct defaulted_delete {
+struct defaulted_delete { // expected-note {{defined here}}
   no_default nd;
-  defaulted_delete() = default; // expected-note {{marked deleted here}}
+  defaulted_delete() = default; // expected-note{{declared here}}
 };
-defaulted_delete dd; // expected-error {{call to deleted constructor}}
+defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct late_delete {
   no_default nd;
@@ -121,12 +121,12 @@
 
 // See also rdar://problem/8125400.
 namespace empty {
-  static union {}; // expected-error {{deleted constructor}} expected-note {{here}}
+  static union {}; // expected-error {{implicitly-deleted default constructor}} expected-note {{here}}
   static union { union {}; };
   static union { struct {}; };
   static union { union { union {}; }; };
   static union { union { struct {}; }; };
-  static union { struct { union {}; }; }; // expected-error {{deleted constructor}} expected-note {{here}}
+  static union { struct { union {}; }; }; // expected-error {{implicitly-deleted default constructor}} expected-note {{here}}
   static union { struct { struct {}; }; };
 }
 
diff --git a/test/SemaCXX/dr1301.cpp b/test/SemaCXX/dr1301.cpp
index e3d63be..a348977 100644
--- a/test/SemaCXX/dr1301.cpp
+++ b/test/SemaCXX/dr1301.cpp
@@ -14,13 +14,13 @@
 struct C { // expected-note {{here}}
   B b;
 };
-int c = C().b.n; // expected-error {{call to deleted}}
+int c = C().b.n; // expected-error {{call to implicitly-deleted default}}
 
-struct D {
-  D() = default; // expected-note {{here}}
+struct D { // expected-note {{defined here}}
+  D() = default; // expected-note {{declared here}}
   B b;
 };
-int d = D().b.n; // expected-error {{call to deleted}}
+int d = D().b.n; // expected-error {{call to implicitly-deleted default}}
 
 struct E {
   E() = default;
@@ -37,7 +37,7 @@
 union G { // expected-note {{here}}
   F f;
 };
-int g = G().f.n; // expected-error {{call to deleted}}
+int g = G().f.n; // expected-error {{call to implicitly-deleted default}}
 
 struct H {
   int n;
@@ -49,7 +49,7 @@
 struct I { // expected-note {{here}}
   H h;
 };
-int i = I().h.n; // expected-error {{call to deleted}}
+int i = I().h.n; // expected-error {{call to implicitly-deleted default}}
 
 struct J {
   J();
@@ -63,5 +63,5 @@
   J j;
   int m;
 };
-int k1 = K().j.n; // expected-error {{call to deleted}}
-int k2 = K().j.f(); // expected-error {{call to deleted}}
+int k1 = K().j.n; // expected-error {{call to implicitly-deleted default}}
+int k2 = K().j.f(); // expected-error {{call to implicitly-deleted default}}
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index 559c301..f8ee767 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -54,10 +54,9 @@
 // The same problem arises in delayed parsing of default arguments,
 // which clang does not yet support.
 namespace DefaultArgument {
-  // FIXME: this diagnostic is completely wrong.
-  struct Default { // expected-note {{explicitly marked deleted here}}
+  struct Default { // expected-note {{defined here}}
     struct T {
-      T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to deleted constructor}}
+      T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
     } t;
   };
 }
diff --git a/test/SemaCXX/value-initialization.cpp b/test/SemaCXX/value-initialization.cpp
index 19be03a..3b552e2 100644
--- a/test/SemaCXX/value-initialization.cpp
+++ b/test/SemaCXX/value-initialization.cpp
@@ -1,11 +1,11 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
 
-struct A { //expected-note {{marked deleted here}} \
+struct A { //expected-note {{defined here}} \
      // expected-warning {{does not declare any constructor to initialize}}
      const int i; // expected-note{{const member 'i' will never be initialized}}
      virtual void f() { } 
 };
 
 int main () {
-      (void)A(); // expected-error {{call to deleted constructor}}
+      (void)A(); // expected-error {{call to implicitly-deleted default constructor}}
 }