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

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
(In reply to David Malcolm from comment #0)
[...]
> There are various issues here:
>   * non-display of inlining information
[...]

[CCing Jakub]

I tracked this down to what appears to me to be an overzealous removal of a
block in tree-ssa-live.c's remove_unused_scope_block_p, when optimization is on
and debuginfo generation is off (and various other conditions).

Specifically, when "foo" is inlined into "bar", various lexical BLOCKs are
created, including one with a nonzero BLOCK_SOURCE_LOCATION, representing "foo"
as a whole, where the location is that of the callsite.

inlined_function_outer_scope_p () is true for this block.

However, this block is later removed by tree-ssa-live.c's
remove_unused_scope_block_p.


remove_unused_scope_block_p has this code:

563        /* See if this block is important for representation of inlined
function.
564           Inlined functions are always represented by block with
565           block_ultimate_origin being set to FUNCTION_DECL and
DECL_SOURCE_LOCATION
566           set...  */
567        else if (inlined_function_outer_scope_p (scope))
568          unused = false;
569        else

which I'd hoped would ensure that these blocks are preserved, but it isn't
reached.

Instead this clause is reached:

538        /* When not generating debug info we can eliminate info on unused
539           variables.  */
540        else if (!flag_auto_profile && debug_info_level == DINFO_LEVEL_NONE)
541          {
542            /* Even for -g0 don't prune outer scopes from artificial
543               functions, otherwise diagnostics using
tree_nonartificial_location
544               will not be emitted properly.  */
545            if (inlined_function_outer_scope_p (scope))
546              {
547                tree ao = scope;
548     
549                while (ao
550                       && TREE_CODE (ao) == BLOCK
551                       && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
552                  ao = BLOCK_ABSTRACT_ORIGIN (ao);
553                if (ao
554                    && TREE_CODE (ao) == FUNCTION_DECL
555                    && DECL_DECLARED_INLINE_P (ao)
556                    && lookup_attribute ("artificial", DECL_ATTRIBUTES
(ao)))
557                  unused = false;
558              }
559          }

which was added by Jakub in r148212 (f63d3ecc34e8b969b3c940f14e725815c1ef3215)
to fix PR middle-end/40340.

The logic in this clause seems wrong to me: the comment reads:

542            /* Even for -g0 don't prune outer scopes from artificial
543               functions, otherwise diagnostics using
tree_nonartificial_location
544               will not be emitted properly.  */

but it appears to only apply to artificial functions.
If an inlining of a non-artificial function is reached, then we enter the
clause, but fail the final condition (lookup_attribute), and hence unused is
left as true, and hence the block is removed, and the diagnostic fails to
mention the callsite in the inlining chain.

If I remove these lines, the test cases for pr40340 still pass:

  make -k -j64 && make check-gcc RUNTESTFLAGS="-v -v dg.exp=pr40340*.c"
  # of expected passes          13

(though this may be due to other patches I have locally)

As is, using gcc (GCC) 8.0.0 20171113:

$ gcc -c d.c -O2
d.c: In function ‘bar’:
d.c:3:19: warning: ‘__builtin_memcpy’ writing 8 bytes into a region of size 3
overflows the destination [-Wstringop-overflow=]
 #define FOO(d, s) strcpy (d, s)
                   ^~~~~~~~~~~~~
d.c:5:37: note: in expansion of macro ‘FOO’
 void foo (char *d, const char *s) { FOO (d, s); }
                                     ^~~

...note the absence of a report on function 'foo' inlined from bar).


Whereas if I supply "-g", thus avoiding the clause above:

$ gcc -c d.c -O2 -g
In function ‘foo’,
    inlined from ‘bar’ at d.c:13:3:
d.c:3:19: warning: ‘__builtin_memcpy’ writing 8 bytes into a region of size 3
overflows the destination [-Wstringop-overflow=]
 #define FOO(d, s) strcpy (d, s)
                   ^~~~~~~~~~~~~
d.c:5:37: note: in expansion of macro ‘FOO’
 void foo (char *d, const char *s) { FOO (d, s); }
                                     ^~~

...and it correctly reports the inlining information.

Reply via email to