re PR c++/36089 (Funny rejects valid with constant integral expression)
authorJakub Jelinek <jakub@redhat.com>
Mon, 17 Nov 2008 07:55:52 +0000 (08:55 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 17 Nov 2008 07:55:52 +0000 (08:55 +0100)
PR c++/36089
* init.c (constant_value_1): Handle TREE_LIST init.

* g++.dg/template/init8.C: New test.

From-SVN: r141941

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/init8.C [new file with mode: 0644]

index e6fbdfb..f184028 100644 (file)
@@ -1,3 +1,8 @@
+2008-11-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/36089
+       * init.c (constant_value_1): Handle TREE_LIST init.
+
 2008-11-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/37561
index d68dd2d..61c78e1 100644 (file)
@@ -1659,6 +1659,15 @@ constant_value_1 (tree decl, bool integral_p)
        }
       if (init == error_mark_node)
        return decl;
+      /* Initializers in templates are generally expanded during
+        instantiation, so before that for const int i(2)
+        INIT is a TREE_LIST with the actual initializer as
+        TREE_VALUE.  */
+      if (processing_template_decl
+         && init
+         && TREE_CODE (init) == TREE_LIST
+         && TREE_CHAIN (init) == NULL_TREE)
+       init = TREE_VALUE (init);
       if (!init
          || !TREE_TYPE (init)
          || (integral_p
index ae6939f..4520da3 100644 (file)
@@ -1,3 +1,8 @@
+2008-11-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/36089
+       * g++.dg/template/init8.C: New test.
+
 2008-11-16  Mikael Morin <mikael.morin@tele2.fr>
 
        PR fortran/35681
diff --git a/gcc/testsuite/g++.dg/template/init8.C b/gcc/testsuite/g++.dg/template/init8.C
new file mode 100644 (file)
index 0000000..1bcda12
--- /dev/null
@@ -0,0 +1,68 @@
+// PR c++/36089
+// { dg-do run }
+
+extern "C" void abort ();
+
+int f ()
+{
+  const int c(2);
+  int d[c] = { 0, 0 };
+  return d[0] + sizeof d;
+}
+
+struct A
+{
+  static int f ()
+  {
+    const int c(2);
+    int d[c] = { 0, 0 };
+    return d[0] + sizeof d;
+  }
+};
+
+template <int> struct B
+{
+  static int f ()
+  {
+    const int c = 2;
+    int d[c] = { 0, 0 };
+    return d[0] + sizeof d;
+  }
+};
+
+template <int> struct C
+{
+  static int f ()
+  {
+    const int c(2);
+    int d[c] = { 0, 0 };
+    return d[0] + sizeof d;
+  }
+};
+
+template <int> struct D
+{
+  static int f ()
+  {
+    const int e(2);
+    const int c(e);
+    int d[c] = { 0, 0 };
+    return d[0] + sizeof d;
+  }
+};
+
+int
+main (void)
+{
+  int v = f ();
+  if (v != 2 * sizeof (int))
+    abort ();
+  if (v != A::f ())
+    abort ();
+  if (v != B<6>::f ())
+    abort ();
+  if (v != C<0>::f ())
+    abort ();
+  if (v != D<1>::f ())
+    abort ();
+}