[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