From: David Malcolm Date: Wed, 8 Sep 2021 18:37:19 +0000 (-0400) Subject: analyzer: fix ICE when discarding result of realloc [PR102225] X-Git-Tag: upstream/12.2.0~5275 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e66b9f6779f46433b0e2c093b58403604ed131cc;p=platform%2Fupstream%2Fgcc.git analyzer: fix ICE when discarding result of realloc [PR102225] gcc/analyzer/ChangeLog: PR analyzer/102225 * analyzer.h (compat_types_p): New decl. * constraint-manager.cc (constraint_manager::get_or_add_equiv_class): Guard against NULL type when checking for pointer types. * region-model-impl-calls.cc (region_model::impl_call_realloc): Guard against NULL lhs type/region. Guard against the size value not being of a compatible type for dynamic extents. * region-model.cc (compat_types_p): Make non-static. gcc/testsuite/ChangeLog: PR analyzer/102225 * gcc.dg/analyzer/realloc-1.c (test_10): New. * gcc.dg/analyzer/torture/pr102225.c: New test. --- diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index 7ad1081..3ba4e21 100644 --- a/gcc/analyzer/analyzer.h +++ b/gcc/analyzer/analyzer.h @@ -203,6 +203,8 @@ private: extern location_t get_stmt_location (const gimple *stmt, function *fun); +extern bool compat_types_p (tree src_type, tree dst_type); + /* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */ class plugin_analyzer_init_iface diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index dc65c8d..6df23fb 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -2088,10 +2088,11 @@ constraint_manager::get_or_add_equiv_class (const svalue *sval) /* Convert all NULL pointers to (void *) to avoid state explosions involving all of the various (foo *)NULL vs (bar *)NULL. */ - if (POINTER_TYPE_P (sval->get_type ())) - if (tree cst = sval->maybe_get_constant ()) - if (zerop (cst)) - sval = m_mgr->get_or_create_constant_svalue (null_pointer_node); + if (sval->get_type ()) + if (POINTER_TYPE_P (sval->get_type ())) + if (tree cst = sval->maybe_get_constant ()) + if (zerop (cst)) + sval = m_mgr->get_or_create_constant_svalue (null_pointer_node); /* Try svalue match. */ if (get_equiv_class_by_svalue (sval, &result)) diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 875719f..ff2ae9c 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -540,11 +540,14 @@ region_model::impl_call_realloc (const call_details &cd) { /* Return NULL; everything else is unchanged. */ const call_details cd (get_call_details (model, ctxt)); - const svalue *zero - = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0); - model->set_value (cd.get_lhs_region (), - zero, - cd.get_ctxt ()); + if (cd.get_lhs_type ()) + { + const svalue *zero + = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0); + model->set_value (cd.get_lhs_region (), + zero, + cd.get_ctxt ()); + } return true; } }; @@ -575,11 +578,17 @@ region_model::impl_call_realloc (const call_details &cd) const svalue *ptr_sval = cd.get_arg_svalue (0); const svalue *size_sval = cd.get_arg_svalue (1); if (const region *buffer_reg = ptr_sval->maybe_get_region ()) - model->set_dynamic_extents (buffer_reg, size_sval); - model->set_value (cd.get_lhs_region (), ptr_sval, cd.get_ctxt ()); - const svalue *zero - = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0); - return model->add_constraint (ptr_sval, NE_EXPR, zero, cd.get_ctxt ()); + if (compat_types_p (size_sval->get_type (), size_type_node)) + model->set_dynamic_extents (buffer_reg, size_sval); + if (cd.get_lhs_region ()) + { + model->set_value (cd.get_lhs_region (), ptr_sval, cd.get_ctxt ()); + const svalue *zero + = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0); + return model->add_constraint (ptr_sval, NE_EXPR, zero, cd.get_ctxt ()); + } + else + return true; } }; @@ -643,10 +652,15 @@ region_model::impl_call_realloc (const call_details &cd) and the new_ptr_sval as "nonnull". */ model->on_realloc_with_move (cd, old_ptr_sval, new_ptr_sval); - const svalue *zero - = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0); - return model->add_constraint (new_ptr_sval, NE_EXPR, zero, - cd.get_ctxt ()); + if (cd.get_lhs_type ()) + { + const svalue *zero + = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0); + return model->add_constraint (new_ptr_sval, NE_EXPR, zero, + cd.get_ctxt ()); + } + else + return true; } }; diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 3bfc4ba..a14d107 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1713,7 +1713,7 @@ assert_compat_types (tree src_type, tree dst_type) /* Return true if SRC_TYPE can be converted to DST_TYPE as a no-op. */ -static bool +bool compat_types_p (tree src_type, tree dst_type) { if (src_type && dst_type && !VOID_TYPE_P (dst_type)) diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c index 606a19a..ef117ad 100644 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c @@ -88,3 +88,8 @@ void test_9 (void *p) free (p); void *q = realloc (p, 1024); /* { dg-warning "double-'free' of 'p'" } */ } + +void test_10 (char *s, int n) +{ + __builtin_realloc(s, n); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" } */ +} /* { dg-warning "leak" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c new file mode 100644 index 0000000..a7c3249 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c @@ -0,0 +1,6 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +void bad_realloc(char *s, int n) +{ + char *p = __builtin_realloc(s, n); +} /* { dg-warning "leak" } */