From: Eli Friedman Date: Wed, 14 Nov 2012 23:57:08 +0000 (+0000) Subject: Make template diffing handle integral expressions of various widths correctly. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c2c982c78b0f964d8f7430b2f396b829520a80a1;p=platform%2Fupstream%2Fllvm.git Make template diffing handle integral expressions of various widths correctly. PR14342. llvm-svn: 168005 --- diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 0b9c524..3115d00 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -848,6 +848,9 @@ class TemplateDiff { dyn_cast(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 @@ class TemplateDiff { 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 @@ class TemplateDiff { 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 @@ class TemplateDiff { 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 @@ class TemplateDiff { 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(); diff --git a/clang/test/Misc/diag-template-diffing-cxx98.cpp b/clang/test/Misc/diag-template-diffing-cxx98.cpp new file mode 100644 index 0000000..cd40ccc --- /dev/null +++ b/clang/test/Misc/diag-template-diffing-cxx98.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only %s -std=c++98 2>&1 | FileCheck %s + +namespace PR14342 { + template struct X {}; + X x = X(); + // CHECK: error: no viable conversion from 'X' to 'X' +} \ No newline at end of file diff --git a/clang/test/Misc/diag-template-diffing.cpp b/clang/test/Misc/diag-template-diffing.cpp index 2c044f8..7d01f46 100644 --- a/clang/test/Misc/diag-template-diffing.cpp +++ b/clang/test/Misc/diag-template-diffing.cpp @@ -792,6 +792,13 @@ void Play3() { // CHECK-NOELIDE-TREE: [1 != (no argument)]> } +namespace PR14342 { + template struct X {}; + X x = X(); + X y = X(); + // CHECK-ELIDE-NOTREE: error: no viable conversion from 'X' to 'X' + // 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.