[cfe-commits] r127747 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp test/CXX/expr/expr.unary/expr.unary.op/p6.cpp test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp test/SemaCXX/alignof-sizeof-reference.cpp test/SemaCXX/decltype-overloaded-functions.cpp test/SemaCXX/overloaded-name.cpp test/SemaTemplate/resolve-single-template-id.cpp test/SemaTemplate/resolve-single-template-id.patch

Douglas Gregor dgregor at apple.com
Wed Mar 16 12:16:25 PDT 2011


Author: dgregor
Date: Wed Mar 16 14:16:25 2011
New Revision: 127747

URL: http://llvm.org/viewvc/llvm-project?rev=127747&view=rev
Log:
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>).

Added:
    cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp
      - copied, changed from r127734, cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch
Removed:
    cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
    cfe/trunk/test/SemaCXX/alignof-sizeof-reference.cpp
    cfe/trunk/test/SemaCXX/decltype-overloaded-functions.cpp
    cfe/trunk/test/SemaCXX/overloaded-name.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar 16 14:16:25 2011
@@ -1499,7 +1499,7 @@
 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<

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Mar 16 14:16:25 2011
@@ -9790,17 +9790,8 @@
 
   // 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);
 }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Mar 16 14:16:25 2011
@@ -3944,14 +3944,17 @@
   //  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();
   }
 
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Mar 16 14:16:25 2011
@@ -7518,13 +7518,17 @@
             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;
 }
 

Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp Wed Mar 16 14:16:25 2011
@@ -29,8 +29,8 @@
 
 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}}
 
 }

Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp Wed Mar 16 14:16:25 2011
@@ -29,8 +29,8 @@
 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}}

Modified: cfe/trunk/test/SemaCXX/alignof-sizeof-reference.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/alignof-sizeof-reference.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/alignof-sizeof-reference.cpp (original)
+++ cfe/trunk/test/SemaCXX/alignof-sizeof-reference.cpp Wed Mar 16 14:16:25 2011
@@ -8,8 +8,8 @@
   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}}
 }

Modified: cfe/trunk/test/SemaCXX/decltype-overloaded-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decltype-overloaded-functions.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decltype-overloaded-functions.cpp (original)
+++ cfe/trunk/test/SemaCXX/decltype-overloaded-functions.cpp Wed Mar 16 14:16:25 2011
@@ -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}}

Modified: cfe/trunk/test/SemaCXX/overloaded-name.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-name.cpp?rev=127747&r1=127746&r2=127747&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overloaded-name.cpp (original)
+++ cfe/trunk/test/SemaCXX/overloaded-name.cpp Wed Mar 16 14:16:25 2011
@@ -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>);
 }

Copied: cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp (from r127734, cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp?p2=cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp&p1=cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch&r1=127734&r2=127747&rev=127747&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch (original)
+++ cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp Wed Mar 16 14:16:25 2011
@@ -1,11 +1,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
-//#include <typeinfo>
+
+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<class T> void twoT() { } // expected-note 4{{candidate}}
-template<class T> void twoT(int) { } // expected-note 4{{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 @@
    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 @@
   (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 @@
   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}}
+}

Removed: cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch?rev=127746&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch (original)
+++ cfe/trunk/test/SemaTemplate/resolve-single-template-id.patch (removed)
@@ -1,68 +0,0 @@
-// 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}}
-
-template<class T> void oneT() { }
-template<class T, class U> void oneT(U) { }
-/*
-The target can be
- an object or reference being initialized (8.5, 8.5.3),
- the left side of an assignment (5.17),
- a parameter of a function (5.2.2),
- a parameter of a user-defined operator (13.5),
- the return value of a function, operator function, or conversion (6.6.3),
- an explicit type conversion (5.2.3, 5.2.9, 5.4), or
- a non-type template-parameter (14.3.2)
-*/
-//#include <typeinfo>
-template<void (*p)(int)> struct test { };
-
-int main()
-{
-   one;         // expected-warning {{expression result unused}}
-   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>}}
-  sizeof(oneT<int>); // expected-warning {{expression result unused}}
-  sizeof(twoT<int>); //expected-error {{cannot resolve overloaded function 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}}
-  !oneT<int>;  // expected-warning {{expression result unused}}
-  +oneT<int>;  // expected-warning {{expression result unused}}
-  -oneT<int>;  //expected-error {{invalid argument type}}
-  oneT<int> == 0;   // expected-warning {{expression result unused}}
-  0 == oneT<int>;   // expected-warning {{expression result unused}}
-  0 != oneT<int>;    // expected-warning {{expression result unused}}
-  (false ? one : oneT<int>);   // expected-warning {{expression result unused}}
-  void (*p1)(int); p1 = oneT<int>;
-  
-  int i = (int) (false ? (void (*)(int))twoT<int> : oneT<int>); //expected-error {{incompatible operand}}
-  (twoT<int>) == oneT<int>; //expected-error {{invalid operands to binary expression}}
-  bool b = oneT<int>;
-  void (*p)() = oneT<int>;
-  test<oneT<int>> ti;
-  void (*u)(int) = oneT<int>;
-
-  b = (void (*)()) twoT<int>;
-  
-  one < one; //expected-warning {{self-comparison always evaluates to false}} \
-             //expected-warning {{expression result unused}}         
-
-  oneT<int> < oneT<int>;  //expected-warning {{self-comparison always evaluates to false}} \
-                          //expected-warning {{expression result unused}}
-
-  two < two; //expected-error {{invalid operands to binary expression}}
-  twoT<int> < twoT<int>; //expected-error {{invalid operands to binary expression}}
-  oneT<int> == 0;   // expected-warning {{expression result unused}}
-
-}





More information about the cfe-commits mailing list