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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |10.2.0, 11.0
             Status|UNCONFIRMED                 |NEW
           Keywords|                            |alias, missed-optimization
   Last reconfirmed|                            |2021-04-22
     Ever confirmed|0                           |1
          Component|c++                         |tree-optimization

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning only runs at -O2 (and with -Wextra).  It works as designed.  It's
issued for the IL below.  The String::_smallBuffer is defined as:

   char _smallBuffer[8];

The reason for the warning is missing folding/constant prtopagation due to
overly conservative alias analysis: GCC assumes that the call to printf() might
modify the String object because it's passed the this pointer (the address of
&s).  That prevents the constant store to _buffLen from being propagated.  But
the only standard directive that can clobber an object is %n, so the assumption
could be avoided by scanning the format string for %n (and either matching it
to the argument or simply assuming it clobbers any argument).  This is the
missed-optimization part.

The same false positive would still happen with any other function whose
semantics GCC doesn't have knowledge of.  To avoid it in those cases the
warning (but not optimizers) could assume that the argument might be clobbered
only when passed to a non-const pointer/reference.  This would be a good change
to make in all these flow-sensitive warnings (all of which are subject to the
same class of false positives as a result of the overly conservative
escape/alias analysis).  This is the diagnostic aspect of this bug.

int main (int D.4559, char * * D.4560)
{
  bool D.4665;
  const size_t sLen;
  struct String s;
  int _1;
  int _6;
  long unsigned int _8;
  char * _9;
  long unsigned int _10;
  char * _11;
  long unsigned int _20;
  char * iftmp.2_21;
  int _22;
  char * iftmp.2_24;
  void * _26;
  long unsigned int _27;
  const char * iftmp.3_28;

  <bb 2> [local count: 1073741824]:
  s ={v} {CLOBBER};
  s._length = 0;
  s._bufferLen = 128;                               <<< store
  _26 = malloc (128);
  s._bigBuffer = _26;
  __printf_chk (1, "EnsureBufSize on String %p:  _bigBuffer=%p
_bufferLen=%zu\n", &s, _26, 128);                                    <<<
assumed to clobber s._bufferLen
  _20 = MEM[(const struct String *)&s]._bufferLen;  <<< load
  if (_20 > 8)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [local count: 536870913]:
  iftmp.2_21 = s._bigBuffer;

  <bb 4> [local count: 1073741824]:
  # iftmp.2_24 = PHI <iftmp.2_21(3), &s._smallBuffer(2)>
  __builtin_memcpy (iftmp.2_24, "1234567890", 11);
  s._length = 10;
  _1 = rand ();
  if (_1 != 0)
    goto <bb 6>; [50.00%]
  else
    goto <bb 5>; [50.00%]

  <bb 5> [local count: 714038312]:
  _8 = s._bufferLen;
  if (_8 > 8)
    goto <bb 8>; [24.44%]
  else
    goto <bb 10>; [75.56%]

  <bb 6> [local count: 536870913]:
  _27 = s._bufferLen;                               <<< load
  if (_27 > 8)
    goto <bb 7>; [50.00%]
  else
    goto <bb 15>; [50.00%]

  <bb 7> [local count: 268435456]:
  iftmp.3_28 = s._bigBuffer;
  _22 = strcmp (iftmp.3_28, "1234567890");
  if (_22 == 0)
    goto <bb 9>; [33.00%]
  else
    goto <bb 8>; [67.00%]

  <bb 8> [local count: 354334801]:
  _9 = s._bigBuffer;
  free (_9);
  goto <bb 11>; [100.00%]

  <bb 9> [local count: 177167400]:
  __builtin_puts (&"Mwahey!"[0]);
  goto <bb 5>; [100.00%]

  <bb 10> [local count: 719407023]:

  <bb 11> [local count: 1073741824]:
  s ={v} {CLOBBER};
  s ={v} {CLOBBER};
  return 0;

  <bb 12> [count: 0]:
<L10>:
  _10 = s._bufferLen;
  if (_10 > 8)
    goto <bb 13>; [0.00%]
  else
    goto <bb 14>; [0.00%]

  <bb 13> [count: 0]:
  _11 = s._bigBuffer;
  free (_11);

  <bb 14> [count: 0]:
  s ={v} {CLOBBER};
  resx 2

  <bb 15> [local count: 268435457]:
  _6 = strcmp (&s._smallBuffer, "1234567890");      <<< -Wstring-compare
  if (_6 == 0)
    goto <bb 9>; [33.00%]
  else
    goto <bb 10>; [67.00%]

}

Reply via email to