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. Martin