gcc/ChangeLog:

2016-07-18  Martin Liska  <mli...@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  <mli...@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 --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; }
-- 
2.8.4


Reply via email to