Patchwork C++ PATCH for c++/49855, c++/49896 (ICE with named constants in templates)

login
register
mail settings
Submitter Jason Merrill
Date Oct. 11, 2011, 6:19 p.m.
Message ID <4E9488B0.2020002@redhat.com>
Download mbox | patch
Permalink /patch/119041/
State New
Headers show

Comments

Jason Merrill - Oct. 11, 2011, 6:19 p.m.
For the 4.6 branch I'm only making the change for scalars.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit d8978a333ab71a4ad2c38446764c1b37092ea098
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Oct 3 17:06:02 2011 -0400

    	PR c++/49855
    	PR c++/49896
    	* call.c (perform_implicit_conversion_flags): Do perform
    	scalar conversions in templates.
    	* pt.c (tsubst_copy, tsubst_copy_and_build): Handle CONVERT_EXPR.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0ec0a07..c54ce7b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8068,7 +8068,8 @@  perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain
 	}
       expr = error_mark_node;
     }
-  else if (processing_template_decl)
+  else if (processing_template_decl
+	   && !(SCALAR_TYPE_P (type) && SCALAR_TYPE_P (TREE_TYPE (expr))))
     {
       /* In a template, we are only concerned about determining the
 	 type of non-dependent expressions, so we do not have to
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2ca1ce4..9a48bb4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11486,6 +11486,7 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case STATIC_CAST_EXPR:
     case DYNAMIC_CAST_EXPR:
     case NOP_EXPR:
+    case CONVERT_EXPR:
       return build1
 	(code, tsubst (TREE_TYPE (t), args, complain, in_decl),
 	 tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
@@ -12637,6 +12638,12 @@  tsubst_copy_and_build (tree t,
 	(tsubst (TREE_TYPE (t), args, complain, in_decl),
 	 RECUR (TREE_OPERAND (t, 0)));
 
+    case CONVERT_EXPR:
+      return build1
+	(CONVERT_EXPR,
+	 tsubst (TREE_TYPE (t), args, complain, in_decl),
+	 RECUR (TREE_OPERAND (t, 0)));
+
     case CAST_EXPR:
     case REINTERPRET_CAST_EXPR:
     case CONST_CAST_EXPR:
diff --git a/gcc/testsuite/g++.dg/template/constant1.C b/gcc/testsuite/g++.dg/template/constant1.C
new file mode 100644
index 0000000..a2c5a08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/constant1.C
@@ -0,0 +1,13 @@ 
+// PR c++/49855
+
+extern void foo(int);
+
+template <class Key, class Value> void Basic() {
+  const int kT = 1.5e6;        // <--- causes ICE
+  int size = kT*2/3;
+  do {
+    foo(size);
+    size = size * 0.5 - 1;
+  } while (size >= 0 );
+
+}
diff --git a/gcc/testsuite/g++.dg/template/constant2.C b/gcc/testsuite/g++.dg/template/constant2.C
new file mode 100644
index 0000000..f71e4f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/constant2.C
@@ -0,0 +1,22 @@ 
+// PR c++/49896
+
+template<class C>
+class test {
+ protected:
+  static const int versionConst = 0x80000000;
+  enum { versionEnum = versionConst };
+ public:
+  int getVersion();
+};
+
+template<class C>
+int test<C>::getVersion() {
+  return versionEnum;
+}
+
+class dummy_class {};
+
+int main() {
+  test<dummy_class> t;
+  return t.getVersion();
+}