diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ae7b901b18..7f4f4dd33af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-10-01 Tamar Christina + + * params.c (validate_param): New. + (add_params): Use it. + (set_param_value): Refactor param validation into validate_param. + (diagnostic.h): Include. + * diagnostic.h (diagnostic_ready_p): New. + 2018-10-01 Tamar Christina * params.c (set_param_value): diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 34ea03bb694..d4c605ea8f3 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -274,6 +274,10 @@ diagnostic_inhibit_notes (diagnostic_context * context) and similar functions. */ extern diagnostic_context *global_dc; +/* Returns whether the diagnostic framework has been intialized already and is + ready for use. */ +#define diagnostic_ready_p() (global_dc->printer != NULL) + /* The total count of a KIND of diagnostics emitted so far. */ #define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)] diff --git a/gcc/params.c b/gcc/params.c index eb663be880a..b6a33dfd6bf 100644 --- a/gcc/params.c +++ b/gcc/params.c @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "params-enum.h" #include "diagnostic-core.h" +#include "diagnostic.h" #include "spellcheck.h" /* An array containing the compiler parameters and their current @@ -58,6 +59,10 @@ static const param_info lang_independent_params[] = { { NULL, 0, 0, 0, NULL, NULL } }; +static bool +validate_param (const int value, const param_info param, const int index); + + /* Add the N PARAMS to the current list of compiler parameters. */ void @@ -68,12 +73,26 @@ add_params (const param_info params[], size_t n) /* Allocate enough space for the new parameters. */ compiler_params = XRESIZEVEC (param_info, compiler_params, num_compiler_params + n); + param_info *dst_params = compiler_params + num_compiler_params; + /* Copy them into the table. */ - memcpy (compiler_params + num_compiler_params, - params, - n * sizeof (param_info)); + memcpy (dst_params, params, n * sizeof (param_info)); + /* Keep track of how many parameters we have. */ num_compiler_params += n; + + /* Initialize the pretty printing machinery in case we need to print an error, + but be sure not to initialize it if something else already has, e.g. a + language front-end like cc1. */ + if (!diagnostic_ready_p ()) + diagnostic_initialize (global_dc, 0); + + /* Now perform some validation and set the value if it validates. */ + for (size_t i = 0; i < n; i++) + { + if (validate_param (dst_params[i].default_value, dst_params[i], (int)i)) + dst_params[i].default_value = dst_params[i].default_value; + } } /* Add all parameters and default values that can be set in both the @@ -127,6 +146,31 @@ set_param_value_internal (compiler_param num, int value, params_set[i] = true; } +/* Validate PARAM and write an error if invalid. */ + +static bool +validate_param (const int value, const param_info param, const int index) +{ + /* These paremeters interpret bounds of 0 to be unbounded, as such don't + perform any range validation on 0 parameters. */ + if (value < param.min_value && param.min_value != 0) + { + error ("minimum value of parameter %qs is %u", + param.option, param.min_value); + return false; + } + else if (param.max_value > param.min_value && value > param.max_value) + { + error ("maximum value of parameter %qs is %u", + param.option, param.max_value); + return false; + } + else if (targetm_common.option_validate_param (value, index)) + return true; + + return false; +} + /* Return true if it can find the matching entry for NAME in the parameter table, and assign the entry index to INDEX. Return false otherwise. */ @@ -200,23 +244,14 @@ set_param_value (const char *name, int value, } i = (size_t)index; - if (value < compiler_params[i].min_value) - error ("minimum value of parameter %qs is %u", - compiler_params[i].option, - compiler_params[i].min_value); - else if (compiler_params[i].max_value > compiler_params[i].min_value - && value > compiler_params[i].max_value) - error ("maximum value of parameter %qs is %u", - compiler_params[i].option, - compiler_params[i].max_value); - else if (targetm_common.option_validate_param (value, (int)i)) + if (validate_param (value, compiler_params[i], i)) set_param_value_internal ((compiler_param) i, value, params, params_set, true); } /* Set the value of the parameter given by NUM to VALUE in PARAMS and PARAMS_SET, implicitly, if it has not been set explicitly by the - user. */ + user either via the commandline or configure. */ void maybe_set_param_value (compiler_param num, int value,