https://github.com/tengwu created 
https://github.com/llvm/llvm-project/pull/206230

GCC supports tying an aggregate register output to a pointer input in cases 
such as an array operand after array-to-pointer decay. Clang currently accepts 
this, but codegen crashes when lowering the mismatched tied operands.

Add a Sema check for pointer inputs tied to larger aggregate register outputs 
when the aggregate can be scalarized to an integer register value. This turns 
the crash into an unsupported inline asm diagnostic.

Fixes #204775

From 57cfb356fd0eccdda85dd5c504308891e0ac7445 Mon Sep 17 00:00:00 2001
From: wt <[email protected]>
Date: Sat, 27 Jun 2026 07:59:18 +0000
Subject: [PATCH] [InlineAsm] Diagnose pointer input tied to larger aggregate
 output

GCC supports tying an aggregate register output to a pointer input in cases such
as an array operand after array-to-pointer decay. Clang currently accepts this,
but codegen crashes when lowering the mismatched tied operands.

Add a Sema check for pointer inputs tied to larger aggregate register outputs
when the aggregate can be scalarized to an integer register value. This turns 
the
crash into an unsupported inline asm diagnostic.

Fixes #204775
---
 clang/lib/Sema/SemaStmtAsm.cpp | 12 ++++++++++++
 clang/test/Sema/asm.c          |  3 +++
 2 files changed, 15 insertions(+)

diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 96d372c89d2b1..8b53697bd01f7 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -743,6 +743,18 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, 
bool IsSimple,
         return NS;
       }
 
+      // FIXME: GCC supports this, but codegen currently crashes when lowering
+      // a pointer input tied to a larger aggregate register output.
+      if (OutputDomain == AD_Other && InTy->isPointerType() &&
+          OutSize > InSize &&
+          !Context.getIntTypeForBitwidth(OutSize, /*Signed*/ false).isNull()) {
+        targetDiag(InputExpr->getBeginLoc(),
+                   diag::err_asm_tying_incompatible_types)
+            << InTy << OutTy << OutputExpr->getSourceRange()
+            << InputExpr->getSourceRange();
+        return NS;
+      }
+
       continue;
     }
 
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index a666b45b3150c..6d638be77dc9d 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -352,6 +352,7 @@ void test19(long long x)
   st_size16 c;
   st_size32 d;
   st_size128 e;
+  char f[16];
   asm ("" : "=rm" (a): "0" (1)); // no-error
   asm ("" : "=rm" (d): "0" (1)); // no-error
   asm ("" : "=rm" (c): "0" (x)); // no-error
@@ -364,6 +365,8 @@ void test19(long long x)
   asm ("" : "=rm" (e): "0" (1)); // no-error
   // FIXME: This case should be supported by codegen, but it fails now.
   asm ("" : "=rm" (x): "0" (e)); // expected-error {{unsupported inline asm: 
input with type 'st_size128' (aka 'struct _st_size128') matching output with 
type 'long long'}}
+  // FIXME: This case should be supported by codegen, but it fails now.
+  asm ("" : "=r" (f): "0" (f)); // expected-error {{unsupported inline asm: 
input with type 'char *' matching output with type 'char[16]'}}
 }
 
 typedef int int2 __attribute__((ext_vector_type(2)));

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to