[clang] [Clang] Diagnose nested inline asm variants (PR #232686)

Shray Jaiswal via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 16 04:10:43 PDT 2026


https://github.com/shrayjaiswal050-design created https://github.com/llvm/llvm-project/pull/232686

Fixes #232406

Clang currently accepts nested GCC inline-assembly dialect variants and
later crashes in the backend. Diagnose nested variants during Sema instead.

Testing:
- i686 and x86-64 Sema -verify tests
- Valid inline-asm output-variant codegen test
- Reduced Clang build: 572/572 targets
- Original reproducer now emits the diagnostic instead of crashing

>From 4d88efa98053905a3b26e89f596af6707a0216a4 Mon Sep 17 00:00:00 2001
From: shrayjaiswal050-design <shray.jaiswal050 at gmail.com>
Date: Fri, 16 Oct 2026 16:22:11 +0530
Subject: [PATCH 1/2] [Clang] Diagnose nested inline asm variants

---
 clang/include/clang/Basic/DiagnosticASTKinds.td |  2 ++
 clang/lib/AST/Stmt.cpp                          | 15 +++++++++++++--
 clang/test/Sema/inline-asm-validate-x86.c       |  4 ++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 48241ebe5c3dcb..d059835a636f5d 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -454,6 +454,8 @@ def err_invalid_is_within_lifetime : Note<
 let CategoryName = "Inline Assembly Issue" in {
   def err_asm_invalid_escape : Error<
     "invalid %% escape in inline assembly string">;
+  def err_asm_nested_variant : Error<
+    "nested variants found in inline assembly string">;
   def err_asm_unknown_symbolic_operand_name : Error<
     "unknown symbolic operand name in inline assembly string">;
 
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 15d0e6435aaf3a..51c9ea86725967 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -698,6 +698,7 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
   std::string CurStringPiece;
 
   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
+  bool InVariant = false;
 
   unsigned LastAsmStringToken = 0;
   unsigned LastAsmStringOffset = 0;
@@ -713,9 +714,19 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
     char CurChar = *CurPtr++;
     switch (CurChar) {
     case '$': CurStringPiece += "$$"; continue;
-    case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
+    case '{':
+      if (HasVariants && InVariant) {
+        DiagOffs = CurPtr - StrStart - 1;
+        return diag::err_asm_nested_variant;
+      }
+      CurStringPiece += (HasVariants ? "$(" : "{");
+      InVariant = HasVariants;
+      continue;
     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
-    case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
+    case '}':
+      CurStringPiece += (HasVariants ? "$)" : "}");
+      InVariant = false;
+      continue;
     case '%':
       break;
     default:
diff --git a/clang/test/Sema/inline-asm-validate-x86.c b/clang/test/Sema/inline-asm-validate-x86.c
index d4c10c36f5fbea..c44c534ff8fd1d 100644
--- a/clang/test/Sema/inline-asm-validate-x86.c
+++ b/clang/test/Sema/inline-asm-validate-x86.c
@@ -138,3 +138,7 @@ void test_W(int i) {
   // Codegen error
   __asm__("" : : "Ws"(i));
 }
+
+void test_nested_variants(long num) {
+  __asm__("{{movq $42, %0|}" : "=r"(num)); // expected-error{{nested variants found in inline assembly string}}
+}

>From 12580ad9e32ca23162ebdbb08586f23d209ff133 Mon Sep 17 00:00:00 2001
From: shrayjaiswal050-design <shray.jaiswal050 at gmail.com>
Date: Fri, 16 Oct 2026 16:22:11 +0530
Subject: [PATCH 2/2] [Clang] Diagnose nested inline asm variants

---
 clang/include/clang/Basic/DiagnosticASTKinds.td |  2 ++
 clang/lib/AST/Stmt.cpp                          | 15 +++++++++++++--
 clang/test/Sema/inline-asm-validate-x86.c       |  4 ++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 48241ebe5c3dcb..d059835a636f5d 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -454,6 +454,8 @@ def err_invalid_is_within_lifetime : Note<
 let CategoryName = "Inline Assembly Issue" in {
   def err_asm_invalid_escape : Error<
     "invalid %% escape in inline assembly string">;
+  def err_asm_nested_variant : Error<
+    "nested variants found in inline assembly string">;
   def err_asm_unknown_symbolic_operand_name : Error<
     "unknown symbolic operand name in inline assembly string">;
 
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 15d0e6435aaf3a..51c9ea86725967 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -698,6 +698,7 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
   std::string CurStringPiece;
 
   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
+  bool InVariant = false;
 
   unsigned LastAsmStringToken = 0;
   unsigned LastAsmStringOffset = 0;
@@ -713,9 +714,19 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
     char CurChar = *CurPtr++;
     switch (CurChar) {
     case '$': CurStringPiece += "$$"; continue;
-    case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
+    case '{':
+      if (HasVariants && InVariant) {
+        DiagOffs = CurPtr - StrStart - 1;
+        return diag::err_asm_nested_variant;
+      }
+      CurStringPiece += (HasVariants ? "$(" : "{");
+      InVariant = HasVariants;
+      continue;
     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
-    case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
+    case '}':
+      CurStringPiece += (HasVariants ? "$)" : "}");
+      InVariant = false;
+      continue;
     case '%':
       break;
     default:
diff --git a/clang/test/Sema/inline-asm-validate-x86.c b/clang/test/Sema/inline-asm-validate-x86.c
index d4c10c36f5fbea..c44c534ff8fd1d 100644
--- a/clang/test/Sema/inline-asm-validate-x86.c
+++ b/clang/test/Sema/inline-asm-validate-x86.c
@@ -138,3 +138,7 @@ void test_W(int i) {
   // Codegen error
   __asm__("" : : "Ws"(i));
 }
+
+void test_nested_variants(long num) {
+  __asm__("{{movq $42, %0|}" : "=r"(num)); // expected-error{{nested variants found in inline assembly string}}
+}



More information about the cfe-commits mailing list