aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-11-14 23:57:08 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-11-14 23:57:08 +0000
commit924d5c9853fbdfabc54a473e680f3b6bb8a1b940 (patch)
treeee0e8da08184048f8e78e26c42f75bc6fca481e2 /lib
parent62221b17c90457df9ca0ff20bb54d634e8951def (diff)
Make template diffing handle integral expressions of various widths correctly.
PR14342. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168005 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTDiagnostic.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 0b9c524944..3115d00b50 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -848,6 +848,9 @@ class TemplateDiff {
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 @@ 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();