summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2019-03-20 19:26:33 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2019-03-20 19:26:33 +0000
commit13ee62f7d7eed3303f13374b25b8e51d38b2951b (patch)
treed5b87efeef55926f08b2beab9ab25754c7c8adcb
parent9dde31ecc1578768eeddb508ac17cebcfd71e3d6 (diff)
downloadbcm5719-llvm-13ee62f7d7eed3303f13374b25b8e51d38b2951b.tar.gz
bcm5719-llvm-13ee62f7d7eed3303f13374b25b8e51d38b2951b.zip
[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 llvm-svn: 356599
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td11
-rw-r--r--clang/include/clang/Sema/Sema.h8
-rw-r--r--clang/lib/Sema/SemaExpr.cpp11
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp6
-rw-r--r--clang/lib/Sema/SemaInit.cpp4
-rw-r--r--clang/lib/Sema/SemaOverload.cpp61
-rw-r--r--clang/test/Sema/enable_if.c22
-rw-r--r--clang/test/Sema/overloadable.c11
-rw-r--r--clang/test/SemaCXX/attr-unavailable.cpp85
-rw-r--r--clang/test/SemaCXX/coroutines.cpp23
-rw-r--r--clang/test/SemaObjCXX/overload.mm6
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-4.cpp4
12 files changed, 111 insertions, 141 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c37dad11d1b..ebbbbc72bbe 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3605,12 +3605,11 @@ def err_ovl_no_viable_member_function_in_call : Error<
"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 to constructor of %0 is ambiguous">;
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 : Error<
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 : Error<
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">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 75a06cd009f..cb9d65db6d6 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -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);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ff5a6265faf..3af87b6fd4f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -333,17 +333,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
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
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 6e66b5e7020..ee096745532 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -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 resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
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;
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index bf897389ec3..090192e2acd 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -8635,7 +8635,7 @@ bool InitializationSequence::Diagnose(Sema &S,
= 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(Sema &S,
<< DestType << ArgsRange;
else
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
- << true << DestType << ArgsRange;
+ << DestType << ArgsRange;
S.NoteDeletedFunction(Best->Function);
break;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 2409acd44f5..2f6f94313b2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1229,24 +1229,6 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
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(Sema &S, SourceLocation Loc,
}
// 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 &S, OverloadCandidate *Cand,
// 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 FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
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(SourceLocation OpLoc, UnaryOperatorKind Opc,
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(SourceLocation OpLoc,
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(SourceLocation LLoc,
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, Expr *MemExprE,
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 *S, Expr *Obj,
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, Expr *Base, SourceLocation OpLoc,
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();
}
diff --git a/clang/test/Sema/enable_if.c b/clang/test/Sema/enable_if.c
index 9125bfaf0f1..b4bb2ecd0d2 100644
--- a/clang/test/Sema/enable_if.c
+++ b/clang/test/Sema/enable_if.c
@@ -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, size_t maxlen) // expected-note{{candidate
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 maxlen) // expected-note{{candidate disabl
"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
}
diff --git a/clang/test/Sema/overloadable.c b/clang/test/Sema/overloadable.c
index 4bdec85f9ca..61ef3fddaf3 100644
--- a/clang/test/Sema/overloadable.c
+++ b/clang/test/Sema/overloadable.c
@@ -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
diff --git a/clang/test/SemaCXX/attr-unavailable.cpp b/clang/test/SemaCXX/attr-unavailable.cpp
index bafae2ab43a..c5c3cff6bc8 100644
--- a/clang/test/SemaCXX/attr-unavailable.cpp
+++ b/clang/test/SemaCXX/attr-unavailable.cpp
@@ -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 &UC) __attribute__((unavailable)) {
}
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@-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@-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@-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__((unavailable)) UnavailableStructTemplate
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@-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@-1 {{'unavailable_template<int>' is unavailable}}
+
+int instantiate_it = has_default_arg_template<int>();
+// expected-note@-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@-1 {{'unavailable_int' is unavailable}}
+
+template <class T>
+int phase_one_unavailable2(int x = unavailable_int()) __attribute__((unavailable)) {}
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index e6eededf887..99964ef6bcb 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -649,26 +649,26 @@ template coro<bad_promise_7> no_unhandled_exception_dependent(bad_promise_7); //
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@-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@-1 {{'unhandled_exception' is unavailable}}
+ // expected-error@-2 {{'return_void' is a private member}}
co_await a;
}
template <class T>
coro<T> calls_unhandled_exception_dependent(T) {
- // expected-error@-1 {{call to unavailable member function 'unhandled_exception'}}
+ // expected-error@-1 {{'unhandled_exception' is unavailable}}
+ // expected-error@-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@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
+ co_await 42; // expected-error {{'await_transform' is unavailable}}
}
struct bad_promise_10 {
diff --git a/clang/test/SemaObjCXX/overload.mm b/clang/test/SemaObjCXX/overload.mm
index 018afc9b429..f3c06b4f228 100644
--- a/clang/test/SemaObjCXX/overload.mm
+++ b/clang/test/SemaObjCXX/overload.mm
@@ -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}}
}
}
diff --git a/clang/test/SemaTemplate/instantiate-expr-4.cpp b/clang/test/SemaTemplate/instantiate-expr-4.cpp
index 9a1a1d2bb69..055f37bb05f 100644
--- a/clang/test/SemaTemplate/instantiate-expr-4.cpp
+++ b/clang/test/SemaTemplate/instantiate-expr-4.cpp
@@ -106,12 +106,12 @@ template struct New2<X, int, int*>; // expected-note{{instantiation}}
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}}
OpenPOWER on IntegriCloud