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]

[PATCH] Fix PR c++/36767


Hello,

The attached patch fixes PR C++/36767. It's a regression reported on the gcc-4_3-branch that is present on trunk as well.

The patch has been regtested on x86_64 in gcc-4_3-branch and in trunk.

OK to apply to those two branches ?

Thanks.

gcc/cp/ChangeLog:
2008-07-28  Dodji Seketeli  <dseketel@redhat.com>

	PR c++/36767
	* decl2.c (fix_temporary_vars_context_r): New function.
	 (one_static_initialization_or_destruction): Make sure temporary
	 variables part of the initialiser have their DECL_CONTEXT()
	 properly set.

gcc/testsuite/ChangeLog:
2008-07-28  Dodji Seketeli  <dseketel@redhat.com>

	PR c++/36767
	* g++.dg/parse/crash41.C: New test.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a156e32..5f4aea8 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2812,6 +2812,38 @@ get_priority_info (int priority)
 						    || DECL_ONE_ONLY (decl) \
 						    || DECL_WEAK (decl)))
 
+/* Called from one_static_initialization_or_destruction(),
+   via walk_tree.
+   Walks the initializer list of a global variable and looks for
+   temporary variables (DECL_NAME() == NULL and DECL_ARTIFICIAL != 0)
+   and that have their DECL_CONTEXT() == NULL.
+   For each such temporary variable, set their DECL_CONTEXT() to
+   the current function. This is necessary because otherwise
+   some optimizers (enabled by -O2 -fprofile-arcs) might crash
+   when trying to refer to a temporary variable that does not have
+   it's DECL_CONTECT() properly set.  */
+static tree 
+fix_temporary_vars_context_r (tree *node,
+			      int  *unused ATTRIBUTE_UNUSED,
+			      void *unused1 ATTRIBUTE_UNUSED)
+{
+  gcc_assert (current_function_decl);
+
+  if (TREE_CODE (*node) == BIND_EXPR)
+    {
+      tree var;
+
+      for (var = BIND_EXPR_VARS (*node); var; var = TREE_CHAIN (var))
+	  if (TREE_CODE (var) == VAR_DECL
+	      && !DECL_NAME (var)
+	      && DECL_ARTIFICIAL (var)
+	      && !DECL_CONTEXT (var))
+	      DECL_CONTEXT (var) = current_function_decl;
+    }
+
+  return NULL_TREE;
+}
+
 /* Set up to handle the initialization or destruction of DECL.  If
    INITP is nonzero, we are initializing the variable.  Otherwise, we
    are destroying it.  */
@@ -2834,6 +2866,20 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp)
      information.  */
   input_location = DECL_SOURCE_LOCATION (decl);
 
+  /* Make sure temporary variables in the initialiser all have
+     their DECL_CONTEXT() set to a value different from NULL_TREE.
+     This can happen when global variables initialisers are built.
+     In that case, the DECL_CONTEXT() of the global variables _AND_ of all 
+     the temporary variables that might have been generated in the
+     accompagning initialisers is NULL_TREE, meaning the variables have been
+     declared in the global namespace.
+     What we want to do here is to fix that and make sure the DECL_CONTEXT()
+     of the temporaries are set to the current function decl.  */
+  cp_walk_tree (&init,
+		fix_temporary_vars_context_r,
+		current_function_decl,
+		NULL);
+
   /* Because of:
 
        [class.access.spec]
diff --git a/gcc/testsuite/g++.dg/parse/crash42.C b/gcc/testsuite/g++.dg/parse/crash42.C
new file mode 100644
index 0000000..9cb07d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash42.C
@@ -0,0 +1,9 @@
+// Created by: Dodji Seketeli <dseketel@redhat.com>
+// { dg-do compile }
+// { dg-options "-O2 -fprofile-arcs" }
+// Origin: PR C++/36767
+
+struct A { A (); ~A (); };
+A a[2];
+
+

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