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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158777
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
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)
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
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));
{
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...
--- /dev/null
+/* { 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 { }