Having just one bit control whether an expression or statement should
be allowed to trigger warnings has been a source of bug reports about
false negatives for years.  PR 74765 has a representative test case
that shows how by setting the bit to avoid -Wparentheses the C++ front
end also ends up preventing valid -Wuninitialized in the middle end,
but there are other such reports for C (e.g., PR 74762) as well as
the middle end.

This patch series solves the problem by associating an expression
(whether a tree node or a GIMPLE statement) with more than one such
bit through its location.  Each new bit in the mapping corresponds
to a group of warnings (e.g., lexical, access, etc.), and each
location may be associated with a simple bitmap with one bit for
each group.  The initial groups are mostly ad hoc and should be
refined over time.  The rare expressions that have no location
continue to have just one bit[1].

The first patch introduces three new APIs without making use of them
in existing code:

  bool get_no_warning (..., int option);
  void set_no_warning (..., int option, ...);
  void copy_no_warning (...);

Subsequent patches then replace invocations of the TREE_NO_WARNING()
macro and the gimple_no_warning_p() and gimple_set_no_warning()
functions throughout GCC with those and remove the legacy APIs to
keep them from being accidentally reintroduced along with the problem.
These are mostly mechanical changes, except that most of the new
invocations also specify the option whose disposition to query for
the expression or location, or which to enable or disable[2].
The last function, copy_no_warning(), copies the disposition from
one expression or location to another.

A couple of design choices might be helpful to explain:

First, introducing "warning groups" rather than controlling each
individual warning is motivated by a) the fact that the latter
would make avoiding redundant warnings for related problems
cumbersome (e.g., after issuing a -Warray-bounds we want to
suppress -Wstringop-overflow as well -Wstringop-overread for
the same access and vice versa), and b) simplicity and efficiency
of the implementation (mapping each option would require a more
complex data structure like a bitmap).

Second, using location_t to associate expressions/statements with
the warning groups also turns out to be more useful in practice
than a direct association between a tree or gimple*, and also
simplifies managing the data structure.  Trees and gimple* come
and go across passes, and maintaining a mapping for them that
accounts for the possibility of them being garbage-collected
and the same addresses reused is less than straightforward.

Martin

[1] My expectation is to work toward providing locations for all
expressions/statements, even if it's the opening or closing brace
of the function they're used in.)

[2] A number of {get,set}_no_warning() calls introduced by the patch
don't provide an option argument and query or set just the one bit in
the expression/statement.  Some of these may be correct as they are,
but others could be refined to also specify an option.  I can do that
in a follow-up patch if someone helps me find the right option.

Reply via email to