On 06/13/2018 01:58 AM, Jakub Jelinek wrote:
On Wed, Jun 13, 2018 at 09:46:28AM +0200, Richard Biener wrote:
gcc/ChangeLog:

        PR c/85931
        * fold-const.c (operand_equal_p): Handle SAVE_EXPR.

gcc/testsuite/ChangeLog:

        PR c/85931
        * gcc.dg/Wstringop-truncation-3.c: New test.
OK for the trunk.  Richi and Jakub have the final say for the branch.

I'm a bit surprised that you don't just use operand_equal_p for both the
INTEGER_CST and !INTEGER_CST cases when testing dstsz == srcsz

It seemed that since the CST case compared the values of the size
expressions and the other case their lexicographic form they needed
to be different.  But operand_equal_p() does value comparison for
constants so the conditional can be simplified by using just it
for both cases.  Thanks for the suggestion!  I've made that
simplification and committed r261515.

Jakub/Richard, can you please review the commit and let me know
if you have any concerns with backporting it to the GCC 8 branch?
(I will proceed if I don't hear anything this week.)

I'm fine with backporting it.

I'm actually worried about the fold-const.c change and don't understand, why
it has been done at all in the context of this PR.

        case SAVE_EXPR:
          if (flags & OEP_LEXICOGRAPHIC)
            return OP_SAME (0);
          return 0;

means it does something different from the state before the patch:
        default:
          return 0;
only if OEP_LEXICOGRAPHIC is set, which AFAIK is only in the
-Wduplicated-branches warning code, so why it is needed for
-Wstringop-truncation warning is unclear to me.

It lets sizeof_pointer_memaccess_warning detect that sizeof b
refers to the size of the VLA b in cases like the one below
(the sizeof b expression is represented as SAVE_EXPR (n)) and
avoid false positives:

  void f (void*, ...);

  void g (unsigned n)
  {
    char a[n], b[n];
    f (a, b);
    strncpy (a, b, sizeof b);   // bogus -Wsizeof-pointer-memaccess
    f (a);
  }

Short of moving the SAVE_EXPR logic out of operand_equal_p()
and into sizeof_pointer_memaccess_warning, is there a better
way to determine that?  (I would expect the SAVE_EXPR logic
in operand_equal_p() to be useful in other contexts besides
this warning.)

Martin

More importantly,
especially -fsanitize=undefined has a tendency of creating trees
which contain two or more uses of the same SAVE_EXPR at each level, and very
deep nesting levels of such SAVE_EXPRs, so if we handle it without checking
for duplicates, it results in exponential compile time complexity.
So, if we really want to handle SAVE_EXPR here, we'd need to create some
cache where we'd remember if in the same toplevel operand_equal_p call we've
already compared two particular SAVE_EXPRs and what was the result.

        Jakub


Reply via email to