Index: lib/AST/ASTDiagnostic.cpp =================================================================== --- lib/AST/ASTDiagnostic.cpp +++ lib/AST/ASTDiagnostic.cpp @@ -959,25 +959,27 @@ ToIter.isEnd() && ToExpr); if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) { if (FromExpr) - FromInt = GetInt(FromIter, FromExpr); + HasFromInt = GetInt(FromIter, FromExpr, FromInt); if (ToExpr) - ToInt = GetInt(ToIter, ToExpr); - Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr); + HasToInt = GetInt(ToIter, ToExpr, ToInt); + } + if (HasFromInt && HasToInt) { + Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); Tree.SetKind(DiffTree::Integer); + } else if (HasFromInt || HasToInt) { + Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); + Tree.SetSame(false); + Tree.SetKind(DiffTree::Integer); } else { Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr)); Tree.SetKind(DiffTree::Expression); } } else if (HasFromInt || HasToInt) { - if (!HasFromInt && FromExpr) { - FromInt = GetInt(FromIter, FromExpr); - HasFromInt = true; - } - if (!HasToInt && ToExpr) { - ToInt = GetInt(ToIter, ToExpr); - HasToInt = true; - } + if (!HasFromInt && FromExpr) + HasFromInt = GetInt(FromIter, FromExpr, FromInt); + if (!HasToInt && ToExpr) + HasToInt = GetInt(ToIter, ToExpr, ToInt); Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); Tree.SetDefault(FromIter.isEnd() && HasFromInt, @@ -1121,20 +1123,27 @@ /// GetInt - Retrieves the template integer argument, including evaluating /// default arguments. - llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) { + bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) { // Default, value-depenedent expressions require fetching - // from the desugared TemplateArgument - if (Iter.isEnd() && ArgExpr->isValueDependent()) - switch (Iter.getDesugar().getKind()) { - case TemplateArgument::Integral: - return Iter.getDesugar().getAsIntegral(); - case TemplateArgument::Expression: - ArgExpr = Iter.getDesugar().getAsExpr(); - return ArgExpr->EvaluateKnownConstInt(Context); - default: - llvm_unreachable("Unexpected template argument kind"); + // from the desugared TemplateArgument, otherwise expression needs to + // be evaluatable. + if (Iter.isEnd() && ArgExpr->isValueDependent()) { + TemplateArgument::ArgKind Kind = Iter.getDesugar().getKind(); + if (Kind == TemplateArgument::Integral) { + Int = Iter.getDesugar().getAsIntegral(); + } else if (Kind == TemplateArgument::Expression) { + ArgExpr = Iter.getDesugar().getAsExpr(); + Int = ArgExpr->EvaluateKnownConstInt(Context); + } else { + llvm_unreachable("Unexpected template argument kind"); } - return ArgExpr->EvaluateKnownConstInt(Context); + return true; + } else if (ArgExpr->isEvaluatable(Context)) { + Int = ArgExpr->EvaluateKnownConstInt(Context); + return true; + } + + return false; } /// GetValueDecl - Retrieves the template Decl argument, including @@ -1517,6 +1526,8 @@ Bold(); } OS << Val.toString(10); + } else if (E) { + PrintExpr(E); } else { OS << "(no argument)"; } Index: test/Misc/diag-template-diffing.cpp =================================================================== --- test/Misc/diag-template-diffing.cpp +++ test/Misc/diag-template-diffing.cpp @@ -1068,6 +1068,43 @@ } } +namespace PR15677 { +template +struct A{}; + +template +using B = A; + +template +using B = A; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A' vs 'A') + +template +struct C{}; + +template +using D = C; + +template +using D = C; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C' vs 'C') + +template +using E = C; + +template +using E = C<42>; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<42>' vs 'C') + +template +using F = C; + +template +using F = C<21 + 21>; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<21 + 21 aka 42>' vs 'C') +} +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.