xref: /netbsd-src/external/gpl3/gcc/dist/gcc/diagnostic-spec.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg /* Functions to enable and disable individual warnings on an expression
2*b1e83836Smrg    and statement basis.
3*b1e83836Smrg    Copyright (C) 2021-2022 Free Software Foundation, Inc.
4*b1e83836Smrg    Contributed by Martin Sebor <msebor@redhat.com>
5*b1e83836Smrg 
6*b1e83836Smrg    This file is part of GCC.
7*b1e83836Smrg 
8*b1e83836Smrg    GCC is free software; you can redistribute it and/or modify it under
9*b1e83836Smrg    the terms of the GNU General Public License as published by the Free
10*b1e83836Smrg    Software Foundation; either version 3, or (at your option) any later
11*b1e83836Smrg    version.
12*b1e83836Smrg 
13*b1e83836Smrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*b1e83836Smrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*b1e83836Smrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*b1e83836Smrg    for more details.
17*b1e83836Smrg 
18*b1e83836Smrg    You should have received a copy of the GNU General Public License
19*b1e83836Smrg    along with GCC; see the file COPYING3.  If not see
20*b1e83836Smrg    <http://www.gnu.org/licenses/>.  */
21*b1e83836Smrg 
22*b1e83836Smrg #include "config.h"
23*b1e83836Smrg #include "system.h"
24*b1e83836Smrg #include "coretypes.h"
25*b1e83836Smrg #include "backend.h"
26*b1e83836Smrg #include "bitmap.h"
27*b1e83836Smrg #include "tree.h"
28*b1e83836Smrg #include "cgraph.h"
29*b1e83836Smrg #include "hash-map.h"
30*b1e83836Smrg #include "diagnostic-spec.h"
31*b1e83836Smrg #include "pretty-print.h"
32*b1e83836Smrg #include "options.h"
33*b1e83836Smrg 
34*b1e83836Smrg /* Initialize *THIS from warning option OPT.  */
35*b1e83836Smrg 
nowarn_spec_t(opt_code opt)36*b1e83836Smrg nowarn_spec_t::nowarn_spec_t (opt_code opt)
37*b1e83836Smrg {
38*b1e83836Smrg   /* Create a very simple mapping based on testing and experience.
39*b1e83836Smrg      It should become more refined with time. */
40*b1e83836Smrg   switch (opt)
41*b1e83836Smrg     {
42*b1e83836Smrg     case no_warning:
43*b1e83836Smrg       m_bits = 0;
44*b1e83836Smrg       break;
45*b1e83836Smrg 
46*b1e83836Smrg     case all_warnings:
47*b1e83836Smrg       m_bits = -1;
48*b1e83836Smrg       break;
49*b1e83836Smrg 
50*b1e83836Smrg       /* Flow-sensitive warnings about pointer problems issued by both
51*b1e83836Smrg 	 front ends and the middle end.  */
52*b1e83836Smrg     case OPT_Waddress:
53*b1e83836Smrg     case OPT_Wnonnull:
54*b1e83836Smrg       m_bits = NW_NONNULL;
55*b1e83836Smrg       break;
56*b1e83836Smrg 
57*b1e83836Smrg       /* Flow-sensitive warnings about arithmetic overflow issued by both
58*b1e83836Smrg 	 front ends and the middle end.  */
59*b1e83836Smrg     case OPT_Woverflow:
60*b1e83836Smrg     case OPT_Wshift_count_negative:
61*b1e83836Smrg     case OPT_Wshift_count_overflow:
62*b1e83836Smrg     case OPT_Wstrict_overflow:
63*b1e83836Smrg       m_bits = NW_VFLOW;
64*b1e83836Smrg       break;
65*b1e83836Smrg 
66*b1e83836Smrg       /* Lexical warnings issued by front ends.  */
67*b1e83836Smrg     case OPT_Wabi:
68*b1e83836Smrg     case OPT_Wlogical_op:
69*b1e83836Smrg     case OPT_Wparentheses:
70*b1e83836Smrg     case OPT_Wreturn_type:
71*b1e83836Smrg     case OPT_Wsizeof_array_div:
72*b1e83836Smrg     case OPT_Wstrict_aliasing:
73*b1e83836Smrg     case OPT_Wunused:
74*b1e83836Smrg     case OPT_Wunused_function:
75*b1e83836Smrg     case OPT_Wunused_but_set_variable:
76*b1e83836Smrg     case OPT_Wunused_variable:
77*b1e83836Smrg     case OPT_Wunused_but_set_parameter:
78*b1e83836Smrg       m_bits = NW_LEXICAL;
79*b1e83836Smrg       break;
80*b1e83836Smrg 
81*b1e83836Smrg       /* Access warning group.  */
82*b1e83836Smrg     case OPT_Warray_bounds:
83*b1e83836Smrg     case OPT_Warray_bounds_:
84*b1e83836Smrg     case OPT_Wformat_overflow_:
85*b1e83836Smrg     case OPT_Wformat_truncation_:
86*b1e83836Smrg     case OPT_Wrestrict:
87*b1e83836Smrg     case OPT_Wsizeof_pointer_memaccess:
88*b1e83836Smrg     case OPT_Wstrict_aliasing_:
89*b1e83836Smrg     case OPT_Wstringop_overflow_:
90*b1e83836Smrg     case OPT_Wstringop_overread:
91*b1e83836Smrg     case OPT_Wstringop_truncation:
92*b1e83836Smrg       m_bits = NW_ACCESS;
93*b1e83836Smrg       break;
94*b1e83836Smrg 
95*b1e83836Smrg       /* Initialization warning group.  */
96*b1e83836Smrg     case OPT_Winit_self:
97*b1e83836Smrg     case OPT_Wuninitialized:
98*b1e83836Smrg     case OPT_Wmaybe_uninitialized:
99*b1e83836Smrg 	m_bits = NW_UNINIT;
100*b1e83836Smrg       break;
101*b1e83836Smrg 
102*b1e83836Smrg     case OPT_Wdangling_pointer_:
103*b1e83836Smrg     case OPT_Wreturn_local_addr:
104*b1e83836Smrg     case OPT_Wuse_after_free_:
105*b1e83836Smrg       m_bits = NW_DANGLING;
106*b1e83836Smrg       break;
107*b1e83836Smrg 
108*b1e83836Smrg     default:
109*b1e83836Smrg       /* A catchall group for everything else.  */
110*b1e83836Smrg       m_bits = NW_OTHER;
111*b1e83836Smrg     }
112*b1e83836Smrg }
113*b1e83836Smrg 
114*b1e83836Smrg /* A mapping from a 'location_t' to the warning spec set for it.  */
115*b1e83836Smrg 
116*b1e83836Smrg GTY(()) nowarn_map_t *nowarn_map;
117*b1e83836Smrg 
118*b1e83836Smrg /* Return the no-warning disposition for location LOC and option OPT
119*b1e83836Smrg    or for all/any otions by default.  */
120*b1e83836Smrg 
121*b1e83836Smrg bool
warning_suppressed_at(location_t loc,opt_code opt)122*b1e83836Smrg warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
123*b1e83836Smrg {
124*b1e83836Smrg   gcc_checking_assert (!RESERVED_LOCATION_P (loc));
125*b1e83836Smrg 
126*b1e83836Smrg   if (!nowarn_map)
127*b1e83836Smrg     return false;
128*b1e83836Smrg 
129*b1e83836Smrg   if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
130*b1e83836Smrg     {
131*b1e83836Smrg       const nowarn_spec_t optspec (opt);
132*b1e83836Smrg       return *pspec & optspec;
133*b1e83836Smrg     }
134*b1e83836Smrg 
135*b1e83836Smrg   return false;
136*b1e83836Smrg }
137*b1e83836Smrg 
138*b1e83836Smrg  /* Change the supression of warnings for location LOC.
139*b1e83836Smrg     OPT controls which warnings are affected.
140*b1e83836Smrg     The wildcard OPT of -1 controls all warnings.
141*b1e83836Smrg     If SUPP is true (the default), enable the suppression of the warnings.
142*b1e83836Smrg     If SUPP is false, disable the suppression of the warnings.  */
143*b1e83836Smrg 
144*b1e83836Smrg bool
suppress_warning_at(location_t loc,opt_code opt,bool supp)145*b1e83836Smrg suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
146*b1e83836Smrg 		     bool supp /* = true */)
147*b1e83836Smrg {
148*b1e83836Smrg   gcc_checking_assert (!RESERVED_LOCATION_P (loc));
149*b1e83836Smrg 
150*b1e83836Smrg   const nowarn_spec_t optspec (supp ? opt : opt_code ());
151*b1e83836Smrg 
152*b1e83836Smrg   if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL)
153*b1e83836Smrg     {
154*b1e83836Smrg       if (supp)
155*b1e83836Smrg 	{
156*b1e83836Smrg 	  *pspec |= optspec;
157*b1e83836Smrg 	  return true;
158*b1e83836Smrg 	}
159*b1e83836Smrg 
160*b1e83836Smrg       *pspec &= optspec;
161*b1e83836Smrg       if (*pspec)
162*b1e83836Smrg 	return true;
163*b1e83836Smrg 
164*b1e83836Smrg       nowarn_map->remove (loc);
165*b1e83836Smrg       return false;
166*b1e83836Smrg     }
167*b1e83836Smrg 
168*b1e83836Smrg   if (!supp || opt == no_warning)
169*b1e83836Smrg     return false;
170*b1e83836Smrg 
171*b1e83836Smrg   if (!nowarn_map)
172*b1e83836Smrg     nowarn_map = nowarn_map_t::create_ggc (32);
173*b1e83836Smrg 
174*b1e83836Smrg   nowarn_map->put (loc, optspec);
175*b1e83836Smrg   return true;
176*b1e83836Smrg }
177*b1e83836Smrg 
178*b1e83836Smrg /* Copy the no-warning disposition from one location to another.  */
179*b1e83836Smrg 
180*b1e83836Smrg void
copy_warning(location_t to,location_t from)181*b1e83836Smrg copy_warning (location_t to, location_t from)
182*b1e83836Smrg {
183*b1e83836Smrg   if (!nowarn_map)
184*b1e83836Smrg     return;
185*b1e83836Smrg 
186*b1e83836Smrg   nowarn_spec_t *from_spec;
187*b1e83836Smrg   if (RESERVED_LOCATION_P (from))
188*b1e83836Smrg     from_spec = NULL;
189*b1e83836Smrg   else
190*b1e83836Smrg     from_spec = nowarn_map->get (from);
191*b1e83836Smrg   if (RESERVED_LOCATION_P (to))
192*b1e83836Smrg     /* We cannot set no-warning dispositions for 'to', so we have no chance but
193*b1e83836Smrg        lose those potentially set for 'from'.  */
194*b1e83836Smrg     ;
195*b1e83836Smrg   else
196*b1e83836Smrg     {
197*b1e83836Smrg       if (from_spec)
198*b1e83836Smrg 	{
199*b1e83836Smrg 	  nowarn_spec_t tem = *from_spec;
200*b1e83836Smrg 	  nowarn_map->put (to, tem);
201*b1e83836Smrg 	}
202*b1e83836Smrg       else
203*b1e83836Smrg 	nowarn_map->remove (to);
204*b1e83836Smrg     }
205*b1e83836Smrg }
206