r184043 - A quick fix to allow return type deduction on member templates

Faisal Vali faisalv at yahoo.com
Sat Jun 15 04:54:38 PDT 2013


Author: faisalv
Date: Sat Jun 15 06:54:37 2013
New Revision: 184043

URL: http://llvm.org/viewvc/llvm-project?rev=184043&view=rev
Log:
A quick fix to allow return type deduction on member templates
by ensuring DiagnoseUseOfDecl is called both on the found decl and the
decl being used (i.e the specialization in the case of member templates) whenever they are different.
Per the exchange captured in
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130610/081636.html
a more comprehensive fix that allows both decls to be passed into DiagnoseUseOfDecl is (or should be) forthcoming relatively soon.


Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=184043&r1=184042&r2=184043&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jun 15 06:54:37 2013
@@ -43,8 +43,15 @@ CreateFunctionRefExpr(Sema &S, FunctionD
                       SourceLocation Loc = SourceLocation(), 
                       const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
   if (S.DiagnoseUseOfDecl(FoundDecl, Loc))
+    return ExprError(); 
+  // If FoundDecl is different from Fn (such as if one is a template
+  // and the other a specialization), make sure DiagnoseUseOfDecl is 
+  // called on both.
+  // FIXME: This would be more comprehensively addressed by modifying
+  // DiagnoseUseOfDecl to accept both the FoundDecl and the decl
+  // being used.
+  if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc))
     return ExprError();
-
   DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
                                                  VK_LValue, Loc, LocInfo);
   if (HadMultipleCandidates)
@@ -11001,6 +11008,15 @@ Sema::BuildCallToMemberFunction(Scope *S
       CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
       if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
         return ExprError();
+      // If FoundDecl is different from Method (such as if one is a template
+      // and the other a specialization), make sure DiagnoseUseOfDecl is 
+      // called on both.
+      // FIXME: This would be more comprehensively addressed by modifying
+      // DiagnoseUseOfDecl to accept both the FoundDecl and the decl
+      // being used.
+      if (Method != FoundDecl.getDecl() && 
+                      DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc()))
+        return ExprError();
       break;
 
     case OR_No_Viable_Function:
@@ -11246,7 +11262,8 @@ Sema::BuildCallToObjectOfClassType(Scope
     CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
     if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
       return ExprError();
-
+    assert(Conv == Best->FoundDecl.getDecl() && 
+             "Found Decl & conversion-to-functionptr should be same, right?!");
     // We selected one of the surrogate functions that converts the
     // object parameter to a function pointer. Perform the conversion
     // on the object argument, then let ActOnCallExpr finish the job.

Modified: cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp?rev=184043&r1=184042&r2=184043&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp Sat Jun 15 06:54:37 2013
@@ -339,5 +339,37 @@ namespace ExplicitInstantiationDecl {
   extern template auto f(int);
   int (*p)(int) = f;
 }
-
+namespace MemberTemplatesWithDeduction {
+  struct M {
+    template<class T> auto foo(T t) { return t; }
+    template<class T> auto operator()(T t) const { return t; }
+    template<class T> static __attribute__((unused)) int static_foo(T) {
+      return 5;
+    }
+    template<class T> operator T() { return T{}; }
+    operator auto() { return &static_foo<int>; } 
+  };
+  struct N : M {
+    using M::foo;
+    using M::operator();
+    using M::static_foo;
+    using M::operator auto;
+  };
+  
+  template <class T> int test() {
+    int i = T{}.foo(3);
+    T m = T{}.foo(M{});
+    int j = T{}(3);
+    M m2 = M{}(M{});
+    int k = T{}.static_foo(4);
+    int l = T::static_foo(5);
+    int l2 = T{};
+    struct X { };
+    X x = T{};
+    return 0;
+  }
+  int Minst = test<M>();
+  int Ninst = test<N>();
+  
+}
 }





More information about the cfe-commits mailing list