r356599 - [Sema] Deduplicate some availability checking logic

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 20 12:26:33 PDT 2019


Author: epilk
Date: Wed Mar 20 12:26:33 2019
New Revision: 356599

URL: http://llvm.org/viewvc/llvm-project?rev=356599&view=rev
Log:
[Sema] Deduplicate some availability checking logic

Before this commit, we emit unavailable errors for calls to functions during
overload resolution, and for references to all other declarations in
DiagnoseUseOfDecl. The early checks during overload resolution aren't as good as
the DiagnoseAvailabilityOfDecl based checks, as they error on the code from
PR40991. This commit fixes this by removing the early checking.

llvm.org/PR40991
rdar://48564179

Differential revision: https://reviews.llvm.org/D59394

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/Sema/enable_if.c
    cfe/trunk/test/Sema/overloadable.c
    cfe/trunk/test/SemaCXX/attr-unavailable.cpp
    cfe/trunk/test/SemaCXX/coroutines.cpp
    cfe/trunk/test/SemaObjCXX/overload.mm
    cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar 20 12:26:33 2019
@@ -3605,12 +3605,11 @@ def err_ovl_no_viable_member_function_in
   "no matching member function for call to %0">;
 def err_ovl_ambiguous_call : Error<
   "call to %0 is ambiguous">;
-def err_ovl_deleted_call : Error<
-  "call to %select{unavailable|deleted}0 function %1%2">;
+def err_ovl_deleted_call : Error<"call to deleted function %0">;
 def err_ovl_ambiguous_member_call : Error<
   "call to member function %0 is ambiguous">;
 def err_ovl_deleted_member_call : Error<
-  "call to %select{unavailable|deleted}0 member function %1%2">;
+  "call to deleted member function %0">;
 def note_ovl_too_many_candidates : Note<
     "remaining %0 candidate%s0 omitted; "
     "pass -fshow-overloads=all to show them">;
@@ -3824,7 +3823,7 @@ def err_ovl_ambiguous_init : Error<"call
 def err_ref_init_ambiguous : Error<
   "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">;
+  "call to deleted constructor of %0">;
 def err_ovl_deleted_special_init : Error<
   "call to implicitly-deleted %select{default constructor|copy constructor|"
   "move constructor|copy assignment operator|move assignment operator|"
@@ -3836,7 +3835,7 @@ def err_ovl_ambiguous_oper_binary : Erro
 def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
 def note_assign_lhs_incomplete : Note<"type %0 is incomplete">;
 def err_ovl_deleted_oper : Error<
-  "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
+  "overload resolution selected deleted operator '%0'">;
 def err_ovl_deleted_special_oper : Error<
   "object of type %0 cannot be %select{constructed|copied|moved|assigned|"
   "assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">;
@@ -3857,7 +3856,7 @@ def err_ovl_no_viable_object_call : Erro
 def err_ovl_ambiguous_object_call : Error<
   "call to object of type %0 is ambiguous">;
 def err_ovl_deleted_object_call : Error<
-  "call to %select{unavailable|deleted}0 function call operator in type %1%2">;
+  "call to deleted function call operator in type %0">;
 def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">;
 def err_member_call_without_object : Error<
   "call to non-static member function without an object argument">;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 20 12:26:33 2019
@@ -2634,13 +2634,6 @@ public:
   bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl,
                   bool ConsiderCudaAttrs = true);
 
-  /// Checks availability of the function depending on the current
-  /// function context.Inside an unavailable function,unavailability is ignored.
-  ///
-  /// \returns true if \p FD is unavailable and current context is inside
-  /// an available function, false otherwise.
-  bool isFunctionConsideredUnavailable(FunctionDecl *FD);
-
   ImplicitConversionSequence
   TryImplicitConversion(Expr *From, QualType ToType,
                         bool SuppressUserConversions,
@@ -4102,7 +4095,6 @@ public:
                          ObjCInterfaceDecl *ClassReciever = nullptr);
   void NoteDeletedFunction(FunctionDecl *FD);
   void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD);
-  std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
                                         ObjCMethodDecl *Getter,
                                         SourceLocation Loc);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Mar 20 12:26:33 2019
@@ -333,17 +333,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *
   return false;
 }
 
-/// Retrieve the message suffix that should be added to a
-/// diagnostic complaining about the given function being deleted or
-/// unavailable.
-std::string Sema::getDeletedOrUnavailableSuffix(const FunctionDecl *FD) {
-  std::string Message;
-  if (FD->getAvailability(&Message))
-    return ": " + Message;
-
-  return std::string();
-}
-
 /// DiagnoseSentinelCalls - This routine checks whether a call or
 /// message-send is to a declaration with the sentinel attribute, and
 /// if so, it checks that the requirements of the sentinel are

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Mar 20 12:26:33 2019
@@ -2338,8 +2338,7 @@ static bool resolveAllocationOverload(
   case OR_Deleted: {
     if (Diagnose) {
       S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
-          << Best->Function->isDeleted() << R.getLookupName()
-          << S.getDeletedOrUnavailableSuffix(Best->Function) << Range;
+          << R.getLookupName() << Range;
       Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
     }
     return true;
@@ -3517,8 +3516,7 @@ static bool resolveBuiltinNewDeleteOverl
 
   case OR_Deleted: {
     S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
-        << Best->Function->isDeleted() << R.getLookupName()
-        << S.getDeletedOrUnavailableSuffix(Best->Function) << Range;
+        << R.getLookupName() << Range;
     Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
     return true;
   }

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Mar 20 12:26:33 2019
@@ -8635,7 +8635,7 @@ bool InitializationSequence::Diagnose(Se
           = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
         if (Ovl != OR_Deleted) {
           S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
-            << true << DestType << ArgsRange;
+              << DestType << ArgsRange;
           llvm_unreachable("Inconsistent overload resolution?");
           break;
         }
@@ -8649,7 +8649,7 @@ bool InitializationSequence::Diagnose(Se
             << DestType << ArgsRange;
         else
           S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
-            << true << DestType << ArgsRange;
+              << DestType << ArgsRange;
 
         S.NoteDeletedFunction(Best->Function);
         break;

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Mar 20 12:26:33 2019
@@ -1229,24 +1229,6 @@ bool Sema::IsOverload(FunctionDecl *New,
   return false;
 }
 
-/// Checks availability of the function depending on the current
-/// function context. Inside an unavailable function, unavailability is ignored.
-///
-/// \returns true if \arg FD is unavailable and current context is inside
-/// an available function, false otherwise.
-bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) {
-  if (!FD->isUnavailable())
-    return false;
-
-  // Walk up the context of the caller.
-  Decl *C = cast<Decl>(CurContext);
-  do {
-    if (C->isUnavailable())
-      return false;
-  } while ((C = cast_or_null<Decl>(C->getDeclContext())));
-  return true;
-}
-
 /// Tries a user-defined conversion from From to ToType.
 ///
 /// Produces an implicit conversion sequence for when a standard conversion
@@ -9453,9 +9435,7 @@ OverloadCandidateSet::BestViableFunction
   }
 
   // Best is the best viable function.
-  if (Best->Function &&
-      (Best->Function->isDeleted() ||
-       S.isFunctionConsideredUnavailable(Best->Function)))
+  if (Best->Function && Best->Function->isDeleted())
     return OR_Deleted;
 
   if (!EquivalentCands.empty())
@@ -10367,7 +10347,7 @@ static void NoteFunctionCandidate(Sema &
 
   // Note deleted candidates, but only if they're viable.
   if (Cand->Viable) {
-    if (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn)) {
+    if (Fn->isDeleted()) {
       std::string FnDesc;
       std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair =
           ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc);
@@ -12132,9 +12112,7 @@ static ExprResult FinishOverloadedCallEx
 
   case OR_Deleted: {
     SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_deleted_call)
-        << (*Best)->Function->isDeleted() << ULE->getName()
-        << SemaRef.getDeletedOrUnavailableSuffix((*Best)->Function)
-        << Fn->getSourceRange();
+        << ULE->getName() << Fn->getSourceRange();
     CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, Args);
 
     // We emitted an error for the unavailable/deleted function call but keep
@@ -12379,10 +12357,7 @@ Sema::CreateOverloadedUnaryOp(SourceLoca
 
   case OR_Deleted:
     Diag(OpLoc, diag::err_ovl_deleted_oper)
-      << Best->Function->isDeleted()
-      << UnaryOperator::getOpcodeStr(Opc)
-      << getDeletedOrUnavailableSuffix(Best->Function)
-      << Input->getSourceRange();
+        << UnaryOperator::getOpcodeStr(Opc) << Input->getSourceRange();
     CandidateSet.NoteCandidates(*this, OCD_AllCandidates, ArgsArray,
                                 UnaryOperator::getOpcodeStr(Opc), OpLoc);
     return ExprError();
@@ -12670,10 +12645,8 @@ Sema::CreateOverloadedBinOp(SourceLocati
         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();
+            << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange()
+            << Args[1]->getSourceRange();
       }
       CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args,
                                   BinaryOperator::getOpcodeStr(Opc), OpLoc);
@@ -12842,11 +12815,8 @@ Sema::CreateOverloadedArraySubscriptExpr
 
     case OR_Deleted:
       Diag(LLoc, diag::err_ovl_deleted_oper)
-        << Best->Function->isDeleted() << "[]"
-        << getDeletedOrUnavailableSuffix(Best->Function)
-        << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args,
-                                  "[]", LLoc);
+          << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, "[]", LLoc);
       return ExprError();
     }
 
@@ -13031,10 +13001,7 @@ Sema::BuildCallToMemberFunction(Scope *S
 
     case OR_Deleted:
       Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
-        << Best->Function->isDeleted()
-        << DeclName
-        << getDeletedOrUnavailableSuffix(Best->Function)
-        << MemExprE->getSourceRange();
+          << DeclName << MemExprE->getSourceRange();
       CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
       // FIXME: Leaking incoming expressions!
       return ExprError();
@@ -13258,9 +13225,7 @@ Sema::BuildCallToObjectOfClassType(Scope
 
   case OR_Deleted:
     Diag(Object.get()->getBeginLoc(), diag::err_ovl_deleted_object_call)
-        << Best->Function->isDeleted() << Object.get()->getType()
-        << getDeletedOrUnavailableSuffix(Best->Function)
-        << Object.get()->getSourceRange();
+        << Object.get()->getType() << Object.get()->getSourceRange();
     CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
     break;
   }
@@ -13488,11 +13453,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S,
     return ExprError();
 
   case OR_Deleted:
-    Diag(OpLoc,  diag::err_ovl_deleted_oper)
-      << Best->Function->isDeleted()
-      << "->"
-      << getDeletedOrUnavailableSuffix(Best->Function)
-      << Base->getSourceRange();
+    Diag(OpLoc, diag::err_ovl_deleted_oper) << "->" << Base->getSourceRange();
     CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Base);
     return ExprError();
   }

Modified: cfe/trunk/test/Sema/enable_if.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/enable_if.c?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/test/Sema/enable_if.c (original)
+++ cfe/trunk/test/Sema/enable_if.c Wed Mar 20 12:26:33 2019
@@ -21,12 +21,12 @@ void test1() {
 
 size_t __strnlen_chk(const char *s, size_t requested_amount, size_t s_len);
 
-size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate function}}
+size_t strnlen(const char *s, size_t maxlen)
   __attribute__((overloadable))
   __asm__("strnlen_real1");
 
 __attribute__((always_inline))
-inline size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate function}}
+inline size_t strnlen(const char *s, size_t maxlen)
   __attribute__((overloadable))
   __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
                            "chosen when target buffer size is known")))
@@ -34,7 +34,7 @@ inline size_t strnlen(const char *s, siz
   return __strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
 }
 
-size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate disabled: chosen when 'maxlen' is known to be less than or equal to the buffer size}}
+size_t strnlen(const char *s, size_t maxlen)
   __attribute__((overloadable))
   __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
                            "chosen when target buffer size is known")))
@@ -42,7 +42,7 @@ size_t strnlen(const char *s, size_t max
                            "chosen when 'maxlen' is known to be less than or equal to the buffer size")))
   __asm__("strnlen_real2");
 
-size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate function has been explicitly made unavailable}}
+size_t strnlen(const char *s, size_t maxlen) // expected-note {{'strnlen' has been explicitly marked unavailable here}}
   __attribute__((overloadable))
   __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
                            "chosen when target buffer size is known")))
@@ -62,12 +62,12 @@ void test2(const char *s, int i) {
   strnlen(c, i);
 // CHECK: call {{.*}}strnlen_chk
 #ifndef CODEGEN
-  strnlen(c, 999);  // expected-error{{call to unavailable function 'strnlen': 'maxlen' is larger than the buffer size}}
+  strnlen(c, 999);  // expected-error{{'strnlen' is unavailable: 'maxlen' is larger than the buffer size}}
 #endif
 }
 
-int isdigit(int c) __attribute__((overloadable));  // expected-note{{candidate function}}
-int isdigit(int c) __attribute__((overloadable))  // expected-note{{candidate function has been explicitly made unavailable}}
+int isdigit(int c) __attribute__((overloadable));
+int isdigit(int c) __attribute__((overloadable)) // expected-note {{'isdigit' has been explicitly marked unavailable here}}
   __attribute__((enable_if(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
   __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
 
@@ -75,13 +75,13 @@ void test3(int c) {
   isdigit(c); // expected-warning{{ignoring return value of function declared with pure attribute}}
   isdigit(10); // expected-warning{{ignoring return value of function declared with pure attribute}}
 #ifndef CODEGEN
-  isdigit(-10);  // expected-error{{call to unavailable function 'isdigit': 'c' must have the value of an unsigned char or EOF}}
+  isdigit(-10);  // expected-error{{'isdigit' is unavailable: 'c' must have the value of an unsigned char or EOF}}
 #endif
 }
 
 // Verify that the alternate spelling __enable_if__ works as well.
-int isdigit2(int c) __attribute__((overloadable));  // expected-note{{candidate function}}
-int isdigit2(int c) __attribute__((overloadable))  // expected-note{{candidate function has been explicitly made unavailable}}
+int isdigit2(int c) __attribute__((overloadable));
+int isdigit2(int c) __attribute__((overloadable)) // expected-note {{'isdigit2' has been explicitly marked unavailable here}}
   __attribute__((__enable_if__(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
   __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
 
@@ -89,7 +89,7 @@ void test4(int c) {
   isdigit2(c);
   isdigit2(10);
 #ifndef CODEGEN
-  isdigit2(-10);  // expected-error{{call to unavailable function 'isdigit2': 'c' must have the value of an unsigned char or EOF}}
+  isdigit2(-10);  // expected-error{{'isdigit2' is unavailable: 'c' must have the value of an unsigned char or EOF}}
 #endif
 }
 

Modified: cfe/trunk/test/Sema/overloadable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/overloadable.c?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/test/Sema/overloadable.c (original)
+++ cfe/trunk/test/Sema/overloadable.c Wed Mar 20 12:26:33 2019
@@ -41,16 +41,15 @@ void test_struct(struct X x, struct Y y)
 
 double *f(int) __attribute__((overloadable)); // expected-error{{conflicting types for 'f'}}
 
-double promote(float) __attribute__((__overloadable__)); // expected-note {{candidate}}
-double promote(double) __attribute__((__overloadable__)); // expected-note {{candidate}}
-long double promote(long double) __attribute__((__overloadable__)); // expected-note {{candidate}}
+double promote(float) __attribute__((__overloadable__));
+double promote(double) __attribute__((__overloadable__));
+long double promote(long double) __attribute__((__overloadable__));
 
-void promote(...) __attribute__((__overloadable__, __unavailable__)); // \
-    // expected-note{{candidate function}}
+void promote(...) __attribute__((__overloadable__, __unavailable__)); // expected-note {{marked unavailable here}}
 
 void test_promote(short* sp) {
   promote(1.0);
-  promote(sp); // expected-error{{call to unavailable function 'promote'}}
+  promote(sp); // expected-error{{'promote' is unavailable}}
 }
 
 // PR6600

Modified: cfe/trunk/test/SemaCXX/attr-unavailable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-unavailable.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-unavailable.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-unavailable.cpp Wed Mar 20 12:26:33 2019
@@ -1,17 +1,16 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-int &foo(int); // expected-note {{candidate}}
-double &foo(double); // expected-note {{candidate}}
-void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
-// expected-note{{'foo' has been explicitly marked unavailable here}}
+int &foo(int);
+double &foo(double);
+void foo(...) __attribute__((__unavailable__)); // \
+// expected-note 2 {{'foo' has been explicitly marked unavailable here}}
 
-void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} \
-       // expected-note 2{{candidate function has been explicitly made unavailable}}
+void bar(...) __attribute__((__unavailable__)); // expected-note 4 {{explicitly marked unavailable}}
 
 void test_foo(short* sp) {
   int &ir = foo(1);
   double &dr = foo(1.0);
-  foo(sp); // expected-error{{call to unavailable function 'foo'}}
+  foo(sp); // expected-error{{'foo' is unavailable}}
 
   void (*fp)(...) = &bar; // expected-error{{'bar' is unavailable}}
   void (*fp2)(...) = bar; // expected-error{{'bar' is unavailable}}
@@ -24,9 +23,9 @@ namespace radar9046492 {
 // rdar://9046492
 #define FOO __attribute__((unavailable("not available - replaced")))
 
-void foo() FOO; // expected-note {{candidate function has been explicitly made unavailable}}
+void foo() FOO; // expected-note{{'foo' has been explicitly marked unavailable here}}
 void bar() {
-  foo(); // expected-error {{call to unavailable function 'foo': not available - replaced}}
+  foo(); // expected-error {{'foo' is unavailable: not available - replaced}}
 }
 }
 
@@ -79,19 +78,19 @@ void untemplated_marked(UnavailableClass
 }
 
 template <class T> void templated_calls_bar() { bar(); } // \
-           // expected-error{{call to unavailable function 'bar'}}
+           // expected-error{{'bar' is unavailable}}
 template <class T> void templated_calls_bar_arg(T v) { bar(v); } // \
-           // expected-error{{call to unavailable function 'bar'}}
+           // expected-error{{'bar' is unavailable}}
 template <class T> void templated_calls_bar_arg_never_called(T v) { bar(v); }
 
 template <class T>
-void unavail_templated_calls_bar() __attribute__((unavailable)) { // \
-  expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
+void unavail_templated_calls_bar() __attribute__((unavailable)) { //  \
+// expected-note {{'unavail_templated_calls_bar<int>' has been explicitly marked unavailable here}}
   bar(5);
 }
 template <class T>
-void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) { // \
-  expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
+void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) {
+// expected-note at -1 {{'unavail_templated_calls_bar_arg<int>' has been explicitly marked unavailable here}}
   bar(v);
 }
 
@@ -102,34 +101,34 @@ void calls_templates_which_call_bar() {
   expected-note{{in instantiation of function template specialization 'templated_calls_bar_arg<int>' requested here}}
 
   unavail_templated_calls_bar<int>(); // \
-  expected-error{{call to unavailable function 'unavail_templated_calls_bar'}}
+  expected-error{{'unavail_templated_calls_bar<int>' is unavailable}}
 
   unavail_templated_calls_bar_arg(5); // \
-  expected-error{{call to unavailable function 'unavail_templated_calls_bar_arg'}}
+  expected-error{{'unavail_templated_calls_bar_arg<int>' is unavailable}}
 }
 
-template <class T> void unavail_templated(T) __attribute__((unavailable)); // \
-           expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
+template <class T> void unavail_templated(T) __attribute__((unavailable));
+// expected-note at -1 {{'unavail_templated<int>' has been explicitly marked unavailable here}}
 void calls_unavail_templated() {
-  unavail_templated(5); // expected-error{{call to unavailable function 'unavail_templated'}}
+  unavail_templated(5); // expected-error{{'unavail_templated<int>' is unavailable}}
 }
 void unavail_calls_unavail_templated() __attribute__((unavailable)) {
   unavail_templated(5);
 }
 
-void unavailable() __attribute((unavailable)); // \
-       expected-note 4{{candidate function has been explicitly made unavailable}}
+void unavailable() __attribute((unavailable));
+// expected-note at -1 4 {{'unavailable' has been explicitly marked unavailable here}}
 struct AvailableStruct {
   void calls_unavailable() { unavailable(); } // \
-  expected-error{{call to unavailable function 'unavailable'}}
+  expected-error{{'unavailable' is unavailable}}
   template <class U> void calls_unavailable() { unavailable(); } // \
-  expected-error{{call to unavailable function 'unavailable'}}
+  expected-error{{'unavailable' is unavailable}}
 };
 template <class T> struct AvailableStructTemplated {
   void calls_unavailable() { unavailable(); } // \
-  expected-error{{call to unavailable function 'unavailable'}}
+  expected-error{{'unavailable' is unavailable}}
   template <class U> void calls_unavailable() { unavailable(); } // \
-  expected-error{{call to unavailable function 'unavailable'}}
+  expected-error{{'unavailable' is unavailable}}
 };
 struct __attribute__((unavailable)) UnavailableStruct {
   void calls_unavailable() { unavailable(); }
@@ -139,3 +138,37 @@ template <class T> struct __attribute__(
   void calls_unavailable() { unavailable(); }
   template <class U> void calls_unavailable() { unavailable(); }
 };
+
+int unavailable_int() __attribute__((unavailable)); // expected-note 2 {{'unavailable_int' has been explicitly marked unavailable here}}
+int has_default_arg(int x = unavailable_int()) { // expected-error{{'unavailable_int' is unavailable}}
+  return x;
+}
+
+int has_default_arg2(int x = unavailable_int()) __attribute__((unavailable)) {
+  return x;
+}
+
+template <class T>
+T unavailable_template() __attribute__((unavailable));
+// expected-note at -1 {{'unavailable_template<int>' has been explicitly marked unavailable here}}
+
+template <class T>
+int has_default_arg_template(T x = unavailable_template<T>()) {}
+// expected-error at -1 {{'unavailable_template<int>' is unavailable}}
+
+int instantiate_it = has_default_arg_template<int>();
+// expected-note at -1 {{in instantiation of default function argument expression for 'has_default_arg_template<int>' required here}}
+
+template <class T>
+int has_default_arg_template2(T x = unavailable_template<T>())
+    __attribute__((unavailable)) {}
+
+__attribute__((unavailable))
+int instantiate_it2 = has_default_arg_template2<int>();
+
+template <class T>
+int phase_one_unavailable(int x = unavailable_int()) {}
+// expected-error at -1 {{'unavailable_int' is unavailable}}
+
+template <class T>
+int phase_one_unavailable2(int x = unavailable_int()) __attribute__((unavailable)) {}

Modified: cfe/trunk/test/SemaCXX/coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutines.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/coroutines.cpp (original)
+++ cfe/trunk/test/SemaCXX/coroutines.cpp Wed Mar 20 12:26:33 2019
@@ -649,26 +649,26 @@ template coro<bad_promise_7> no_unhandle
 
 struct bad_promise_base {
 private:
-  void return_void();
+  void return_void(); // expected-note 2 {{declared private here}}
 };
 struct bad_promise_8 : bad_promise_base {
   coro<bad_promise_8> get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend();
-  void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{made unavailable}}
-  void unhandled_exception() const;                        // expected-note 2 {{candidate}}
-  void unhandled_exception(void *) const;                  // expected-note 2 {{requires 1 argument, but 0 were provided}}
+  void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{marked unavailable here}}
+  void unhandled_exception() const;
+  void unhandled_exception(void *) const;
 };
 coro<bad_promise_8> calls_unhandled_exception() {
-  // expected-error at -1 {{call to unavailable member function 'unhandled_exception'}}
-  // FIXME: also warn about private 'return_void' here. Even though building
-  // the call to unhandled_exception has already failed.
+  // expected-error at -1 {{'unhandled_exception' is unavailable}}
+  // expected-error at -2 {{'return_void' is a private member}}
   co_await a;
 }
 
 template <class T>
 coro<T> calls_unhandled_exception_dependent(T) {
-  // expected-error at -1 {{call to unavailable member function 'unhandled_exception'}}
+  // expected-error at -1 {{'unhandled_exception' is unavailable}}
+  // expected-error at -2 {{'return_void' is a private member}}
   co_await a;
 }
 template coro<bad_promise_8> calls_unhandled_exception_dependent(bad_promise_8); // expected-note {{in instantiation}}
@@ -677,14 +677,13 @@ struct bad_promise_9 {
   coro<bad_promise_9> get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend();
-  void await_transform(void *);                                // expected-note {{candidate}}
-  awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
+  void await_transform(void *);
+  awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly marked unavailable}}
   void return_void();
   void unhandled_exception();
 };
 coro<bad_promise_9> calls_await_transform() {
-  co_await 42; // expected-error {{call to unavailable member function 'await_transform'}}
-  // expected-note at -1 {{call to 'await_transform' implicitly required by 'co_await' here}}
+  co_await 42; // expected-error {{'await_transform' is unavailable}}
 }
 
 struct bad_promise_10 {

Modified: cfe/trunk/test/SemaObjCXX/overload.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/overload.mm?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/overload.mm (original)
+++ cfe/trunk/test/SemaObjCXX/overload.mm Wed Mar 20 12:26:33 2019
@@ -111,11 +111,11 @@ namespace test5 {
 
 // rdar://problem/8592139
 namespace test6 {
-  void foo(id); // expected-note{{candidate function}}
-  void foo(A*) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
+  void foo(id);
+  void foo(A*) __attribute__((unavailable)); // expected-note {{marked unavailable here}}
 
   void test(B *b) {
-    foo(b); // expected-error {{call to unavailable function 'foo'}}
+    foo(b); // expected-error {{'foo' is unavailable}}
   }
 }
 

Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp?rev=356599&r1=356598&r2=356599&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp Wed Mar 20 12:26:33 2019
@@ -106,12 +106,12 @@ template struct New2<X, int, int*>; // e
 struct New3 {
   New3();
 
-  void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}}
+  void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly marked unavailable here}}
 };
 
 template<class C>
 void* object_creator() {
-  return new C(); // expected-error{{call to unavailable function 'operator new[]'}}
+  return new C(); // expected-error{{'operator new[]' is unavailable}}
 }
 
 template void *object_creator<New3[4]>(); // expected-note{{instantiation}}




More information about the cfe-commits mailing list