jtbandes updated this revision to Diff 133440.
jtbandes added a comment.

Using a slightly more invasive fix. I haven't come up with any other test cases 
that exhibit the problem, which makes me unsure this fix is needed in all these 
locations. Maybe someone with more knowledge of this function can advise.


Repository:
  rC Clang

https://reviews.llvm.org/D40284

Files:
  lib/Sema/SemaTemplateDeduction.cpp
  test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp

Index: test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
===================================================================
--- test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
+++ test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
@@ -45,3 +45,11 @@
     func(foo<int>()); // expected-error {{no matching function}}
   }
 }
+
+namespace test4 {
+  // expected-note@+1 {{candidate template ignored: could not match 'int [N]' against 'int []'}}
+  template<int N> void f1(int (&arr)[N]);
+  template<int N> void f2(int (&arr)[]) {
+    f1(arr); // expected-error {{no matching function}}
+  }
+}
Index: lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- lib/Sema/SemaTemplateDeduction.cpp
+++ lib/Sema/SemaTemplateDeduction.cpp
@@ -1289,27 +1289,34 @@
     return Sema::TDK_Success;
   }
 
-  // Set up the template argument deduction information for a failure.
-  Info.FirstArg = TemplateArgument(ParamIn);
-  Info.SecondArg = TemplateArgument(ArgIn);
-
   // If the parameter is an already-substituted template parameter
   // pack, do nothing: we don't know which of its arguments to look
   // at, so we have to wait until all of the parameter packs in this
   // expansion have arguments.
   if (isa<SubstTemplateTypeParmPackType>(Param))
     return Sema::TDK_Success;
 
+  // Use this when returning a failure result in order to fill in the
+  // corresponding failure info. Don't use this when returning the
+  // result of a recursive call, as the callee will have already set
+  // their own failure info.
+  const auto WithFailureInfo =
+    [&Info, &ParamIn, &ArgIn](Sema::TemplateDeductionResult Result) {
+      Info.FirstArg = TemplateArgument(ParamIn);
+      Info.SecondArg = TemplateArgument(ArgIn);
+      return Result;
+    };
+
   // Check the cv-qualifiers on the parameter and argument types.
   CanQualType CanParam = S.Context.getCanonicalType(Param);
   CanQualType CanArg = S.Context.getCanonicalType(Arg);
   if (!(TDF & TDF_IgnoreQualifiers)) {
     if (TDF & TDF_ParamWithReferenceType) {
       if (hasInconsistentOrSupersetQualifiersOf(Param, Arg))
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     } else if (!IsPossiblyOpaquelyQualifiedType(Param)) {
       if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     }
 
     // If the parameter type is not dependent, there is nothing to deduce.
@@ -1319,9 +1326,8 @@
             (TDF & TDF_AllowCompatibleFunctionType)
                 ? !S.isSameOrCompatibleFunctionType(CanParam, CanArg)
                 : Param != Arg;
-        if (NonDeduced) {
-          return Sema::TDK_NonDeducedMismatch;
-        }
+        if (NonDeduced)
+          return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
       }
       return Sema::TDK_Success;
     }
@@ -1366,7 +1372,10 @@
         Arg = Arg.getUnqualifiedType();
       }
 
-      return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch;
+      if (Param == Arg)
+        return Sema::TDK_Success;
+
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     }
 
     //     _Complex T   [placeholder extension]
@@ -1377,7 +1386,7 @@
                                     ComplexArg->getElementType(),
                                     Info, Deduced, TDF);
 
-      return Sema::TDK_NonDeducedMismatch;
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
     //     _Atomic T   [extension]
     case Type::Atomic:
@@ -1387,7 +1396,7 @@
                                        AtomicArg->getValueType(),
                                        Info, Deduced, TDF);
 
-      return Sema::TDK_NonDeducedMismatch;
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
     //     T *
     case Type::Pointer: {
@@ -1398,7 +1407,7 @@
                    = Arg->getAs<ObjCObjectPointerType>()) {
         PointeeType = PointerArg->getPointeeType();
       } else {
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
       }
 
       unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
@@ -1413,7 +1422,7 @@
       const LValueReferenceType *ReferenceArg =
           Arg->getAs<LValueReferenceType>();
       if (!ReferenceArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
                            cast<LValueReferenceType>(Param)->getPointeeType(),
@@ -1425,7 +1434,7 @@
       const RValueReferenceType *ReferenceArg =
           Arg->getAs<RValueReferenceType>();
       if (!ReferenceArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
                              cast<RValueReferenceType>(Param)->getPointeeType(),
@@ -1438,7 +1447,7 @@
       const IncompleteArrayType *IncompleteArrayArg =
         S.Context.getAsIncompleteArrayType(Arg);
       if (!IncompleteArrayArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
       return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
@@ -1452,12 +1461,12 @@
       const ConstantArrayType *ConstantArrayArg =
         S.Context.getAsConstantArrayType(Arg);
       if (!ConstantArrayArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       const ConstantArrayType *ConstantArrayParm =
         S.Context.getAsConstantArrayType(Param);
       if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
       return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
@@ -1470,7 +1479,7 @@
     case Type::DependentSizedArray: {
       const ArrayType *ArrayArg = S.Context.getAsArrayType(Arg);
       if (!ArrayArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
 
@@ -1510,7 +1519,7 @@
                                                Info, Deduced);
 
       // Incomplete type does not match a dependently-sized array type
-      return Sema::TDK_NonDeducedMismatch;
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     }
 
     //     type(*)(T)
@@ -1521,7 +1530,7 @@
       const FunctionProtoType *FunctionProtoArg =
         dyn_cast<FunctionProtoType>(Arg);
       if (!FunctionProtoArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       const FunctionProtoType *FunctionProtoParam =
         cast<FunctionProtoType>(Param);
@@ -1531,7 +1540,7 @@
           FunctionProtoParam->getRefQualifier()
             != FunctionProtoArg->getRefQualifier() ||
           FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       // Check return types.
       if (auto Result = DeduceTemplateArgumentsByTypeMatch(
@@ -1715,7 +1724,7 @@
       const MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param);
       const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg);
       if (!MemPtrArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       QualType ParamPointeeType = MemPtrParam->getPointeeType();
       if (ParamPointeeType->isFunctionType())
@@ -1751,7 +1760,7 @@
       const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg);
 
       if (!BlockPtrArg)
-        return Sema::TDK_NonDeducedMismatch;
+        return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
       return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
                                                 BlockPtrParam->getPointeeType(),
@@ -1767,7 +1776,7 @@
       if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
         // Make sure that the vectors have the same number of elements.
         if (VectorParam->getNumElements() != VectorArg->getNumElements())
-          return Sema::TDK_NonDeducedMismatch;
+          return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
 
         // Perform deduction on the element types.
         return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
@@ -1789,7 +1798,7 @@
                                                   Info, Deduced, TDF);
       }
 
-      return Sema::TDK_NonDeducedMismatch;
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     }
 
     //     (clang extension)
@@ -1845,7 +1854,7 @@
                                              Info, Deduced);
       }
 
-      return Sema::TDK_NonDeducedMismatch;
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     }
 
     //     (clang extension)
@@ -1898,7 +1907,7 @@
                                              true, Info, Deduced);
       }
 
-      return Sema::TDK_NonDeducedMismatch;
+      return WithFailureInfo(Sema::TDK_NonDeducedMismatch);
     }
 
     case Type::TypeOfExpr:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D40284: [Sema]... Jacob Bandes-Storch via Phabricator via cfe-commits

Reply via email to