https://github.com/el-ev created https://github.com/llvm/llvm-project/pull/196462
As suggested by @jmorse and @efriedma-quic in #196223. >From bdf2a67e1040548b95393bac50aed1578a072fbd Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Fri, 8 May 2026 10:45:03 +0800 Subject: [PATCH] [clang][diagnostics] Reject embedded NUL characters in inline asm constraints and clobbers --- clang/docs/ReleaseNotes.rst | 3 +++ .../include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/SemaStmtAsm.cpp | 18 ++++++++++++++++++ .../inline-asm-constraint-embedded-null.c | 8 -------- .../Sema/inline-asm-constraint-embedded-null.c | 16 ++++++++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-) delete mode 100644 clang/test/CodeGen/inline-asm-constraint-embedded-null.c create mode 100644 clang/test/Sema/inline-asm-constraint-embedded-null.c 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}} +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
