On Mon, Jan 8, 2018 at 3:11 AM, Martin Sebor <mse...@gmail.com> wrote: > GCC is able to fold references to members of global aggregate > constants in many expressions but it doesn't known how do it > for strlen() arguments. As a result, strlen calls with such > arguments such the one below are not optimized: > > const struct { char a[4]; } s = { "123" }; > > void f (void) > { > if (s.a[3]) abort (); // folded/eliminated > } > > void g (void) > { > if (strlen (s.a) != 3) abort (); // not folded > } > > The attached patch enables gimple_fold_builtin_strlen() to extract > constant strings from aggregate initializers, analogously to how > it extracts data of other types.
Hmm. You do diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fe3e0b4..f277324 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -3517,8 +3517,14 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi) wide_int minlen; wide_int maxlen; + /* Try to extract a constant from an object's CONSTRUCTOR first. */ + tree arg = gimple_call_arg (stmt, 0); + if (TREE_CODE (arg) == ADDR_EXPR) + if (tree str = fold_const_aggregate_ref (TREE_OPERAND (arg, 0))) + arg = str; + (patch is not against trunk?) but then fold_const_aggregate_ref of, say, &s.a[2] will simply return '3' which then yields to a bougs result? So I'm not sure this flys as-is or at least needs a comment how such simplification will end up _not_ disturbing the following code (maybe by noticing '3' aka an INTEGER_CST isn't a valid string and thus not folding). Richard. > Martin