[cfe-commits] r124197 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 25 09:19:08 PST 2011


Author: dgregor
Date: Tue Jan 25 11:19:08 2011
New Revision: 124197

URL: http://llvm.org/viewvc/llvm-project?rev=124197&view=rev
Log:
Implement the rvalue-reference deduction transformation (from T&& ->
T) when taking the address of an overloaded function or matching a
specialization to a template (C++0x [temp.deduct.type]p10). Fixes
PR9044.

Added:
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp
Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=124197&r1=124196&r2=124197&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Jan 25 11:19:08 2011
@@ -49,7 +49,10 @@
     /// \brief Allow non-dependent types to differ, e.g., when performing
     /// template argument deduction from a function call where conversions
     /// may apply.
-    TDF_SkipNonDependent = 0x08
+    TDF_SkipNonDependent = 0x08,
+    /// \brief Whether we are performing template argument deduction for
+    /// parameters and arguments in a top-level template argument 
+    TDF_TopLevelParameterTypeList = 0x10
   };
 }
 
@@ -763,9 +766,9 @@
       
       // Deduce template arguments from the pattern.
       if (Sema::TemplateDeductionResult Result 
-          = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
-                                    Info, Deduced, PartialOrdering,
-                                    RefParamComparisons))
+            = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
+                                      Info, Deduced, TDF, PartialOrdering,
+                                      RefParamComparisons))
         return Result;
       
       // Capture the deduced template arguments for each parameter pack expanded
@@ -898,6 +901,29 @@
                              Arg.getCVRQualifiers());
       Param = S.Context.getQualifiedType(UnqualParam, Quals);
     }
+    
+    if ((TDF & TDF_TopLevelParameterTypeList) && !Param->isFunctionType()) {
+      // C++0x [temp.deduct.type]p10:
+      //   If P and A are function types that originated from deduction when
+      //   taking the address of a function template (14.8.2.2) or when deducing
+      //   template arguments from a function declaration (14.8.2.6) and Pi and
+      //   Ai are parameters of the top-level parameter-type-list of P and A, 
+      //   respectively, Pi is adjusted if it is an rvalue reference to a 
+      //   cv-unqualified template parameter and Ai is an lvalue reference, in 
+      //   which case the type of Pi is changed to be the template parameter 
+      //   type (i.e., T&& is changed to simply T). [ Note: As a result, when
+      //   Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be
+      //   deduced as X&. — end note ]
+      TDF &= ~TDF_TopLevelParameterTypeList;
+      
+      if (const RValueReferenceType *ParamRef
+                                        = Param->getAs<RValueReferenceType>()) {
+        if (isa<TemplateTypeParmType>(ParamRef->getPointeeType()) &&
+            !ParamRef->getPointeeType().getQualifiers())
+          if (Arg->isLValueReferenceType())
+            Param = ParamRef->getPointeeType();
+      }
+    }
   }
   
   // If the parameter type is not dependent, there is nothing to deduce.
@@ -1119,6 +1145,7 @@
     //     T(*)()
     //     T(*)(T)
     case Type::FunctionProto: {
+      unsigned SubTDF = TDF & TDF_TopLevelParameterTypeList;
       const FunctionProtoType *FunctionProtoArg =
         dyn_cast<FunctionProtoType>(Arg);
       if (!FunctionProtoArg)
@@ -1147,7 +1174,7 @@
                                      FunctionProtoParam->getNumArgs(),
                                      FunctionProtoArg->arg_type_begin(),
                                      FunctionProtoArg->getNumArgs(),
-                                     Info, Deduced, 0);
+                                     Info, Deduced, SubTDF);
     }
 
     case Type::InjectedClassName: {
@@ -2767,7 +2794,7 @@
     if (TemplateDeductionResult Result
           = ::DeduceTemplateArguments(*this, TemplateParams,
                                       FunctionType, ArgFunctionType, Info,
-                                      Deduced, 0))
+                                      Deduced, TDF_TopLevelParameterTypeList))
       return Result;
   }
 

Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp?rev=124197&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp Tue Jan 25 11:19:08 2011
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+template<typename T> void f(T&&);
+template<> void f(int&) { }
+void (*fp)(int&) = &f;





More information about the cfe-commits mailing list