From: Douglas Gregor Date: Wed, 16 Mar 2011 19:16:25 +0000 (+0000) Subject: Clean up our handling of template-ids that resolve down to a single X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=db2eae639d3b7ed61ceb56890b73168517ef57f1;p=clang 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 (). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127747 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c42a82b5f6..c8ac4337f3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 6acd2a5b03..a27864f673 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index fe0d413a76..9955b0378b 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3944,14 +3944,17 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) { // fooT; 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(); } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index d746c7bb1e..110f8cdc1c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7518,13 +7518,17 @@ ExprResult Sema::ResolveAndFixSingleFunctionTemplateSpecialization( DefaultFunctionArrayLvalueConversion(SingleFunctionExpression); } } - if (!SingleFunctionExpression && Complain) { - OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression; - Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining) - << oe->getName() << DestTypeForComplaining << OpRangeForComplaining - << oe->getQualifierLoc().getSourceRange(); - NoteAllOverloadCandidates(SrcExpr); + 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; } diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp index 543a86d4e3..30f8c54919 100644 --- a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp @@ -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}} } diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp index 9ec8f0c90e..1140aaee6c 100644 --- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp @@ -29,8 +29,8 @@ struct is_same { int typeof0[is_same<__typeof__(f), void (int)>::value? 1 : -1]; int typeof1[is_same<__typeof__(&f), void (*)(int)>::value? 1 : -1]; -template void g(T); -template void g(T, T); +template void g(T); // expected-note{{candidate function}} +template void g(T, T); // expected-note{{candidate function}} int typeof2[is_same<__typeof__(g), void (int)>::value? 1 : -1]; // \ - // expected-error{{cannot resolve overloaded function from context}} + // expected-error{{cannot resolve overloaded function 'g' from context}} diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp index 761edfc639..b517e43cf1 100644 --- a/test/SemaCXX/alignof-sizeof-reference.cpp +++ b/test/SemaCXX/alignof-sizeof-reference.cpp @@ -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}} } diff --git a/test/SemaCXX/decltype-overloaded-functions.cpp b/test/SemaCXX/decltype-overloaded-functions.cpp index c11a47ecdf..f4aacd64dd 100644 --- a/test/SemaCXX/decltype-overloaded-functions.cpp +++ b/test/SemaCXX/decltype-overloaded-functions.cpp @@ -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 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 b; // expected-note{{in instantiation of template class 'S' requested here}} diff --git a/test/SemaCXX/overloaded-name.cpp b/test/SemaCXX/overloaded-name.cpp index 289d5c92ec..5a87cc8e67 100644 --- a/test/SemaCXX/overloaded-name.cpp +++ b/test/SemaCXX/overloaded-name.cpp @@ -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 T ovl(T); +template 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 : &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 : &ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}} (void)(b? ovl : ovl); } diff --git a/test/SemaTemplate/resolve-single-template-id.patch b/test/SemaTemplate/resolve-single-template-id.cpp similarity index 79% rename from test/SemaTemplate/resolve-single-template-id.patch rename to test/SemaTemplate/resolve-single-template-id.cpp index 8be2f6c65f..7f5d471b90 100644 --- a/test/SemaTemplate/resolve-single-template-id.patch +++ b/test/SemaTemplate/resolve-single-template-id.cpp @@ -1,11 +1,15 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -//#include + +namespace std { + class type_info {}; +} + void one() { } -void two() { } // expected-note 3{{candidate}} -void two(int) { } // expected-note 3{{candidate}} +void two() { } // expected-note 2{{candidate}} +void two(int) { } // expected-note 2{{candidate}} -template void twoT() { } // expected-note 4{{candidate}} -template void twoT(int) { } // expected-note 4{{candidate}} +template void twoT() { } // expected-note 3{{candidate}} +template void twoT(int) { } // expected-note 3{{candidate}} template void oneT() { } template void oneT(U) { } @@ -28,15 +32,15 @@ int main() two; // expected-error {{address of overloaded}} oneT; // expected-warning {{expression result unused}} twoT; // expected-error {{address of overloaded}} - typeid(oneT); //expected-error {{you need to include }} + typeid(oneT); // expected-warning{{expression result unused}} sizeof(oneT); // expected-warning {{expression result unused}} - sizeof(twoT); //expected-error {{cannot resolve overloaded function from context}} + sizeof(twoT); //expected-error {{cannot resolve overloaded function 'twoT' from context}} decltype(oneT)* fun = 0; *one; // expected-warning {{expression result unused}} *oneT; // expected-warning {{expression result unused}} - *two; //expected-error {{cannot resolve overloaded function from context}} - *twoT; //expected-error {{cannot resolve overloaded function from context}} + *two; //expected-error {{cannot resolve overloaded function 'two' from context}} + *twoT; //expected-error {{cannot resolve overloaded function 'twoT' from context}} !oneT; // expected-warning {{expression result unused}} +oneT; // expected-warning {{expression result unused}} -oneT; //expected-error {{invalid argument type}} @@ -50,7 +54,7 @@ int main() (twoT) == oneT; //expected-error {{invalid operands to binary expression}} bool b = oneT; void (*p)() = oneT; - test> ti; + test > ti; void (*u)(int) = oneT; b = (void (*)()) twoT; @@ -66,3 +70,11 @@ int main() oneT == 0; // expected-warning {{expression result unused}} } + +struct rdar9108698 { + template void f(); +}; + +void test_rdar9108698(rdar9108698 x) { + x.f; // expected-error{{a bound member function may only be called}} +}