diff options
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 11 | ||||
-rw-r--r-- | test/SemaTemplate/deduction.cpp | 12 |
2 files changed, 22 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 2514b48de3..3ac190e1d4 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4152,7 +4152,16 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, else BT = T; - return Owned(IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc)); + Expr *E = IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc); + 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); } /// \brief Match two template parameters within template parameter lists. diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp index 15c061c261..aecb5ee7c8 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -150,3 +150,15 @@ namespace test3 { } }; } + +// Verify that we can deduce enum-typed arguments correctly. +namespace test14 { + enum E { E0, E1 }; + template <E> struct A {}; + template <E e> void foo(const A<e> &a) {} + + void test() { + A<E0> a; + foo(a); + } +} |