mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-27 12:57:21 +00:00
255 lines
6.1 KiB
C++
255 lines
6.1 KiB
C++
/* Functions to enable and disable individual warnings on an expression
|
|
and statement basis.
|
|
|
|
Copyright (C) 2021-2022 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 statement 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_spec_t tem = *from_spec;
|
|
nowarn_map->put (to_loc, tem);
|
|
}
|
|
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);
|
|
}
|