[clang] [clang] do not abort on u8 string in inline asm (PR #177096)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 21 23:53:27 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 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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() {
More information about the cfe-commits
mailing list