re PR c++/36767 (Segmentation fault with -fprofile-arcs -O2)
authorDodji Seketeli <dseketel@redhat.com>
Wed, 30 Jul 2008 13:07:50 +0000 (13:07 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Wed, 30 Jul 2008 13:07:50 +0000 (15:07 +0200)
2008-07-30  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.

From-SVN: r138308

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/crash42.C [new file with mode: 0644]

index 0e236b1ef3bd254779152d5e50faed0820cbeb3a..e98283ad6ca00ee1cc26ccc93ec94f2eb573fb34 100644 (file)
@@ -1,3 +1,11 @@
+2008-07-30  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.
+
 2008-07-30  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR 34389
index 05f75f7de8413087d0e212a1dc7357d2b58c9de7..eb92dfd68cf8589bd1dc8727a461cca599f8378c 100644 (file)
@@ -2811,6 +2811,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.  */
@@ -2833,6 +2865,19 @@ 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_without_duplicates (&init,
+                                  fix_temporary_vars_context_r,
+                                  NULL);
+
   /* Because of:
 
        [class.access.spec]
index 46820ff4535cfeed2e93da8dcb0d14ce32fae0b4..95f4d4e9bc7998f6546dec0a601e52ade7adb581 100644 (file)
@@ -1,3 +1,8 @@
+2008-07-30  Dodji Seketeli  <dseketel@redhat.com>
+
+       PR c++/36767
+       * g++.dg/parse/crash42.C: New test.
+
 2008-07-30  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR 34389
diff --git a/gcc/testsuite/g++.dg/parse/crash42.C b/gcc/testsuite/g++.dg/parse/crash42.C
new file mode 100644 (file)
index 0000000..9cb07d5
--- /dev/null
@@ -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];
+
+