Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -173,6 +173,7 @@ def InvalidIOSDeploymentTarget : DiagGroup<"invalid-ios-deployment-target">; +def CXX14CompatCTAD : DiagGroup<"c++14-compat-ctad">; def CXX17CompatMangling : DiagGroup<"c++17-compat-mangling">; def : DiagGroup<"c++1z-compat-mangling", [CXX17CompatMangling]>; // Name of this warning in GCC. @@ -183,7 +184,8 @@ def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic", [CXXPre14Compat, CXXPre14CompatBinaryLiteral]>; -def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">; +def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat", + [CXX14CompatCTAD]>; def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic", [CXXPre17Compat]>; def CXXPre2aCompat : DiagGroup<"c++98-c++11-c++14-c++17-compat">; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2164,7 +2164,7 @@ def warn_cxx14_compat_class_template_argument_deduction : Warning< "class template argument deduction is incompatible with C++ standards " "before C++17%select{|; for compatibility, use explicit type name %1}0">, - InGroup, DefaultIgnore; + InGroup, DefaultIgnore; // C++14 deduced return types def err_auto_fn_deduction_failure : Error< Index: test/SemaCXX/cxx14-compat-ctad.cpp =================================================================== --- /dev/null +++ test/SemaCXX/cxx14-compat-ctad.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++14-compat-ctad -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++2a -Wc++14-compat-ctad -verify %s + +template struct X {}; +X x; // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17; for compatibility, use explicit type name 'X'}} + +template class> struct Y {}; +Y yx; // ok, not class template argument deduction + +template void f(T t) { + X x = t; // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17}} +} + +template void g(T t) { + typename T::X x = t; // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17; for compatibility, use explicit type name 'typename A::X' (aka 'A::X')}} +} + +struct A { template struct X { X(T); }; }; +void h(A a) { g(a); } // expected-note {{in instantiation of function template specialization 'g'}} + +template struct V { V(const T&) {} }; + +V(int) -> V; // ok, deduction guide is not a use of class template argument deduction + +void f2() { V v('a'); } // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17; for compatibility, use explicit type name 'V'}} +void g2() { V v(0); } // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17; for compatibility, use explicit type name 'V'}} + +void h2() { + auto lam = [](){}; + V v(lam); // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17}} +}