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

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 16 04:11:35 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Shray Jaiswal (shrayjaiswal050-design)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/232686.diff


3 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticASTKinds.td (+2) 
- (modified) clang/lib/AST/Stmt.cpp (+13-2) 
- (modified) clang/test/Sema/inline-asm-validate-x86.c (+4) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 48241ebe5c3dc..d059835a636f5 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 15d0e6435aaf3..51c9ea8672596 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 d4c10c36f5fbe..c44c534ff8fd1 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}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/232686


More information about the cfe-commits mailing list