diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c85aa652527..9bb55173ed3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-02-02 Jan Hubicka + Tom de Vries + + PR middle-end/51998 + * cgraphunit.c (cgraph_analyze_function): Break cyclic aliases. + * varpool.c (varpool_analyze_pending_decls): Likewise. + 2012-02-02 Sumanth G Jayant R Sonar diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 8f96d3859bf..ddc026163ce 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -836,6 +836,16 @@ cgraph_analyze_function (struct cgraph_node *node) if (node->alias && node->thunk.alias) { struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); + struct cgraph_node *n; + + for (n = tgt; n && n->alias; + n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL) + if (n == node) + { + error ("function %q+D part of alias cycle", node->decl); + node->alias = false; + return; + } if (!VEC_length (ipa_ref_t, node->ref_list.references)) ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL); if (node->same_body_alias) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bad0b702bf1..2e97e5b5670 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2012-02-02 Jan Hubicka + Tom de Vries + + PR middle-end/51998 + * testsuite/gcc.dg/alias-12.c: New testcase. + * testsuite/gcc.dg/alias-13.c: New testcase. + 2012-02-02 Jakub Jelinek PR target/52086 diff --git a/gcc/testsuite/gcc.dg/alias-12.c b/gcc/testsuite/gcc.dg/alias-12.c new file mode 100644 index 00000000000..721716c2d64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/alias-12.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-alias "" } */ +/* { dg-options "-O2" } */ +static void f (void) __attribute__((alias("f"))); // { dg-error "part of alias cycle" "" } + +void g () +{ + f (); +} diff --git a/gcc/testsuite/gcc.dg/alias-13.c b/gcc/testsuite/gcc.dg/alias-13.c new file mode 100644 index 00000000000..a8390d45c31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/alias-13.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-alias "" } */ +/* { dg-options "-O2" } */ +static void f (void) __attribute__((alias("g"))); static void g (void) __attribute__((alias("f"))); // { dg-error "part of alias cycle" "" } + +void h () +{ + f (); +} diff --git a/gcc/varpool.c b/gcc/varpool.c index e01accb21dc..c2d88c3bd76 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -477,6 +477,16 @@ varpool_analyze_pending_decls (void) if (node->alias && node->alias_of) { struct varpool_node *tgt = varpool_node (node->alias_of); + struct varpool_node *n; + + for (n = tgt; n && n->alias; + n = n->analyzed ? varpool_alias_aliased_node (n) : NULL) + if (n == node) + { + error ("variable %q+D part of alias cycle", node->decl); + node->alias = false; + continue; + } if (!VEC_length (ipa_ref_t, node->ref_list.references)) ipa_record_reference (NULL, node, NULL, tgt, IPA_REF_ALIAS, NULL); /* C++ FE sometimes change linkage flags after producing same body aliases. */