[llvm] [llvm] Add format check for MCSubtargetFeatures (PR #180943)

Georgiy Samoylov via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 3 07:07:13 PST 2026


https://github.com/sga-sc updated https://github.com/llvm/llvm-project/pull/180943

>From e7175bace6032e7cf85f002a67a6191461db23cf Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <Ignitor21838 at gmail.com>
Date: Wed, 11 Feb 2026 16:50:34 +0300
Subject: [PATCH 1/2] [MC] Add format check for MCSubtargetFeatures

---
 llvm/include/llvm/MC/TargetRegistry.h | 6 ++++++
 llvm/lib/MC/TargetRegistry.cpp        | 9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 4451dfa72a5f4..ae4774cbc045f 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -452,6 +452,8 @@ class Target {
                                          StringRef Features) const {
     if (!MCSubtargetInfoCtorFn)
       return nullptr;
+    if (!isValidFeatureListFormat(Features))
+      return nullptr;
     return MCSubtargetInfoCtorFn(TheTriple, CPU, Features);
   }
 
@@ -630,6 +632,10 @@ class Target {
     return nullptr;
   }
 
+  /// isValidFeatureListFormat - check that FeatureString
+  /// has valid format.
+  static bool isValidFeatureListFormat(StringRef FeaturesString);
+
   /// @}
 };
 
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index 9263dda65a8b0..cc0218a5a7cca 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -15,6 +15,7 @@
 #include "llvm/MC/MCInstPrinter.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>
@@ -23,6 +24,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,

>From c1eeb5e1e1c409ea5202ecf098c04473cfa74a45 Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <Ignitor21838 at gmail.com>
Date: Wed, 25 Feb 2026 13:39:19 +0300
Subject: [PATCH 2/2] [MC][unittest] Add unit-test for feature list format

---
 llvm/unittests/MC/TargetRegistry.cpp | 43 ++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/llvm/unittests/MC/TargetRegistry.cpp b/llvm/unittests/MC/TargetRegistry.cpp
index cc464b7681ce1..adeefb2ff6058 100644
--- a/llvm/unittests/MC/TargetRegistry.cpp
+++ b/llvm/unittests/MC/TargetRegistry.cpp
@@ -42,4 +42,47 @@ 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"));
+
+  // 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("-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