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
This commit is contained in:
parent
5b56d3bbca
commit
78eaf7bf18
@ -1,3 +1,13 @@
|
||||
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)
|
||||
|
37
gcc/ipa.c
37
gcc/ipa.c
@ -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
|
||||
|
@ -1,3 +1,8 @@
|
||||
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...
|
||||
|
38
gcc/testsuite/g++.dg/ipa/pr43812.C
Normal file
38
gcc/testsuite/g++.dg/ipa/pr43812.C
Normal file
@ -0,0 +1,38 @@
|
||||
/* { 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 { }
|
Loading…
x
Reference in New Issue
Block a user