From 97bacec221dbaffa74825a180efaa6684a65f6d9 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Sat, 26 Jul 2014 02:10:52 +0000 Subject: [PATCH] If a template argument is non-evaluable expression, use the profile ID to see if the two arguments are equal. llvm-svn: 214008 --- clang/lib/AST/ASTDiagnostic.cpp | 15 ++++++------- clang/test/Misc/diag-template-diffing.cpp | 35 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index ad71335..8c8b1df 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1291,11 +1291,8 @@ class TemplateDiff { if (!FromExpr || !ToExpr) return false; - FromExpr = FromExpr->IgnoreParens(); - ToExpr = ToExpr->IgnoreParens(); - - DeclRefExpr *FromDRE = dyn_cast(FromExpr), - *ToDRE = dyn_cast(ToExpr); + DeclRefExpr *FromDRE = dyn_cast(FromExpr->IgnoreParens()), + *ToDRE = dyn_cast(ToExpr->IgnoreParens()); if (FromDRE || ToDRE) { if (!FromDRE || !ToDRE) @@ -1305,8 +1302,12 @@ class TemplateDiff { Expr::EvalResult FromResult, ToResult; if (!FromExpr->EvaluateAsRValue(FromResult, Context) || - !ToExpr->EvaluateAsRValue(ToResult, Context)) - return false; + !ToExpr->EvaluateAsRValue(ToResult, Context)) { + llvm::FoldingSetNodeID FromID, ToID; + FromExpr->Profile(FromID, Context, true); + ToExpr->Profile(ToID, Context, true); + return FromID == ToID; + } APValue &FromVal = FromResult.Val; APValue &ToVal = ToResult.Val; diff --git a/clang/test/Misc/diag-template-diffing.cpp b/clang/test/Misc/diag-template-diffing.cpp index 32d67b9..bdd6d62 100644 --- a/clang/test/Misc/diag-template-diffing.cpp +++ b/clang/test/Misc/diag-template-diffing.cpp @@ -1212,6 +1212,41 @@ A a2 = A(); // CHECK-ELIDE-NOTREE: no viable conversion from 'A' to 'A' } +namespace TypeAlias { +template class A {}; + +template using a = A; +template using a = A; + +template using A1 = A; +template using A1 = A; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A' vs 'A') + +template using A2 = A<1 + T::num>; +template using A2 = A; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A' vs 'A<1 + T::num>') + +template using A3 = A<(T::num)>; +template using A3 = A; +// CHECK-ELIDE-NOTREE: error: type alias template redefinition with different types ('A' vs 'A<(T::num)>') + + template using A4 = A<(T::num)>; +template using A4 = A<((T::num))>; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<((T::num))>' vs 'A<(T::num)>') + +template using A5 = A; +template using A5 = A; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<[...], (default) 0>' vs 'A<[...], 1>') + +template using A6 = A; +template using A6 = A; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<[...], (default) 0>' vs 'A<[...], 1>') + +template using A7 = A; +template using A7 = A<(T::num)>; +// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<(T::num), (default) 0>' vs 'A') +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated. -- 2.7.4