From: Douglas Gregor Date: Fri, 18 Feb 2011 02:12:44 +0000 (+0000) Subject: When we're creating an expression for an integral template argument of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f5667d06a785719691c1139b961411d7f0aedf5;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125818 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 88ba3f9a88..12ed3732e7 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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); } diff --git a/test/SemaTemplate/instantiate-non-type-template-parameter.cpp b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp index cbadcde2c1..027c1e8bb7 100644 --- a/test/SemaTemplate/instantiate-non-type-template-parameter.cpp +++ b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp @@ -34,3 +34,22 @@ namespace PR6986 { ckey_m m; } } + +namespace rdar8980215 { + enum E { E1, E2, E3 }; + + template + struct X0 { + X0() {} + template X0(const X0 &); + }; + + template + struct X1 : X0 { + X1() {} + template X1(const X1 &x) : X0(x) { } + }; + + X1 x1i; + X1 x1f(x1i); +}