Hi!

Martin, thanks for your review.  Now need someone to formally approve the
third patch.

On 2021-09-01T18:14:46-0600, Martin Sebor <mse...@gmail.com> wrote:
> On 9/1/21 1:35 PM, Thomas Schwinge wrote:
>> On 2021-06-23T13:47:08-0600, Martin Sebor via Gcc-patches 
>> <gcc-patches@gcc.gnu.org> wrote:
>>> On 6/22/21 5:28 PM, David Malcolm wrote:
>>>> On Tue, 2021-06-22 at 19:18 -0400, David Malcolm wrote:
>>>>> On Fri, 2021-06-04 at 15:41 -0600, Martin Sebor wrote:
>>>>>> The attached patch introduces the suppress_warning(),
>>>>>> warning_suppressed(), and copy_no_warning() APIs [etc.]

>> I now had a bit of a deep dive into some aspects of this, in context of
>> <https://gcc.gnu.org/PR101574> "gcc/sparseset.h:215:20: error: suggest
>> parentheses around assignment used as truth value [-Werror=parentheses]"
>> that I recently filed.  This seems difficult to reproduce, but I'm still
>> able to reliably reproduce it in one specific build
>> configuration/directory/machine/whatever.  Initially, we all quickly
>> assumed that it'd be some GC issue -- but "alas", it's not, at least not
>> directly.  (But I'll certainly assume that some GC aspects are involved
>> which make this issue come and go across different GCC sources revisions,
>> and difficult to reproduce.)

>> First, two pieces of cleanup:

ACKed by Martin, again attached for convenience.


>>> --- /dev/null
>>> +++ b/gcc/diagnostic-spec.h
>>
>>> +typedef location_t key_type_t;
>>> +typedef int_hash <key_type_t, 0, UINT_MAX> xint_hash_t;

> By the way, it seems we should probably also use a manifest constant
> for Empty (probably UNKNOWN_LOCATION since we're reserving it).

Yes, that will be part of another patch here -- waiting for approval of
"Generalize 'gcc/input.h:struct location_hash'" posted elsewhere.


>> attached "Don't maintain a warning spec for
>> 'UNKNOWN_LOCATION'/'BUILTINS_LOCATION' [PR101574]".  OK to push?
>
> [...].  So I agree that it ought to be fixed.

>> I'm reasonably confident that my changes are doing the right things in
>> general, but please carefully review, especially here:
>>
>>    - 'gcc/warning-control.cc:suppress_warning' functions: is it correct to
>>      conditionalize on '!RESERVED_LOCATION_P' the 'suppress_warning_at'
>>      calls and 'supp' update?  Or, should instead 'suppress_warning_at'
>>      handle the case of '!RESERVED_LOCATION_P'?  (How?)
>
> It seems like six of one vs half a dozen of the other.  I'd say go
> with whatever makes more sense to you here :)

OK, was just trying to make sure that I don't fail to see any non-obvious
intentions here.

>>    - 'gcc/diagnostic-spec.c:copy_warning' and
>>      'gcc/warning-control.cc:copy_warning': is the rationale correct for
>>      the 'gcc_checking_assert (!from_spec)': "If we cannot set no-warning
>>      dispositions for 'to', ascertain that we don't have any for 'from'.
>>      Otherwise, we'd lose these."?  If the rationale is correct, then
>>      observing that in 'gcc/warning-control.cc:copy_warning' this
>>      currently "triggers during GCC build" is something to be looked into,
>>      later, I suppose, and otherwise, how should I change this code?
>
> copy_warning(location_t, location_t) is called [only] from
> gimple_set_location().  The middle end does clear the location of
> some statements for which it was previously valid (e.g., return
> statements).

What I observed was that the 'assert' never triggered for the
'location_t' variant "called [only] from gimple_set_location" -- but does
trigger for some other variant.  Anyway:

> So I wouldn't expect this assumption to be safe.  If
> that happens, we have no choice but to lose the per-warning detail
> and fall back on the no-warning bit.

ACK.  I'm thus clarifying that as follows:

    --- gcc/diagnostic-spec.c
    +++ gcc/diagnostic-spec.c
    @@ -185,7 +185,5 @@ copy_warning (location_t to, location_t from)
       if (RESERVED_LOCATION_P (to))
    -    {
    -      /* If we cannot set no-warning dispositions for 'to', ascertain that 
we
    -    don't have any for 'from'.  Otherwise, we'd lose these.  */
    -      gcc_checking_assert (!from_spec);
    -    }
    +    /* We cannot set no-warning dispositions for 'to', so we have no 
chance but
    +       lose those potentially set for 'from'.  */
    +    ;
       else
    --- gcc/warning-control.cc
    +++ gcc/warning-control.cc
    @@ -197,9 +197,5 @@ void copy_warning (ToType to, FromType from)
       if (RESERVED_LOCATION_P (to_loc))
    -    {
    -#if 0 //TODO triggers during GCC build
    -      /* If we cannot set no-warning dispositions for 'to', ascertain that 
we
    -    don't have any for 'from'.  Otherwise, we'd lose these.  */
    -      gcc_checking_assert (!from_spec);
    -#endif
    -    }
    +    /* We cannot set no-warning dispositions for 'to', so we have no 
chance but
    +       lose those potentially set for 'from'.  */
    +    ;
       else

> (Either David or a middle end maintainer will need to approve the last
> patch once it's final.)

As far as I'm concerned that would be the attached third patch:
"Don't maintain a warning spec for 'UNKNOWN_LOCATION'/'BUILTINS_LOCATION'
[PR101574]".  OK to push?


Grüße
 Thomas


>> PS.  Relevant code quoted for reference, in case that's useful:
>>
>>> --- /dev/null
>>> +++ b/gcc/diagnostic-spec.h
>>
>>> [...]
>>
>>> +typedef location_t key_type_t;
>>> +typedef int_hash <key_type_t, 0, UINT_MAX> xint_hash_t;
>>> +typedef hash_map<xint_hash_t, nowarn_spec_t> xint_hash_map_t;
>>> +
>>> +/* A mapping from the location of an expression to the warning spec
>>> +   set for it.  */
>>> +extern GTY(()) xint_hash_map_t *nowarn_map;
>>
>>> [...]
>>
>>> --- /dev/null
>>> +++ b/gcc/diagnostic-spec.c
>>
>>> [...]
>>
>>> +/* Map from location to its no-warning disposition.  */
>>> +
>>> +GTY(()) xint_hash_map_t *nowarn_map;
>>> +
>>> +/* Return the no-warning disposition for location LOC and option OPT
>>> +   or for all/any otions by default.  */
>>> +
>>> +bool
>>> +warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
>>> +{
>>> +  if (!nowarn_map)
>>> +    return false;
>>> +
>>> +  if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
>>> +    {
>>> +      const nowarn_spec_t optspec (opt);
>>> +      return *pspec & optspec;
>>> +    }
>>> +
>>> +  return false;
>>> +}
>>> +
>>> + /* Change the supression of warnings at location LOC.
>>> +    OPT controls which warnings are affected.
>>> +    The wildcard OPT of -1 controls all warnings.
>>> +    If SUPP is true (the default), enable the suppression of the warnings.
>>> +    If SUPP is false, disable the suppression of the warnings.  */
>>> +
>>> +bool
>>> +suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
>>> +                  bool supp /* = true */)
>>> +{
>>> +  const nowarn_spec_t optspec (supp ? opt : opt_code ());
>>> +
>>> +  if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL)
>>> +    {
>>> +      if (supp)
>>> +     {
>>> +       *pspec |= optspec;
>>> +       return true;
>>> +     }
>>> +
>>> +      *pspec &= optspec;
>>> +      if (*pspec)
>>> +     return true;
>>> +
>>> +      nowarn_map->remove (loc);
>>> +      return false;
>>> +    }
>>> +
>>> +  if (!supp || opt == no_warning)
>>> +    return false;
>>> +
>>> +  if (!nowarn_map)
>>> +    nowarn_map = xint_hash_map_t::create_ggc (32);
>>> +
>>> +  nowarn_map->put (loc, optspec);
>>> +  return true;
>>> +}
>>> +
>>> +/* Copy the no-warning disposition from one location to another.  */
>>> +
>>> +void
>>> +copy_warning (location_t to, location_t from)
>>> +{
>>> +  if (!nowarn_map)
>>> +    return;
>>> +
>>> +  if (nowarn_spec_t *pspec = nowarn_map->get (from))
>>> +    nowarn_map->put (to, *pspec);
>>> +  else
>>> +    nowarn_map->remove (to);
>>> +}
>>
>>> --- /dev/null
>>> +++ b/gcc/warning-control.cc
>>
>>> [...]
>>
>>> +/* Return the no-warning bit for EXPR.  */
>>> +
>>> +static inline bool
>>> +get_no_warning_bit (const_tree expr)
>>> +{
>>> +  return expr->base.nowarning_flag;
>>> +}
>>> +
>>> +/* Return the no-warning bit for statement STMT.  */
>>> +
>>> +static inline bool
>>> +get_no_warning_bit (const gimple *stmt)
>>> +{
>>> +  return stmt->no_warning;
>>> +}
>>> +
>>> +/* Set the no-warning bit for EXPR to VALUE.  */
>>> +
>>> +static inline void
>>> +set_no_warning_bit (tree expr, bool value)
>>> +{
>>> +  expr->base.nowarning_flag = value;
>>> +}
>>> +
>>> +/* Set the no-warning bit for statement STMT to VALUE.  */
>>> +
>>> +static inline void
>>> +set_no_warning_bit (gimple *stmt, bool value)
>>> +{
>>> +  stmt->no_warning = value;
>>> +}
>>> +
>>> +/* Return EXPR location or zero.  */
>>> +
>>> +static inline key_type_t
>>> +convert_to_key (const_tree expr)
>>> +{
>>> +  if (DECL_P (expr))
>>> +    return DECL_SOURCE_LOCATION (expr);
>>> +  if (EXPR_P (expr))
>>> +    return EXPR_LOCATION (expr);
>>> +  return 0;
>>> +}
>>> +
>>> +/* Return STMT location (may be zero).  */
>>> +
>>> +static inline key_type_t
>>> +convert_to_key (const gimple *stmt)
>>> +{
>>> +  return gimple_location (stmt);
>>> +}
>>> +
>>> +/* Return the no-warning bitmap for decl/expression EXPR.  */
>>> +
>>> +static nowarn_spec_t *
>>> +get_nowarn_spec (const_tree expr)
>>> +{
>>> +  const key_type_t key = convert_to_key (expr);
>>> +
>>> +  if (!get_no_warning_bit (expr) || !key)
>>> +    return NULL;
>>> +
>>> +  return nowarn_map ? nowarn_map->get (key) : NULL;
>>> +}
>>> +
>>> +/* Return the no-warning bitmap for stateemt STMT.  */
>>> +
>>> +static nowarn_spec_t *
>>> +get_nowarn_spec (const gimple *stmt)
>>> +{
>>> +  const key_type_t key = convert_to_key (stmt);
>>> +
>>> +  if (!get_no_warning_bit (stmt))
>>> +    return NULL;
>>> +
>>> +  return nowarn_map ? nowarn_map->get (key) : NULL;
>>> +}
>>> +
>>> +/* Return true if warning OPT is suppressed for decl/expression EXPR.
>>> +   By default tests the disposition for any warning.  */
>>> +
>>> +bool
>>> +warning_suppressed_p (const_tree expr, opt_code opt /* = all_warnings */)
>>> +{
>>> +  const nowarn_spec_t *spec = get_nowarn_spec (expr);
>>> +
>>> +  if (!spec)
>>> +    return get_no_warning_bit (expr);
>>> +
>>> +  const nowarn_spec_t optspec (opt);
>>> +  bool dis = *spec & optspec;
>>> +  gcc_assert (get_no_warning_bit (expr) || !dis);
>>> +  return dis;
>>> +}
>>> +
>>> +/* Return true if warning OPT is suppressed for statement STMT.
>>> +   By default tests the disposition for any warning.  */
>>> +
>>> +bool
>>> +warning_suppressed_p (const gimple *stmt, opt_code opt /* = all_warnings 
>>> */)
>>> +{
>>> +  const nowarn_spec_t *spec = get_nowarn_spec (stmt);
>>> +
>>> +  if (!spec)
>>> +    /* Fall back on the single no-warning bit.  */
>>> +    return get_no_warning_bit (stmt);
>>> +
>>> +  const nowarn_spec_t optspec (opt);
>>> +  bool dis = *spec & optspec;
>>> +  gcc_assert (get_no_warning_bit (stmt) || !dis);
>>> +  return dis;
>>> +}
>>> +
>>> +/* Enable, or by default disable, a warning for the expression.
>>> +   The wildcard OPT of -1 controls all warnings.  */
>>> +
>>> +void
>>> +suppress_warning (tree expr, opt_code opt /* = all_warnings */,
>>> +               bool supp /* = true */)
>>> +{
>>> +  if (opt == no_warning)
>>> +    return;
>>> +
>>> +  const key_type_t key = convert_to_key (expr);
>>> +
>>> +  supp = suppress_warning_at (key, opt, supp) || supp;
>>> +  set_no_warning_bit (expr, supp);
>>> +}
>>> +
>>> +/* Enable, or by default disable, a warning for the statement STMT.
>>> +   The wildcard OPT of -1 controls all warnings.  */
>>> +
>>> +void
>>> +suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */,
>>> +               bool supp /* = true */)
>>> +{
>>> +  if (opt == no_warning)
>>> +    return;
>>> +
>>> +  const key_type_t key = convert_to_key (stmt);
>>> +
>>> +  supp = suppress_warning_at (key, opt, supp) || supp;
>>> +  set_no_warning_bit (stmt, supp);
>>> +}
>>> +
>>> +/* Copy the warning disposition mapping between an expression and/or
>>> +   a statement.  */
>>> +
>>> +template <class ToType, class FromType>
>>> +void copy_warning (ToType to, FromType from)
>>> +{
>>> +  const key_type_t to_key = convert_to_key (to);
>>> +
>>> +  if (nowarn_spec_t *from_map = get_nowarn_spec (from))
>>> +    {
>>> +      /* If there's an entry in the map the no-warning bit must be set.  */
>>> +      gcc_assert (get_no_warning_bit (from));
>>> +
>>> +      if (!nowarn_map)
>>> +     nowarn_map = xint_hash_map_t::create_ggc (32);
>>> +
>>> +      nowarn_map->put (to_key, *from_map);
>>> +      set_no_warning_bit (to, true);
>>> +    }
>>> +  else
>>> +    {
>>> +      if (nowarn_map)
>>> +     nowarn_map->remove (to_key);
>>> +
>>> +      /* The no-warning bit might be set even if there's no entry
>>> +      in the map.  */
>>> +      set_no_warning_bit (to, get_no_warning_bit (from));
>>> +    }
>>> +}
>>> +
>>> +/* Copy the warning disposition mapping from one expression to another.  */
>>> +
>>> +void
>>> +copy_warning (tree to, const_tree from)
>>> +{
>>> +  copy_warning<tree, const_tree>(to, from);
>>> +}
>>> +
>>> +/* Copy the warning disposition mapping from a statement to an expression. 
>>>  */
>>> +
>>> +void
>>> +copy_warning (tree to, const gimple *from)
>>> +{
>>> +  copy_warning<tree, const gimple *>(to, from);
>>> +}
>>> +
>>> +/* Copy the warning disposition mapping from an expression to a statement. 
>>>  */
>>> +
>>> +void
>>> +copy_warning (gimple *to, const_tree from)
>>> +{
>>> +  copy_warning<gimple *, const_tree>(to, from);
>>> +}
>>> +
>>> +/* Copy the warning disposition mapping from one statement to another.  */
>>> +
>>> +void
>>> +copy_warning (gimple *to, const gimple *from)
>>> +{
>>> +  copy_warning<gimple *, const gimple *>(to, from);
>>> +}


-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
>From 095c16ead5d432726f2b6de5ce12fd367600076d Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tho...@codesourcery.com>
Date: Wed, 1 Sep 2021 16:48:55 +0200
Subject: [PATCH 1/3] Simplify 'gcc/diagnostic-spec.h:nowarn_map' setup

If we've just read something from the map, we can be sure that it exists.

	gcc/
	* warning-control.cc (copy_warning): Remove 'nowarn_map' setup.
---
 gcc/warning-control.cc | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc
index ec8ed232763..9c506e163d6 100644
--- a/gcc/warning-control.cc
+++ b/gcc/warning-control.cc
@@ -188,9 +188,7 @@ void copy_warning (ToType to, FromType from)
       /* If there's an entry in the map the no-warning bit must be set.  */
       gcc_assert (get_no_warning_bit (from));
 
-      if (!nowarn_map)
-	nowarn_map = xint_hash_map_t::create_ggc (32);
-
+      gcc_checking_assert (nowarn_map);
       nowarn_map->put (to_key, *from_map);
       set_no_warning_bit (to, true);
     }
-- 
2.30.2

>From 23d9b93401349fca03efaef0fef0960933f4c316 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tho...@codesourcery.com>
Date: Tue, 31 Aug 2021 22:01:23 +0200
Subject: [PATCH 2/3] Clarify 'key_type_t' to 'location_t' as used for
 'gcc/diagnostic-spec.h:nowarn_map'

To make it obvious what exactly the key type is.  No change in behavior.

	gcc/
	* diagnostic-spec.h (typedef xint_hash_t): Use 'location_t' instead of...
	(typedef key_type_t): ... this.  Remove.
	(nowarn_map): Document.
	* diagnostic-spec.c (nowarn_map): Likewise.
	* warning-control.cc (convert_to_key): Evolve functions into...
	(get_location): ... these.  Adjust all users.
---
 gcc/diagnostic-spec.c  |  2 +-
 gcc/diagnostic-spec.h  |  6 ++----
 gcc/warning-control.cc | 41 ++++++++++++++++++++++-------------------
 3 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/gcc/diagnostic-spec.c b/gcc/diagnostic-spec.c
index 5e961e1b9f9..eac5a3317c8 100644
--- a/gcc/diagnostic-spec.c
+++ b/gcc/diagnostic-spec.c
@@ -105,7 +105,7 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
     }
 }
 
-/* Map from location to its no-warning disposition.  */
+/* A mapping from a 'location_t' to the warning spec set for it.  */
 
 GTY(()) xint_hash_map_t *nowarn_map;
 
diff --git a/gcc/diagnostic-spec.h b/gcc/diagnostic-spec.h
index 4e4d260f74a..9b3aaaa3ce6 100644
--- a/gcc/diagnostic-spec.h
+++ b/gcc/diagnostic-spec.h
@@ -130,12 +130,10 @@ operator!= (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
   return !(lhs == rhs);
 }
 
-typedef location_t key_type_t;
-typedef int_hash <key_type_t, 0, UINT_MAX> xint_hash_t;
+typedef int_hash <location_t, 0, UINT_MAX> xint_hash_t;
 typedef hash_map<xint_hash_t, nowarn_spec_t> xint_hash_map_t;
 
-/* A mapping from the location of an expression to the warning spec
-   set for it.  */
+/* A mapping from a 'location_t' to the warning spec set for it.  */
 extern GTY(()) xint_hash_map_t *nowarn_map;
 
 #endif // DIAGNOSTIC_SPEC_H_INCLUDED
diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc
index 9c506e163d6..8d6c0828445 100644
--- a/gcc/warning-control.cc
+++ b/gcc/warning-control.cc
@@ -62,22 +62,22 @@ set_no_warning_bit (gimple *stmt, bool value)
   stmt->no_warning = value;
 }
 
-/* Return EXPR location or zero.  */
+/* Return EXPR location or 'UNKNOWN_LOCATION'.  */
 
-static inline key_type_t
-convert_to_key (const_tree expr)
+static inline location_t
+get_location (const_tree expr)
 {
   if (DECL_P (expr))
     return DECL_SOURCE_LOCATION (expr);
   if (EXPR_P (expr))
     return EXPR_LOCATION (expr);
-  return 0;
+  return UNKNOWN_LOCATION;
 }
 
-/* Return STMT location (may be zero).  */
+/* Return STMT location (may be 'UNKNOWN_LOCATION').  */
 
-static inline key_type_t
-convert_to_key (const gimple *stmt)
+static inline location_t
+get_location (const gimple *stmt)
 {
   return gimple_location (stmt);
 }
@@ -87,12 +87,15 @@ convert_to_key (const gimple *stmt)
 static nowarn_spec_t *
 get_nowarn_spec (const_tree expr)
 {
-  const key_type_t key = convert_to_key (expr);
+  const location_t loc = get_location (expr);
 
-  if (!get_no_warning_bit (expr) || !key)
+  if (loc == UNKNOWN_LOCATION)
     return NULL;
 
-  return nowarn_map ? nowarn_map->get (key) : NULL;
+  if (!get_no_warning_bit (expr))
+    return NULL;
+
+  return nowarn_map ? nowarn_map->get (loc) : NULL;
 }
 
 /* Return the no-warning bitmap for stateemt STMT.  */
@@ -100,12 +103,12 @@ get_nowarn_spec (const_tree expr)
 static nowarn_spec_t *
 get_nowarn_spec (const gimple *stmt)
 {
-  const key_type_t key = convert_to_key (stmt);
+  const location_t loc = get_location (stmt);
 
   if (!get_no_warning_bit (stmt))
     return NULL;
 
-  return nowarn_map ? nowarn_map->get (key) : NULL;
+  return nowarn_map ? nowarn_map->get (loc) : NULL;
 }
 
 /* Return true if warning OPT is suppressed for decl/expression EXPR.
@@ -153,9 +156,9 @@ suppress_warning (tree expr, opt_code opt /* = all_warnings */,
   if (opt == no_warning)
     return;
 
-  const key_type_t key = convert_to_key (expr);
+  const location_t loc = get_location (expr);
 
-  supp = suppress_warning_at (key, opt, supp) || supp;
+  supp = suppress_warning_at (loc, opt, supp) || supp;
   set_no_warning_bit (expr, supp);
 }
 
@@ -169,9 +172,9 @@ suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */,
   if (opt == no_warning)
     return;
 
-  const key_type_t key = convert_to_key (stmt);
+  const location_t loc = get_location (stmt);
 
-  supp = suppress_warning_at (key, opt, supp) || supp;
+  supp = suppress_warning_at (loc, opt, supp) || supp;
   set_no_warning_bit (stmt, supp);
 }
 
@@ -181,7 +184,7 @@ suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */,
 template <class ToType, class FromType>
 void copy_warning (ToType to, FromType from)
 {
-  const key_type_t to_key = convert_to_key (to);
+  const location_t to_loc = get_location (to);
 
   if (nowarn_spec_t *from_map = get_nowarn_spec (from))
     {
@@ -189,13 +192,13 @@ void copy_warning (ToType to, FromType from)
       gcc_assert (get_no_warning_bit (from));
 
       gcc_checking_assert (nowarn_map);
-      nowarn_map->put (to_key, *from_map);
+      nowarn_map->put (to_loc, *from_map);
       set_no_warning_bit (to, true);
     }
   else
     {
       if (nowarn_map)
-	nowarn_map->remove (to_key);
+	nowarn_map->remove (to_loc);
 
       /* The no-warning bit might be set even if there's no entry
 	 in the map.  */
-- 
2.30.2

>From 51c9a8ac2caa0432730c78d00989fd01f3ac6fe5 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tho...@codesourcery.com>
Date: Mon, 30 Aug 2021 22:36:47 +0200
Subject: [PATCH 3/3] Don't maintain a warning spec for
 'UNKNOWN_LOCATION'/'BUILTINS_LOCATION' [PR101574]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This resolves PR101574 "gcc/sparseset.h:215:20: error: suggest parentheses
around assignment used as truth value [-Werror=parentheses]", as (bogusly)
reported at commit a61f6afbee370785cf091fe46e2e022748528307:

    In file included from [...]/source-gcc/gcc/lra-lives.c:43:
    [...]/source-gcc/gcc/lra-lives.c: In function ‘void make_hard_regno_dead(int)’:
    [...]/source-gcc/gcc/sparseset.h:215:20: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
      215 |        && (((ITER) = sparseset_iter_elm (SPARSESET)) || 1);             \
          |            ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    [...]/source-gcc/gcc/lra-lives.c:304:3: note: in expansion of macro ‘EXECUTE_IF_SET_IN_SPARSESET’
      304 |   EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i)
          |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~

	gcc/
	PR bootstrap/101574
	* diagnostic-spec.c (warning_suppressed_at, copy_warning): Handle
	'RESERVED_LOCATION_P' locations.
	* warning-control.cc (get_nowarn_spec, suppress_warning)
	(copy_warning): Likewise.
---
 gcc/diagnostic-spec.c  | 22 ++++++++++++++++---
 gcc/warning-control.cc | 48 +++++++++++++++++++++++++++---------------
 2 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/gcc/diagnostic-spec.c b/gcc/diagnostic-spec.c
index eac5a3317c8..85ffb725c02 100644
--- a/gcc/diagnostic-spec.c
+++ b/gcc/diagnostic-spec.c
@@ -115,6 +115,8 @@ GTY(()) xint_hash_map_t *nowarn_map;
 bool
 warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
 {
+  gcc_checking_assert (!RESERVED_LOCATION_P (loc));
+
   if (!nowarn_map)
     return false;
 
@@ -137,6 +139,8 @@ bool
 suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
 		     bool supp /* = true */)
 {
+  gcc_checking_assert (!RESERVED_LOCATION_P (loc));
+
   const nowarn_spec_t optspec (supp ? opt : opt_code ());
 
   if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL)
@@ -173,8 +177,20 @@ copy_warning (location_t to, location_t from)
   if (!nowarn_map)
     return;
 
-  if (nowarn_spec_t *pspec = nowarn_map->get (from))
-    nowarn_map->put (to, *pspec);
+  nowarn_spec_t *from_spec;
+  if (RESERVED_LOCATION_P (from))
+    from_spec = NULL;
+  else
+    from_spec = nowarn_map->get (from);
+  if (RESERVED_LOCATION_P (to))
+    /* We cannot set no-warning dispositions for 'to', so we have no chance but
+       lose those potentially set for 'from'.  */
+    ;
   else
-    nowarn_map->remove (to);
+    {
+      if (from_spec)
+	nowarn_map->put (to, *from_spec);
+      else
+	nowarn_map->remove (to);
+    }
 }
diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc
index 8d6c0828445..36a47ab6bae 100644
--- a/gcc/warning-control.cc
+++ b/gcc/warning-control.cc
@@ -89,7 +89,7 @@ get_nowarn_spec (const_tree expr)
 {
   const location_t loc = get_location (expr);
 
-  if (loc == UNKNOWN_LOCATION)
+  if (RESERVED_LOCATION_P (loc))
     return NULL;
 
   if (!get_no_warning_bit (expr))
@@ -105,6 +105,9 @@ get_nowarn_spec (const gimple *stmt)
 {
   const location_t loc = get_location (stmt);
 
+  if (RESERVED_LOCATION_P (loc))
+    return NULL;
+
   if (!get_no_warning_bit (stmt))
     return NULL;
 
@@ -158,7 +161,8 @@ suppress_warning (tree expr, opt_code opt /* = all_warnings */,
 
   const location_t loc = get_location (expr);
 
-  supp = suppress_warning_at (loc, opt, supp) || supp;
+  if (!RESERVED_LOCATION_P (loc))
+    supp = suppress_warning_at (loc, opt, supp) || supp;
   set_no_warning_bit (expr, supp);
 }
 
@@ -174,7 +178,8 @@ suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */,
 
   const location_t loc = get_location (stmt);
 
-  supp = suppress_warning_at (loc, opt, supp) || supp;
+  if (!RESERVED_LOCATION_P (loc))
+    supp = suppress_warning_at (loc, opt, supp) || supp;
   set_no_warning_bit (stmt, supp);
 }
 
@@ -186,24 +191,33 @@ void copy_warning (ToType to, FromType from)
 {
   const location_t to_loc = get_location (to);
 
-  if (nowarn_spec_t *from_map = get_nowarn_spec (from))
-    {
-      /* If there's an entry in the map the no-warning bit must be set.  */
-      gcc_assert (get_no_warning_bit (from));
+  bool supp = get_no_warning_bit (from);
 
-      gcc_checking_assert (nowarn_map);
-      nowarn_map->put (to_loc, *from_map);
-      set_no_warning_bit (to, true);
-    }
+  nowarn_spec_t *from_spec = get_nowarn_spec (from);
+  if (RESERVED_LOCATION_P (to_loc))
+    /* We cannot set no-warning dispositions for 'to', so we have no chance but
+       lose those potentially set for 'from'.  */
+    ;
   else
     {
-      if (nowarn_map)
-	nowarn_map->remove (to_loc);
-
-      /* The no-warning bit might be set even if there's no entry
-	 in the map.  */
-      set_no_warning_bit (to, get_no_warning_bit (from));
+      if (from_spec)
+	{
+	  /* If there's an entry in the map the no-warning bit must be set.  */
+	  gcc_assert (supp);
+
+	  gcc_checking_assert (nowarn_map);
+	  nowarn_map->put (to_loc, *from_spec);
+	}
+      else
+	{
+	  if (nowarn_map)
+	    nowarn_map->remove (to_loc);
+	}
     }
+
+  /* The no-warning bit might be set even if the map has not been consulted, or
+     otherwise if there's no entry in the map.  */
+  set_no_warning_bit (to, supp);
 }
 
 /* Copy the warning disposition mapping from one expression to another.  */
-- 
2.25.1

Reply via email to