[cfe-commits] r168005 - in /cfe/trunk: lib/AST/ASTDiagnostic.cpp test/Misc/diag-template-diffing-cxx98.cpp test/Misc/diag-template-diffing.cpp

Eli Friedman eli.friedman at gmail.com
Wed Nov 14 15:57:09 PST 2012


Author: efriedma
Date: Wed Nov 14 17:57:08 2012
New Revision: 168005

URL: http://llvm.org/viewvc/llvm-project?rev=168005&view=rev
Log:
Make template diffing handle integral expressions of various widths correctly.
PR14342.


Added:
    cfe/trunk/test/Misc/diag-template-diffing-cxx98.cpp
Modified:
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/test/Misc/diag-template-diffing.cpp

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=168005&r1=168004&r2=168005&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Wed Nov 14 17:57:08 2012
@@ -848,6 +848,9 @@
               dyn_cast<NonTypeTemplateParmDecl>(ParamND)) {
         Expr *FromExpr, *ToExpr;
         llvm::APSInt FromInt, ToInt;
+        unsigned ParamWidth = 0;
+        if (DefaultNTTPD->getType()->isIntegralOrEnumerationType())
+          ParamWidth = Context.getIntWidth(DefaultNTTPD->getType());
         bool HasFromInt = !FromIter.isEnd() &&
                           FromIter->getKind() == TemplateArgument::Integral;
         bool HasToInt = !ToIter.isEnd() &&
@@ -865,7 +868,7 @@
 
         if (!HasFromInt && !HasToInt) {
           Tree.SetNode(FromExpr, ToExpr);
-          Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
+          Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
           Tree.SetDefault(FromIter.isEnd() && FromExpr,
                           ToIter.isEnd() && ToExpr);
         } else {
@@ -878,7 +881,7 @@
             HasToInt = true;
           }
           Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
-          Tree.SetSame(llvm::APSInt::isSameValue(FromInt, ToInt));
+          Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
           Tree.SetDefault(FromIter.isEnd() && HasFromInt,
                           ToIter.isEnd() && HasToInt);
         }
@@ -1010,8 +1013,18 @@
       ArgDecl = DefaultTD;
   }
 
+  /// IsSameConvertedInt - Returns true if both integers are equal when
+  /// converted to an integer type with the given width.
+  static bool IsSameConvertedInt(unsigned Width, const llvm::APSInt &X,
+                                 const llvm::APSInt &Y) {
+    llvm::APInt ConvertedX = X.extOrTrunc(Width);
+    llvm::APInt ConvertedY = Y.extOrTrunc(Width);
+    return ConvertedX == ConvertedY;
+  }
+
   /// IsEqualExpr - Returns true if the expressions evaluate to the same value.
-  static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
+  static bool IsEqualExpr(ASTContext &Context, unsigned ParamWidth,
+                          Expr *FromExpr, Expr *ToExpr) {
     if (FromExpr == ToExpr)
       return true;
 
@@ -1042,7 +1055,7 @@
 
     switch (FromVal.getKind()) {
       case APValue::Int:
-        return FromVal.getInt() == ToVal.getInt();
+        return IsSameConvertedInt(ParamWidth, FromVal.getInt(), ToVal.getInt());
       case APValue::LValue: {
         APValue::LValueBase FromBase = FromVal.getLValueBase();
         APValue::LValueBase ToBase = ToVal.getLValueBase();

Added: cfe/trunk/test/Misc/diag-template-diffing-cxx98.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing-cxx98.cpp?rev=168005&view=auto
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing-cxx98.cpp (added)
+++ cfe/trunk/test/Misc/diag-template-diffing-cxx98.cpp Wed Nov 14 17:57:08 2012
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++98 2>&1 | FileCheck %s
+
+namespace PR14342 {
+  template<typename T, char a> struct X {};
+  X<int, 1> x = X<long, 257>();
+  // CHECK: error: no viable conversion from 'X<long, [...]>' to 'X<int, [...]>'
+}
\ No newline at end of file

Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=168005&r1=168004&r2=168005&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Wed Nov 14 17:57:08 2012
@@ -792,6 +792,13 @@
 // CHECK-NOELIDE-TREE:     [1 != (no argument)]>
 }
 
+namespace PR14342 {
+  template<typename T, short a> struct X {};
+  X<int, (signed char)-1> x = X<long, -1>();
+  X<int, 3UL> y = X<int, 2>();
+  // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<long, [...]>' to 'X<int, [...]>'
+  // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X<[...], 2>' to 'X<[...], 3UL>'
+}
 
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.





More information about the cfe-commits mailing list