diff mbox series

[front-end,opt-framework] Update options framework for parameters to properly handle and validate configure time params. [Patch (2/3)]

Message ID 20180711112437.GA16063@arm.com
State New
Headers show
Series [front-end,opt-framework] Update options framework for parameters to properly handle and validate configure time params. [Patch (2/3)] | expand

Commit Message

Tamar Christina July 11, 2018, 11:24 a.m. UTC
Hi All,

This patch builds on a previous patch to pass param options down from configure
by adding more expansive validation and correctness checks.

These are set very early on and allow the target to validate or reject the
values as they see fit.

To do this compiler_param has been extended to hold a value set at configure
time, this value is used to be able to distinguish between

1) default value
2) configure value
3) back-end default
4) user specific value.

The priority of the values should be 4 > 2 > 3 > 1.  The compiler will now also
validate the values in params.def after setting them.  This means invalid values
will no longer be accepted.

This also changes it so that default parameters are validated during
initialization. This change is needed to ensure parameters set via configure
or by the target specific common initialization routines still keep the
parameters within the valid range.

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
Both targets were tested with stack clash on and off by default.

Ok for trunk?

Thanks,
Tamar

gcc/
2018-07-11  Tamar Christina  <tamar.christina@arm.com>

	* params.h (struct param_info): Add configure_value.
	* params.c (DEFPARAMCONF): New.
	(DEFPARAM, DEFPARAMENUM5): Set configure_value.
	(validate_param): New.
	(add_params): Use it.
	(set_param_value): Refactor param validation into validate_param.
	(maybe_set_param_value): Don't override value from configure.
	(diagnostic.h): Include.
	* params-enum.h (DEFPARAMCONF): New.
	* params-list.h: Likewise.
	* params-options.h: Likewise.
	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE): Use it.
	* diagnostic.h (diagnostic_ready_p): New.

--

Comments

Jeff Law July 11, 2018, 7:24 p.m. UTC | #1
On 07/11/2018 05:24 AM, Tamar Christina wrote:
> Hi All,
> 
> This patch builds on a previous patch to pass param options down from configure
> by adding more expansive validation and correctness checks.
> 
> These are set very early on and allow the target to validate or reject the
> values as they see fit.
> 
> To do this compiler_param has been extended to hold a value set at configure
> time, this value is used to be able to distinguish between
> 
> 1) default value
> 2) configure value
> 3) back-end default
> 4) user specific value.
> 
> The priority of the values should be 4 > 2 > 3 > 1.  The compiler will now also
> validate the values in params.def after setting them.  This means invalid values
> will no longer be accepted.
> 
> This also changes it so that default parameters are validated during
> initialization. This change is needed to ensure parameters set via configure
> or by the target specific common initialization routines still keep the
> parameters within the valid range.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
> Both targets were tested with stack clash on and off by default.
> 
> Ok for trunk?
> 
> Thanks,
> Tamar
> 
> gcc/
> 2018-07-11  Tamar Christina  <tamar.christina@arm.com>
> 
> 	* params.h (struct param_info): Add configure_value.
> 	* params.c (DEFPARAMCONF): New.
> 	(DEFPARAM, DEFPARAMENUM5): Set configure_value.
> 	(validate_param): New.
> 	(add_params): Use it.
> 	(set_param_value): Refactor param validation into validate_param.
> 	(maybe_set_param_value): Don't override value from configure.
> 	(diagnostic.h): Include.
> 	* params-enum.h (DEFPARAMCONF): New.
> 	* params-list.h: Likewise.
> 	* params-options.h: Likewise.
> 	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE): Use it.
> 	* diagnostic.h (diagnostic_ready_p): New.
Generally OK, though probably should depend on what we decide WRT
configurability.  ie, I'm not convinced we need to be able to set the
default via a configure time option.  And if we don't support that this
patch gets somewhat simpler.

jeff
>
Tamar Christina July 24, 2018, 10:29 a.m. UTC | #2
Hi All,

This patch is re-spun to handle the configure changes in patch 4 / 6 of the previous series.

This patch now 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.

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
Both targets were tested with stack clash on and off by default.

Ok for trunk?

Thanks,
Tamar

gcc/
2018-07-24  Tamar Christina  <tamar.christina@arm.com>

	* 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.

> -----Original Message-----
> From: Jeff Law <law@redhat.com>
> Sent: Wednesday, July 11, 2018 20:24
> To: Tamar Christina <Tamar.Christina@arm.com>; gcc-patches@gcc.gnu.org
> Cc: nd <nd@arm.com>; joseph@codesourcery.com
> Subject: Re: [PATCH][GCC][front-end][opt-framework] Update options
> framework for parameters to properly handle and validate configure time
> params. [Patch (2/3)]
> 
> On 07/11/2018 05:24 AM, Tamar Christina wrote:
> > Hi All,
> >
> > This patch builds on a previous patch to pass param options down from
> > configure by adding more expansive validation and correctness checks.
> >
> > These are set very early on and allow the target to validate or reject
> > the values as they see fit.
> >
> > To do this compiler_param has been extended to hold a value set at
> > configure time, this value is used to be able to distinguish between
> >
> > 1) default value
> > 2) configure value
> > 3) back-end default
> > 4) user specific value.
> >
> > The priority of the values should be 4 > 2 > 3 > 1.  The compiler will
> > now also validate the values in params.def after setting them.  This
> > means invalid values will no longer be accepted.
> >
> > This also changes it so that default parameters are validated during
> > initialization. This change is needed to ensure parameters set via
> > configure or by the target specific common initialization routines
> > still keep the parameters within the valid range.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
> and no issues.
> > Both targets were tested with stack clash on and off by default.
> >
> > Ok for trunk?
> >
> > Thanks,
> > Tamar
> >
> > gcc/
> > 2018-07-11  Tamar Christina  <tamar.christina@arm.com>
> >
> > 	* params.h (struct param_info): Add configure_value.
> > 	* params.c (DEFPARAMCONF): New.
> > 	(DEFPARAM, DEFPARAMENUM5): Set configure_value.
> > 	(validate_param): New.
> > 	(add_params): Use it.
> > 	(set_param_value): Refactor param validation into validate_param.
> > 	(maybe_set_param_value): Don't override value from configure.
> > 	(diagnostic.h): Include.
> > 	* params-enum.h (DEFPARAMCONF): New.
> > 	* params-list.h: Likewise.
> > 	* params-options.h: Likewise.
> > 	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE):
> Use it.
> > 	* diagnostic.h (diagnostic_ready_p): New.
> Generally OK, though probably should depend on what we decide WRT
> configurability.  ie, I'm not convinced we need to be able to set the default
> via a configure time option.  And if we don't support that this patch gets
> somewhat simpler.
> 
> jeff
> >
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index cf3a610f3d945f2dbbfde7d9cf7a66f46ad6f0b1..584b5877b489d3cce5c18da2db5f73b7b41a72a4 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -250,6 +250,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 eb663be880a91dc0adce2a84c6bad7e06b4c72c3..b6a33dfd6bf8c4df43fdac91e30ac6d082f39071 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,
Jeff Law Aug. 3, 2018, 5:56 p.m. UTC | #3
On 07/24/2018 04:29 AM, tamar.christina@arm.com wrote:
> Hi All,
> 
> This patch is re-spun to handle the configure changes in patch 4 / 6 of the previous series.
> 
> This patch now 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.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
> Both targets were tested with stack clash on and off by default.
> 
> Ok for trunk?
> 
> Thanks,
> Tamar
> 
> gcc/
> 2018-07-24  Tamar Christina  <tamar.christina@arm.com>
> 
> 	* 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.
> 
>> -----Original Message-----
>> From: Jeff Law <law@redhat.com>
>> Sent: Wednesday, July 11, 2018 20:24
>> To: Tamar Christina <Tamar.Christina@arm.com>; gcc-patches@gcc.gnu.org
>> Cc: nd <nd@arm.com>; joseph@codesourcery.com
>> Subject: Re: [PATCH][GCC][front-end][opt-framework] Update options
>> framework for parameters to properly handle and validate configure time
>> params. [Patch (2/3)]
>>
>> On 07/11/2018 05:24 AM, Tamar Christina wrote:
>>> Hi All,
>>>
>>> This patch builds on a previous patch to pass param options down from
>>> configure by adding more expansive validation and correctness checks.
>>>
>>> These are set very early on and allow the target to validate or reject
>>> the values as they see fit.
>>>
>>> To do this compiler_param has been extended to hold a value set at
>>> configure time, this value is used to be able to distinguish between
>>>
>>> 1) default value
>>> 2) configure value
>>> 3) back-end default
>>> 4) user specific value.
>>>
>>> The priority of the values should be 4 > 2 > 3 > 1.  The compiler will
>>> now also validate the values in params.def after setting them.  This
>>> means invalid values will no longer be accepted.
>>>
>>> This also changes it so that default parameters are validated during
>>> initialization. This change is needed to ensure parameters set via
>>> configure or by the target specific common initialization routines
>>> still keep the parameters within the valid range.
>>>
>>> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
>> and no issues.
>>> Both targets were tested with stack clash on and off by default.
>>>
>>> Ok for trunk?
>>>
>>> Thanks,
>>> Tamar
>>>
>>> gcc/
>>> 2018-07-11  Tamar Christina  <tamar.christina@arm.com>
>>>
>>> 	* params.h (struct param_info): Add configure_value.
>>> 	* params.c (DEFPARAMCONF): New.
>>> 	(DEFPARAM, DEFPARAMENUM5): Set configure_value.
>>> 	(validate_param): New.
>>> 	(add_params): Use it.
>>> 	(set_param_value): Refactor param validation into validate_param.
>>> 	(maybe_set_param_value): Don't override value from configure.
>>> 	(diagnostic.h): Include.
>>> 	* params-enum.h (DEFPARAMCONF): New.
>>> 	* params-list.h: Likewise.
>>> 	* params-options.h: Likewise.
>>> 	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE):
>> Use it.
>>> 	* diagnostic.h (diagnostic_ready_p): New.
>> Generally OK, though probably should depend on what we decide WRT
>> configurability.  ie, I'm not convinced we need to be able to set the default
>> via a configure time option.  And if we don't support that this patch gets
>> somewhat simpler.
>>
>> jeff
> 
> 
> rb9153-2.patch
[ ... ]
I think this is fine now.

jeff
Alexander Monakov Oct. 2, 2018, 7 a.m. UTC | #4
Hello,

On Tue, 24 Jul 2018, tamar.christina@arm.com wrote:
> 
> 	* 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.

this patch was committed to trunk recently, and an automated email from
Coverity static checker has pointed out a useless self-assignment in a new
loop. It seems wrong indeed.

@@ -68,12 +73,26 @@ add_params (const param_info params[], size_t n)
[...]
+
+  /* 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;
+    }
 }
 

Alexander
Tamar Christina Oct. 2, 2018, 12:48 p.m. UTC | #5
Hi Alexander,

> -----Original Message-----
> From: Alexander Monakov <amonakov@ispras.ru>
> Sent: Tuesday, October 2, 2018 08:01
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: Jeff Law <law@redhat.com>; gcc-patches@gcc.gnu.org; nd
> <nd@arm.com>; joseph@codesourcery.com
> Subject: RE: [PATCH][GCC][front-end][opt-framework] Update options
> framework for parameters to properly handle and validate configure time
> params. [Patch (2/3)]
> 
> Hello,
> 
> On Tue, 24 Jul 2018, tamar.christina@arm.com wrote:
> >
> > 	* 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.
> 
> this patch was committed to trunk recently, and an automated email from
> Coverity static checker has pointed out a useless self-assignment in a new
> loop. It seems wrong indeed.
> 

It's not wrong it's just unneeded. I'll write a patch to remove the assignment.

Thanks,
Tamar

> @@ -68,12 +73,26 @@ add_params (const param_info params[], size_t n) [...]
> +
> +  /* 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;
> +    }
>  }
> 
> 
> Alexander
diff mbox series

Patch

diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index cf3a610f3d945f2dbbfde7d9cf7a66f46ad6f0b1..584b5877b489d3cce5c18da2db5f73b7b41a72a4 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -250,6 +250,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-enum.h b/gcc/params-enum.h
index 5f9ac3050257ea5ec3f8be5c0909a4d558b97861..a2d19d18bdceedd7fc9c4fdbc62c6902ddf967fe 100644
--- a/gcc/params-enum.h
+++ b/gcc/params-enum.h
@@ -18,6 +18,7 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
+#define DEFPARAMCONF(ENUM, OPTION, HELP, MACRO, DEFAULT, MIN, MAX)
 #define DEFPARAMENUMNAME(ENUM) ENUM ## _KIND
 #define DEFPARAMENUMVAL(ENUM, V) ENUM ## _KIND_ ## V
 #define DEFPARAMENUMTERM(ENUM) ENUM ## _KIND_ ## LAST
@@ -36,4 +37,5 @@  along with GCC; see the file COPYING3.  If not see
 #undef DEFPARAMENUMTERM
 #undef DEFPARAMENUMVAL
 #undef DEFPARAMENUMNAME
+#undef DEFPARAMCONF
 #undef DEFPARAM
diff --git a/gcc/params-list.h b/gcc/params-list.h
index 4889c39a180abb3d0efaaf12e148deb1d011f65f..acb6ffd291d169642d44a05cd3b634029c53d50a 100644
--- a/gcc/params-list.h
+++ b/gcc/params-list.h
@@ -19,8 +19,11 @@  along with GCC; see the file COPYING3.  If not see
 
 #define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \
   enumerator,
+#define DEFPARAMCONF(enumerator, option, nocmsgid, macro, default, min, max) \
+  enumerator,
 #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \
 		      v0, v1, v2, v3, v4) enumerator,
 #include "params.def"
 #undef DEFPARAM
+#undef DEFPARAMCONF
 #undef DEFPARAMENUM5
diff --git a/gcc/params-options.h b/gcc/params-options.h
index e9ac2e73522ddb6c199ed0af462ebc7e4777d676..fbb2f73c894da9505f233408979e5789b44c5fd6 100644
--- a/gcc/params-options.h
+++ b/gcc/params-options.h
@@ -19,9 +19,12 @@  along with GCC; see the file COPYING3.  If not see
 
 #define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \
   option=default,min,max
+#define DEFPARAMCONF(enumerator, option, nocmsgid, macro, default, min, max) \
+  option=macro,default,min,max
 #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \
 		      v0, v1, v2, v3, v4) \
   option=v0,v1,v2,v3,v4
 #include "params.def"
 #undef DEFPARAM
+#undef DEFPARAMCONF
 #undef DEFPARAMENUM5
diff --git a/gcc/params.c b/gcc/params.c
index eb663be880a91dc0adce2a84c6bad7e06b4c72c3..e99c0bff48dafdd7fcca122b1c30df21ec75e6f2 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
@@ -40,24 +41,33 @@  static size_t num_compiler_params;
 static bool params_finished;
 
 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
+#define DEFPARAMCONF(ENUM, OPTION, HELP, CONF, DEFAULT, MIN, MAX)
 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4)	\
   static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };
 #include "params.def"
 #undef DEFPARAMENUM5
+#undef DEFPARAMCONF
 #undef DEFPARAM
 
 static const param_info lang_independent_params[] = {
 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \
-  { OPTION, DEFAULT, MIN, MAX, HELP, NULL },
+  { OPTION, 0, DEFAULT, MIN, MAX, HELP, NULL },
+#define DEFPARAMCONF(ENUM, OPTION, HELP, CONF, DEFAULT, MIN, MAX) \
+  { OPTION, CONF, DEFAULT, MIN, MAX, HELP, NULL },
 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT,	     \
 		      V0, V1, V2, V3, V4)		     \
-  { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },
+  { OPTION, 0, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },
 #include "params.def"
 #undef DEFPARAM
+#undef DEFPARAMCONF
 #undef DEFPARAMENUM5
-  { NULL, 0, 0, 0, NULL, NULL }
+  { NULL, 0, 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 +78,30 @@  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 override the value with that set through
+     configure if one exists.  */
+  for (size_t i = 0; i < n; i++)
+    {
+       int value = dst_params[i].configure_value
+		   ? dst_params[i].configure_value
+		   : dst_params[i].default_value;
+       if (validate_param (value, dst_params[i], (int)i))
+	  dst_params[i].default_value = value;
+    }
 }
 
 /* Add all parameters and default values that can be set in both the
@@ -127,6 +155,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,29 +253,20 @@  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,
 		       int *params, int *params_set)
 {
-  if (!params_set[(int) num])
+  if (!(params_set[(int) num] || compiler_params[(int) num].configure_value))
     set_param_value_internal (num, value, params, params_set, false);
 }
 
diff --git a/gcc/params.def b/gcc/params.def
index d4e0461844dc958cebaefaa9004fd98c78c31419..f4486e416dba6e60eefbfdcc95b616c88fdf00c4 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -215,10 +215,11 @@  DEFPARAM(PARAM_STACK_FRAME_GROWTH,
 
 /* These values are stored in configure.ac, update them there to keep everything
    in sync.  */
-DEFPARAM(PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE,
+DEFPARAMCONF(PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE,
 	 "stack-clash-protection-guard-size",
 	 "Size of the stack guard expressed as a power of two.",
-	 DEFAULT_STK_CLASH_GUARD_SIZE ? DEFAULT_STK_CLASH_GUARD_SIZE : STK_CLASH_GUARD_SIZE_DEFAULT,
+	 DEFAULT_STK_CLASH_GUARD_SIZE,
+	 STK_CLASH_GUARD_SIZE_DEFAULT,
 	 STK_CLASH_GUARD_SIZE_MIN,
 	 STK_CLASH_GUARD_SIZE_MAX)
 
diff --git a/gcc/params.h b/gcc/params.h
index 8aa960a904ee7f7ce239aa1323ab25e6043ae7ba..dd0436537f4fa6c5b5896a92fe2f70cdc089f0c2 100644
--- a/gcc/params.h
+++ b/gcc/params.h
@@ -44,6 +44,9 @@  struct param_info
      value.  */
   const char *option;
 
+  /* The value set through configure.  */
+  int configure_value;
+
   /* The default value.  */
   int default_value;