Skip to content

[clang][diagnostics] Reject embedded NUL characters in inline asm#196462

Open
el-ev wants to merge 4 commits into
users/el-ev/fix-173900from
users/el-ev/invalid_nul_constraint_diag
Open

[clang][diagnostics] Reject embedded NUL characters in inline asm#196462
el-ev wants to merge 4 commits into
users/el-ev/fix-173900from
users/el-ev/invalid_nul_constraint_diag

Conversation

@el-ev
Copy link
Copy Markdown
Member

@el-ev el-ev commented May 8, 2026

As suggested by @jmorse and @efriedma-quic in #196223.

@llvmorg-github-actions llvmorg-github-actions Bot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 8, 2026
@llvmorg-github-actions
Copy link
Copy Markdown

@llvm/pr-subscribers-clang

Author: Iris Shi (el-ev)

Changes

As suggested by @jmorse and @efriedma-quic in #196223.


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

5 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+3)
  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+18)
  • (removed) clang/test/CodeGen/inline-asm-constraint-embedded-null.c (-8)
  • (added) clang/test/Sema/inline-asm-constraint-embedded-null.c (+16)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cb19b80b7e994..51e98aef4d251 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -479,6 +479,9 @@ Improvements to Clang's diagnostics
 
 - Removed the body of lambdas from some diagnostic messages.
 
+- Clang now rejects inline asm constraints and clobbers that contain an
+  embedded null character, instead of silently truncating them. (#GH173900)
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c69b2ce3648f8..c30ddf445ed65 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10074,6 +10074,9 @@ let CategoryName = "Inline Assembly Issue" in {
     "invalid lvalue in asm input for constraint '%0'">;
   def err_asm_invalid_input_constraint : Error<
     "invalid input constraint '%0' in asm">;
+  def err_asm_constraint_embedded_null : Error<
+    "%select{output constraint|input constraint|clobber}0 contains "
+    "embedded null character">;
   def err_asm_tying_incompatible_types : Error<
     "unsupported inline asm: input with type "
     "%diff{$ matching output with type $|}0,1">;
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index f957bdf7156c7..f80c1a5b65f93 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -306,6 +306,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
     std::string ConstraintStr =
         GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint);
 
+    if (ConstraintStr.find('\0') != std::string::npos) {
+      Diag(Constraint->getBeginLoc(), diag::err_asm_constraint_embedded_null)
+          << /*output*/0;
+      return CreateGCCAsmStmt();
+    }
+
     TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
     if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
         !(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
@@ -396,6 +402,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
     std::string ConstraintStr =
         GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint);
 
+    if (ConstraintStr.find('\0') != std::string::npos) {
+      Diag(Constraint->getBeginLoc(), diag::err_asm_constraint_embedded_null)
+          << /*input*/1;
+      return CreateGCCAsmStmt();
+    }
+
     TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
     if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
                                                          Info)) {
@@ -503,6 +515,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
     std::string Clobber =
         GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
 
+    if (Clobber.find('\0') != std::string::npos) {
+      Diag(ClobberExpr->getBeginLoc(), diag::err_asm_constraint_embedded_null)
+          << /*clobber*/2;
+      return CreateGCCAsmStmt();
+    }
+
     if (!Context.getTargetInfo().isValidClobber(Clobber)) {
       targetDiag(ClobberExpr->getBeginLoc(),
                  diag::err_asm_unknown_register_name)
diff --git a/clang/test/CodeGen/inline-asm-constraint-embedded-null.c b/clang/test/CodeGen/inline-asm-constraint-embedded-null.c
deleted file mode 100644
index c2cd3ace0ddd3..0000000000000
--- a/clang/test/CodeGen/inline-asm-constraint-embedded-null.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// REQUIRES: x86-registered-target
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
-
-// Regression test for issue173900.
-
-// CHECK-LABEL: define {{.*}}void @f(
-// CHECK: call void asm sideeffect "", "f,{{[^"]*}}"(double 0.000000e+00)
-void f(void) { __asm__("" : : "f\0001"(0.0)); }
diff --git a/clang/test/Sema/inline-asm-constraint-embedded-null.c b/clang/test/Sema/inline-asm-constraint-embedded-null.c
new file mode 100644
index 0000000000000..e8587e469ba85
--- /dev/null
+++ b/clang/test/Sema/inline-asm-constraint-embedded-null.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s
+
+// Regression test for issue173900.
+
+void test_input(void) {
+  __asm__("" : : "f\0001"(0.0)); // expected-error {{input constraint contains embedded null character}}
+}
+
+void test_output(void) {
+  double x;
+  __asm__("" : "=r\0"(x)); // expected-error {{output constraint contains embedded null character}}
+}
+
+void test_clobber(void) {
+  __asm__("" : : : "rax\0"); // expected-error {{clobber contains embedded null character}}
+}

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@el-ev el-ev force-pushed the users/el-ev/invalid_nul_constraint_diag branch from bdf2a67 to fd83d89 Compare May 8, 2026 02:50
Comment thread clang/include/clang/Basic/DiagnosticSemaKinds.td Outdated
el-ev and others added 2 commits May 8, 2026 16:21
Co-authored-by: Corentin Jabot <corentinjabot@gmail.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

🐧 Linux x64 Test Results

  • 116031 tests passed
  • 4688 tests skipped

✅ The build succeeded and all tests passed.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

🪟 Windows x64 Test Results

  • 55484 tests passed
  • 2526 tests skipped

✅ The build succeeded and all tests passed.

Copy link
Copy Markdown
Member

@jmorse jmorse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for refining this into a diagnostic, I feel it's a much more complete solution. In principle this looks good to me, but it's a lot further into clang than I usually venture, so I'd much prefer someone else tick the approve button.

Copy link
Copy Markdown
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants