aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Cook <simon.cook@embecosm.com>2020-07-15 09:23:35 +0100
committerSimon Cook <simon.cook@embecosm.com>2020-07-15 09:23:35 +0100
commitde7bf722c23a1ab006bd306165c094669071577f (patch)
treede424abba4d80610980bcdddb141120f36c98bb0
parent14bc5e149d11766dee21cd679a9794fdf2e9414e (diff)
downloadllvm-de7bf722c23a1ab006bd306165c094669071577f.zip
llvm-de7bf722c23a1ab006bd306165c094669071577f.tar.gz
llvm-de7bf722c23a1ab006bd306165c094669071577f.tar.bz2
[RISCV] Add error checking for extensions missing separating underscores
Currently if two multi-letter extensions are provided in a -march= string, the verification code checks the version of the first and consumes the second, resulting in that part of the architecture string being ignored. This adds a test that when a version number has been parsed for an extension, there are no subsequent characters. Differential Revision: https://reviews.llvm.org/D83819
-rw-r--r--clang/lib/Driver/ToolChains/Arch/RISCV.cpp12
-rw-r--r--clang/test/Driver/riscv-arch.c4
2 files changed, 15 insertions, 1 deletions
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 8659ebf..80d12e5 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -89,7 +89,7 @@ static bool getExtensionVersion(const Driver &D, const ArgList &Args,
if (Major.size() && In.consume_front("p")) {
Minor = std::string(In.take_while(isDigit));
- In = In.substr(Major.size());
+ In = In.substr(Major.size() + 1);
// Expected 'p' to be followed by minor version number.
if (Minor.empty()) {
@@ -101,6 +101,16 @@ static bool getExtensionVersion(const Driver &D, const ArgList &Args,
}
}
+ // Expected multi-character extension with version number to have no
+ // subsequent characters (i.e. must either end string or be followed by
+ // an underscore).
+ if (Ext.size() > 1 && In.size()) {
+ std::string Error =
+ "multi-character extensions must be separated by underscores";
+ D.Diag(diag::err_drv_invalid_riscv_ext_arch_name) << MArch << Error << In;
+ return false;
+ }
+
// If experimental extension, require use of current version number number
if (auto ExperimentalExtension = isExperimentalExtension(Ext)) {
if (!Args.hasArg(options::OPT_menable_experimental_extensions)) {
diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c
index e3062fe..13d0748 100644
--- a/clang/test/Driver/riscv-arch.c
+++ b/clang/test/Driver/riscv-arch.c
@@ -361,6 +361,10 @@
// RV32-EXPERIMENTAL-ZBB-ZBP: "-target-feature" "+experimental-zbb"
// RV32-EXPERIMENTAL-ZBB-ZBP: "-target-feature" "+experimental-zbp"
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbb0p92zbp0p92 -menable-experimental-extensions -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE %s
+// RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE: error: invalid arch name 'rv32izbb0p92zbp0p92', multi-character extensions must be separated by underscores
+
// RUN: %clang -target riscv32-unknown-elf -march=rv32iv -### %s -c 2>&1 | \
// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V-NOFLAG %s
// RV32-EXPERIMENTAL-V-NOFLAG: error: invalid arch name 'rv32iv'