On 02/22/2017 11:02 AM, Jason Merrill wrote:
On Tue, Feb 21, 2017 at 4:27 PM, Martin Sebor <mse...@gmail.com> wrote:
Ah, I see, your patch changes attribute unused handling for local
variables from tracking TREE_USED to lookup_attribute.  I'm not
opposed to this change, but I'd like to understand why the TREE_USED
handling wasn't working.


In the test case in the bug:

  template <class T>
  void g ()
  {
    T t;   // warning, ok

    typedef T U;
    U u;   // no warning, bug
  }

  template void g<int>();

both TREE_USED(T) and TREE_USED(t) are zero in initialize_local_var
so the function doesn't set already_used or TREE_USED(t) and we get
a warning as expected.

But because TREE_USED(U) is set to 1 in maybe_record_typedef_use
(to implement -Wunused-local-typedefs),  initialize_local_var then
sets already_used to 1 and later also TREE_USED(u) to 1, suppressing
the warning.

Hmm, I would expect maybe_record_typedef_use to set TREE_USED on the
TYPE_DECL, not on the *_TYPE which initialize_local_var checks.

That's what it does:

  void
  maybe_record_typedef_use (tree t)
  {
    if (!is_typedef_decl (t))
      return;

    TREE_USED (t) = true;
  }

Here, t is a TYPE_DECL of the typedef U.

It has the effect of TREE_USED (TREE_TYPE (decl)) being set in
initialize_local_var.  The TREE_USED bit on the type (i.e., on
TREE_TYPE(decl) where decl is the u in the test case above) is
set when the function template is instantiated, in
set_underlying_type called from tsubst_decl.

Martin

Reply via email to