1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
/* Functions to enable and disable individual warnings on an expression
and statement basis.
Copyright (C) 2021-2022 Free Software Foundation, Inc.
Contributed by Martin Sebor <msebor@redhat.com>
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 "cgraph.h"
#include "hash-map.h"
#include "diagnostic-spec.h"
#include "pretty-print.h"
#include "options.h"
/* Initialize *THIS from warning option OPT. */
nowarn_spec_t::nowarn_spec_t (opt_code opt)
{
/* Create a very simple mapping based on testing and experience.
It should become more refined with time. */
switch (opt)
{
case no_warning:
m_bits = 0;
break;
case all_warnings:
m_bits = -1;
break;
/* Flow-sensitive warnings about pointer problems issued by both
front ends and the middle end. */
case OPT_Waddress:
case OPT_Wnonnull:
m_bits = NW_NONNULL;
break;
/* Flow-sensitive warnings about arithmetic overflow issued by both
front ends and the middle end. */
case OPT_Woverflow:
case OPT_Wshift_count_negative:
case OPT_Wshift_count_overflow:
case OPT_Wstrict_overflow:
m_bits = NW_VFLOW;
break;
/* Lexical warnings issued by front ends. */
case OPT_Wabi:
case OPT_Wlogical_op:
case OPT_Wparentheses:
case OPT_Wreturn_type:
case OPT_Wsizeof_array_div:
case OPT_Wstrict_aliasing:
case OPT_Wunused:
case OPT_Wunused_function:
case OPT_Wunused_but_set_variable:
case OPT_Wunused_variable:
case OPT_Wunused_but_set_parameter:
m_bits = NW_LEXICAL;
break;
/* Access warning group. */
case OPT_Warray_bounds:
case OPT_Warray_bounds_:
case OPT_Wformat_overflow_:
case OPT_Wformat_truncation_:
case OPT_Wrestrict:
case OPT_Wsizeof_pointer_memaccess:
case OPT_Wstrict_aliasing_:
case OPT_Wstringop_overflow_:
case OPT_Wstringop_overread:
case OPT_Wstringop_truncation:
m_bits = NW_ACCESS;
break;
/* Initialization warning group. */
case OPT_Winit_self:
case OPT_Wuninitialized:
case OPT_Wmaybe_uninitialized:
m_bits = NW_UNINIT;
break;
case OPT_Wdangling_pointer_:
case OPT_Wreturn_local_addr:
case OPT_Wuse_after_free_:
m_bits = NW_DANGLING;
break;
default:
/* A catchall group for everything else. */
m_bits = NW_OTHER;
}
}
/* A mapping from a 'location_t' to the warning spec set for it. */
GTY(()) nowarn_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 */)
{
gcc_checking_assert (!RESERVED_LOCATION_P (loc));
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 for 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 */)
{
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)
{
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 = nowarn_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;
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
{
if (from_spec)
{
nowarn_spec_t tem = *from_spec;
nowarn_map->put (to, tem);
}
else
nowarn_map->remove (to);
}
}
|