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