This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 28338
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 Jul 2006 15:51:34 -0700
- Subject: C++ PATCH: PR 28338
- Reply-to: mark at codesourcery dot com
This patch fixes PR c++/28338, a rejects-valid regression. When
initializing a function-local reference with static storage duration,
we sometimes need to create a guard variable to prevent duplicate
initialization. The mangled name of the guard variable is based on
the managled name of the local variable. So, we need to ensure
that local name discriminator for the local variable is set up before
processing the initializer.
Tested on x86_64-unknown-linux-gnu, applied on the mainline. Will
apply to 4.1 as soon as testing completes.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-07-19 Mark Mitchell <mark@codesourcery.com>
PR c++/28338
* decl.c (layout_var_decl): Don't call push_local_name here.
(initialize_artificial_var): Assert artificiality.
(cp_finish_decl): Call push_local_name here.
2006-07-19 Mark Mitchell <mark@codesourcery.com>
PR c++/28338
* g++.dg/init/ref13.C: New test.
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 115544)
+++ gcc/cp/decl.c (working copy)
@@ -4189,12 +4189,6 @@ layout_var_decl (tree decl)
{
tree type;
- if (TREE_STATIC (decl)
- && !DECL_ARTIFICIAL (decl)
- && current_function_decl
- && DECL_CONTEXT (decl) == current_function_decl)
- push_local_name (decl);
-
type = TREE_TYPE (decl);
if (type == error_mark_node)
return;
@@ -5002,6 +4996,7 @@ initialize_local_var (tree decl, tree in
void
initialize_artificial_var (tree decl, tree init)
{
+ gcc_assert (DECL_ARTIFICIAL (decl));
if (TREE_CODE (init) == TREE_LIST)
init = build_constructor_from_list (NULL_TREE, init);
gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
@@ -5143,6 +5138,17 @@ cp_finish_decl (tree decl, tree init, bo
if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
error ("%qD cannot be thread-local because it has non-POD type %qT",
decl, TREE_TYPE (decl));
+ /* If this is a local variable that will need a mangled name,
+ register it now. We must do this before processing the
+ initializer for the variable, since the initialization might
+ 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)
+ && TREE_STATIC (decl)
+ && !DECL_ARTIFICIAL (decl))
+ push_local_name (decl);
/* Convert the initializer to the type of DECL, if we have not
already initialized DECL. */
if (!DECL_INITIALIZED_P (decl)
Index: gcc/testsuite/g++.dg/init/ref13.C
===================================================================
--- gcc/testsuite/g++.dg/init/ref13.C (revision 0)
+++ gcc/testsuite/g++.dg/init/ref13.C (revision 0)
@@ -0,0 +1,7 @@
+// PR c++/28338
+
+void foo()
+{
+ { static const int& i = 0; }
+ { static const int& i = 0; }
+}