forked from OSchip/llvm-project
Clean up our handling of template-ids that resolve down to a single
overload, so that we actually do the resolution for full expressions and emit more consistent, useful diagnostics. Also fixes an IRGen crasher, where Sema wouldn't diagnose a resolvable bound member function template-id used in a full-expression (<rdar://problem/9108698>). llvm-svn: 127747
This commit is contained in:
parent
5a4a0f75d4
commit
89f3cd5c15
|
@ -1499,7 +1499,7 @@ def err_ovl_no_viable_subscript :
|
|||
def err_ovl_no_oper :
|
||||
Error<"type %0 does not provide a %select{subscript|call}1 operator">;
|
||||
def err_ovl_unresolvable :
|
||||
Error<"cannot resolve overloaded function from context">;
|
||||
Error<"cannot resolve overloaded function %0 from context">;
|
||||
|
||||
|
||||
def err_ovl_no_viable_object_call : Error<
|
||||
|
|
|
@ -9790,17 +9790,8 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E, SourceLocation Loc) {
|
|||
|
||||
// If this is overload, check for a single overload.
|
||||
assert(BT->getKind() == BuiltinType::Overload);
|
||||
|
||||
if (FunctionDecl *Specialization
|
||||
= ResolveSingleFunctionTemplateSpecialization(E)) {
|
||||
// The access doesn't really matter in this case.
|
||||
DeclAccessPair Found = DeclAccessPair::make(Specialization,
|
||||
Specialization->getAccess());
|
||||
E = FixOverloadedFunctionReference(E, Found, Specialization);
|
||||
if (!E) return ExprError();
|
||||
return Owned(E);
|
||||
}
|
||||
|
||||
Diag(Loc, diag::err_ovl_unresolvable) << E->getSourceRange();
|
||||
return ExprError();
|
||||
return ResolveAndFixSingleFunctionTemplateSpecialization(E, false, true,
|
||||
E->getSourceRange(),
|
||||
QualType(),
|
||||
diag::err_ovl_unresolvable);
|
||||
}
|
||||
|
|
|
@ -3944,14 +3944,17 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
|
|||
// fooT<int>;
|
||||
|
||||
if (FullExpr->getType() == Context.OverloadTy) {
|
||||
if (!ResolveSingleFunctionTemplateSpecialization(FullExpr,
|
||||
/* Complain */ false)) {
|
||||
OverloadExpr* OvlExpr = OverloadExpr::find(FullExpr).Expression;
|
||||
Diag(FullExpr->getLocStart(), diag::err_addr_ovl_ambiguous)
|
||||
<< OvlExpr->getName();
|
||||
NoteAllOverloadCandidates(OvlExpr);
|
||||
ExprResult Fixed
|
||||
= ResolveAndFixSingleFunctionTemplateSpecialization(FullExpr,
|
||||
/*DoFunctionPointerConversion=*/false,
|
||||
/*Complain=*/true,
|
||||
FullExpr->getSourceRange(),
|
||||
QualType(),
|
||||
diag::err_addr_ovl_ambiguous);
|
||||
if (Fixed.isInvalid())
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
FullExpr = Fixed.get();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7518,13 +7518,17 @@ ExprResult Sema::ResolveAndFixSingleFunctionTemplateSpecialization(
|
|||
DefaultFunctionArrayLvalueConversion(SingleFunctionExpression);
|
||||
}
|
||||
}
|
||||
if (!SingleFunctionExpression && Complain) {
|
||||
if (!SingleFunctionExpression) {
|
||||
if (Complain) {
|
||||
OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
|
||||
Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
|
||||
<< oe->getName() << DestTypeForComplaining << OpRangeForComplaining
|
||||
<< oe->getQualifierLoc().getSourceRange();
|
||||
NoteAllOverloadCandidates(SrcExpr);
|
||||
}
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
return SingleFunctionExpression;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ bool b8 = !S(); //expected-error {{invalid argument type 'S'}}
|
|||
|
||||
namespace PR8181
|
||||
{
|
||||
void f() { }
|
||||
void f(char) { }
|
||||
bool b = !&f; //expected-error {{cannot resolve overloaded function from context}}
|
||||
void f() { } // expected-note{{candidate function}}
|
||||
void f(char) { } // expected-note{{candidate function}}
|
||||
bool b = !&f; //expected-error {{cannot resolve overloaded function 'f' from context}}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ struct is_same<T, T> {
|
|||
int typeof0[is_same<__typeof__(f<int>), void (int)>::value? 1 : -1];
|
||||
int typeof1[is_same<__typeof__(&f<int>), void (*)(int)>::value? 1 : -1];
|
||||
|
||||
template <typename T> void g(T);
|
||||
template <typename T> void g(T, T);
|
||||
template <typename T> void g(T); // expected-note{{candidate function}}
|
||||
template <typename T> void g(T, T); // expected-note{{candidate function}}
|
||||
|
||||
int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \
|
||||
// expected-error{{cannot resolve overloaded function from context}}
|
||||
// expected-error{{cannot resolve overloaded function 'g' from context}}
|
||||
|
|
|
@ -8,8 +8,8 @@ void test() {
|
|||
static_assert(sizeof(r) == 1, "bad size");
|
||||
}
|
||||
|
||||
void f();
|
||||
void f(int);
|
||||
void f(); // expected-note{{candidate function}}
|
||||
void f(int); // expected-note{{candidate function}}
|
||||
void g() {
|
||||
sizeof(&f); // expected-error{{cannot resolve overloaded function from context}}
|
||||
sizeof(&f); // expected-error{{cannot resolve overloaded function 'f' from context}}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
|
||||
|
||||
void f();
|
||||
void f(int);
|
||||
decltype(f) a; // expected-error{{cannot resolve overloaded function from context}}
|
||||
void f(); // expected-note{{candidate function}}
|
||||
void f(int); // expected-note{{candidate function}}
|
||||
decltype(f) a; // expected-error{{cannot resolve overloaded function 'f' from context}}
|
||||
|
||||
template<typename T> struct S {
|
||||
decltype(T::f) * f; // expected-error{{cannot resolve overloaded function from context}}
|
||||
decltype(T::f) * f; // expected-error{{cannot resolve overloaded function 'f' from context}}
|
||||
};
|
||||
|
||||
struct K { void f(); void f(int); };
|
||||
struct K {
|
||||
void f(); // expected-note{{candidate function}}
|
||||
void f(int); // expected-note{{candidate function}}
|
||||
};
|
||||
S<K> b; // expected-note{{in instantiation of template class 'S<K>' requested here}}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
int ovl(int);
|
||||
float ovl(float);
|
||||
int ovl(int); // expected-note 3{{candidate function}}
|
||||
float ovl(float); // expected-note 3{{candidate function}}
|
||||
|
||||
template<typename T> T ovl(T);
|
||||
template<typename T> T ovl(T); // expected-note 3{{candidate function}}
|
||||
|
||||
void test(bool b) {
|
||||
(void)((void)0, ovl); // expected-error{{cannot resolve overloaded function from context}}
|
||||
(void)((void)0, ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}}
|
||||
// PR7863
|
||||
(void)(b? ovl : &ovl); // expected-error{{cannot resolve overloaded function from context}}
|
||||
(void)(b? ovl<float> : &ovl); // expected-error{{cannot resolve overloaded function from context}}
|
||||
(void)(b? ovl : &ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}}
|
||||
(void)(b? ovl<float> : &ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}}
|
||||
(void)(b? ovl<float> : ovl<float>);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
|
||||
//#include <typeinfo>
|
||||
void one() { }
|
||||
void two() { } // expected-note 3{{candidate}}
|
||||
void two(int) { } // expected-note 3{{candidate}}
|
||||
|
||||
template<class T> void twoT() { } // expected-note 4{{candidate}}
|
||||
template<class T> void twoT(int) { } // expected-note 4{{candidate}}
|
||||
namespace std {
|
||||
class type_info {};
|
||||
}
|
||||
|
||||
void one() { }
|
||||
void two() { } // expected-note 2{{candidate}}
|
||||
void two(int) { } // expected-note 2{{candidate}}
|
||||
|
||||
template<class T> void twoT() { } // expected-note 3{{candidate}}
|
||||
template<class T> void twoT(int) { } // expected-note 3{{candidate}}
|
||||
|
||||
template<class T> void oneT() { }
|
||||
template<class T, class U> void oneT(U) { }
|
||||
|
@ -28,15 +32,15 @@ int main()
|
|||
two; // expected-error {{address of overloaded}}
|
||||
oneT<int>; // expected-warning {{expression result unused}}
|
||||
twoT<int>; // expected-error {{address of overloaded}}
|
||||
typeid(oneT<int>); //expected-error {{you need to include <typeinfo>}}
|
||||
typeid(oneT<int>); // expected-warning{{expression result unused}}
|
||||
sizeof(oneT<int>); // expected-warning {{expression result unused}}
|
||||
sizeof(twoT<int>); //expected-error {{cannot resolve overloaded function from context}}
|
||||
sizeof(twoT<int>); //expected-error {{cannot resolve overloaded function 'twoT' from context}}
|
||||
decltype(oneT<int>)* fun = 0;
|
||||
|
||||
*one; // expected-warning {{expression result unused}}
|
||||
*oneT<int>; // expected-warning {{expression result unused}}
|
||||
*two; //expected-error {{cannot resolve overloaded function from context}}
|
||||
*twoT<int>; //expected-error {{cannot resolve overloaded function from context}}
|
||||
*two; //expected-error {{cannot resolve overloaded function 'two' from context}}
|
||||
*twoT<int>; //expected-error {{cannot resolve overloaded function 'twoT' from context}}
|
||||
!oneT<int>; // expected-warning {{expression result unused}}
|
||||
+oneT<int>; // expected-warning {{expression result unused}}
|
||||
-oneT<int>; //expected-error {{invalid argument type}}
|
||||
|
@ -50,7 +54,7 @@ int main()
|
|||
(twoT<int>) == oneT<int>; //expected-error {{invalid operands to binary expression}}
|
||||
bool b = oneT<int>;
|
||||
void (*p)() = oneT<int>;
|
||||
test<oneT<int>> ti;
|
||||
test<oneT<int> > ti;
|
||||
void (*u)(int) = oneT<int>;
|
||||
|
||||
b = (void (*)()) twoT<int>;
|
||||
|
@ -66,3 +70,11 @@ int main()
|
|||
oneT<int> == 0; // expected-warning {{expression result unused}}
|
||||
|
||||
}
|
||||
|
||||
struct rdar9108698 {
|
||||
template<typename> void f();
|
||||
};
|
||||
|
||||
void test_rdar9108698(rdar9108698 x) {
|
||||
x.f<int>; // expected-error{{a bound member function may only be called}}
|
||||
}
|
Loading…
Reference in New Issue