Index: lib/AST/ASTDiagnostic.cpp =================================================================== --- lib/AST/ASTDiagnostic.cpp +++ lib/AST/ASTDiagnostic.cpp @@ -1290,6 +1290,9 @@ 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)); @@ -1298,6 +1301,9 @@ 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; 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] 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 struct A {}; +template > 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' cannot bind to a temporary of type 'A' +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.