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.
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r15-7626-g58b90139e093ae.
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 <[email protected]>
---
gcc/analyzer/kf.cc | 22 ++++++++++++++-----
.../gcc.dg/analyzer/ubsan-pr118300.c | 15 +++++++++++++
2 files changed, 31 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/analyzer/ubsan-pr118300.c
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index f3aa2b1b7d25..dceedd4569d3 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -2061,11 +2061,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))). */
@@ -2202,6 +2197,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.
@@ -2219,6 +2221,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> ());
}
@@ -2236,7 +2247,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
index 000000000000..87cdc0a37e71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/ubsan-pr118300.c
@@ -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);
+}
--
2.26.3