зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
62221b17c9
Коммит
924d5c9853
|
@ -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();
|
||||
|
|
|
@ -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, [...]>'
|
||||
}
|
|
@ -792,6 +792,13 @@ void Play3() {
|
|||
// 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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче