re PR c++/36767 (Segmentation fault with -fprofile-arcs -O2)

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
This commit is contained in:
Dodji Seketeli 2008-07-30 13:07:50 +00:00 committed by Dodji Seketeli
parent 6ca2b0a038
commit e44c800e35
4 changed files with 67 additions and 0 deletions

View 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

View 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]

View 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

View File

@ -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];