On 8/22/19 4:37 PM, Jeff Law wrote:
On 8/22/19 4:23 PM, Martin Sebor wrote:
On 8/22/19 3:27 PM, Jeff Law wrote:
On 8/21/19 2:50 PM, Martin Sebor wrote:
This patch is a subset of the solution for PR 91457 whose main
goal is to eliminate inconsistencies in warnings issued for
out-of-bounds accesses to the various flavors of flexible array
members of constant objects. That patch was posted here:
https://gcc.gnu.org/ml/gcc-patches/2019-08/msg01202.html
Like PR 91457, this patch also relies on improving optimization
to issue better quality warnings. (I.e., with the latter being
what motivated it.)
The optimization enhances string_constant to recognize empty
CONSTRUCTORs returned by fold_ctor_reference for references
to members of constant objects with either "insufficient"
initializers (e.g., given struct S { char n, a[]; } s = { 0 };)
or with braced-list initializers (e.g., given
struct S s = { 3 { 1, 2, 3, 0 } }; The patch lets string_constant
convert the CONSTRUCTOR for s.a into a STRING_CST, which in turn
enables the folding of calls to built-ins like strlen, strchr, or
strcmp with such arguments.
Exposing the strings to the folder then also lets it detect and
issue warnings for out-of-bounds offsets in more instances of
such references than before.
The remaining changes in the patch mostly enhance the places
that use the no-warning bit to prevent redundant diagnostics.
Tested on x86_64-linux.
Martin
gcc-91490.diff
PR middle-end/91490 - bogus argument missing terminating nul warning
on strlen of a flexible array member
gcc/c-family/ChangeLog:
PR middle-end/91490
* c-common.c (braced_list_to_string): Add argument and overload.
Handle flexible length arrays.
gcc/testsuite/ChangeLog:
PR middle-end/91490
* c-c++-common/Warray-bounds-7.c: New test.
* gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or
-Wstringop-overflow.
* gcc.dg/strlenopt-78.c: New test.
gcc/ChangeLog:
PR middle-end/91490
* builtins.c (c_strlen): Rename argument and introduce new local.
Set no-warning bit on original argument.
* expr.c (string_constant): Pass argument type to
fold_ctor_reference.
* gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST
for missing initializers.
* tree.c (build_string_literal): Handle optional argument.
* tree.h (build_string_literal): Add defaulted argument.
* gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check
no-warning bit on original expression.
diff --git a/gcc/builtins.c b/gcc/builtins.c
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11402,6 +11402,16 @@ is_aligning_offset (const_tree offset,
const_tree exp)
tree
string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree
*decl)
{
+ tree dummy = NULL_TREE;;
+ if (!mem_size)
+ mem_size = &dummy;
+
+ tree chartype = TREE_TYPE (arg);
+ if (POINTER_TYPE_P (chartype))
+ chartype = TREE_TYPE (chartype);
+ while (TREE_CODE (chartype) == ARRAY_TYPE)
+ chartype = TREE_TYPE (chartype);
+
tree array;
STRIP_NOPS (arg);
So per our conversation today, I took a closer look at this. As you
noted CHARTYPE is only used for the empty constructor code you're adding
as a part of this patch.
Rather than stripping away types like this to compute chartype, couldn't
we just use char_type_node instead of chartype in this code below?
We can't. string_constant is also called for wide strings (e.g.,
by the sprintf pass). Returning a narrow string when the caller
asks for a wide one breaks the sprintf stuff.
Sigh. And presumably we can't just move the block down because other
bits in string_constant modify ARG.
So I think a quick comment before that fragment about its purpose and
we're good to go for the patch as a whole based on the one you posted an
hour or so ago.
I did move it down into the block with the STRING_CST transform.
A comment is also there so I committed the patch in r274837.
Thanks
Martin