5

I have some code that Clang is generating a warning for. This is simplified from the actual code, but the spirit is the same. this_t in the local class is used to instantiate some other template class.

template<class T>
struct value_holder
{
    T  value;
};

template<class T>
int get_value()
{
    struct value_t
    {
        using this_t = value_t;
        //    ^ here
        static value_holder<this_t> val()
        {
            return value_holder<this_t>();
        }

        operator int()
        { return 0; }
    };
    return value_t::val().value;
}

int main(int argc, char** argv) {
    return get_value<void>();
}

When compiled with -std=c++1z -Wall, Clang warns about unused type alias:

main.cpp:14:15: warning: unused type alias 'this_t' [-Wunused-local-typedef]
        using this_t = value_t;
              ^
1 warning generated.

You can see the error on godbolt (6.0, trunk) and locally I'm using Clang 7 which reports the same thing.

This warning only appears when the local class is nested in a template function or method of a template class. When the class is nested in a concrete class or function there is no warning.

Is Clang correct to emit this warning here? The this_t type is used in the return type of value_t::val().

Chris Hunt
  • 3,840
  • 3
  • 30
  • 46
  • 2
    @VTT It is used in the definition of `val()` so it definitely seems like it's not an "unused" type alias. If you take out the `using` the code doesn't compile. – jcai May 06 '18 at 23:15
  • My guess is that after having resolved the template type, when it compiles the concrete code, it has some `value_holder_value_t` class and "forgot" that it used `this_t` to resolve the template type. – Max Vollmer May 06 '18 at 23:24
  • In the godbolt output, note the return type in the signature `int get_value()::value_t::val()`. Somehow it is recognizing that the type `value_holder` will never be seen outside of `get_value()` and is "optimizing" the function signature. – jcai May 06 '18 at 23:33
  • I set `-Wno-unused-local-typedef` years ago and have never looked back – M.M May 07 '18 at 02:53
  • Remember that POSIX reserves all names ending in `_t` for use by the implementation, so such names are usually a bad choice for your own types/functions/aliases. – Jesper Juhl May 07 '18 at 05:40
  • @JesperJuhl oof, that's disappointing... thanks for saying something. – Chris Hunt May 07 '18 at 05:52

1 Answers1

6

It looks like it is a bug in Clang (24883, 33298), first reported in 2015 against Clang 3.7. I tried in godbolt and it appears to occur as far back as 3.6.

Chris Hunt
  • 3,840
  • 3
  • 30
  • 46