On Wed, Feb 22, 2017 at 3:44 PM, Martin Sebor <mse...@gmail.com> wrote: > 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.
Yes. It is a TYPE_DECL, not a type. > 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. Aha! That seems like the problem. Does removing that copy of TREE_USED from the decl to the type break anything? Jason