summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@sifive.com>2024-05-03 09:29:11 -0700
committerGitHub <noreply@github.com>2024-05-03 09:29:11 -0700
commit7a6847e00142e72f09d7dbaa512425871ba7134f (patch)
tree089a9784f235ff8fe206116ec5a5d2770f57402f
parent55ad294893093b3918b3467ac44404cbd643b6ba (diff)
[RISCV] Add partial validation of Z extension name to RISCVISAInfo::parseNormalizedArchString (#90895)
If 'z' is given as the complete extension name or with a digit after it, it will crash in the extension map compare function. Check for these cases and give an error.
-rw-r--r--llvm/lib/Support/RISCVISAUtils.cpp3
-rw-r--r--llvm/lib/TargetParser/RISCVISAInfo.cpp5
-rw-r--r--llvm/unittests/TargetParser/RISCVISAInfoTest.cpp10
3 files changed, 16 insertions, 2 deletions
diff --git a/llvm/lib/Support/RISCVISAUtils.cpp b/llvm/lib/Support/RISCVISAUtils.cpp
index ca7518f71907..46efe9369507 100644
--- a/llvm/lib/Support/RISCVISAUtils.cpp
+++ b/llvm/lib/Support/RISCVISAUtils.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/RISCVISAUtils.h"
+#include "llvm/ADT/StringExtras.h"
#include <cassert>
using namespace llvm;
@@ -35,7 +36,7 @@ enum RankFlags {
// Get the rank for single-letter extension, lower value meaning higher
// priority.
static unsigned singleLetterExtensionRank(char Ext) {
- assert(Ext >= 'a' && Ext <= 'z');
+ assert(isLower(Ext));
switch (Ext) {
case 'i':
return 0;
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index c1d50afee09b..d244326537fa 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -485,6 +485,11 @@ RISCVISAInfo::parseNormalizedArchString(StringRef Arch) {
if (MajorVersionStr.getAsInteger(10, MajorVersion))
return createStringError(errc::invalid_argument,
"failed to parse major version number");
+
+ if (ExtName[0] == 'z' && (ExtName.size() == 1 || isDigit(ExtName[1])))
+ return createStringError(errc::invalid_argument,
+ "'z' must be followed by a letter");
+
ISAInfo->addExtension(ExtName, {MajorVersion, MinorVersion});
}
ISAInfo->updateImpliedLengths();
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index ec886bad4f67..eb8eab736869 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -46,7 +46,7 @@ TEST(ParseNormalizedArchString, RejectsMalformedInputs) {
}
}
-TEST(ParseNormalizedArchString, OnlyVersion) {
+TEST(ParseNormalizedArchString, RejectsOnlyVersion) {
for (StringRef Input : {"rv64i2p0_1p0", "rv32i2p0_1p0"}) {
EXPECT_EQ(
toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
@@ -54,6 +54,14 @@ TEST(ParseNormalizedArchString, OnlyVersion) {
}
}
+TEST(ParseNormalizedArchString, RejectsBadZ) {
+ for (StringRef Input : {"rv64i2p0_z1p0", "rv32i2p0_z2a1p0"}) {
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
+ "'z' must be followed by a letter");
+ }
+}
+
TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) {
auto MaybeRV32I = RISCVISAInfo::parseNormalizedArchString("rv32i2p0");
ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());