[cfe-commits] r133327 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp

Chandler Carruth chandlerc at gmail.com
Fri Jun 17 18:19:03 PDT 2011


Author: chandlerc
Date: Fri Jun 17 20:19:03 2011
New Revision: 133327

URL: http://llvm.org/viewvc/llvm-project?rev=133327&view=rev
Log:
Accept no-return stripping conversions for pointer type arguments after
deducing template parameter types. Recently Clang began enforcing the
more strict checking that the argument type and the deduced function
parameter type (after substitution) match, but that only consideres
qualification conversions.

One problem with this patch is that we check noreturn conversions and
qualification conversions independently. If a valid conversion would
require *both*, perhaps interleaved with each other, it will be
rejected. If this actually occurs (I'm not yet sure it does) and is in
fact a problem (I'm not yet sure it is), there is a FIXME to implement
more intelligent conversion checking.

However, this step at least allows Clang to resume accepting valid code
we're seeing in the wild.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=133327&r1=133326&r2=133327&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun 17 20:19:03 2011
@@ -1351,6 +1351,8 @@
                                     bool IgnoreBaseAccess);
   bool IsQualificationConversion(QualType FromType, QualType ToType,
                                  bool CStyle, bool &ObjCLifetimeConversion);
+  bool IsNoReturnConversion(QualType FromType, QualType ToType,
+                            QualType &ResultTy);
   bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
 
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=133327&r1=133326&r2=133327&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jun 17 20:19:03 2011
@@ -924,8 +924,8 @@
 
 /// \brief Determine whether the conversion from FromType to ToType is a valid
 /// conversion that strips "noreturn" off the nested function type.
-static bool IsNoReturnConversion(ASTContext &Context, QualType FromType,
-                                 QualType ToType, QualType &ResultTy) {
+bool Sema::IsNoReturnConversion(QualType FromType, QualType ToType,
+                                QualType &ResultTy) {
   if (Context.hasSameUnqualifiedType(FromType, ToType))
     return false;
 
@@ -1066,7 +1066,7 @@
                       S.ExtractUnqualifiedFunctionType(ToType), FromType)) {
         QualType resultTy;
         // if the function type matches except for [[noreturn]], it's ok
-        if (!IsNoReturnConversion(S.Context, FromType, 
+        if (!S.IsNoReturnConversion(FromType,
               S.ExtractUnqualifiedFunctionType(ToType), resultTy))
           // otherwise, only a boolean conversion is standard   
           if (!ToType->isBooleanType()) 
@@ -1234,7 +1234,7 @@
     // Compatible conversions (Clang extension for C function overloading)
     SCS.Second = ICK_Compatible_Conversion;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsNoReturnConversion(S.Context, FromType, ToType, FromType)) {
+  } else if (S.IsNoReturnConversion(FromType, ToType, FromType)) {
     // Treat a conversion that strips "noreturn" as an identity conversion.
     SCS.Second = ICK_NoReturn_Adjustment;
   } else if (IsTransparentUnionStandardConversion(S, From, ToType,
@@ -7597,8 +7597,8 @@
       QualType ResultTy;
       if (Context.hasSameUnqualifiedType(TargetFunctionType, 
                                          FunDecl->getType()) ||
-          IsNoReturnConversion(Context, FunDecl->getType(), TargetFunctionType, 
-                               ResultTy)) {
+          S.IsNoReturnConversion(FunDecl->getType(), TargetFunctionType,
+                                 ResultTy)) {
         Matches.push_back(std::make_pair(CurAccessFunPair,
           cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
         FoundNonTemplateFunction = true;

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=133327&r1=133326&r2=133327&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Jun 17 20:19:03 2011
@@ -2371,9 +2371,16 @@
   //    - The transformed A can be another pointer or pointer to member 
   //      type that can be converted to the deduced A via a qualification 
   //      conversion.
+  //
+  // Also allow conversions which merely strip [[noreturn]] from function types
+  // (recursively) as an extension.
+  // FIXME: Currently, this doesn't place nicely with qualfication conversions.
   bool ObjCLifetimeConversion = false;
+  QualType ResultTy;
   if ((A->isAnyPointerType() || A->isMemberPointerType()) &&
-      S.IsQualificationConversion(A, DeducedA, false, ObjCLifetimeConversion))
+      (S.IsQualificationConversion(A, DeducedA, false,
+                                   ObjCLifetimeConversion) ||
+       S.IsNoReturnConversion(A, DeducedA, ResultTy)))
     return false;
   
   

Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp?rev=133327&r1=133326&r2=133327&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp Fri Jun 17 20:19:03 2011
@@ -71,7 +71,21 @@
   A<int> a0 = f3(ip);
   A<volatile int> a1 = f3(vip);
 }
-                             
+
+// Also accept conversions for pointer types which require removing
+// [[noreturn]].
+namespace noreturn_stripping {
+  template <class R>
+  void f(R (*function)());
+
+  void g() __attribute__ ((__noreturn__));
+  void h();
+  void test() {
+    f(g);
+    f(h);
+  }
+}
+
 //   - If P is a class, and P has the form template-id, then A can be a 
 //     derived class of the deduced A. Likewise, if P is a pointer to a class
 //     of the form template-id, A can be a pointer to a derived class pointed 





More information about the cfe-commits mailing list