On Thu, 24 May 2018, Martin Sebor wrote:

On 05/24/2018 03:40 PM, Marc Glisse wrote:
On Wed, 23 May 2018, Martin Sebor wrote:

On 05/23/2018 08:57 AM, Jeff Law wrote:
On 05/10/2018 04:05 PM, Marc Glisse wrote:
On Thu, 10 May 2018, Martin Sebor wrote:

Can you please comment/respond to Jeff's question below and
confirm whether my understanding of the restriction (below)
is correct?

I don't remember it at all, I really should have expanded that
comment...

The documentation of nonzero_chars seems to indicate that, unless
full_string_p, it is only a lower bound on the length of the string, so
not suitable for this kind of alias check. I don't know if we also have
easy access to some upper bound.

(I noticed while looking at this pass that it could probably use
POINTER_DIFF_EXPR more)
So ISTM that we'd need to guard the code that uses si->nonzero_chars in
maybe_invalidate to also check FULL_STRING_P since it appears we're
using si->nonzero_chars as a string length.

I'm not sure I see why.  Can you explain?

Here's my explanation of the current approach.  si->nonzero_chars
is the lower bound on si's length.  maybe_invalidate() invalidates
the string length which is only necessary when something overwrites
one of the first si->nonzero_chars of the array.  It doesn't matter
whether si is nul-terminated at that point.

When you say "invalidates the string length", does that mean it only
invalidates nonzero_chars (the lower bound), or does that also determine
if you can CSE a call to strlen before and after this instruction? Your
argument only applies in the first case.

"invalidates the string length" means that maybe_invalidate(STMT)
removes the length information record for a string whose length
might be modified by STMT.

If the exact string length is known (full_string_p is true) then
its length can only be modified by writing a nul into one of
the leading nonzero_chars.  If the exact string length is not
known (i.e., full_string_p is false), then nonzero_chars is not
constant

Why couldn't nonzero_chars be constant in that case?

void f(const char*s){
  s[0]='a';
  // I know that strlen(s) is at least 1 here
}

and writes into the string are assumed to change its
length, and thus invalidate it.

But I'm not sure I understand from your brief description what
use case you have in mind.  If you have an example I'll test it.

The example may be completely off, but just to try and describe what I am wondering about:

int f(const char*s,char*restrict t,char c){
// we know nothing about s for now.
s[0]='a'; // nonzero_chars should now be 1
strcpy(t,s);
s[2]=c; // this is after nonzero_chars
strcpy(t,s);
}

If we assume that writing to s[2] is after the end of the original string s, we can remove one of the strcpy. But that's not a valid transformation in general.

I originally wanted to see if we could CSE calls to strlen(s) before and after the write, but the lhs of the first call to strlen would replace nonzero_chars. And I don't know so well what we use strinfo for and thus how dangerous it is not to invalidate it.

--
Marc Glisse

Reply via email to