[binutils-gdb] RISC-V: error handling for subset parsing

Jan Beulich via Binutils-cvs <[email protected]>
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=11cbe94d245c06313541e4e4c87745f74856d5dd

commit 11cbe94d245c06313541e4e4c87745f74856d5dd
Author: Jan Beulich <[email protected]>
Date:   Fri Jun 5 11:10:28 2026 +0200

    RISC-V: error handling for subset parsing
    
    The parsing of both the argument of -march= and the operand(s) of
    ".option arch, ..." can fail. In such a case for .option (and equally
    for .attribute) prior state should continue to be used, while for -march=
    defaults should be put in place. In particular, extensions conflicting
    with previously enabled extensions should not suddenly become available.
    
    While re-indenting riscv_set_rvc() invocations, leverage that C implies
    Zca (and hence a check for the latter suffices). Mirror that change to
    riscv_set_arch() for consistency.
    
    Reviewed-by: Jiawei <[email protected]>

Diff:
---
 bfd/elfxx-riscv.c                             | 23 +++++++++-
 gas/config/tc-riscv.c                         | 60 ++++++++++++++++++---------
 gas/testsuite/gas/riscv/x-thead-vector-fail.d |  2 +-
 3 files changed, 64 insertions(+), 21 deletions(-)

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 91337013ba3..8e56322b512 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -2768,7 +2768,28 @@ bool
 riscv_update_subset (riscv_parse_subset_t *rps,
 		     const char *str)
 {
-  return riscv_update_subset1 (rps, NULL, str);
+  unsigned int newxlen = *rps->xlen;
+  riscv_parse_subset_t newrps = {
+    .subset_list = riscv_copy_subset_list (rps->subset_list),
+    .error_handler = rps->error_handler,
+    .xlen = &newxlen,
+    .isa_spec = rps->isa_spec,
+    .check_unknown_prefixed_ext = rps->check_unknown_prefixed_ext,
+  };
+
+  if (!riscv_update_subset1 (&newrps, NULL, str))
+    {
+      riscv_release_subset_list (newrps.subset_list);
+      free (newrps.subset_list);
+      return false;
+    }
+
+  *rps->xlen = newxlen;
+  riscv_release_subset_list (rps->subset_list);
+  *rps->subset_list = *newrps.subset_list;
+  free (newrps.subset_list);
+
+  return true;
 }
 
 /* Called from .option norvc directives.  */
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 22d002a3309..be3501930b3 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -350,20 +350,38 @@ riscv_set_arch (const char *s)
       s = DEFAULT_RISCV_ARCH_WITH_EXT;
     }
 
-  if (riscv_rps_as.subset_list == NULL)
+  unsigned int newxlen = xlen;
+  riscv_parse_subset_t newrps = {
+    .subset_list = XCNEW (riscv_subset_list_t),
+    .error_handler = as_bad,
+    .xlen = &newxlen,
+    .isa_spec = &default_isa_spec,
+    .check_unknown_prefixed_ext = true,
+  };
+
+  if (!riscv_parse_subset (&newrps, s))
     {
-      riscv_rps_as.subset_list = XNEW (riscv_subset_list_t);
-      riscv_rps_as.subset_list->head = NULL;
-      riscv_rps_as.subset_list->tail = NULL;
-      riscv_rps_as.subset_list->arch_str = NULL;
+      riscv_release_subset_list (newrps.subset_list);
+      if (file_arch_str != NULL)
+	{
+	  free (newrps.subset_list);
+	  return;
+	}
+      if (!riscv_parse_subset (&newrps, DEFAULT_RISCV_ARCH_WITH_EXT))
+	abort ();
     }
-  riscv_release_subset_list (riscv_rps_as.subset_list);
-  riscv_parse_subset (&riscv_rps_as, s);
+  xlen = newxlen;
+  if (riscv_rps_as.subset_list != NULL)
+    {
+      riscv_release_subset_list (riscv_rps_as.subset_list);
+      free (riscv_rps_as.subset_list);
+    }
+  riscv_rps_as.subset_list = newrps.subset_list;
+
   riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
   file_arch_str = xstrdup (riscv_rps_as.subset_list->arch_str);
 
-  riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "c")
-		 || riscv_subset_supports (&riscv_rps_as, "zca"));
+  riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "zca"));
 
   if (riscv_subset_supports (&riscv_rps_as, "ztso"))
     riscv_set_tso ();
@@ -5037,13 +5055,16 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
 
   if (strcmp (name, "rvc") == 0)
     {
-      riscv_update_subset (&riscv_rps_as, "+c");
-      riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
-      riscv_set_rvc (true);
+      if (riscv_update_subset (&riscv_rps_as, "+c"))
+	{
+	  riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
+	  riscv_set_rvc (true);
+	}
     }
   else if (strcmp (name, "norvc") == 0)
     {
-      riscv_update_subset_norvc (&riscv_rps_as);
+      if (!riscv_update_subset_norvc (&riscv_rps_as))
+	abort ();
       riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
       riscv_set_rvc (false);
     }
@@ -5064,14 +5085,15 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
       name += 5;
       if (is_whitespace (*name) && *name != '\0')
 	name++;
-      riscv_update_subset (&riscv_rps_as, name);
-      riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
+      if (riscv_update_subset (&riscv_rps_as, name))
+	{
+	  riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
 
-      riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "c")
-		     || riscv_subset_supports (&riscv_rps_as, "zca"));
+	  riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "zca"));
 
-      if (riscv_subset_supports (&riscv_rps_as, "ztso"))
-	riscv_set_tso ();
+	  if (riscv_subset_supports (&riscv_rps_as, "ztso"))
+	    riscv_set_tso ();
+	}
     }
   else if (strcmp (name, "push") == 0)
     {
diff --git a/gas/testsuite/gas/riscv/x-thead-vector-fail.d b/gas/testsuite/gas/riscv/x-thead-vector-fail.d
index 35231d983ff..dec068c13ff 100644
--- a/gas/testsuite/gas/riscv/x-thead-vector-fail.d
+++ b/gas/testsuite/gas/riscv/x-thead-vector-fail.d
@@ -1,3 +1,3 @@
 #as: -march=rv64gc_zve32x_xtheadvector
-#source: x-thead-vector.s
+#source: empty.s
 #error_output: x-thead-vector-fail.l
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.