]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: handle more IFN_UBSAN_* as no-ops [PR118300]
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 19 Feb 2025 14:44:46 +0000 (09:44 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 21 Oct 2025 00:50:53 +0000 (20:50 -0400)
Previously the analyzer treated IFN_UBSAN_BOUNDS as a no-op, but
the other IFN_UBSAN_* were unrecognized and conservatively treated
as having arbitrary behavior.

Treat IFN_UBSAN_NULL and IFN_UBSAN_PTR also as no-ops, which should
make -fanalyzer behave better with -fsanitize=undefined.

gcc/analyzer/ChangeLog:
PR analyzer/118300
* kf.cc (class kf_ubsan_bounds): Replace this with...
(class kf_ubsan_noop): ...this.
(register_sanitizer_builtins): Use it to handle IFN_UBSAN_NULL,
IFN_UBSAN_BOUNDS, and IFN_UBSAN_PTR as nop-ops.
(register_known_functions): Drop handling of IFN_UBSAN_BOUNDS
here, as it's now handled by register_sanitizer_builtins above.

gcc/testsuite/ChangeLog:
PR analyzer/118300
* gcc.dg/analyzer/ubsan-pr118300.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
(cherry picked from commit 58b90139e093aeb5494627d92257a97aebb4a6d9)

gcc/analyzer/kf.cc
gcc/testsuite/gcc.dg/analyzer/ubsan-pr118300.c [new file with mode: 0644]

index e47786d0bcbf5d65e9ff768ca2e23ad0380be7b3..c04186bec722f7e0de602a4c1c2b211979519817 100644 (file)
@@ -2057,11 +2057,6 @@ private:
   const private_region m_private_reg;
 };
 
-class kf_ubsan_bounds : public internal_known_function
-{
-  /* Empty.  */
-};
-
 /* Handle calls to functions referenced by
    __attribute__((malloc(FOO))).  */
 
@@ -2198,6 +2193,13 @@ register_atomic_builtins (known_function_manager &kfm)
           make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
 }
 
+/* Handle calls to the various IFN_UBSAN_* with no return value.
+   For now, treat these as no-ops.  */
+
+class kf_ubsan_noop : public internal_known_function
+{
+};
+
 /* Handle calls to the various __builtin___ubsan_handle_*.
    These can return, but continuing after such a return
    isn't likely to be interesting to the user of the analyzer.
@@ -2215,6 +2217,15 @@ class kf_ubsan_handler : public internal_known_function
 static void
 register_sanitizer_builtins (known_function_manager &kfm)
 {
+  /* Handle calls to the various IFN_UBSAN_* with no return value.
+     For now, treat these as no-ops.  */
+  kfm.add (IFN_UBSAN_NULL,
+          make_unique<kf_ubsan_noop> ());
+  kfm.add (IFN_UBSAN_BOUNDS,
+          make_unique<kf_ubsan_noop> ());
+  kfm.add (IFN_UBSAN_PTR,
+          make_unique<kf_ubsan_noop> ());
+
   kfm.add (BUILT_IN_UBSAN_HANDLE_NONNULL_ARG,
           make_unique<kf_ubsan_handler> ());
 }
@@ -2232,7 +2243,6 @@ register_known_functions (known_function_manager &kfm,
   /* Internal fns the analyzer has known_functions for.  */
   {
     kfm.add (IFN_BUILTIN_EXPECT, make_unique<kf_expect> ());
-    kfm.add (IFN_UBSAN_BOUNDS, make_unique<kf_ubsan_bounds> ());
   }
 
   /* GCC built-ins that do not correspond to a function
diff --git a/gcc/testsuite/gcc.dg/analyzer/ubsan-pr118300.c b/gcc/testsuite/gcc.dg/analyzer/ubsan-pr118300.c
new file mode 100644 (file)
index 0000000..87cdc0a
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsanitize=undefined" } */
+
+#include <stdlib.h>
+
+void test ()
+{
+  int*** ptr = (int ***)malloc(sizeof(int**));
+  *ptr = (int **)malloc(sizeof(int*)); /* { dg-warning "dereference of possibly-NULL" } */
+  **ptr = (int *)malloc(sizeof(int)); /* { dg-warning "dereference of possibly-NULL" } */
+
+  free(**ptr);
+  free(*ptr);
+  free(ptr);
+}