[Ada] Missing range check on assignment to bit-packed array
[official-gcc.git] / gcc / params.c
blob8d5e58f314530f797dbe1ae55f8ab2e8884bad75
1 /* params.c - Run-time parameters.
2 Copyright (C) 2001-2019 Free Software Foundation, Inc.
3 Written by Mark Mitchell <mark@codesourcery.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "common/common-target.h"
25 #include "params.h"
26 #include "params-enum.h"
27 #include "diagnostic-core.h"
28 #include "diagnostic.h"
29 #include "spellcheck.h"
31 /* An array containing the compiler parameters and their current
32 values. */
34 param_info *compiler_params;
36 /* The number of entries in the table. */
37 static size_t num_compiler_params;
39 /* Whether the parameters have all been initialized and had their
40 default values determined. */
41 static bool params_finished;
43 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
44 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4) \
45 static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };
46 #include "params.def"
47 #undef DEFPARAMENUM5
48 #undef DEFPARAM
50 static const param_info lang_independent_params[] = {
51 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \
52 { OPTION, DEFAULT, MIN, MAX, HELP, NULL },
53 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, \
54 V0, V1, V2, V3, V4) \
55 { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },
56 #include "params.def"
57 #undef DEFPARAM
58 #undef DEFPARAMENUM5
59 { NULL, 0, 0, 0, NULL, NULL }
62 static bool
63 validate_param (const int value, const param_info param, const int index);
66 /* Add the N PARAMS to the current list of compiler parameters. */
68 void
69 add_params (const param_info params[], size_t n)
71 gcc_assert (!params_finished);
73 /* Allocate enough space for the new parameters. */
74 compiler_params = XRESIZEVEC (param_info, compiler_params,
75 num_compiler_params + n);
76 param_info *dst_params = compiler_params + num_compiler_params;
78 /* Copy them into the table. */
79 memcpy (dst_params, params, n * sizeof (param_info));
81 /* Keep track of how many parameters we have. */
82 num_compiler_params += n;
84 /* Initialize the pretty printing machinery in case we need to print an error,
85 but be sure not to initialize it if something else already has, e.g. a
86 language front-end like cc1. */
87 if (!diagnostic_ready_p ())
88 diagnostic_initialize (global_dc, 0);
90 /* Now perform some validation and validation failures trigger an error so
91 initialization will stop. */
92 for (size_t i = num_compiler_params - n; i < n; i++)
93 validate_param (params[i].default_value, params[i], (int)i);
96 /* Add all parameters and default values that can be set in both the
97 driver and the compiler proper. */
99 void
100 global_init_params (void)
102 gcc_assert (!params_finished);
104 add_params (lang_independent_params, LAST_PARAM);
105 targetm_common.option_default_params ();
108 /* Note that all parameters have been added and all default values
109 set. */
111 void
112 finish_params (void)
114 params_finished = true;
117 /* Reset all state within params.c so that we can rerun the compiler
118 within the same process. For use by toplev::finalize. */
120 void
121 params_c_finalize (void)
123 XDELETEVEC (compiler_params);
124 compiler_params = NULL;
125 num_compiler_params = 0;
126 params_finished = false;
129 /* Set the value of the parameter given by NUM to VALUE in PARAMS and
130 PARAMS_SET. If EXPLICIT_P, this is being set by the user;
131 otherwise it is being set implicitly by the compiler. */
133 static void
134 set_param_value_internal (compiler_param num, int value,
135 int *params, int *params_set,
136 bool explicit_p)
138 size_t i = (size_t) num;
140 gcc_assert (params_finished);
142 params[i] = value;
143 if (explicit_p)
144 params_set[i] = true;
147 /* Validate PARAM and write an error if invalid. */
149 static bool
150 validate_param (const int value, const param_info param, const int index)
152 /* These paremeters interpret bounds of 0 to be unbounded, as such don't
153 perform any range validation on 0 parameters. */
154 if (value < param.min_value && param.min_value != 0)
156 error ("minimum value of parameter %qs is %u",
157 param.option, param.min_value);
158 return false;
160 else if (param.max_value > param.min_value && value > param.max_value)
162 error ("maximum value of parameter %qs is %u",
163 param.option, param.max_value);
164 return false;
166 else if (targetm_common.option_validate_param (value, index))
167 return true;
169 return false;
172 /* Return true if it can find the matching entry for NAME in the parameter
173 table, and assign the entry index to INDEX. Return false otherwise. */
175 bool
176 find_param (const char *name, enum compiler_param *index)
178 for (size_t i = 0; i < num_compiler_params; ++i)
179 if (strcmp (compiler_params[i].option, name) == 0)
181 *index = (enum compiler_param) i;
182 return true;
185 return false;
188 /* Look for the closest match for NAME in the parameter table, returning it
189 if it is a reasonable suggestion for a misspelling. Return NULL
190 otherwise. */
192 const char *
193 find_param_fuzzy (const char *name)
195 best_match <const char *, const char *> bm (name);
196 for (size_t i = 0; i < num_compiler_params; ++i)
197 bm.consider (compiler_params[i].option);
198 return bm.get_best_meaningful_candidate ();
201 /* Return true if param with entry index INDEX should be defined using strings.
202 If so, return the value corresponding to VALUE_NAME in *VALUE_P. */
204 bool
205 param_string_value_p (enum compiler_param index, const char *value_name,
206 int *value_p)
208 param_info *entry = &compiler_params[(int) index];
209 if (entry->value_names == NULL)
210 return false;
212 *value_p = -1;
214 for (int i = 0; entry->value_names[i] != NULL; ++i)
215 if (strcmp (entry->value_names[i], value_name) == 0)
217 *value_p = i;
218 return true;
221 return true;
224 /* Set the VALUE associated with the parameter given by NAME in PARAMS
225 and PARAMS_SET. */
227 void
228 set_param_value (const char *name, int value,
229 int *params, int *params_set)
231 size_t i;
233 /* Make sure nobody tries to set a parameter to an invalid value. */
234 gcc_assert (value != INVALID_PARAM_VAL);
236 enum compiler_param index;
237 if (!find_param (name, &index))
239 /* If we didn't find this parameter, issue an error message. */
240 error ("invalid parameter %qs", name);
241 return;
243 i = (size_t)index;
245 if (validate_param (value, compiler_params[i], i))
246 set_param_value_internal ((compiler_param) i, value,
247 params, params_set, true);
250 /* Set the value of the parameter given by NUM to VALUE in PARAMS and
251 PARAMS_SET, implicitly, if it has not been set explicitly by the
252 user either via the commandline or configure. */
254 void
255 maybe_set_param_value (compiler_param num, int value,
256 int *params, int *params_set)
258 if (!params_set[(int) num])
259 set_param_value_internal (num, value, params, params_set, false);
262 /* Set the default value of a parameter given by NUM to VALUE, before
263 option processing. */
265 void
266 set_default_param_value (compiler_param num, int value)
268 gcc_assert (!params_finished);
270 compiler_params[(int) num].default_value = value;
273 /* Return the default value of parameter NUM. */
276 default_param_value (compiler_param num)
278 return compiler_params[(int) num].default_value;
281 /* Initialize an array PARAMS with default values of the
282 parameters. */
284 void
285 init_param_values (int *params)
287 size_t i;
289 gcc_assert (params_finished);
291 for (i = 0; i < num_compiler_params; i++)
292 params[i] = compiler_params[i].default_value;
295 /* Return the current value of num_compiler_params, for the benefit of
296 plugins that use parameters as features. */
298 size_t
299 get_num_compiler_params (void)
301 return num_compiler_params;