From f622a56bcb4049083fcbb63bb27eca9230c89456 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Mon, 1 Oct 2018 13:08:10 +0000 Subject: [PATCH] Update options framework for parameters to properly handle and validate configure time params. This patch changes it so that default parameters are validated during initialization. This change is needed to ensure parameters set via by the target specific common initialization routines still keep the parameters within the valid range. gcc/ * 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. From-SVN: r264756 --- gcc/ChangeLog | 8 ++++++ gcc/diagnostic.h | 4 +++ gcc/params.c | 63 +++++++++++++++++++++++++++++++++++++----------- 3 files changed, 61 insertions(+), 14 deletions(-) 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,