[llvm] 2c67f2f - [llvm] Add format check for MCSubtargetFeatures (#180943)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 07:17:47 PDT 2026
Author: Georgiy Samoylov
Date: 2026-04-16T17:17:41+03:00
New Revision: 2c67f2fdfc41afd9acfe28e3cb42850a97f1db54
URL: https://github.com/llvm/llvm-project/commit/2c67f2fdfc41afd9acfe28e3cb42850a97f1db54
DIFF: https://github.com/llvm/llvm-project/commit/2c67f2fdfc41afd9acfe28e3cb42850a97f1db54.diff
LOG: [llvm] Add format check for MCSubtargetFeatures (#180943)
`SubtargetFeatures` class has next constraints:
https://github.com/llvm/llvm-project/blob/c9d065abc15846deb95a23fb0b3e1855d3d26314/llvm/include/llvm/TargetParser/SubtargetFeature.h#L167-L174
At this moment feature string isn't checked for fitting in such format.
This leads to assertion failure, for example in lldb:
https://github.com/llvm/llvm-project/pull/180901, when features from
user's input don't meet the requirements.
With implementing additional format check we can avoid such problems.
Added:
Modified:
llvm/include/llvm/MC/TargetRegistry.h
llvm/lib/MC/TargetRegistry.cpp
llvm/unittests/MC/TargetRegistry.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 5594ede0aa5c1..6b45274f9dc95 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -466,6 +466,8 @@ class Target {
StringRef Features) const {
if (!MCSubtargetInfoCtorFn)
return nullptr;
+ if (!isValidFeatureListFormat(Features))
+ return nullptr;
return MCSubtargetInfoCtorFn(TheTriple, CPU, Features);
}
@@ -652,6 +654,20 @@ class Target {
return nullptr;
}
+ /// isValidFeatureListFormat - check that FeatureString
+ /// has the format:
+ /// "+attr1,+attr2,-attr3,...,+attrN"
+ /// A comma separates each feature from the next (all lowercase).
+ /// Each of the remaining features is prefixed with '+' or '-' indicating
+ /// whether that feature should be enabled or disabled contrary to the cpu
+ /// specification.
+ /// The string must match exactly that format otherwise
+ /// MCSubtargetInfo::ApplyFeatureFlag will fail.
+ /// For example feature string "+a,+m,c" is accepted, and results in feature
+ /// list {"+a", "+m", "c"}. Later in ApplyFeatureFlag, it asserts
+ /// that all features must start with '+' or '-' and assert is failed.
+ static bool isValidFeatureListFormat(StringRef FeaturesString);
+
/// @}
};
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index db743ef9bdcb6..948fb5034f726 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCLFI.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <vector>
@@ -24,6 +25,14 @@ using namespace llvm;
// Clients are responsible for avoid race conditions in registration.
static Target *FirstTarget = nullptr;
+bool Target::isValidFeatureListFormat(StringRef Features) {
+ if (Features.empty())
+ return true;
+
+ static const llvm::Regex pattern("^([+-][^,]+)(,[+-][^,]+)*,?$");
+ return pattern.match(Features);
+}
+
MCStreamer *Target::createMCObjectStreamer(
const Triple &T, MCContext &Ctx, std::unique_ptr<MCAsmBackend> TAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
diff --git a/llvm/unittests/MC/TargetRegistry.cpp b/llvm/unittests/MC/TargetRegistry.cpp
index cc464b7681ce1..f06072d4d9647 100644
--- a/llvm/unittests/MC/TargetRegistry.cpp
+++ b/llvm/unittests/MC/TargetRegistry.cpp
@@ -42,4 +42,51 @@ TEST(TargetRegistry, TargetHasArchType) {
ASSERT_NE(Count, 0);
}
+TEST(TargetRegistry, IsValidFeatureListFormat) {
+ // Valid strings
+
+ // Empty string is a valid feature string
+ EXPECT_TRUE(Target::isValidFeatureListFormat(""));
+
+ EXPECT_TRUE(Target::isValidFeatureListFormat("+some_feature"));
+ EXPECT_TRUE(Target::isValidFeatureListFormat("-some_feature"));
+ EXPECT_TRUE(
+ Target::isValidFeatureListFormat("+feature1,-feature2,+feature3"));
+ EXPECT_TRUE(Target::isValidFeatureListFormat("+123"));
+
+ // Strings with single trailing comma are also valid
+ EXPECT_TRUE(Target::isValidFeatureListFormat("-feature,"));
+ EXPECT_TRUE(
+ Target::isValidFeatureListFormat("-feature1,+feature2,+feature3,"));
+
+ // Invalid strings
+
+ // Feature don't start with '+' or '-'
+ EXPECT_FALSE(Target::isValidFeatureListFormat("invalid_string"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat("+good,bad"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat("bad,+good"));
+
+ // String has spaces
+ EXPECT_FALSE(Target::isValidFeatureListFormat(" "));
+ EXPECT_FALSE(Target::isValidFeatureListFormat(", "));
+ EXPECT_FALSE(Target::isValidFeatureListFormat(" avx"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat("+avx, -sse"));
+
+ // Redundant commas
+ EXPECT_FALSE(Target::isValidFeatureListFormat("+feature1,,+feature2"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat(",+feature"));
+ EXPECT_FALSE(
+ Target::isValidFeatureListFormat("+feature1,,,+feature2,,+feature3"));
+
+ // Feature consists only of '+' or '-'
+ EXPECT_FALSE(Target::isValidFeatureListFormat("+"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat("-"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat("+avx,-"));
+
+ // Only commas
+ EXPECT_FALSE(Target::isValidFeatureListFormat(","));
+ EXPECT_FALSE(Target::isValidFeatureListFormat(",,"));
+ EXPECT_FALSE(Target::isValidFeatureListFormat(",,,"));
+}
+
} // end namespace
More information about the llvm-commits
mailing list