[C++ PATCH] Don't call make_rtl_for_nonlocal_decl with incorrect TREE_READONLY flag (PR target/33168)

Jakub Jelinek jakub@redhat.com
Mon Nov 5 22:00:00 GMT 2007


Hi!

This patch fixes a bootstrap failure on ppc64-linux.
The problem is that cp_finish_decl temporarily clears TREE_READONLY flag
for REFERENCE_TYPE definitions, does a lot of magic, then calls
make_rtl_for_nonlocal_decl, if needed builds runtime initialization and
then restores TREE_READONLY flag.  If make_rtl_for_nonlocal_decl takes
into account the state of the TREE_READONLY flag (such as with
-fdata-sections), then e.g. a reference can be created in some
.data.* section (writable), but later on when cp_finish_decl determines
no dynamic initialization is needed, as static one is sufficient,
it will be TREE_READONLY again and section flag mismatch detection can
later on error that section flags are inconsistent.

The following patch fixes this by making sure the TREE_READONLY flag has
the desired final value already before it calls make_rtl_for_nonlocal_decl
(which we already know at that point).
Additionally, I have noticed there are some !processing_template_decl
or processing_template_decl checks in this part of the function, eventhough
there is:
  saved_processing_template_decl = processing_template_decl;
...
  if (processing_template_decl)
    {
...
      processing_template_decl = 0;
    }
earlier in the function and:
  processing_template_decl = saved_processing_template_decl;
later (and no labels where code could bypass that clearing).

Regtested on x86_64-linux, will start ppc64-linux and ia64-linux bootstrap
soon.  Ok for trunk?

2007-11-05  Jakub Jelinek  <jakub@redhat.com>

	PR target/33168
	* decl.c (cp_finish_decl): Call make_rtl_for_nonlocal_decl already
	with the final TREE_READONLY flag in place.  processing_template_decl
	is known to be 0 in this part of function.

	* g++.dg/other/datasec1.C: New test.

--- gcc/cp/decl.c.jj	2007-11-05 15:06:09.000000000 +0100
+++ gcc/cp/decl.c	2007-11-05 22:02:29.000000000 +0100
@@ -5455,8 +5455,7 @@ cp_finish_decl (tree decl, tree init, bo
 	 require a guard variable, and since the mangled name of the
 	 guard variable will depend on the mangled name of this
 	 variable.  */
-      if (!processing_template_decl
-	  && DECL_FUNCTION_SCOPE_P (decl)
+      if (DECL_FUNCTION_SCOPE_P (decl)
 	  && TREE_STATIC (decl)
 	  && !DECL_ARTIFICIAL (decl))
 	push_local_name (decl);
@@ -5561,6 +5560,21 @@ cp_finish_decl (tree decl, tree init, bo
       /* This needs to happen after the linkage is set. */
       determine_visibility (decl);
 
+      if (var_definition_p && TREE_STATIC (decl))
+	{
+	  /* If a TREE_READONLY variable needs initialization
+	     at runtime, it is no longer readonly and we need to
+	     avoid MEM_READONLY_P being set on RTL created for it.  */
+	  if (init)
+	    {
+	      if (TREE_READONLY (decl))
+		TREE_READONLY (decl) = 0;
+	      was_readonly = 0;
+	    }
+	  else if (was_readonly)
+	    TREE_READONLY (decl) = 1;
+	}
+
       make_rtl_for_nonlocal_decl (decl, init, asmspec);
 
       /* Check for abstractness of the type. Notice that there is no
@@ -5583,40 +5597,21 @@ cp_finish_decl (tree decl, tree init, bo
 	  if (init)
 	    DECL_INITIAL (decl) = init;
 	}
-      else
-	{
-	  /* A variable definition.  */
-	  if (DECL_FUNCTION_SCOPE_P (decl))
-	    {
-	      /* Initialize the local variable.  */
-	      if (processing_template_decl)
-		DECL_INITIAL (decl) = init;
-	      else if (!TREE_STATIC (decl))
-		initialize_local_var (decl, init);
-	    }
-
-	  /* If a variable is defined, and then a subsequent
-	     definition with external linkage is encountered, we will
-	     get here twice for the same variable.  We want to avoid
-	     calling expand_static_init more than once.  For variables
-	     that are not static data members, we can call
-	     expand_static_init only when we actually process the
-	     initializer.  It is not legal to redeclare a static data
-	     member, so this issue does not arise in that case.  */
-	  if (var_definition_p && TREE_STATIC (decl))
-	    {
-	      /* If a TREE_READONLY variable needs initialization
-		 at runtime, it is no longer readonly and we need to
-		 avoid MEM_READONLY_P being set on RTL created for it.  */
-	      if (init)
-		{
-		  if (TREE_READONLY (decl))
-		    TREE_READONLY (decl) = 0;
-		  was_readonly = 0;
-		}
-	      expand_static_init (decl, init);
-	    }
-	}
+      /* A variable definition.  */
+      else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
+	/* Initialize the local variable.  */
+	initialize_local_var (decl, init);
+
+      /* If a variable is defined, and then a subsequent
+	 definition with external linkage is encountered, we will
+	 get here twice for the same variable.  We want to avoid
+	 calling expand_static_init more than once.  For variables
+	 that are not static data members, we can call
+	 expand_static_init only when we actually process the
+	 initializer.  It is not legal to redeclare a static data
+	 member, so this issue does not arise in that case.  */
+      else if (var_definition_p && TREE_STATIC (decl))
+	expand_static_init (decl, init);
     }
 
   /* If a CLEANUP_STMT was created to destroy a temporary bound to a
--- gcc/testsuite/g++.dg/other/datasec1.C.jj	2007-11-05 22:12:04.000000000 +0100
+++ gcc/testsuite/g++.dg/other/datasec1.C	2007-11-05 17:55:18.000000000 +0100
@@ -0,0 +1,10 @@
+// PR target/33168
+// { dg-do compile }
+// { dg-options "-O2 -fdata-sections" }
+
+extern const int& foo;
+namespace
+{
+  const int bar = 16;
+}
+const int &foo = bar;

	Jakub



More information about the Gcc-patches mailing list