[clang] [clang] Don't omit null pointer checks with -fms-kernel (PR #193800)

via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 25 00:34:15 PDT 2026


https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/193800

>From e08c1bfe7868fe6655a187218fafe975e5959b4e Mon Sep 17 00:00:00 2001
From: Evgeny Leviant <eleviant at accesssoftek.com>
Date: Thu, 9 Apr 2026 11:58:30 +0200
Subject: [PATCH 1/2] [clang] Don't omit null pointer checks with -fms-kernel

---
 clang/lib/Frontend/CompilerInvocation.cpp |  5 +++++
 clang/test/CodeGen/MSKernel/null-deref.c  | 16 ++++++++++++++++
 2 files changed, 21 insertions(+)
 create mode 100644 clang/test/CodeGen/MSKernel/null-deref.c

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index c6e8644905964..a8a5d57155228 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1924,6 +1924,11 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
     Opts.DIBugsReportFilePath = "";
   }
 
+  if (LangOpts->Kernel &&
+      !Args.hasFlag(OPT_fdelete_null_pointer_checks,
+                    OPT_fno_delete_null_pointer_checks, false))
+    Opts.NullPointerIsValid = true;
+
   Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
                            Args.hasArg(OPT_new_struct_path_tbaa);
   Opts.OptimizeSize = getOptimizationLevelSize(Args);
diff --git a/clang/test/CodeGen/MSKernel/null-deref.c b/clang/test/CodeGen/MSKernel/null-deref.c
new file mode 100644
index 0000000000000..e981f35369bd7
--- /dev/null
+++ b/clang/test/CodeGen/MSKernel/null-deref.c
@@ -0,0 +1,16 @@
+// Check that null pointer checks are not omited in kernel mode compilations
+// RUN: %clang_cc1 -fms-kernel -fms-extensions -triple x86_64-pc-windows-msvc -O2 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK:      define dso_local i32 @process(ptr noundef readonly captures(address_is_null) %p) local_unnamed_addr #0
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %{{.*}} = icmp eq ptr %p, null
+// CHECK:      attributes #0 = {{.*}} null_pointer_is_valid
+
+struct Obj { int value; int extra; };
+
+int process(struct Obj* p) {
+    int v = p->value;
+    if (!p)
+        return -1;
+    return v + p->extra;
+}

>From 6214a0d055f6cefa64a5f4f41efc7eff6c9aae75 Mon Sep 17 00:00:00 2001
From: Evgeny Leviant <eleviant at accesssoftek.com>
Date: Fri, 24 Apr 2026 19:33:32 +0200
Subject: [PATCH 2/2] Address review comments from @AaronBallman

---
 clang/docs/ReleaseNotes.rst               |  2 ++
 clang/include/clang/Options/Options.td    |  4 ++--
 clang/lib/Frontend/CompilerInvocation.cpp |  5 -----
 clang/test/CodeGen/MSKernel/null-deref.c  | 10 +++++-----
 4 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 03362cf4e0f8a..7e1ca92367795 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -276,6 +276,8 @@ Modified Compiler Flags
 - The `-mno-outline` and `-moutline` compiler flags are now allowed on RISC-V and X86, which both support the machine outliner.
 - The `-mno-outline` flag will now add the `nooutline` IR attribute, so that
   `-mno-outline` and `-moutline` objects can be mixed correctly during LTO.
+- 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
 ----------------------
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index c16c41ad4057d..248d697f38638 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3047,10 +3047,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/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index a8a5d57155228..c6e8644905964 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1924,11 +1924,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
     Opts.DIBugsReportFilePath = "";
   }
 
-  if (LangOpts->Kernel &&
-      !Args.hasFlag(OPT_fdelete_null_pointer_checks,
-                    OPT_fno_delete_null_pointer_checks, false))
-    Opts.NullPointerIsValid = true;
-
   Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
                            Args.hasArg(OPT_new_struct_path_tbaa);
   Opts.OptimizeSize = getOptimizationLevelSize(Args);
diff --git a/clang/test/CodeGen/MSKernel/null-deref.c b/clang/test/CodeGen/MSKernel/null-deref.c
index e981f35369bd7..f23409115f50d 100644
--- a/clang/test/CodeGen/MSKernel/null-deref.c
+++ b/clang/test/CodeGen/MSKernel/null-deref.c
@@ -1,10 +1,10 @@
 // Check that null pointer checks are not omited in kernel mode compilations
-// RUN: %clang_cc1 -fms-kernel -fms-extensions -triple x86_64-pc-windows-msvc -O2 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fms-kernel -fms-extensions -triple x86_64-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fms-kernel -fms-extensions -triple x86_64-pc-windows-msvc -fdelete-null-pointer-checks %s -emit-llvm -o - | FileCheck %s --check-prefix=NOCHECK
 
-// CHECK:      define dso_local i32 @process(ptr noundef readonly captures(address_is_null) %p) local_unnamed_addr #0
-// CHECK-NEXT: entry:
-// CHECK-NEXT:   %{{.*}} = icmp eq ptr %p, null
-// CHECK:      attributes #0 = {{.*}} null_pointer_is_valid
+// CHECK: define dso_local i32 @process(ptr noundef %p) #0
+// CHECK: attributes #0 = {{.*}} null_pointer_is_valid
+// NOCHECK-NOT: null_pointer_is_valid
 
 struct Obj { int value; int extra; };
 



More information about the cfe-commits mailing list