[clang] [clang] do not abort on u8 string in inline asm (PR #177096)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 22 01:19:57 PST 2026
https://github.com/nataliakokoromyti updated https://github.com/llvm/llvm-project/pull/177096
>From 989b9b695193cf5e48f5676edbb262acc5b4378f Mon Sep 17 00:00:00 2001
From: Natalia Kokoromyti <knatalia at yost-cm-01-imme.stanford.edu>
Date: Tue, 20 Jan 2026 19:38:52 -0800
Subject: [PATCH 01/11] fix crash on u8 string
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++
clang/lib/Sema/SemaStmtAsm.cpp | 5 ++++-
clang/test/Sema/asm-no-crash-non-ordinary-string.cpp | 7 +++++++
3 files changed, 15 insertions(+), 1 deletion(-)
create mode 100644 clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 44541a4c68197..935e896653fda 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9906,6 +9906,10 @@ let CategoryName = "Inline Assembly Issue" in {
def err_asm_operand_empty_string : Error<
"cannot use an empty string literal in 'asm'">;
+ def err_asm_string_literal_not_ordinary : Error<
+ "cannot use unicode string literal in 'asm'">;
+
+
def err_asm_pmf_through_constraint_not_permitted
: Error<"cannot pass a pointer-to-member through register-constrained "
"inline assembly parameter">;
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index f957bdf7156c7..8f39872fb5b3e 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -240,7 +240,10 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
return ExprError();
if (auto *SL = dyn_cast<StringLiteral>(Expr)) {
- assert(SL->isOrdinary());
+ if (!SL->isOrdinary()) {
+ Diag(SL->getBeginLoc(), diag::err_asm_string_literal_not_ordinary);
+ return ExprError();
+ }
if (ForAsmLabel && SL->getString().empty()) {
Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string)
<< SL->getSourceRange();
diff --git a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
new file mode 100644
index 0000000000000..42a2f30db9138
--- /dev/null
+++ b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 -fsyntax-only -verify %s
+
+void foo() {
+ asm("" ::: (u8""}));
+ // expected-error at -1 {{cannot use unicode string literal in 'asm'}}
+ // expected-error at -2 {{expected ')'}}
+}
>From a5def4857a329357999520b37efd4fd55fe9ec1c Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 20:15:34 -0800
Subject: [PATCH 02/11] address feedback
---
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/Basic/DiagnosticCommonKinds.td | 3 +++
clang/include/clang/Basic/DiagnosticParseKinds.td | 2 --
clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ---
clang/lib/Sema/SemaStmtAsm.cpp | 2 +-
clang/test/Sema/asm-no-crash-non-ordinary-string.cpp | 11 ++++++++++-
6 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 611e3fba2bc2b..83cdcf685a31e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -127,6 +127,7 @@ Improvements to Coverage Mapping
Bug Fixes in This Version
-------------------------
+- Fixed a crash when using non-ordinary string literals (``u8""``, ``L""``, ``u""``, ``U""``) in inline assembly. Clang now properly diagnoses these as errors. (#GH177056)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 6e50e225a8cc1..fd1fe4979508a 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -305,6 +305,9 @@ def err_asm_invalid_type_in_input : Error<
def err_asm_invalid_type : Error<
"invalid type %0 in asm %select{input|output}1">;
+def err_asm_operand_wide_string_literal : Error<
+ "cannot use %select{unicode|wide}0 string literal in 'asm'">;
+
def err_ms_asm_bitfield_unsupported : Error<
"an inline asm block cannot have an operand which is a bit-field">;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 457d3644de35a..ecb3aa9b8ab25 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -348,8 +348,6 @@ def warn_cxx20_compat_label_end_of_compound_statement : Warning<
InGroup<CXXPre23Compat>, DefaultIgnore;
def err_address_of_label_outside_fn : Error<
"use of address-of-label extension outside of a function body">;
-def err_asm_operand_wide_string_literal : Error<
- "cannot use %select{unicode|wide}0 string literal in 'asm'">;
def err_defer_ts_labeled_stmt : Error<
"substatement of defer must not be a label">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 935e896653fda..b6d0d51e268fe 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9906,9 +9906,6 @@ let CategoryName = "Inline Assembly Issue" in {
def err_asm_operand_empty_string : Error<
"cannot use an empty string literal in 'asm'">;
- def err_asm_string_literal_not_ordinary : Error<
- "cannot use unicode string literal in 'asm'">;
-
def err_asm_pmf_through_constraint_not_permitted
: Error<"cannot pass a pointer-to-member through register-constrained "
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 8f39872fb5b3e..34ec64c33aab9 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -241,7 +241,7 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
if (auto *SL = dyn_cast<StringLiteral>(Expr)) {
if (!SL->isOrdinary()) {
- Diag(SL->getBeginLoc(), diag::err_asm_string_literal_not_ordinary);
+ Diag(SL->getBeginLoc(), diag::err_asm_operand_wide_string_literal << (SL->isWide() ? 1 : 0));
return ExprError();
}
if (ForAsmLabel && SL->getString().empty()) {
diff --git a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
index 42a2f30db9138..996464526064d 100644
--- a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
+++ b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
@@ -1,7 +1,16 @@
-// RUN: not %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
void foo() {
asm("" ::: (u8""}));
// expected-error at -1 {{cannot use unicode string literal in 'asm'}}
// expected-error at -2 {{expected ')'}}
}
+
+void test_other_literals() {
+ asm(L""); // expected-error {{cannot use wide string literal in 'asm'}}
+ asm(u""); // expected-error {{cannot use unicode string literal in 'asm'}}
+ asm(U""); // expected-error {{cannot use unicode string literal in 'asm'}}
+
+ // Raw string literals should be accepted (they're still ordinary strings)
+ asm(R"(nop)");
+}
>From 6300cef442d71d885ef0d4aade5f68c17c7dfd76 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 20:26:50 -0800
Subject: [PATCH 03/11] fix format
---
clang/lib/Sema/SemaStmtAsm.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 34ec64c33aab9..f7502eb108f53 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -241,7 +241,8 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
if (auto *SL = dyn_cast<StringLiteral>(Expr)) {
if (!SL->isOrdinary()) {
- Diag(SL->getBeginLoc(), diag::err_asm_operand_wide_string_literal << (SL->isWide() ? 1 : 0));
+ Diag(SL->getBeginLoc(),
+ diag::err_asm_operand_wide_string_literal << (SL->isWide() ? 1 : 0));
return ExprError();
}
if (ForAsmLabel && SL->getString().empty()) {
>From b2446468c707060be9513e8e8dfc8f52e7131383 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 20:27:32 -0800
Subject: [PATCH 04/11] rm line
Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva at intel.com>
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b6d0d51e268fe..44541a4c68197 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9906,7 +9906,6 @@ let CategoryName = "Inline Assembly Issue" in {
def err_asm_operand_empty_string : Error<
"cannot use an empty string literal in 'asm'">;
-
def err_asm_pmf_through_constraint_not_permitted
: Error<"cannot pass a pointer-to-member through register-constrained "
"inline assembly parameter">;
>From de8fdcacd5f72e7a4e33eefe1a567cd82fafc0c1 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 20:39:04 -0800
Subject: [PATCH 05/11] rm whitespace
---
clang/lib/Sema/SemaStmtAsm.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index f7502eb108f53..c4876c4db48c8 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -241,7 +241,7 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
if (auto *SL = dyn_cast<StringLiteral>(Expr)) {
if (!SL->isOrdinary()) {
- Diag(SL->getBeginLoc(),
+ Diag(SL->getBeginLoc(),
diag::err_asm_operand_wide_string_literal << (SL->isWide() ? 1 : 0));
return ExprError();
}
>From 5f65626d667185c71b4479e4feec7ab4a5b53c50 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 23:25:06 -0800
Subject: [PATCH 06/11] fix call to match parser expectation
---
clang/lib/Sema/SemaStmtAsm.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index c4876c4db48c8..15d81e7547971 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -241,8 +241,8 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
if (auto *SL = dyn_cast<StringLiteral>(Expr)) {
if (!SL->isOrdinary()) {
- Diag(SL->getBeginLoc(),
- diag::err_asm_operand_wide_string_literal << (SL->isWide() ? 1 : 0));
+ Diag(SL->getBeginLoc(), diag::err_asm_operand_wide_string_literal)
+ << SL->isWide() << SL->getSourceRange();
return ExprError();
}
if (ForAsmLabel && SL->getString().empty()) {
>From 422b0b4f974f532e380a2337712490cdb09ff405 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 23:36:42 -0800
Subject: [PATCH 07/11] fix test to expect all parser errors
---
clang/test/Sema/asm-no-crash-non-ordinary-string.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
index 996464526064d..d589d8cafca4b 100644
--- a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
+++ b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
@@ -4,6 +4,8 @@ void foo() {
asm("" ::: (u8""}));
// expected-error at -1 {{cannot use unicode string literal in 'asm'}}
// expected-error at -2 {{expected ')'}}
+ // expected-note at -3 {{to match this '('}}
+ // expected-error at -4 {{expected expression}}
}
void test_other_literals() {
>From c59118b636f7a873acce566ad63a033480d6e7bc Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Wed, 21 Jan 2026 23:53:13 -0800
Subject: [PATCH 08/11] put all errors on same line
---
clang/test/Sema/asm-no-crash-non-ordinary-string.cpp | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
index d589d8cafca4b..3e9bdae83df9c 100644
--- a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
+++ b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
@@ -1,11 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
void foo() {
- asm("" ::: (u8""}));
- // expected-error at -1 {{cannot use unicode string literal in 'asm'}}
- // expected-error at -2 {{expected ')'}}
- // expected-note at -3 {{to match this '('}}
- // expected-error at -4 {{expected expression}}
+ asm("" ::: (u8"")); // expected-error {{cannot use unicode string literal in 'asm'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
}
void test_other_literals() {
>From 12b040565135349378398ed3b6e3a8ab5b2bee6d Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Thu, 22 Jan 2026 00:17:13 -0800
Subject: [PATCH 09/11] fix test to expect correct error message for
parenthesized case
---
clang/test/Sema/asm-no-crash-non-ordinary-string.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
index 3e9bdae83df9c..884def5785363 100644
--- a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
+++ b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
@@ -1,13 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
void foo() {
- asm("" ::: (u8"")); // expected-error {{cannot use unicode string literal in 'asm'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ // Test the crash case from GH177056 - this specific syntax triggered the assert
+ asm("" ::: (u8"")); // expected-error {{the expression in this asm operand must be a string literal or an object with 'data()' and 'size()' member functions}}
}
void test_other_literals() {
asm(L""); // expected-error {{cannot use wide string literal in 'asm'}}
asm(u""); // expected-error {{cannot use unicode string literal in 'asm'}}
asm(U""); // expected-error {{cannot use unicode string literal in 'asm'}}
+ asm(u8""); // expected-error {{cannot use unicode string literal in 'asm'}}
// Raw string literals should be accepted (they're still ordinary strings)
asm(R"(nop)");
>From f5c53f0d429021ef701fd14c5746e84d2054b03d Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Thu, 22 Jan 2026 01:01:22 -0800
Subject: [PATCH 10/11] integrate test to existing asm.c file
---
.../Sema/asm-no-crash-non-ordinary-string.cpp | 16 ----------------
clang/test/Sema/asm.c | 4 ++++
2 files changed, 4 insertions(+), 16 deletions(-)
delete mode 100644 clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
diff --git a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp b/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
deleted file mode 100644
index 884def5785363..0000000000000
--- a/clang/test/Sema/asm-no-crash-non-ordinary-string.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-void foo() {
- // Test the crash case from GH177056 - this specific syntax triggered the assert
- asm("" ::: (u8"")); // expected-error {{the expression in this asm operand must be a string literal or an object with 'data()' and 'size()' member functions}}
-}
-
-void test_other_literals() {
- asm(L""); // expected-error {{cannot use wide string literal in 'asm'}}
- asm(u""); // expected-error {{cannot use unicode string literal in 'asm'}}
- asm(U""); // expected-error {{cannot use unicode string literal in 'asm'}}
- asm(u8""); // expected-error {{cannot use unicode string literal in 'asm'}}
-
- // Raw string literals should be accepted (they're still ordinary strings)
- asm(R"(nop)");
-}
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index a666b45b3150c..5340f8265c4d1 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -43,6 +43,10 @@ void test3(void) {
int x;
asm(L"foo" : "=r"(x)); // expected-error {{wide string}}
asm("foo" : L"=r"(x)); // expected-error {{wide string}}
+
+ // GH177056
+ asm("" ::: (u8"")); // expected-error {{the expression in this asm operand must be a string literal or an object with 'data()' and 'size()' member functions}}
+ asm(R"(nop)");
}
void test4(const volatile void *addr)
>From f62dd5b594da938f275b997cff17589b1b1b7b0c Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Thu, 22 Jan 2026 01:19:42 -0800
Subject: [PATCH 11/11] fix error message
---
clang/test/Sema/asm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index 5340f8265c4d1..b6c64777166fc 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -45,7 +45,7 @@ void test3(void) {
asm("foo" : L"=r"(x)); // expected-error {{wide string}}
// GH177056
- asm("" ::: (u8"")); // expected-error {{the expression in this asm operand must be a string literal or an object with 'data()' and 'size()' member functions}}
+ asm("" ::: (u8"")); // expected-error {{expected string literal in 'asm'}} expected-error {{expected ')'}}
asm(R"(nop)");
}
More information about the cfe-commits
mailing list