(!HasFromValueDecl && !HasToValueDecl)) &&
"Template argument cannot be both integer and declaration");
+ unsigned ParamWidth = 128; // Safe default
+ if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType())
+ ParamWidth = Context.getIntWidth(FromDefaultNonTypeDecl->getType());
+
if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
Tree.SetNode(FromExpr, ToExpr);
Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr);
}
if (HasFromInt && HasToInt) {
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
- Tree.SetSame(FromInt == ToInt);
+ Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetKind(DiffTree::Integer);
} else if (HasFromInt || HasToInt) {
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(false);
Tree.SetKind(DiffTree::Integer);
} else {
- Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) ||
+ Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) ||
(FromNullPtr && ToNullPtr));
Tree.SetNullPtr(FromNullPtr, ToNullPtr);
Tree.SetKind(DiffTree::Expression);
if (!HasToInt && ToExpr)
HasToInt = GetInt(Context, ToIter, ToExpr, ToInt);
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
- if (HasFromInt && HasToInt) {
- Tree.SetSame(FromInt == ToInt);
- } else {
- Tree.SetSame(false);
- }
+ Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetDefault(FromIter.isEnd() && HasFromInt,
ToIter.isEnd() && HasToInt);
Tree.SetKind(DiffTree::Integer);
/// GetInt - Retrieves the template integer argument, including evaluating
/// default arguments.
static bool GetInt(ASTContext &Context, const TSTiterator &Iter,
- Expr *ArgExpr, llvm::APSInt &Int) {
+ Expr *ArgExpr, llvm::APInt &Int) {
// Default, value-depenedent expressions require fetching
// from the desugared TemplateArgument, otherwise expression needs to
// be evaluatable.
return nullptr;
}
+ /// 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;
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();
}
Unbold();
}
-
+
/// HasExtraInfo - Returns true if E is not an integer literal or the
/// negation of an integer literal
bool HasExtraInfo(Expr *E) {
if (!E) return false;
-
- E = E->IgnoreImpCasts();
-
if (isa<IntegerLiteral>(E)) return false;
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))