https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/204658
>From 58cdbf46ffa1c44098c7be03a87fafe308f56643 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant <[email protected]> Date: Thu, 25 Jun 2026 20:36:36 +0200 Subject: [PATCH 1/3] [clang] Don't omit null pointer checks with -fms-kernel MSVC preserves null check after dereference, e.g ``` struct Obj { int value, extra; }; int null_check_is_kept(Obj* p) { int v = p->value; if (p == nullptr) return -1; return v + p->extra; } ``` Also MSVC keeps standard library calls (e.g memcpy), where target is null pointer. Make null pointer defined in kernel mode, as some low level code depends on it. --- clang/include/clang/Options/Options.td | 4 +-- clang/test/CodeGen/null-checks.c | 35 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/null-checks.c diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 59bfd621a5994..c498b4e6acc44 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -3083,10 +3083,10 @@ defm rewrite_includes : BoolFOption<"rewrite-includes", defm directives_only : OptInCC1FFlag<"directives-only", "">; defm delete_null_pointer_checks : BoolFOption<"delete-null-pointer-checks", - CodeGenOpts<"NullPointerIsValid">, DefaultFalse, + CodeGenOpts<"NullPointerIsValid">, Default<"LangOpts->Kernel">, NegFlag<SetTrue, [], [ClangOption, CC1Option], "Do not treat usage of null pointers as undefined behavior">, - PosFlag<SetFalse, [], [ClangOption], "Treat usage of null pointers as undefined behavior (default)">, + PosFlag<SetFalse, [], [ClangOption, CC1Option], "Treat usage of null pointers as undefined behavior (default)">, BothFlags<[], [ClangOption, CLOption]>>, DocBrief<[{When enabled, treat null pointer dereference, creation of a reference to null, or passing a null pointer to a function parameter annotated with the "nonnull" diff --git a/clang/test/CodeGen/null-checks.c b/clang/test/CodeGen/null-checks.c new file mode 100644 index 0000000000000..403a08e19de89 --- /dev/null +++ b/clang/test/CodeGen/null-checks.c @@ -0,0 +1,35 @@ +// Check that null pointer checks are not optimized out if -fms-compatibility is set +// RUN: %clang_cc1 -fms-kernel -O2 -triple x86_64-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -O2 -triple x86_64-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=NOCHECK +// RUN: %clang_cc1 -fms-kernel -O2 -triple x86_64-pc-windows-msvc -fdelete-null-pointer-checks %s -emit-llvm -o - | FileCheck %s --check-prefix=NOCHECK + +// CHECK-LABEL: i32 @process +// CHECK-NEXT: entry: +// CHECK-NEXT: %tobool.not = icmp eq ptr %p, null +// CHECK-NEXT: br i1 %tobool.not, label %cleanup, label %if.end + +// CHECK-LABEL: ptr @call_memcpy +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64 +// CHECK-NEXT: ret ptr null + + +// NOCHECK-LABEL: i32 @process +// NOCHECK-NOT: icmp eq ptr %p, null + +// NOCHECK-LABEL: ptr @call_memcpy +// NOCHECK-NEXT: entry: +// NOCHECK-NEXT: ret ptr null + +struct Obj { int value; int extra; }; + +int process(struct Obj* p) { + int v = p->value; + if (!p) + return -1; + return v + p->extra; +} + +void* call_memcpy(void* p, long long size) { + return __builtin_memcpy(0, p, size); +} >From e1b642b20cc6ace5b824748d83d3121044e3e9d8 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant <[email protected]> Date: Fri, 26 Jun 2026 11:51:38 +0200 Subject: [PATCH 2/3] Added release notes --- clang/docs/ReleaseNotes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 0626c41774960..4bb4063e499ed 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -460,6 +460,8 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the - The `-cl` `/Brepro` option was modified to match the original CL's option and now defines the standard macros `__DATE__`, `__TIME__` and `__TIMESTAMP__` to "1". The previous functionality remains unchanged. +- The `-fms-kernel` flag will now implicitly add `-fno-delete-null-pointer-checks`. + Still `-fdelete-null-pointer-checks` can be used to override this behavior. ### Removed Compiler Flags >From 22465494150b64c4cb87b2d5827a6836e1002c15 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant <[email protected]> Date: Thu, 9 Jul 2026 15:02:32 +0200 Subject: [PATCH 3/3] Add test for different command line options order --- clang/test/CodeGen/null-checks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/CodeGen/null-checks.c b/clang/test/CodeGen/null-checks.c index 403a08e19de89..a0ff4cc4dbed0 100644 --- a/clang/test/CodeGen/null-checks.c +++ b/clang/test/CodeGen/null-checks.c @@ -2,6 +2,7 @@ // RUN: %clang_cc1 -fms-kernel -O2 -triple x86_64-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -O2 -triple x86_64-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=NOCHECK // RUN: %clang_cc1 -fms-kernel -O2 -triple x86_64-pc-windows-msvc -fdelete-null-pointer-checks %s -emit-llvm -o - | FileCheck %s --check-prefix=NOCHECK +// RUN: %clang_cc1 -O2 -triple x86_64-pc-windows-msvc -fdelete-null-pointer-checks -fms-kernel %s -emit-llvm -o - | FileCheck %s --check-prefix=NOCHECK // CHECK-LABEL: i32 @process // CHECK-NEXT: entry: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
