From 9a27acc30a34b7854db32eac562306cebac6fa1e Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 26 Oct 2021 14:38:11 -0600 Subject: Make full use of context-sensitive ranges in access warnings. gcc/ChangeLog: * builtins.c (check_strncat_sizes): Pass access_data ctor additional arguments. (expand_builtin_memcmp): Move code to gimple-ssa-warn-access.cc. (expand_builtin_fork_or_exec): Same. * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref): Pass compute_objsize additional arguments. (inbounds_memaccess_p): Same. (array_bounds_checker::check_array_bounds): Add an assert. Stash statement in a member. (check_array_bounds_dom_walker::before_dom_children): Same. * gimple-array-bounds.h (array_bounds_checker::m_stmt): New member. * gimple-ssa-sprintf.c (get_destination_size): Add an argument. (handle_printf_call): Pass a new argument. * gimple-ssa-warn-access.cc (get_size_range): Add an argument. (check_access): Add an argument and pass it along to callees. (check_read_access): Make a member function. (pass_waccess::check_strcat): Pass access_data ctor additional arguments. (pass_waccess::check_strncat): Same. (pass_waccess::check_stxcpy): Same. (pass_waccess::check_stxncpy): Same. (pass_waccess::check_strncmp): Same. (pass_waccess::check_read_access): Same. (pass_waccess::check_builtin): Same. (pass_waccess::maybe_check_access_sizes): Same. (pass_waccess::maybe_check_dealloc_call): Same. * gimple-ssa-warn-access.h (check_read_access): Declare a new member function. * pointer-query.cc (compute_objsize_r): Add an argument. (gimple_call_return_array): Same. (gimple_call_alloc_size): Same. (access_ref::access_ref): Same. (access_ref::get_ref): Same. (pointer_query::get_ref): Same. (handle_min_max_size): Pass an arguments to callees. (handle_array_ref): Add an argument. (handle_mem_ref): Same. (compute_objsize): Same. * pointer-query.h (struct access_ref): Adjust signatures. (struct access_data): Same. (gimple_call_alloc_size): Add an argument. (gimple_parm_array_size): Same. (compute_objsize): Same. * tree-ssa-strlen.c (strlen_pass::adjust_last_stmt): Pass an additional argument to compute_objsize. (strlen_pass::maybe_warn_overflow): Same. (maybe_diag_stxncpy_trunc): Same. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-22.c: Correct typos. * gcc.dg/Wstringop-overflow-81.c: New test. libstdc++-v3/ChangeLog: * testsuite/21_strings/basic_string/capacity/1.cc: Also suppress -Wstringop-overread. * testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc: Same. --- gcc/pointer-query.h | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'gcc/pointer-query.h') diff --git a/gcc/pointer-query.h b/gcc/pointer-query.h index 3c8172c..96c5001 100644 --- a/gcc/pointer-query.h +++ b/gcc/pointer-query.h @@ -60,18 +60,16 @@ class pointer_query; /* Describes a reference to an object used in an access. */ struct access_ref { - /* Set the bounds of the reference to at most as many bytes - as the first argument or unknown when null, and at least - one when the second argument is true unless the first one - is a constant zero. */ - access_ref (tree = NULL_TREE, bool = false); + /* Set the bounds of the reference. */ + access_ref (range_query *query = nullptr, tree = NULL_TREE, + gimple * = nullptr, bool = false); /* Return the PHI node REF refers to or null if it doesn't. */ gphi *phi () const; /* Return the object to which REF refers. */ - tree get_ref (vec *, access_ref * = NULL, int = 1, - ssa_name_limit_t * = NULL, pointer_query * = NULL) const; + tree get_ref (vec *, access_ref * = nullptr, int = 1, + ssa_name_limit_t * = nullptr, pointer_query * = nullptr) const; /* Return true if OFFRNG is the constant zero. */ bool offset_zero () const @@ -85,7 +83,7 @@ struct access_ref /* Return the maximum amount of space remaining and if non-null, set argument to the minimum. */ - offset_int size_remaining (offset_int * = NULL) const; + offset_int size_remaining (offset_int * = nullptr) const; /* Return true if the offset and object size are in range for SIZE. */ bool offset_in_range (const offset_int &) const; @@ -172,13 +170,13 @@ public: }; /* Construct an object with the given Ranger instance and cache. */ - explicit pointer_query (range_query * = NULL, cache_type * = NULL); + explicit pointer_query (range_query * = nullptr, cache_type * = nullptr); /* Retrieve the access_ref for a variable from cache if it's there. */ const access_ref* get_ref (tree, int = 1) const; /* Retrieve the access_ref for a variable from cache or compute it. */ - bool get_ref (tree, access_ref*, int = 1); + bool get_ref (tree, gimple *, access_ref*, int = 1); /* Add an access_ref for the SSA_NAME to the cache. */ void put_ref (tree, const access_ref&, int = 1); @@ -208,19 +206,23 @@ struct access_data { /* Set the access to at most MAXWRITE and MAXREAD bytes, and at least 1 when MINWRITE or MINREAD, respectively, is set. */ - access_data (gimple *stmt, access_mode mode, + access_data (range_query *query, gimple *stmt, access_mode mode, tree maxwrite = NULL_TREE, bool minwrite = false, tree maxread = NULL_TREE, bool minread = false) : stmt (stmt), call (), - dst (maxwrite, minwrite), src (maxread, minread), mode (mode) { } + dst (query, maxwrite, stmt, minwrite), + src (query, maxread, stmt, minread), + mode (mode) { } /* Set the access to at most MAXWRITE and MAXREAD bytes, and at least 1 when MINWRITE or MINREAD, respectively, is set. */ - access_data (tree expr, access_mode mode, + access_data (range_query *query, tree expr, access_mode mode, tree maxwrite = NULL_TREE, bool minwrite = false, tree maxread = NULL_TREE, bool minread = false) : stmt (), call (expr), - dst (maxwrite, minwrite), src (maxread, minread), mode (mode) { } + dst (query, maxwrite, nullptr, minwrite), + src (query, maxread, nullptr, minread), + mode (mode) { } /* Access statement. */ gimple *stmt; @@ -245,14 +247,23 @@ extern bool get_size_range (tree, tree[2], int = 0); extern bool get_size_range (range_query *, tree, gimple *, tree[2], int = 0); class range_query; -extern tree gimple_call_alloc_size (gimple *, wide_int[2] = NULL, - range_query * = NULL); -extern tree gimple_parm_array_size (tree, wide_int[2], bool * = NULL); +extern tree gimple_call_alloc_size (gimple *, wide_int[2] = nullptr, + range_query * = nullptr); + +/* Compute the size of an object referenced by the first argument in + a statement given by second argument, using Object Size Type given + by third argument. Store result in an access_ref. */ +extern tree compute_objsize (tree, gimple *, int, access_ref *, + range_query * = nullptr); +extern tree compute_objsize (tree, gimple *, int, access_ref *, + pointer_query *); +inline tree compute_objsize (tree ptr, int ostype, access_ref *pref) +{ + return compute_objsize (ptr, nullptr, ostype, pref, (range_query *)nullptr); +} -extern tree compute_objsize (tree, int, access_ref *, range_query * = NULL); /* Legacy/transitional API. Should not be used in new code. */ -extern tree compute_objsize (tree, int, access_ref *, pointer_query *); -extern tree compute_objsize (tree, int, tree * = NULL, tree * = NULL, - range_query * = NULL); +extern tree compute_objsize (tree, int, tree * = nullptr, tree * = nullptr, + range_query * = nullptr); #endif // GCC_POINTER_QUERY_H -- cgit v1.1 From 1ff4dbddcf74203a1e16316b18e12f9e1b5085f0 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 26 Oct 2021 14:40:33 -0600 Subject: Improve/correct detection of overlapping aggregates [PR102238, PR102919]. Resolves: PR tree-optimization/102238 - alias_offset in gimple-ssa-sprintf.c is broken PR tree-optimization/102919 - spurious -Wrestrict warning for sprintf into the same member array as argument plus offset gcc/ChangeLog: PR tree-optimization/102238 PR tree-optimization/102919 * gimple-ssa-sprintf.c (get_string_length): Add an argument. (array_elt_at_offset): Move to pointer-query. (set_aggregate_size_and_offset): New function. (field_at_offset): Move to pointer-query. (get_origin_and_offset): Rename... (get_origin_and_offset_r): this. Add an argument. Make aggregate handling more robust. (get_origin_and_offset): New. (alias_offset): Add an argument. (format_string): Use subobject size determined by get_origin_and_offset. * pointer-query.cc (field_at_offset): Move from gimple-ssa-sprintf.c. Improve/correct handling of aggregates. (array_elt_at_offset): Same. * pointer-query.h (field_at_offset): Declare. (array_elt_at_offset): Declare. gcc/testsuite/ChangeLog: PR tree-optimization/102238 PR tree-optimization/102919 * gcc.dg/tree-ssa/builtin-sprintf-warn-23.c: Remove warnings. * gcc.dg/Wrestrict-23.c: New test. --- gcc/pointer-query.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'gcc/pointer-query.h') diff --git a/gcc/pointer-query.h b/gcc/pointer-query.h index 96c5001..c8215b6 100644 --- a/gcc/pointer-query.h +++ b/gcc/pointer-query.h @@ -266,4 +266,13 @@ inline tree compute_objsize (tree ptr, int ostype, access_ref *pref) extern tree compute_objsize (tree, int, tree * = nullptr, tree * = nullptr, range_query * = nullptr); +/* Return the field at the constant offset. */ +extern tree field_at_offset (tree, tree, HOST_WIDE_INT, + HOST_WIDE_INT * = nullptr, + HOST_WIDE_INT * = nullptr); +/* Return the array at the constant offset. */ +extern tree array_elt_at_offset (tree, HOST_WIDE_INT, + HOST_WIDE_INT * = nullptr, + HOST_WIDE_INT * = nullptr); + #endif // GCC_POINTER_QUERY_H -- cgit v1.1