On Wed, Jul 13, 2022 at 11:06 PM Martin Jambor <mjam...@suse.cz> wrote:
>
> Hi,
>
> with -fno-toplevel-reorder (and -fwhole-program), there apparently can
> be local functions without any callers.

Did you check why?  Can't we fix that?

>  This is something that IPA-CP
> does not like because its propagation verifier checks that local
> functions do not end up with TOP in their lattices.  Therefore there
> is an assert checking that all call-less unreachable functions have
> been removed, which triggers in PR 106260 with these two options.
>
> This patch detects the situation and marks the lattices as variable,
> thus avoiding both the assert trigger and the verification failure.
>
> Bootstrapped and tested on x86_64-linux.  OK for master and then all
> active release branches?
>
> Thanks,
>
> Martin
>
>
> gcc/ChangeLog:
>
> 2022-07-13  Martin Jambor  <mjam...@suse.cz>
>
>         PR ipa/106260
>         * ipa-cp.cc (initialize_node_lattices): Replace assert that there are
>         callers with handling that situation when -fno-toplevel_reorder.
>
> gcc/testsuite/ChangeLog:
>
> 2022-07-13  Martin Jambor  <mjam...@suse.cz>
>
>         PR ipa/106260
>         * g++.dg/ipa/pr106260.C: New test.
> ---
>  gcc/ipa-cp.cc                       |  6 ++-
>  gcc/testsuite/g++.dg/ipa/pr106260.C | 64 +++++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/ipa/pr106260.C
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index 543a9334e2c..f699a8dadc0 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -1286,10 +1286,14 @@ initialize_node_lattices (struct cgraph_node *node)
>        int caller_count = 0;
>        node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
>                                                 true);
> -      gcc_checking_assert (caller_count > 0);
>        if (caller_count == 1)
>         node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
>                                                   NULL, true);
> +      else if (caller_count == 0)
> +       {
> +         gcc_checking_assert (!opt_for_fn (node->decl, 
> flag_toplevel_reorder));
> +         variable = true;
> +       }
>      }
>    else
>      {
> diff --git a/gcc/testsuite/g++.dg/ipa/pr106260.C 
> b/gcc/testsuite/g++.dg/ipa/pr106260.C
> new file mode 100644
> index 00000000000..bd3b6e0af79
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ipa/pr106260.C
> @@ -0,0 +1,64 @@
> +// { dg-do compile }
> +// { dg-options "-O2 -std=gnu++14 -fwhole-program -fno-unit-at-a-time" }
> +
> +struct A;
> +template <class T>
> +struct Q { Q (T); };
> +template<typename T, class D>
> +struct U {
> +  ~U () { m1 (nullptr); }
> +  D m2 ();
> +  T *u;
> +  void m1 (T *) { m2 () (u); }
> +};
> +struct F { F (int *); };
> +template <class, class T = F>
> +using W = Q<T>;
> +int a, b;
> +void fn1 (void *);
> +template <class T>
> +void
> +fn2 (T *x)
> +{
> +  if (x)
> +    x->~T();
> +  fn1 (x);
> +}
> +template <typename T>
> +struct C {
> +  void operator() (T *x) { fn2 (x); }
> +};
> +struct D;
> +template <typename T, typename D = C<T> >
> +using V = U<T, D>;
> +struct A {
> +  A (int *);
> +};
> +struct S;
> +struct G {
> +  V<S> m3 ();
> +};
> +struct S {
> +  int e;
> +  virtual ~S () {}
> +};
> +template<typename T>
> +struct H {
> +  H (int, T x, int) : h(x) {}
> +  G g;
> +  void m4 () { g.m3 (); }
> +  T h;
> +};
> +struct I {
> +  I(A, W<D>);
> +};
> +void
> +test ()
> +{
> +  A c (&b);
> +  W<D> d (&b);
> +  I e (c, d);
> +  H<I> f (0, e, a);
> +  f.m4 ();
> +}
> +
> --
> 2.36.1
>

Reply via email to