When we're creating an expression for an integral template argument of

enumeration type, we were generating an integer literal implicitly
casted to the appropriate enumeration type. However, later checks on
that expression would strip the implicit cast.

This commit tweaks the lame hack, by creating an explicit cast instead
of an implicit cast. The right answer is to introduce a 
SubstNonTypeTemplateParmExpr expression that acts like the substituted
result. I'll investigate that soon.

llvm-svn: 125818
This commit is contained in:
Douglas Gregor 2011-02-18 02:12:44 +00:00
parent 43e7f31f11
commit 9543c40df1
2 changed files with 28 additions and 2 deletions

View File

@ -3707,8 +3707,15 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
BT = T;
Expr *E = IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc);
ImpCastExprToType(E, T, CK_IntegralCast);
if (T->isEnumeralType()) {
// FIXME: This is a hack. We need a better way to handle substituted
// non-type template parameters.
E = CStyleCastExpr::Create(Context, T, VK_RValue, CK_IntegralCast,
E, 0,
Context.getTrivialTypeSourceInfo(T, Loc),
Loc, Loc);
}
return Owned(E);
}

View File

@ -34,3 +34,22 @@ namespace PR6986 {
ckey_m m;
}
}
namespace rdar8980215 {
enum E { E1, E2, E3 };
template<typename T, E e = E2>
struct X0 {
X0() {}
template<typename U> X0(const X0<U, e> &);
};
template<typename T>
struct X1 : X0<T> {
X1() {}
template<typename U> X1(const X1<U> &x) : X0<T>(x) { }
};
X1<int> x1i;
X1<float> x1f(x1i);
}