[PATCH] D15384: Don't ask for the size of dependent integral types in template diffing

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 9 10:34:13 PST 2015


rnk created this revision.
rnk added a reviewer: rsmith.
rnk added a subscriber: cfe-commits.

In the following example, we end up diffing 'A<int, 0>' against 'A<>'.
  template <typename SizeType = int, SizeType = 0> struct A {};
  template <typename R = A<>> R bar();
  A<> &foo() { return bar(); }

It appears that we end up comparing the default argument of
'SizeType = 0' against the instantiated argument of 'int = 0'. The type
of the default argument is still dependent at this point, and this patch
bails out of the comparison at that point.

The diagnostic we ultimately give is not that great, but maybe we can
live with it:
  error: non-const lvalue reference to type 'A<[...], (no argument)>'
         cannot bind to a temporary of type 'A<[...], 0>'

http://reviews.llvm.org/D15384

Files:
  lib/AST/ASTDiagnostic.cpp
  test/Misc/diag-template-diffing.cpp

Index: test/Misc/diag-template-diffing.cpp
===================================================================
--- test/Misc/diag-template-diffing.cpp
+++ test/Misc/diag-template-diffing.cpp
@@ -1274,6 +1274,16 @@
 // CHECK-ELIDE-NOTREE: candidate function [with T = BoolArgumentBitExtended::BoolT<true>] not viable: no known conversion from 'BoolT<0>' to 'BoolT<1>' for 1st argument
 }
 
+namespace DefaultNonTypeArgWithDependentType {
+// We used to crash diffing integer template arguments when the argument type
+// is dependent and default arguments were used.
+template <typename SizeType = int, SizeType = 0> struct A {};
+template <typename R = A<>> R bar();
+A<> &foo() { return bar(); }
+// CHECK-ELIDE-NOTREE: error: non-const lvalue reference to type 'A<[...], (no argument)>' cannot bind to a temporary of type 'A<[...], 0>'
+// CHECK-NOELIDE-NOTREE: error: non-const lvalue reference to type 'A<int, (no argument)>' cannot bind to a temporary of type 'A<int, 0>'
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
Index: lib/AST/ASTDiagnostic.cpp
===================================================================
--- lib/AST/ASTDiagnostic.cpp
+++ lib/AST/ASTDiagnostic.cpp
@@ -1290,14 +1290,20 @@
           Int = Iter.getDesugar().getAsIntegral();
           return true;
         case TemplateArgument::Expression:
+          // Fail if we can't extend or truncate.
+          if (IntegerType->isDependentType())
+            return false;
           ArgExpr = Iter.getDesugar().getAsExpr();
           Int = ArgExpr->EvaluateKnownConstInt(Context);
           Int = Int.extOrTrunc(Context.getTypeSize(IntegerType));
           return true;
         default:
           llvm_unreachable("Unexpected template argument kind");
       }
     } else if (ArgExpr->isEvaluatable(Context)) {
+      // Fail if we can't extend or truncate.
+      if (IntegerType->isDependentType())
+        return false;
       Int = ArgExpr->EvaluateKnownConstInt(Context);
       Int = Int.extOrTrunc(Context.getTypeSize(IntegerType));
       return true;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15384.42316.patch
Type: text/x-patch
Size: 2166 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151209/85d00d65/attachment.bin>


More information about the cfe-commits mailing list