diff mbox

[1/4] Fix PR target/71652

Message ID af65cb68328092b728c53381f48ba5259d5b9ae5.1468847683.git.mliska@suse.cz
State New
Headers show

Commit Message

Martin Liška July 13, 2016, 1:14 p.m. UTC
gcc/ChangeLog:

2016-07-18  Martin Liska  <mliska@suse.cz>

	PR target/71652
	* config/i386/i386.c (ix86_option_override_internal): Change
	signature and return false when there's an error related to
	arch string.
	(release_options_strings): New function.
	(ix86_valid_target_attribute_tree): Call the function.

gcc/testsuite/ChangeLog:

2016-07-18  Martin Liska  <mliska@suse.cz>

	* gcc.target/i386/pr71652.c: New test.
	* gcc.target/i386/pr71652-2.c: New test.
	* gcc.target/i386/pr71652-3.c: New test.
---
 gcc/config/i386/i386.c                    | 62 +++++++++++++++++++++----------
 gcc/testsuite/gcc.target/i386/pr71652-2.c | 13 +++++++
 gcc/testsuite/gcc.target/i386/pr71652-3.c | 14 +++++++
 gcc/testsuite/gcc.target/i386/pr71652.c   | 13 +++++++
 4 files changed, 83 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr71652-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr71652-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr71652.c
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ba35dce..c838790 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4698,9 +4698,10 @@  ix86_override_options_after_change (void)
 
 /* Override various settings based on options.  If MAIN_ARGS_P, the
    options are from the command line, otherwise they are from
-   attributes.  */
+   attributes.  Return true if there's an error related to march
+   option.  */
 
-static void
+static bool
 ix86_option_override_internal (bool main_args_p,
 			       struct gcc_options *opts,
 			       struct gcc_options *opts_set)
@@ -5243,16 +5244,32 @@  ix86_option_override_internal (bool main_args_p,
   for (i = 0; i < pta_size; i++)
     if (! strcmp (opts->x_ix86_arch_string, processor_alias_table[i].name))
       {
+	if (!strcmp (opts->x_ix86_arch_string, "generic"))
+	  {
+	    error ("generic CPU can be used only for %stune=%s %s",
+		   prefix, suffix, sw);
+	    return false;
+	  }
+	else if (!strcmp (opts->x_ix86_arch_string, "intel"))
+	  {
+	    error ("intel CPU can be used only for %stune=%s %s",
+		   prefix, suffix, sw);
+	    return false;
+	  }
+
+	if (TARGET_64BIT_P (opts->x_ix86_isa_flags)
+	    && !(processor_alias_table[i].flags & PTA_64BIT))
+	  {
+	    error ("CPU you selected does not support x86-64 "
+		   "instruction set");
+	    return false;
+	  }
+
 	ix86_schedule = processor_alias_table[i].schedule;
 	ix86_arch = processor_alias_table[i].processor;
 	/* Default cpu tuning to the architecture.  */
 	ix86_tune = ix86_arch;
 
-	if (TARGET_64BIT_P (opts->x_ix86_isa_flags)
-	    && !(processor_alias_table[i].flags & PTA_64BIT))
-	  error ("CPU you selected does not support x86-64 "
-		 "instruction set");
-
 	if (processor_alias_table[i].flags & PTA_MMX
 	    && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_MMX))
 	  opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MMX;
@@ -5450,13 +5467,7 @@  ix86_option_override_internal (bool main_args_p,
   if (TARGET_X32 && (ix86_isa_flags & OPTION_MASK_ISA_MPX))
     error ("Intel MPX does not support x32");
 
-  if (!strcmp (opts->x_ix86_arch_string, "generic"))
-    error ("generic CPU can be used only for %stune=%s %s",
-	   prefix, suffix, sw);
-  else if (!strcmp (opts->x_ix86_arch_string, "intel"))
-    error ("intel CPU can be used only for %stune=%s %s",
-	   prefix, suffix, sw);
-  else if (i == pta_size)
+  if (i == pta_size)
     error ("bad value (%s) for %sarch=%s %s",
 	   opts->x_ix86_arch_string, prefix, suffix, sw);
 
@@ -6045,6 +6056,8 @@  ix86_option_override_internal (bool main_args_p,
       ix86_parse_stringop_strategy_string (str, true);
       free (str);
     }
+
+  return true;
 }
 
 /* Implement the TARGET_OPTION_OVERRIDE hook.  */
@@ -6639,6 +6652,15 @@  ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
   return ret;
 }
 
+/* Release allocated strings.  */
+static void
+release_options_strings (char **option_strings)
+{
+  /* Free up memory allocated to hold the strings */
+  for (unsigned i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++)
+    free (option_strings[i]);
+}
+
 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL.  */
 
 tree
@@ -6653,7 +6675,6 @@  ix86_valid_target_attribute_tree (tree args,
   int orig_arch_specified = ix86_arch_specified;
   char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL };
   tree t = NULL_TREE;
-  int i;
   struct cl_target_option *def
     = TREE_TARGET_OPTION (target_option_default_node);
   struct gcc_options enum_opts_set;
@@ -6714,7 +6735,12 @@  ix86_valid_target_attribute_tree (tree args,
 	}
 
       /* Do any overrides, such as arch=xxx, or tune=xxx support.  */
-      ix86_option_override_internal (false, opts, opts_set);
+      bool r = ix86_option_override_internal (false, opts, opts_set);
+      if (!r)
+	{
+	  release_options_strings (option_strings);
+	  return error_mark_node;
+	}
 
       /* Add any builtin functions with the new isa if any.  */
       ix86_add_new_builtins (opts->x_ix86_isa_flags);
@@ -6727,9 +6753,7 @@  ix86_valid_target_attribute_tree (tree args,
       opts->x_ix86_tune_string = orig_tune_string;
       opts_set->x_ix86_fpmath = orig_fpmath_set;
 
-      /* Free up memory allocated to hold the strings */
-      for (i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++)
-	free (option_strings[i]);
+      release_options_strings (option_strings);
     }
 
   return t;
diff --git a/gcc/testsuite/gcc.target/i386/pr71652-2.c b/gcc/testsuite/gcc.target/i386/pr71652-2.c
new file mode 100644
index 0000000..1dc071d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71652-2.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+
+#pragma GCC push_options
+#pragma GCC target ("arch=intel") /* { dg-error "intel CPU can be used only for option\\(\"tune=\"\\) attribute" } */
+
+__attribute__((constructor)) void foo()
+{
+  asm ("");
+}
+
+#pragma GCC pop_options
+
+int main() { return 0; }
diff --git a/gcc/testsuite/gcc.target/i386/pr71652-3.c b/gcc/testsuite/gcc.target/i386/pr71652-3.c
new file mode 100644
index 0000000..ba99a3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71652-3.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-march=haswell" } */
+
+#pragma GCC push_options
+#pragma GCC target ("arch=geode") /* { dg-error "CPU you selected does not support x86-64 instruction set" } */
+
+__attribute__((constructor)) void foo()
+{
+  asm ("");
+}
+
+#pragma GCC pop_options
+
+int main() { return 0; }
diff --git a/gcc/testsuite/gcc.target/i386/pr71652.c b/gcc/testsuite/gcc.target/i386/pr71652.c
new file mode 100644
index 0000000..22503d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71652.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+
+#pragma GCC push_options
+#pragma GCC target ("arch=generic") /* { dg-error "generic CPU can be used only for option\\(\"tune=\"\\) attribute" } */
+
+__attribute__((constructor)) void foo()
+{
+  asm ("");
+}
+
+#pragma GCC pop_options
+
+int main() { return 0; }