Commit 78eaf7bf by Martin Jambor Committed by Martin Jambor

re PR middle-end/43812 (compiling .cc file with -fwhole-program results in ICE,…

re PR middle-end/43812 (compiling .cc file with -fwhole-program results in ICE, in ipcp_iterate_stage, at ipa-cp.c:760)

2010-04-27  Martin Jambor  <mjambor@suse.cz>

	PR middle-end/43812
	* ipa.c (dissolve_same_comdat_group_list): New function.
	(function_and_variable_visibility): Call
	dissolve_same_comdat_group_list when comdat group contains external or
	newly local nodes.
	* cgraphunit.c (verify_cgraph_node): Verify that same_comdat_group
	lists are circular and that they contain only DECL_ONE_ONLY nodes.

	* testsuite/g++.dg/ipa/pr43812.C: New test.

From-SVN: r158777
parent 5b56d3bb
2010-04-27 Martin Jambor <mjambor@suse.cz>
PR middle-end/43812
* ipa.c (dissolve_same_comdat_group_list): New function.
(function_and_variable_visibility): Call
dissolve_same_comdat_group_list when comdat group contains external or
newly local nodes.
* cgraphunit.c (verify_cgraph_node): Verify that same_comdat_group
lists are circular and that they contain only DECL_ONE_ONLY nodes.
2010-04-27 Eric Botcazou <ebotcazou@adacore.com>
* varasm.c (decode_addr_const): Handle special case of INDIRECT_REF.
......
......@@ -714,6 +714,32 @@ verify_cgraph_node (struct cgraph_node *node)
error ("double linked list of clones corrupted");
error_found = true;
}
if (node->same_comdat_group)
{
struct cgraph_node *n = node->same_comdat_group;
if (!DECL_ONE_ONLY (node->decl))
{
error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
error_found = true;
}
if (n == node)
{
error ("node is alone in a comdat group");
error_found = true;
}
do
{
if (!n->same_comdat_group)
{
error ("same_comdat_group is not a circular list");
error_found = true;
break;
}
n = n->same_comdat_group;
}
while (n != node);
}
if (node->analyzed && gimple_has_body_p (node->decl)
&& !TREE_ASM_WRITTEN (node->decl)
......
......@@ -355,6 +355,21 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program)
return false;
}
/* Dissolve the same_comdat_group list in which NODE resides. */
static void
dissolve_same_comdat_group_list (struct cgraph_node *node)
{
struct cgraph_node *n = node, *next;
do
{
next = n->same_comdat_group;
n->same_comdat_group = NULL;
n = next;
}
while (n != node);
}
/* Mark visibility of all functions.
A local function is one whose calls can occur only in the current
......@@ -385,17 +400,17 @@ function_and_variable_visibility (bool whole_program)
and simplifies later passes. */
if (node->same_comdat_group && DECL_EXTERNAL (node->decl))
{
struct cgraph_node *n = node, *next;
do
{
#ifdef ENABLE_CHECKING
struct cgraph_node *n;
for (n = node->same_comdat_group;
n != node;
n = n->same_comdat_group)
/* If at least one of same comdat group functions is external,
all of them have to be, otherwise it is a front-end bug. */
gcc_assert (DECL_EXTERNAL (n->decl));
next = n->same_comdat_group;
n->same_comdat_group = NULL;
n = next;
}
while (n != node);
#endif
dissolve_same_comdat_group_list (node);
}
gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
|| TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
......@@ -411,6 +426,12 @@ function_and_variable_visibility (bool whole_program)
{
gcc_assert (whole_program || !TREE_PUBLIC (node->decl));
cgraph_make_decl_local (node->decl);
if (node->same_comdat_group)
/* cgraph_externally_visible_p has already checked all other nodes
in the group and they will all be made local. We need to
dissolve the group at once so that the predicate does not
segfault though. */
dissolve_same_comdat_group_list (node);
}
node->local.local = (cgraph_only_called_directly_p (node)
&& node->analyzed
......
2010-04-27 Martin Jambor <mjambor@suse.cz>
PR middle-end/43812
* g++.dg/ipa/pr43812.C: New test.
2010-04-27 Jan Hubicka <jh@suse.cz>
* gcc.dg/ipa/iinline-1.c (main): Rename to...
......
/* { dg-do compile } */
/* { dg-options "-O -fwhole-program -fipa-cp" } */
typedef float scoord_t;
typedef scoord_t sdist_t;
typedef sdist_t dist_t;
template<typename T> class TRay { };
typedef TRay<dist_t> Ray;
class BBox { };
class RenderContext { };
class RefCounted {
public:
void deref () const {
if (--ref_count <= 0) {
delete this;
}
}
mutable int ref_count;
};
template<class T> class Ref {
public:
~Ref () {
if (obj) obj->deref ();
}
T *obj;
};
class Material : public RefCounted { };
class Surface {
public:
virtual ~Surface () { }
class IsecInfo { };
virtual const IsecInfo *intersect (Ray &ray, RenderContext &context) const;
Ref<const Material> material;
};
class LocalSurface : public Surface {
virtual BBox bbox () const;
};
BBox LocalSurface::bbox () const { }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment