diff options
author | Geng Qi <gengqi@linux.alibaba.com> | 2021-05-18 11:16:14 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2021-05-19 22:39:50 +0800 |
commit | 1e6648076498a4644aabbfe3ec74b3b2a5b67772 (patch) | |
tree | adb60c9607cae7c1b5c8c5b651a0e5224244beb8 /gcc/common | |
parent | 45364338209929542b14b805796f40b71a0fa960 (diff) | |
download | gcc-1e6648076498a4644aabbfe3ec74b3b2a5b67772.zip gcc-1e6648076498a4644aabbfe3ec74b3b2a5b67772.tar.gz gcc-1e6648076498a4644aabbfe3ec74b3b2a5b67772.tar.bz2 |
RISC-V: Properly parse the letter 'p' in '-march'.
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.
Diffstat (limited to 'gcc/common')
-rw-r--r-- | gcc/common/config/riscv/riscv-common.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c index d17bea6..10868fd4 100644 --- a/gcc/common/config/riscv/riscv-common.c +++ b/gcc/common/config/riscv/riscv-common.c @@ -518,40 +518,39 @@ 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 we got `p`, that means we are still parsing standard extension. */ + gcc_assert (std_ext_p || *p != 'p'); + + if (*p != 'p') { + 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 +642,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 +770,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) |