================
@@ -6837,64 +6846,55 @@ ExprResult 
Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
   assert(!ParamType.hasQualifiers() &&
          "non-type template parameter type cannot be qualified");
 
+  // If either the parameter has a dependent type or the argument is
+  // type-dependent, there's nothing we can check now.
+  if (ParamType->isDependentType() || DeductionArg->isTypeDependent()) {
+    // Force the argument to the type of the parameter to maintain invariants.
+    ExprResult E = ImpCastExprToType(
+        DeductionArg, ParamType.getNonLValueExprType(Context), CK_Dependent,
+        ParamType->isLValueReferenceType()   ? VK_LValue
+        : ParamType->isRValueReferenceType() ? VK_XValue
+                                             : VK_PRValue);
+    if (E.isInvalid())
+      return ExprError();
+    setDeductionArg(E.get());
+    SugaredConverted = TemplateArgument(Arg);
+    CanonicalConverted = TemplateArgument(
+        Context.getCanonicalTemplateArgument(SugaredConverted));
+    return Arg;
+  }
+
   // FIXME: When Param is a reference, should we check that Arg is an lvalue?
-  if (CTAK == CTAK_Deduced &&
+  if (CTAK == CTAK_Deduced && !StrictCheck &&
       (ParamType->isReferenceType()
            ? !Context.hasSameType(ParamType.getNonReferenceType(),
-                                  Arg->getType())
-           : !Context.hasSameUnqualifiedType(ParamType, Arg->getType()))) {
-    // FIXME: If either type is dependent, we skip the check. This isn't
-    // correct, since during deduction we're supposed to have replaced each
-    // template parameter with some unique (non-dependent) placeholder.
-    // FIXME: If the argument type contains 'auto', we carry on and fail the
-    // type check in order to force specific types to be more specialized than
-    // 'auto'. It's not clear how partial ordering with 'auto' is supposed to
-    // work. Similarly for CTAD, when comparing 'A<x>' against 'A'.
-    if ((ParamType->isDependentType() || Arg->isTypeDependent()) &&
-        !Arg->getType()->getContainedDeducedType()) {
-      SugaredConverted = TemplateArgument(Arg);
-      CanonicalConverted = TemplateArgument(
-          Context.getCanonicalTemplateArgument(SugaredConverted));
-      return Arg;
-    }
+                                  DeductionArg->getType())
+           : !Context.hasSameUnqualifiedType(ParamType,
+                                             DeductionArg->getType()))) {
     // FIXME: This attempts to implement C++ [temp.deduct.type]p17. Per DR1770,
     // we should actually be checking the type of the template argument in P,
     // not the type of the template argument deduced from A, against the
     // template parameter type.
     Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
-      << Arg->getType()
-      << ParamType.getUnqualifiedType();
+        << Arg->getType() << ParamType.getUnqualifiedType();
     NoteTemplateParameterLocation(*Param);
     return ExprError();
   }
 
-  // If either the parameter has a dependent type or the argument is
-  // type-dependent, there's nothing we can check now.
-  if (ParamType->isDependentType() || Arg->isTypeDependent()) {
-    // Force the argument to the type of the parameter to maintain invariants.
-    auto *PE = dyn_cast<PackExpansionExpr>(Arg);
-    if (PE)
-      Arg = PE->getPattern();
-    ExprResult E = ImpCastExprToType(
-        Arg, ParamType.getNonLValueExprType(Context), CK_Dependent,
-        ParamType->isLValueReferenceType()   ? VK_LValue
-        : ParamType->isRValueReferenceType() ? VK_XValue
-                                             : VK_PRValue);
----------------
zyn0217 wrote:

I ran a debugger and it looked like this is where the issue occurred.

It seemed that `ParamType.getNonLValueExprType(Context)` was dropping the const 
qualifier from the template argument and thus there would be a mismatch when 
deducing against the primary template.

This issue seems to have occurred after clang 19 
(https://compiler-explorer.com/z/746nc8vdE), but I couldn't pinpoint the 
regressing commit. So my question is: Did we previously compare the template 
arguments and parameters in a more relaxed manner (at least in this case), 
ignoring the constness mismatch and inadvertently accepting the code? And after 
some work on DeduceTemplateArguments, did it become stricter, causing the issue 
to surface?

https://github.com/llvm/llvm-project/pull/134461
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to