analyzer: fix ICE and false positive with -Wanalyzer-deref-before-check [PR114408]
gcc/analyzer/ChangeLog: PR analyzer/114408 * engine.cc (impl_run_checkers): Free up any dominance info that we may have created. * kf.cc (class kf_ubsan_handler): New. (register_sanitizer_builtins): New. (register_known_functions): Call register_sanitizer_builtins. gcc/testsuite/ChangeLog: PR analyzer/114408 * c-c++-common/analyzer/deref-before-check-pr114408.c: New test. * c-c++-common/ubsan/analyzer-ice-pr114408.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
2e4b3374cb
commit
80a0cb3745
4 changed files with 60 additions and 0 deletions
|
@ -6251,6 +6251,13 @@ impl_run_checkers (logger *logger)
|
|||
eng.get_model_manager ()->dump_untracked_regions ();
|
||||
|
||||
delete purge_map;
|
||||
|
||||
/* Free up any dominance info that we may have created. */
|
||||
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
|
||||
{
|
||||
function *fun = node->get_fun ();
|
||||
free_dominance_info (fun, CDI_DOMINATORS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
|
||||
|
|
|
@ -2198,6 +2198,27 @@ register_atomic_builtins (known_function_manager &kfm)
|
|||
make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
|
||||
}
|
||||
|
||||
/* 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.
|
||||
Hence we terminate the analysis path at one of these calls. */
|
||||
|
||||
class kf_ubsan_handler : public internal_known_function
|
||||
{
|
||||
void impl_call_post (const call_details &cd) const final override
|
||||
{
|
||||
if (cd.get_ctxt ())
|
||||
cd.get_ctxt ()->terminate_path ();
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
register_sanitizer_builtins (known_function_manager &kfm)
|
||||
{
|
||||
kfm.add (BUILT_IN_UBSAN_HANDLE_NONNULL_ARG,
|
||||
make_unique<kf_ubsan_handler> ());
|
||||
}
|
||||
|
||||
/* Populate KFM with instances of known functions supported by the core of the
|
||||
analyzer (as opposed to plugins). */
|
||||
|
||||
|
@ -2224,6 +2245,7 @@ register_known_functions (known_function_manager &kfm,
|
|||
kfm.add (BUILT_IN_STACK_SAVE, make_unique<kf_stack_save> ());
|
||||
|
||||
register_atomic_builtins (kfm);
|
||||
register_sanitizer_builtins (kfm);
|
||||
register_varargs_builtins (kfm);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
extern void unknown_returns (const char *p);
|
||||
extern void unknown_noreturn (const char *p) __attribute__((__noreturn__));
|
||||
|
||||
void test_1 (const char *p)
|
||||
{
|
||||
if (p)
|
||||
unknown_returns (p);
|
||||
__builtin_strcmp ("a", p); /* { dg-message "pointer 'p' is dereferenced here" "" { target c } } */
|
||||
if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" "" { target c } } */
|
||||
unknown_returns (p);
|
||||
__builtin_strcmp ("a", p);
|
||||
}
|
||||
|
||||
void test_2 (const char *p)
|
||||
{
|
||||
if (p)
|
||||
unknown_noreturn (p);
|
||||
__builtin_strcmp ("a", p);
|
||||
if (p) /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */
|
||||
unknown_noreturn (p);
|
||||
__builtin_strcmp ("a", p);
|
||||
}
|
9
gcc/testsuite/c-c++-common/ubsan/analyzer-ice-pr114408.c
Normal file
9
gcc/testsuite/c-c++-common/ubsan/analyzer-ice-pr114408.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target analyzer } */
|
||||
/* { dg-options "-fanalyzer -fsanitize=undefined" } */
|
||||
|
||||
int main(){}
|
||||
|
||||
int HMAP_unset_copy(const char *key) {
|
||||
return __builtin_strcmp("a", key) + __builtin_strcmp("a", key);
|
||||
}
|
Loading…
Add table
Reference in a new issue