Patchwork [C++] Fix -fno-for-scope (PR c++/47388)

login
register
mail settings
Submitter Jakub Jelinek
Date Jan. 21, 2011, 7:42 p.m.
Message ID <20110121194204.GL2724@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/79914/
State New
Headers show

Comments

Jakub Jelinek - Jan. 21, 2011, 7:42 p.m.
Hi!

With -fno-for-scope begin_for_scope in templates sets
init to push_stmt_list () and returns NULL for scope.
cp_parser_for first calls this (thus scope is NULL, but
init is non-NULL, and then cp_parser_{c,range}_for call
begin_*for_stmt which asserts that if scope is NULL
then init is NULL too (which is true for invocations from
pt.c, and for -ffor-scope, but not for -fno-for-scope
if processing_template_decl).

The following patch fixes it by not calling begin_for_scope
in that case again.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

BTW, I was kind of surprised pt.c calls begin_for_stmt
for both FOR_STMT and RANGE_FOR_STMT, I'd kind of expect
it should be begin_range_for_stmt in the latter case, but
haven't investigated in detail...

2011-01-27  Jakub Jelinek  <jakub@redhat.com>

	PR c++/47388
	* semantics.c (begin_for_stmt): If -fno-for-scope, don't
	assume init must be NULL if scope is NULL.
	(begin_range_for_stmt): Likewise.

	* g++.dg/cpp0x/range-for10.C: New test.
	* g++.dg/template/for1.C: New test.


	Jakub
Jason Merrill - Jan. 21, 2011, 9:28 p.m.
On 01/21/2011 02:42 PM, Jakub Jelinek wrote:
> The following patch fixes it by not calling begin_for_scope
> in that case again.

OK.

> BTW, I was kind of surprised pt.c calls begin_for_stmt
> for both FOR_STMT and RANGE_FOR_STMT, I'd kind of expect
> it should be begin_range_for_stmt in the latter case, but
> haven't investigated in detail...

Calling begin_for_stmt is correct; RANGE_FOR_STMT only exists in 
templates, at tsubst time we convert them into the equivalent C-style for.

Jason
Mike Stump - Jan. 21, 2011, 9:29 p.m.
On Jan 21, 2011, at 11:42 AM, Jakub Jelinek wrote:
> With -fno-for-scope begin_for_scope in templates sets

Hum...  I wonder, can we just rm -rf -fno-for-scope now...  Useful a decade ago, I'd hope that everybody has already fixed their code.
Gabriel Dos Reis - Jan. 22, 2011, 3:59 p.m.
On Fri, Jan 21, 2011 at 3:29 PM, Mike Stump <mikestump@comcast.net> wrote:
> On Jan 21, 2011, at 11:42 AM, Jakub Jelinek wrote:
>> With -fno-for-scope begin_for_scope in templates sets
>
> Hum...  I wonder, can we just rm -rf -fno-for-scope now...  Useful a decade ago, I'd hope that everybody has already fixed their code.
>

I'm in favor of removing -fno-for-scope and -fno-elide-copy-constructor.

Patch

--- gcc/cp/semantics.c.jj	2011-01-18 12:20:08.000000000 +0100
+++ gcc/cp/semantics.c	2011-01-21 17:56:47.000000000 +0100
@@ -860,8 +860,9 @@  begin_for_stmt (tree scope, tree init)
 
   if (scope == NULL_TREE)
     {
-      gcc_assert (!init);
-      scope = begin_for_scope (&init);
+      gcc_assert (!init || !(flag_new_for_scope > 0));
+      if (!init)
+	scope = begin_for_scope (&init);
     }
   FOR_INIT_STMT (r) = init;
   TREE_CHAIN (r) = scope;
@@ -962,8 +963,9 @@  begin_range_for_stmt (tree scope, tree i
 
   if (scope == NULL_TREE)
     {
-      gcc_assert (!init);
-      scope = begin_for_scope (&init);
+      gcc_assert (!init || !(flag_new_for_scope > 0));
+      if (!init)
+	scope = begin_for_scope (&init);
     }
 
   /* RANGE_FOR_STMTs do not use nor save the init tree, so we
--- gcc/testsuite/g++.dg/cpp0x/range-for10.C.jj	2011-01-21 18:10:06.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/range-for10.C	2011-01-21 18:10:56.000000000 +0100
@@ -0,0 +1,18 @@ 
+// PR c++/47388
+// { dg-do compile }
+// { dg-options "-fno-for-scope -std=c++0x" }
+
+template <int>
+void
+foo ()
+{
+  int a[] = { 1, 2, 3, 4 };
+  for (int i : a)
+    ;
+}
+
+void
+bar ()
+{
+  foo <0> ();
+}
--- gcc/testsuite/g++.dg/template/for1.C.jj	2011-01-21 18:12:16.000000000 +0100
+++ gcc/testsuite/g++.dg/template/for1.C	2011-01-21 18:12:10.000000000 +0100
@@ -0,0 +1,23 @@ 
+// PR c++/47388
+// { dg-do compile }
+// { dg-options "-fno-for-scope" }
+
+template <int>
+void
+foo ()
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    ;
+  for (int j = 0; j < 16; j++)
+    ;
+  if (j != 16)
+    for (;;)
+      ;
+}
+
+void
+bar ()
+{
+  foo <0> ();
+}