This commit implements the function TARGET_CHECK_TARGET_CLONE_VERSION
for the RISC-V architecture by changing the error to a warning when an
unsupported target clone version is encountered.

This allows the compiler to compatible with future extensions without
failing the build. And also helps for future APIs that need real
implementation of TARGET_CHECK_TARGET_CLONE_VERSION for RISC-V that
no longer always return true.

Signed-off-by: Yangyu Chen <[email protected]>
---
 gcc/config/riscv/riscv-target-attr.cc | 50 +++++++++++++++------------
 gcc/config/riscv/riscv.cc             | 21 +++++------
 2 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/gcc/config/riscv/riscv-target-attr.cc 
b/gcc/config/riscv/riscv-target-attr.cc
index 99af5308fea4..ad5e5a052196 100644
--- a/gcc/config/riscv/riscv-target-attr.cc
+++ b/gcc/config/riscv/riscv-target-attr.cc
@@ -149,18 +149,18 @@ riscv_target_attr_parser::parse_arch (const char *str)
          if (token[0] != '+')
            {
              if (*m_loc)
-               error_at (*m_loc, "unexpected arch for %<target()%> "
-                         "attribute: must start with + or rv");
+               warning_at (*m_loc, 0, "unexpected arch for %<target()%> "
+                           "attribute: must start with + or rv");
              goto fail;
            }
 
          const char *result = m_subset_list->parse_single_ext (token + 1);
          /* Check parse_single_ext has consume all string.  */
-         if (*result != '\0')
+         if (result == nullptr || *result != '\0')
            {
              if (m_loc)
-               error_at (*m_loc, "unexpected arch for %<target()%> "
-                         "attribute: bad string found %qs", token);
+               warning_at (*m_loc, 0, "unexpected arch for %<target()%> "
+                           "attribute: bad string found %qs", token);
              goto fail;
            }
 
@@ -186,7 +186,8 @@ bool
 riscv_target_attr_parser::handle_arch (const char *str)
 {
   if (m_found_arch_p && m_loc)
-    error_at (*m_loc, "%<target()%> attribute: arch appears more than once");
+    warning_at (*m_loc, 0,
+               "%<target()%> attribute: arch appears more than once");
   m_found_arch_p = true;
   return parse_arch (str);
 }
@@ -197,7 +198,8 @@ bool
 riscv_target_attr_parser::handle_cpu (const char *str)
 {
   if (m_found_cpu_p && m_loc)
-    error_at (*m_loc, "%<target()%> attribute: cpu appears more than once");
+    warning_at (*m_loc, 0,
+               "%<target()%> attribute: cpu appears more than once");
 
   m_found_cpu_p = true;
   const riscv_cpu_info *cpu_info = riscv_find_cpu (str);
@@ -205,7 +207,7 @@ riscv_target_attr_parser::handle_cpu (const char *str)
   if (!cpu_info)
     {
       if (m_loc)
-       error_at (*m_loc, "%<target()%> attribute: unknown CPU %qs", str);
+       warning_at (*m_loc, 0, "%<target()%> attribute: unknown CPU %qs", str);
       return false;
     }
 
@@ -226,14 +228,15 @@ bool
 riscv_target_attr_parser::handle_tune (const char *str)
 {
   if (m_found_tune_p && m_loc)
-    error_at (*m_loc, "%<target()%> attribute: tune appears more than once");
+    warning_at (*m_loc, 0,
+               "%<target()%> attribute: tune appears more than once");
   m_found_tune_p = true;
   const struct riscv_tune_info *tune = riscv_parse_tune (str, true);
 
   if (tune == nullptr)
     {
       if (m_loc)
-       error_at (*m_loc, "%<target()%> attribute: unknown TUNE %qs", str);
+       warning_at (*m_loc, 0, "%<target()%> attribute: unknown TUNE %qs", str);
       return false;
     }
 
@@ -246,14 +249,15 @@ bool
 riscv_target_attr_parser::handle_priority (const char *str)
 {
   if (m_found_priority_p && m_loc)
-    error_at (*m_loc, "%<target()%> attribute: priority appears "
+    warning_at (*m_loc, 0, "%<target()%> attribute: priority appears "
              "more than once");
   m_found_priority_p = true;
 
   if (sscanf (str, "%d", &m_priority) != 1)
     {
       if (m_loc)
-       error_at (*m_loc, "%<target()%> attribute: invalid priority %qs", str);
+       warning_at (*m_loc, 0, "%<target()%> attribute: invalid priority %qs",
+                   str);
       return false;
     }
 
@@ -315,7 +319,7 @@ riscv_process_one_target_attr (char *arg_str,
   if (len == 0)
     {
       if (loc)
-       error_at (*loc, "malformed %<target()%> attribute");
+       warning_at (*loc, 0, "malformed %<target()%> attribute");
       return false;
     }
 
@@ -333,8 +337,9 @@ riscv_process_one_target_attr (char *arg_str,
       if (*arg == '\0')
        {
          if (loc)
-           error_at (*loc, "attribute %<target(\"%s\")%> has empty argument",
-                     str_to_check);
+           warning_at (*loc, 0,
+                       "attribute %<target(\"%s\")%> has empty argument",
+                       str_to_check);
          return false;
        }
     }
@@ -349,7 +354,7 @@ riscv_process_one_target_attr (char *arg_str,
       if (attr->requires_arg && !arg)
        {
          if (loc)
-           error_at (*loc, "attribute %<target(\"%s\")%> expects "
+           warning_at (*loc, 0, "attribute %<target(\"%s\")%> expects "
                      "an argument", str_to_check);
          return false;
        }
@@ -357,7 +362,7 @@ riscv_process_one_target_attr (char *arg_str,
       if (!attr->requires_arg && arg)
        {
          if (loc)
-           error_at (*loc, "attribute %<target(\"%s\")%> does not "
+           warning_at (*loc, 0, "attribute %<target(\"%s\")%> does not "
                      "accept an argument", str_to_check);
          return false;
        }
@@ -366,7 +371,7 @@ riscv_process_one_target_attr (char *arg_str,
     }
 
   if (loc)
-    error_at (*loc, "unknown attribute %<target(\"%s\")%>", str_to_check);
+    warning_at (*loc, 0, "unknown attribute %<target(\"%s\")%>", str_to_check);
   return false;
 }
 
@@ -432,7 +437,7 @@ riscv_process_target_str (string_slice args,
   if (num_attrs != num_semicolons + 1)
     {
       if (loc)
-       error_at (*loc, "malformed %<target(\"%B\")%> attribute", &args);
+       warning_at (*loc, 0, "malformed %<target(\"%B\")%> attribute", &args);
       return false;
     }
 
@@ -470,7 +475,7 @@ riscv_process_target_attr (tree args,
   if (TREE_CODE (args) != STRING_CST)
     {
       if (loc)
-       error_at (*loc, "attribute %<target%> argument not a string");
+       warning_at (*loc, 0, "attribute %<target%> argument not a string");
       return false;
     }
 
@@ -549,7 +554,7 @@ riscv_process_target_version_attr (tree args, location_t 
*loc)
       if (TREE_CHAIN (args))
        {
          if (loc)
-           error_at (*loc, "attribute %<target_version%> "
+           warning_at (*loc, 0, "attribute %<target_version%> "
                      "has multiple values");
          return false;
        }
@@ -559,7 +564,8 @@ riscv_process_target_version_attr (tree args, location_t 
*loc)
   if (!args || TREE_CODE (args) != STRING_CST)
     {
       if (loc)
-       error_at (*loc, "attribute %<target_version%> argument not a string");
+       warning_at (*loc, 0,
+                   "attribute %<target_version%> argument not a string");
       return false;
     }
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 32e72128f049..a84e6d7b4831 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -14876,7 +14876,7 @@ riscv_bitint_type_info (int n, struct bitint_info *info)
    priority required to select those targets.
    If LOC is nonnull, report diagnostics against *LOC, otherwise
    remain silent.  */
-static void
+static bool
 parse_features_for_version (string_slice version_str,
                            location_t *loc,
                            struct riscv_feature_bits &res,
@@ -14887,7 +14887,7 @@ parse_features_for_version (string_slice version_str,
     {
       res.length = 0;
       priority = 0;
-      return;
+      return true;
     }
 
   struct cl_target_option cur_target;
@@ -14899,7 +14899,13 @@ parse_features_for_version (string_slice version_str,
   cl_target_option_restore (&global_options, &global_options_set,
                            default_opts);
 
-  riscv_process_target_version_str (version_str, loc);
+  bool ret = riscv_process_target_version_str (version_str, loc);
+  if (!ret)
+    {
+      cl_target_option_restore (&global_options, &global_options_set,
+                               &cur_target);
+    return false;
+    }
 
   priority = global_options.x_riscv_fmv_priority;
   const char *arch_string = global_options.x_riscv_arch_string;
@@ -14909,6 +14915,7 @@ parse_features_for_version (string_slice version_str,
 
   cl_target_option_restore (&global_options, &global_options_set,
                            &cur_target);
+  return true;
 }
 
 /* Compare priorities of two feature masks.  Return:
@@ -15003,13 +15010,7 @@ riscv_check_target_clone_version (string_slice str, 
location_t *loc_p)
   struct riscv_feature_bits mask;
   int prio;
 
-  /* Currently it is not possible to parse without emitting errors on failure
-     so do not reject on a failed parse, as this would then emit two
-     diagnostics.  Instead let errors be emitted which will halt
-     compilation.  */
-  parse_features_for_version (str, loc_p, mask, prio);
-
-  return true;
+  return parse_features_for_version (str, loc_p, mask, prio);
 }
 
 /* Implement TARGET_MANGLE_DECL_ASSEMBLER_NAME, to add function multiversioning
-- 
2.51.0

Reply via email to