diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
commit | e252b51ccde010cbd2a146485d8045103cd99533 (patch) | |
tree | e060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/warning-control.cc | |
parent | f10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff) | |
parent | 104c05c5284b7822d770ee51a7d91946c7e56d50 (diff) | |
download | gcc-e252b51ccde010cbd2a146485d8045103cd99533.zip gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2 |
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/warning-control.cc')
-rw-r--r-- | gcc/warning-control.cc | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc new file mode 100644 index 0000000..36a47ab --- /dev/null +++ b/gcc/warning-control.cc @@ -0,0 +1,253 @@ +/* Functions to enable and disable individual warnings on an expression + and statement basis. + + Copyright (C) 2021 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "bitmap.h" +#include "tree.h" +#include "gimple.h" +#include "cgraph.h" +#include "hash-map.h" +#include "diagnostic-spec.h" + +/* 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 'UNKNOWN_LOCATION'. */ + +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 UNKNOWN_LOCATION; +} + +/* Return STMT location (may be 'UNKNOWN_LOCATION'). */ + +static inline location_t +get_location (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 location_t loc = get_location (expr); + + if (RESERVED_LOCATION_P (loc)) + return 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. */ + +static nowarn_spec_t * +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; + + return nowarn_map ? nowarn_map->get (loc) : 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 location_t loc = get_location (expr); + + if (!RESERVED_LOCATION_P (loc)) + supp = suppress_warning_at (loc, 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 location_t loc = get_location (stmt); + + if (!RESERVED_LOCATION_P (loc)) + supp = suppress_warning_at (loc, 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 location_t to_loc = get_location (to); + + bool supp = get_no_warning_bit (from); + + 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 (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. */ + +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); +} |