This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 28338


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; }
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]