diff mbox series

RISC-V: Properly parse the letter 'p' in '-march'.

Message ID 20210518031614.1808-1-gengqi@linux.alibaba.com
State New
Headers show
Series RISC-V: Properly parse the letter 'p' in '-march'. | expand

Commit Message

Geng Qi May 18, 2021, 3:16 a.m. UTC
gcc/ChangeLog:
	* common/config/riscv/riscv-common.c
	(riscv_subset_list::parsing_subset_version): Properly parse the letter
	'p' in '-march'.
	(riscv_subset_list::parse_std_ext,
	 riscv_subset_list::parse_multiletter_ext): To handle errors generated
	in riscv_subset_list::parsing_subset_version.

gcc/testsuite/ChangeLog:
	* gcc.target/riscv/arch-12.c: New.
	* gcc.target/riscv/attribute-19.c: New.
---
 gcc/common/config/riscv/riscv-common.c        | 67 ++++++++++++++-------------
 gcc/testsuite/gcc.target/riscv/arch-12.c      |  4 ++
 gcc/testsuite/gcc.target/riscv/attribute-19.c |  4 ++
 3 files changed, 42 insertions(+), 33 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-19.c

Comments

Kito Cheng May 19, 2021, 2:45 p.m. UTC | #1
Hi Geng:

Thanks for your patch, committed with minor tweaks for gcc_assert.

On Tue, May 18, 2021 at 2:31 PM Geng Qi via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> gcc/ChangeLog:
>         * common/config/riscv/riscv-common.c
>         (riscv_subset_list::parsing_subset_version): Properly parse the letter
>         'p' in '-march'.
>         (riscv_subset_list::parse_std_ext,
>          riscv_subset_list::parse_multiletter_ext): To handle errors generated
>         in riscv_subset_list::parsing_subset_version.
>
> gcc/testsuite/ChangeLog:
>         * gcc.target/riscv/arch-12.c: New.
>         * gcc.target/riscv/attribute-19.c: New.
> ---
>  gcc/common/config/riscv/riscv-common.c        | 67 ++++++++++++++-------------
>  gcc/testsuite/gcc.target/riscv/arch-12.c      |  4 ++
>  gcc/testsuite/gcc.target/riscv/attribute-19.c |  4 ++
>  3 files changed, 42 insertions(+), 33 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-19.c
>
> diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c
> index 34b74e5..65e5641 100644
> --- a/gcc/common/config/riscv/riscv-common.c
> +++ b/gcc/common/config/riscv/riscv-common.c
> @@ -518,40 +518,38 @@ riscv_subset_list::parsing_subset_version (const char *ext,
>    unsigned version = 0;
>    unsigned major = 0;
>    unsigned minor = 0;
> -  char np;
>    *explicit_version_p = false;
>
> -  for (; *p; ++p)
> -    {
> -      if (*p == 'p')
> -       {
> -         np = *(p + 1);
> -
> -         if (!ISDIGIT (np))
> -           {
> -             /* Might be beginning of `p` extension.  */
> -             if (std_ext_p)
> -               {
> -                 get_default_version (ext, major_version, minor_version);
> -                 return p;
> -               }
> -             else
> -               {
> -                 error_at (m_loc, "%<-march=%s%>: Expect number "
> -                           "after %<%dp%>.", m_arch, version);
> -                 return NULL;
> -               }
> -           }
> -
> -         major = version;
> -         major_p = false;
> -         version = 0;
> -       }
> -      else if (ISDIGIT (*p))
> -       version = (version * 10) + (*p - '0');
> -      else
> -       break;
> -    }
> +  if (*p == 'p')
> +    gcc_assert (std_ext_p);
> +  else {
> +    for (; *p; ++p)
> +      {
> +       if (*p == 'p')
> +         {
> +           if (!ISDIGIT (*(p+1)))
> +             {
> +               error_at (m_loc, "%<-march=%s%>: Expect number "
> +                         "after %<%dp%>.", m_arch, version);
> +               return NULL;
> +             }
> +           if (!major_p)
> +             {
> +               error_at (m_loc, "%<-march=%s%>: For %<%s%dp%dp?%>, version "
> +                         "number with more than 2 level is not supported.",
> +                         m_arch, ext, major, version);
> +               return NULL;
> +             }
> +           major = version;
> +           major_p = false;
> +           version = 0;
> +         }
> +       else if (ISDIGIT (*p))
> +         version = (version * 10) + (*p - '0');
> +       else
> +         break;
> +      }
> +  }
>
>    if (major_p)
>      major = version;
> @@ -643,7 +641,7 @@ riscv_subset_list::parse_std_ext (const char *p)
>        return NULL;
>      }
>
> -  while (*p)
> +  while (p != NULL && *p)
>      {
>        char subset[2] = {0, 0};
>
> @@ -771,6 +769,9 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
>                                   /* std_ext_p= */ false, &explicit_version_p);
>        free (ext);
>
> +      if (end_of_version == NULL)
> +       return NULL;
> +
>        *q = '\0';
>
>        if (strlen (subset) == 1)
> diff --git a/gcc/testsuite/gcc.target/riscv/arch-12.c b/gcc/testsuite/gcc.target/riscv/arch-12.c
> new file mode 100644
> index 0000000..29e16c3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/arch-12.c
> @@ -0,0 +1,4 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv64im1p2p3 -mabi=lp64" } */
> +int foo() {}
> +/* { dg-error "'-march=rv64im1p2p3': For 'm1p2p\\?', version number with more than 2 level is not supported." "" { target *-*-* } 0 } */
> diff --git a/gcc/testsuite/gcc.target/riscv/attribute-19.c b/gcc/testsuite/gcc.target/riscv/attribute-19.c
> new file mode 100644
> index 0000000..18f68d9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/attribute-19.c
> @@ -0,0 +1,4 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mriscv-attribute -march=rv64imp0p9 -mabi=lp64" } */
> +int foo() {}
> +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p0_m2p0_p0p9\"" } } */
> --
> 2.7.4
>
diff mbox series

Patch

diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c
index 34b74e5..65e5641 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -518,40 +518,38 @@  riscv_subset_list::parsing_subset_version (const char *ext,
   unsigned version = 0;
   unsigned major = 0;
   unsigned minor = 0;
-  char np;
   *explicit_version_p = false;
 
-  for (; *p; ++p)
-    {
-      if (*p == 'p')
-	{
-	  np = *(p + 1);
-
-	  if (!ISDIGIT (np))
-	    {
-	      /* Might be beginning of `p` extension.  */
-	      if (std_ext_p)
-		{
-		  get_default_version (ext, major_version, minor_version);
-		  return p;
-		}
-	      else
-		{
-		  error_at (m_loc, "%<-march=%s%>: Expect number "
-			    "after %<%dp%>.", m_arch, version);
-		  return NULL;
-		}
-	    }
-
-	  major = version;
-	  major_p = false;
-	  version = 0;
-	}
-      else if (ISDIGIT (*p))
-	version = (version * 10) + (*p - '0');
-      else
-	break;
-    }
+  if (*p == 'p')
+    gcc_assert (std_ext_p);
+  else {
+    for (; *p; ++p)
+      {
+	if (*p == 'p')
+	  {
+	    if (!ISDIGIT (*(p+1)))
+	      {
+		error_at (m_loc, "%<-march=%s%>: Expect number "
+			  "after %<%dp%>.", m_arch, version);
+		return NULL;
+	      }
+	    if (!major_p)
+	      {
+		error_at (m_loc, "%<-march=%s%>: For %<%s%dp%dp?%>, version "
+			  "number with more than 2 level is not supported.",
+			  m_arch, ext, major, version);
+		return NULL;
+	      }
+	    major = version;
+	    major_p = false;
+	    version = 0;
+	  }
+	else if (ISDIGIT (*p))
+	  version = (version * 10) + (*p - '0');
+	else
+	  break;
+      }
+  }
 
   if (major_p)
     major = version;
@@ -643,7 +641,7 @@  riscv_subset_list::parse_std_ext (const char *p)
       return NULL;
     }
 
-  while (*p)
+  while (p != NULL && *p)
     {
       char subset[2] = {0, 0};
 
@@ -771,6 +769,9 @@  riscv_subset_list::parse_multiletter_ext (const char *p,
 				  /* std_ext_p= */ false, &explicit_version_p);
       free (ext);
 
+      if (end_of_version == NULL)
+	return NULL;
+
       *q = '\0';
 
       if (strlen (subset) == 1)
diff --git a/gcc/testsuite/gcc.target/riscv/arch-12.c b/gcc/testsuite/gcc.target/riscv/arch-12.c
new file mode 100644
index 0000000..29e16c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-12.c
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64im1p2p3 -mabi=lp64" } */
+int foo() {}
+/* { dg-error "'-march=rv64im1p2p3': For 'm1p2p\\?', version number with more than 2 level is not supported." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-19.c b/gcc/testsuite/gcc.target/riscv/attribute-19.c
new file mode 100644
index 0000000..18f68d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-19.c
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mriscv-attribute -march=rv64imp0p9 -mabi=lp64" } */
+int foo() {}
+/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p0_m2p0_p0p9\"" } } */