public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] Fix constant integral vars with parenthesized  initializers in templates (PR c++/36089)
@ 2008-11-10 20:16 Jakub Jelinek
  2008-11-13 14:25 ` Jakub Jelinek
  2008-11-17  5:19 ` Mark Mitchell
  0 siblings, 2 replies; 3+ messages in thread
From: Jakub Jelinek @ 2008-11-10 20:16 UTC (permalink / raw)
  To: Jason Merrill, Mark Mitchell; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1060 bytes --]

Hi!

The testcase below is rejected if array size is determined by const int
var with parenthesized initializer inside of a template, works if
it is initialized with = instead.  [dcl.init]/8 says the two forms
should be generally equivalent except for classes.
cp_finish_decl says:
      /* Generally, initializers in templates are expanded when the
         template is instantiated.  But, if DECL is an integral
         constant static data member, then it can be used in future
         integral constant expressions, and its value must be
         available. */
The problem is that the array size checking is done when
processing_template_decl when the size isn't value dependent,
but can't handle TREE_LIST DECL_INITIAL.  Below are two alternative
patches, the first one teaches integral_constant_value about it,
the second instead canonicalizes DECL_INITIAL at cp_finish_decl time
even when processing_template_decl for integral constant vars.

Both patches passed make check-g++.  I'll do full bootstrap/regtest
on one of them if you pick one.

	Jakub

[-- Attachment #2: Y101 --]
[-- Type: text/plain, Size: 1920 bytes --]

2008-11-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/36089
	* init.c (constant_value_1): Handle TREE_LIST init.

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

--- gcc/cp/init.c.jj	2008-09-23 20:29:44.000000000 +0200
+++ gcc/cp/init.c	2008-11-10 17:48:14.000000000 +0100
@@ -1659,6 +1659,15 @@ constant_value_1 (tree decl, bool integr
 	}
       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
--- gcc/testsuite/g++.dg/template/init8.C.jj	2008-11-10 17:52:27.000000000 +0100
+++ gcc/testsuite/g++.dg/template/init8.C	2008-11-10 17:51:24.000000000 +0100
@@ -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 ();
+}

[-- Attachment #3: Y101a --]
[-- Type: text/plain, Size: 2192 bytes --]

2008-11-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/36089
	* decl.c (cp_finish_decl): For integral constant vars with
	parenthesized initializers in templates call
	build_x_compound_expr_from_list.

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

--- gcc/cp/decl.c.jj	2008-11-10 10:28:22.000000000 +0100
+++ gcc/cp/decl.c	2008-11-10 20:23:08.000000000 +0100
@@ -5539,7 +5539,18 @@ cp_finish_decl (tree decl, tree init, bo
 	    && !value_dependent_init_p (init)))
 	{
 	  if (init)
-	    DECL_INITIAL (decl) = init;
+	    {
+	      /* Handle `const int a (2);' the same way as
+		 `const int a = 2;' early.  */
+	      if (TREE_CODE (init) == TREE_LIST
+		  && TREE_TYPE (init) != unknown_type_node
+		  && TREE_CHAIN (init) == NULL_TREE
+		  && DECL_INTEGRAL_CONSTANT_VAR_P (decl)
+		  && !type_dependent_p
+		  && !value_dependent_init_p (init))
+		init = build_x_compound_expr_from_list (init, "initializer");
+	      DECL_INITIAL (decl) = init;
+	    }
 	  if (TREE_CODE (decl) == VAR_DECL
 	      && !DECL_PRETTY_FUNCTION_P (decl)
 	      && !type_dependent_p)
--- gcc/testsuite/g++.dg/template/init8.C.jj	2008-11-10 20:17:16.000000000 +0100
+++ gcc/testsuite/g++.dg/template/init8.C	2008-11-10 20:17:16.000000000 +0100
@@ -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 ();
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [C++ PATCH] Fix constant integral vars with parenthesized  initializers in templates (PR c++/36089)
  2008-11-10 20:16 [C++ PATCH] Fix constant integral vars with parenthesized initializers in templates (PR c++/36089) Jakub Jelinek
@ 2008-11-13 14:25 ` Jakub Jelinek
  2008-11-17  5:19 ` Mark Mitchell
  1 sibling, 0 replies; 3+ messages in thread
From: Jakub Jelinek @ 2008-11-13 14:25 UTC (permalink / raw)
  To: Mark Mitchell, Jason Merrill; +Cc: gcc-patches

On Mon, Nov 10, 2008 at 09:07:04PM +0100, Jakub Jelinek wrote:
> Both patches passed make check-g++.  I'll do full bootstrap/regtest
> on one of them if you pick one.

FYI, I've bootstrapped/regtested them both in the mean time, no regressions.

> 2008-11-10  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/36089
> 	* init.c (constant_value_1): Handle TREE_LIST init.
> 
> 	* g++.dg/template/init8.C: New test.

or alternatively

> 2008-11-10  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/36089
> 	* decl.c (cp_finish_decl): For integral constant vars with
> 	parenthesized initializers in templates call
> 	build_x_compound_expr_from_list.
> 
> 	* g++.dg/template/init8.C: New test.

	Jakub

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [C++ PATCH] Fix constant integral vars with parenthesized  initializers  in templates (PR c++/36089)
  2008-11-10 20:16 [C++ PATCH] Fix constant integral vars with parenthesized initializers in templates (PR c++/36089) Jakub Jelinek
  2008-11-13 14:25 ` Jakub Jelinek
@ 2008-11-17  5:19 ` Mark Mitchell
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Mitchell @ 2008-11-17  5:19 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches

Jakub Jelinek wrote:

> but can't handle TREE_LIST DECL_INITIAL.  Below are two alternative
> patches, the first one teaches integral_constant_value about it,
> the second instead canonicalizes DECL_INITIAL at cp_finish_decl time
> even when processing_template_decl for integral constant vars.

I think the change in constant_value_1 is better.  We should try to
preserve the value-initialization vs. direct-initialization distinction
until the point of instantiation; even though it doesn't matter for
scalars, it does matter in general, and it's tidier not to mess it up.

So, the constant_value_1 change is OK.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-11-17  4:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-10 20:16 [C++ PATCH] Fix constant integral vars with parenthesized initializers in templates (PR c++/36089) Jakub Jelinek
2008-11-13 14:25 ` Jakub Jelinek
2008-11-17  5:19 ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).