On Tue, Jul 23, 2024 at 05:14:30PM -0400, Patrick Palka wrote:
> On Tue, 23 Jul 2024, Jason Merrill wrote:
> 
> > On 7/7/24 12:39 AM, Nathaniel Shead wrote:
> > > Bootstrapped on x86_64-pc-linux-gnu, successfully regtested modules.exp;
> > > OK for trunk if full regtest passes?
> > 
> > Patrick, I assume this change won't mess with your streaming optimizations?
> 
> Should be fine, those optimizations are currently confined to
> tree_node_bools where we stream many consecutive bools (and so we want
> to avoid conditionally streaming a bit, so that the bit buffer position
> of each streamed bit is statically known).  I don't think the technique
> can really apply to core_vals since it streams mostly trees.
> 
> > 
> > OK with Patrick's approval or on Friday, whichever comes first.
> > 

Thanks, pushed.

> > > -- >8 --
> > > 
> > > Currently we don't stream the contents of 'nowarn_map'; this means that
> > > warning suppressions don't get applied in importers, which is
> > > particularly relevant for templates (as in the linked testcase).
> > > 
> > > Rather than streaming the whole contents of 'nowarn_map', this patch
> > > instead just streams the exported suppressions for each tree node
> > > individually, to not build up additional locations and suppressions for
> > > tree nodes that do not need to be streamed.
> > > 
> > >   PR c++/115757
> > > 
> > > gcc/cp/ChangeLog:
> > > 
> > >   * module.cc (trees_out::core_vals): Write warning specs for
> > >   DECLs and EXPRs.
> > >   (trees_in::core_vals): Read warning specs.
> > > 
> > > gcc/ChangeLog:
> > > 
> > >   * tree.h (put_warning_spec_at): Declare new function.
> > >   (has_warning_spec): Likewise.
> > >   (get_warning_spec): Likewise.
> > >   (put_warning_spec): Likewise.
> > >   * diagnostic-spec.h (nowarn_spec_t::from_bits): New function.
> > >   * diagnostic-spec.cc (put_warning_spec_at): New function.
> > >   * warning-control.cc (has_warning_spec): New function.
> > >   (get_warning_spec): New function.
> > >   (put_warning_spec): New function.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > >   * g++.dg/modules/warn-spec-1_a.C: New test.
> > >   * g++.dg/modules/warn-spec-1_b.C: New test.
> > > 
> > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
> > > ---
> > >   gcc/cp/module.cc                             | 12 +++++++++
> > >   gcc/diagnostic-spec.cc                       | 21 ++++++++++++++++
> > >   gcc/diagnostic-spec.h                        |  7 ++++++
> > >   gcc/testsuite/g++.dg/modules/warn-spec-1_a.C | 10 ++++++++
> > >   gcc/testsuite/g++.dg/modules/warn-spec-1_b.C |  8 ++++++
> > >   gcc/tree.h                                   |  9 +++++++
> > >   gcc/warning-control.cc                       | 26 ++++++++++++++++++++
> > >   7 files changed, 93 insertions(+)
> > >   create mode 100644 gcc/testsuite/g++.dg/modules/warn-spec-1_a.C
> > >   create mode 100644 gcc/testsuite/g++.dg/modules/warn-spec-1_b.C
> > > 
> > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> > > index dc5d046f04d..0f9a689dbec 100644
> > > --- a/gcc/cp/module.cc
> > > +++ b/gcc/cp/module.cc
> > > @@ -6000,6 +6000,10 @@ trees_out::core_vals (tree t)
> > >           if (state)
> > >           state->write_location (*this, t->decl_minimal.locus);
> > > +
> > > +      if (streaming_p ())
> > > + if (has_warning_spec (t))
> > > +   u (get_warning_spec (t));
> > >       }
> > >       if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
> > > @@ -6113,6 +6117,10 @@ trees_out::core_vals (tree t)
> > >         if (state)
> > >           state->write_location (*this, t->exp.locus);
> > >   +      if (streaming_p ())
> > > + if (has_warning_spec (t))
> > > +   u (get_warning_spec (t));
> > > +
> > >         /* Walk in forward order, as (for instance) REQUIRES_EXPR has a
> > >            bunch of unscoped parms on its first operand.  It's safer to
> > >            create those in order.  */
> > > @@ -6576,6 +6584,8 @@ trees_in::core_vals (tree t)
> > >         /* Don't zap the locus just yet, we don't record it correctly
> > >            and thus lose all location information.  */
> > >         t->decl_minimal.locus = state->read_location (*this);
> > > +      if (has_warning_spec (t))
> > > + put_warning_spec (t, u ());
> > >       }
> > >       if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
> > > @@ -6654,6 +6664,8 @@ trees_in::core_vals (tree t)
> > >     if (CODE_CONTAINS_STRUCT (code, TS_EXP))
> > >       {
> > >         t->exp.locus = state->read_location (*this);
> > > +      if (has_warning_spec (t))
> > > + put_warning_spec (t, u ());
> > >           bool vl = TREE_CODE_CLASS (code) == tcc_vl_exp;
> > >         for (unsigned limit = (vl ? VL_EXP_OPERAND_LENGTH (t)
> > > diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
> > > index 996ad6b273a..addaf089f03 100644
> > > --- a/gcc/diagnostic-spec.cc
> > > +++ b/gcc/diagnostic-spec.cc
> > > @@ -179,6 +179,27 @@ suppress_warning_at (location_t loc, opt_code opt /* 
> > > =
> > > all_warnings */,
> > >     return true;
> > >   }
> > >   +/* Change the warning disposition for LOC to match OPTSPEC.  */
> > > +
> > > +void
> > > +put_warning_spec_at (location_t loc, unsigned bits)
> > > +{
> > > +  gcc_checking_assert (!RESERVED_LOCATION_P (loc));
> > > +
> > > +  nowarn_spec_t optspec = nowarn_spec_t::from_bits (bits);
> > > +  if (!optspec)
> > > +    {
> > > +      if (nowarn_map)
> > > + nowarn_map->remove (loc);
> > > +    }
> > > +  else
> > > +    {
> > > +      if (!nowarn_map)
> > > + nowarn_map = nowarn_map_t::create_ggc (32);
> > > +      nowarn_map->put (loc, optspec);
> > > +    }
> > > +}
> > > +
> > >   /* Copy the no-warning disposition from one location to another.  */
> > >     void
> > > diff --git a/gcc/diagnostic-spec.h b/gcc/diagnostic-spec.h
> > > index 22d4c067158..0b155a5cde3 100644
> > > --- a/gcc/diagnostic-spec.h
> > > +++ b/gcc/diagnostic-spec.h
> > > @@ -56,6 +56,13 @@ public:
> > >       nowarn_spec_t (opt_code);
> > >   +  static nowarn_spec_t from_bits (unsigned bits)
> > > +  {
> > > +    nowarn_spec_t spec;
> > > +    spec.m_bits = bits;
> > > +    return spec;
> > > +  }
> > > +
> > >     /* Return the raw bitset.  */
> > >     operator unsigned() const
> > >     {
> > > diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-1_a.C
> > > b/gcc/testsuite/g++.dg/modules/warn-spec-1_a.C
> > > new file mode 100644
> > > index 00000000000..22be880216d
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/modules/warn-spec-1_a.C
> > > @@ -0,0 +1,10 @@
> > > +// PR c++/115757
> > > +// { dg-additional-options "-fmodules-ts -Wunused" }
> > > +// { dg-module-cmi test }
> > > +
> > > +export module test;
> > > +
> > > +export template <typename T>
> > > +void foo(T n [[maybe_unused]]) {
> > > +  int x [[maybe_unused]];
> > > +}
> > > diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-1_b.C
> > > b/gcc/testsuite/g++.dg/modules/warn-spec-1_b.C
> > > new file mode 100644
> > > index 00000000000..aa5f14c8572
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/modules/warn-spec-1_b.C
> > > @@ -0,0 +1,8 @@
> > > +// PR c++/115757
> > > +// { dg-additional-options "-fmodules-ts -Wunused" }
> > > +
> > > +import test;
> > > +
> > > +int main() {
> > > +  foo(0);
> > > +}
> > > diff --git a/gcc/tree.h b/gcc/tree.h
> > > index 28e8e71b036..5dcbb2fb5dd 100644
> > > --- a/gcc/tree.h
> > > +++ b/gcc/tree.h
> > > @@ -6929,6 +6929,8 @@ extern bool warning_suppressed_at (location_t,
> > > opt_code = all_warnings);
> > >      at a location to disabled by default.  */
> > >   extern bool suppress_warning_at (location_t, opt_code = all_warnings,
> > >                                    bool = true);
> > > +/* Overwrite warning disposition bitmap for a location with given spec.  
> > > */
> > > +extern void put_warning_spec_at (location_t loc, unsigned);
> > >   /* Copy warning disposition from one location to another.  */
> > >   extern void copy_warning (location_t, location_t);
> > >   @@ -6942,6 +6944,13 @@ extern void suppress_warning (tree, opt_code =
> > > all_warnings, bool = true)
> > >   /* Copy warning disposition from one expression to another.  */
> > >   extern void copy_warning (tree, const_tree);
> > >   +/* Whether the tree might have a warning spec.  */
> > > +extern bool has_warning_spec (const_tree);
> > > +/* Retrieve warning spec bitmap for tree streaming.  */
> > > +extern unsigned get_warning_spec (const_tree);
> > > +/* Overwrite warning spec bitmap for a tree with given spec.  */
> > > +extern void put_warning_spec (tree, unsigned);
> > > +
> > >   /* Return the zero-based number corresponding to the argument being
> > >      deallocated if FNDECL is a deallocation function or an out-of-bounds
> > >      value if it isn't.  */
> > > diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc
> > > index 08a0bb0e7d5..11ca5db69c3 100644
> > > --- a/gcc/warning-control.cc
> > > +++ b/gcc/warning-control.cc
> > > @@ -256,3 +256,29 @@ copy_warning (gimple *to, const gimple *from)
> > >       return;
> > >     copy_warning<gimple *, const gimple *>(to, from);
> > >   }
> > > +
> > > +/* Whether the tree might have a warning spec.  */
> > > +
> > > +bool has_warning_spec (const_tree t)
> > > +{
> > > +  const location_t loc = get_location (t);
> > > +  return !RESERVED_LOCATION_P (loc) && !get_no_warning_bit (t);
> > > +}
> > > +
> > > +/* Retrieve warning dispostion bitmap for tree streaming.  */
> > > +
> > > +unsigned
> > > +get_warning_spec (const_tree t)
> > > +{
> > > +  const nowarn_spec_t *spec = get_nowarn_spec (t);
> > > +  return spec ? *spec : 0;
> > > +}
> > > +
> > > +/* Write warning disposition bitmap for streamed-in tree.  */
> > > +
> > > +void
> > > +put_warning_spec (tree t, unsigned bits)
> > > +{
> > > +  const location_t loc = get_location (t);
> > > +  put_warning_spec_at (loc, bits);
> > > +}
> > 
> > 
> 

Reply via email to