]> granicus.if.org Git - clang/commitdiff
If a template argument is non-evaluable expression, use the profile ID to see
authorRichard Trieu <rtrieu@google.com>
Sat, 26 Jul 2014 02:10:52 +0000 (02:10 +0000)
committerRichard Trieu <rtrieu@google.com>
Sat, 26 Jul 2014 02:10:52 +0000 (02:10 +0000)
if the two arguments are equal.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214008 91177308-0d34-0410-b5e6-96231b3b80d8

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

index ad71335add78311718bd859f000fe30c9111c7fd..8c8b1dff0cbf6011e20f834bb2eff8c6fe517d85 100644 (file)
@@ -1291,11 +1291,8 @@ class TemplateDiff {
     if (!FromExpr || !ToExpr)
       return false;
 
-    FromExpr = FromExpr->IgnoreParens();
-    ToExpr = ToExpr->IgnoreParens();
-
-    DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr),
-                *ToDRE = dyn_cast<DeclRefExpr>(ToExpr);
+    DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()),
+                *ToDRE = dyn_cast<DeclRefExpr>(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;
index 32d67b9390982a679df7d495ce7a9af2a3e1e96c..bdd6d62fdda2447e643c9306a1303329157c7c85 100644 (file)
@@ -1212,6 +1212,41 @@ A<int> a2 = A<bool>();
 // CHECK-ELIDE-NOTREE: no viable conversion from 'A<bool>' to 'A<int>'
 }
 
+namespace TypeAlias {
+template <int, int = 0> class A {};
+
+template <class T> using a = A<T::num, 0>;
+template <class T> using a = A<T::num>;
+
+template <class T> using A1 = A<T::num>;
+template <class T> using A1 = A<T::num + 0>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<T::num + 0>' vs 'A<T::num>')
+
+template <class T> using A2 = A<1 + T::num>;
+template <class T> using A2 = A<T::num + 1>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<T::num + 1>' vs 'A<1 + T::num>')
+
+template <class T> using A3 = A<(T::num)>;
+template <class T> using A3 = A<T::num>;
+// CHECK-ELIDE-NOTREE: error: type alias template redefinition with different types ('A<T::num>' vs 'A<(T::num)>')
+
+          template <class T> using A4 = A<(T::num)>;
+template <class T> using A4 = A<((T::num))>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<((T::num))>' vs 'A<(T::num)>')
+
+template <class T> using A5 = A<T::num, 1>;
+template <class T> using A5 = A<T::num>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<[...], (default) 0>' vs 'A<[...], 1>')
+
+template <class T> using A6 = A<T::num + 5, 1>;
+template <class T> using A6 = A<T::num + 5>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<[...], (default) 0>' vs 'A<[...], 1>')
+
+template <class T> using A7 = A<T::num, 1>;
+template <class T> using A7 = A<(T::num)>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<(T::num), (default) 0>' vs 'A<T::num, 1>')
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.