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

Reply via email to