https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259

--- Comment #30 from Martin Sebor <msebor at gcc dot gnu.org> ---
(In reply to Bernd Edlinger from comment #28)
> 
> Can someone explain why the example in comment #21 works when
> pointer arithmentic instead of integer arithmetic is used?

Because the optimization (making use of the size of the referenced array)
doesn't apply in the pointer case.  In the integer case, ccp simplifies the
strlen argument to a COMPONENT_REF:

  Visiting statement:
  _2 = sp_ip_9 + 4;
  which is likely CONSTANT
  Match-and-simplified sp_ip_9 + 4 to bp.0_1
  Lattice value changed to CONSTANT bp.0_1.  Adding SSA edges to worklist.
  marking stmt to be not simulated again

  Visiting statement:
  _3 = (const char *) _2;
  which is likely CONSTANT
  Match-and-simplified (const char *) _2 to &u.s.b
  Lattice value changed to CONSTANT &u.s.b.  Adding SSA edges to worklist.
  marking stmt to be not simulated again

The COMPONENT_REF fully describes the structure of an access to a member and so
lends itself to interesting analysis which then opens up opportunities for both
optimization and bug detection (e.g., buffer overflow).

In the pointer case ccp replaces the argument with with a MEM_REF:

  Visiting statement:
  _1 = sp_ip_7 + 4;
  which is likely CONSTANT
  Lattice value changed to CONSTANT &MEM[(void *)&u + 4B].  Adding SSA edges to
worklist.
  marking stmt to be not simulated again

A ME_REF is a concise but low-level way of referencing memory via a base
address an an offset.  It doesn't include reliable information about the
structure of the referenced memory.  It's easier to do some basic things with
but much harder to use for interesting, higher level analysis.  By folding
expressions into MEM_REF early on, GCC effectively disables subsequent
optimizations that are designed to do interesting things at a higher level.

Reply via email to