This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/49855, c++/49896 (ICE with named constants in templates)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 11 Oct 2011 14:19:28 -0400
- Subject: Re: C++ PATCH for c++/49855, c++/49896 (ICE with named constants in templates)
- References: <4E9481F3.4030708@redhat.com>
For the 4.6 branch I'm only making the change for scalars.
Tested x86_64-pc-linux-gnu, applying to trunk.
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();
+}