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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |alias, missed-optimization
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2018-09-04
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Since we allow calloc to be declared with 'malloc' attribute the warning would
need to be special-cased on 'malloc'.  Currently the warning uses the alias
machinery and that sees malloc clobber ints if not -fno-math-errno.  The
machinery doesn't check whether the ref is to the memory returned by malloc.

/* If the call in statement CALL may clobber the memory reference REF
   return true, otherwise return false.  */

bool
call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref)
{
...
        /* Allocating memory does not have any side-effects apart from
           being the definition point for the pointer.  */
        case BUILT_IN_MALLOC:
        case BUILT_IN_ALIGNED_ALLOC:
        case BUILT_IN_CALLOC:
        case BUILT_IN_STRDUP:
        case BUILT_IN_STRNDUP:
          /* Unix98 specifies that errno is set on allocation failure.  */
          if (flag_errno_math
              && targetm.ref_may_alias_errno (ref))
            return true;
          return false;

note that -fno-math-errno doesn't fix it which is because of

              /* Do not warn if it can be initialized outside this function.
                 If we did not reach function entry then we found killing
                 clobbers on all paths to entry.  */
              if (fentry_reached
                  /* ???  We'd like to use ref_may_alias_global_p but that
                     excludes global readonly memory and thus we get bougs
                     warnings from p = cond ? "a" : "b" for example.  */
                  && (!VAR_P (base)
                      || is_global_var (base)))
                continue;

so we do not handle uninit reads from pointer refs in this case.

Reply via email to