sdkrystian wrote: With these changes, we can now issue warnings for the missing `template` keyword in the _vast_ majority of cases: ```cpp template<int I> struct A { int x; };
template<int I, bool J> struct B { int x; }; template<int I, typename T, int J> struct C { int x; }; template<typename T> struct D { int x; }; template<int I> constexpr inline int V = I; int y; template<typename T, int I> void f(T t) { t.A<0>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<int()>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<int(0)>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<int*()>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<static_cast<D<int>>(0)>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<static_cast<const D<int>>(0)>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.B<1, true>::x; // expected-warning {{use 'template' keyword to treat 'B' as a dependent template name}} t.C<2, int, 4>::x; // expected-warning {{use 'template' keyword to treat 'C' as a dependent template name}} t.A<V<0>>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.B<1, V<1>>::x; // expected-warning {{use 'template' keyword to treat 'B' as a dependent template name}} t.C<V<2>, int, V<3>>::x; // expected-warning {{use 'template' keyword to treat 'C' as a dependent template name}} t.A<1 && T::template f<0>()>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<(1 > 2)>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<(1 < 3)>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.B<A<I>::x < int, 1>::x; // expected-warning {{use 'template' keyword to treat 'x' as a dependent template name}} t.B<A<I>::x < 0, 1>::x; // expected-error {{no member named 'x' in the global namespace}} // expected-error {{missing 'template' keyword prior to dependent template name 'B'}} t.A<1 < 4>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<I < 4>::x; // expected-error {{no member named 'x' in the global namespace}} // expected-error {{missing 'template' keyword prior to dependent template name 'A'}} t.A<I ? I < 4 : false>::x; // expected-warning {{use 'template' keyword to treat 'A' as a dependent template name}} t.A<1 > 4>::x; // expected-error {{no member named 'x' in the global namespace}} t.A<0>::y; // ok, parsed as '((t.A) < 0) > ::y' } ``` Would like to get feedback from @AaronBallman, @cor3ntin, @hokein, and perhaps @zygoloid on this :). I highly doubt the [discussion on the reflector](https://lists.isocpp.org/core/2024/07/16028.php) will result in any mitigation mechanisms being added (see my reply [here](https://lists.isocpp.org/core/2024/07/16039.php)). If any action _is_ taken, the most I foresee would be applying it in C++23 & later. https://github.com/llvm/llvm-project/pull/100425 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits