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;
 

