]> granicus.if.org Git - clang/commitdiff
When we're creating an expression for an integral template argument of
authorDouglas Gregor <dgregor@apple.com>
Fri, 18 Feb 2011 02:12:44 +0000 (02:12 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 18 Feb 2011 02:12:44 +0000 (02:12 +0000)
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

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/instantiate-non-type-template-parameter.cpp

index 88ba3f9a8857d8298282e1935fbd11572de6cae0..12ed3732e714a9c03e7d8cb63c525d35610acad7 100644 (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);
 }
 
index cbadcde2c1c157591be477f238dba3c0b69f46e3..027c1e8bb769255b43c8835b41ef5238b6019819 100644 (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);
+}