diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -352,7 +352,7 @@ def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; def warn_drv_deprecated_arg : Warning< - "argument '%0' is deprecated, use '%1' instead">, InGroup; + "argument '%0' is deprecated%select{|, use '%2' instead}1">, InGroup; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; def warn_ignoring_ftabstop_value : Warning< diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -149,7 +149,7 @@ LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly") LANGOPT(Coroutines , 1, 0, "C++20 coroutines") LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods") -LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments") +LANGOPT(RelaxedTemplateTemplateArgs, 1, 1, "C++17 relaxed matching of template template arguments") LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2324,9 +2324,9 @@ PosFlag, NegFlag>; defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-args", - LangOpts<"RelaxedTemplateTemplateArgs">, DefaultFalse, - PosFlag, - NegFlag>; + LangOpts<"RelaxedTemplateTemplateArgs">, DefaultTrue, + PosFlag, + NegFlag>; defm sized_deallocation : BoolFOption<"sized-deallocation", LangOpts<"SizedDeallocation">, DefaultFalse, PosFlag, diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -683,7 +683,8 @@ Arg->claim(); if (LegacySanitizeCoverage != 0) { D.Diag(diag::warn_drv_deprecated_arg) - << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard"; + << Arg->getAsString(Args) << true + << "-fsanitize-coverage=trace-pc-guard"; } continue; } @@ -718,11 +719,11 @@ // enabled. if (CoverageFeatures & CoverageTraceBB) D.Diag(clang::diag::warn_drv_deprecated_arg) - << "-fsanitize-coverage=trace-bb" + << "-fsanitize-coverage=trace-bb" << true << "-fsanitize-coverage=trace-pc-guard"; if (CoverageFeatures & Coverage8bitCounters) D.Diag(clang::diag::warn_drv_deprecated_arg) - << "-fsanitize-coverage=8bit-counters" + << "-fsanitize-coverage=8bit-counters" << true << "-fsanitize-coverage=trace-pc-guard"; int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge; @@ -732,7 +733,7 @@ if ((CoverageFeatures & InsertionPointTypes) && !(CoverageFeatures & InstrumentationTypes)) { D.Diag(clang::diag::warn_drv_deprecated_arg) - << "-fsanitize-coverage=[func|bb|edge]" + << "-fsanitize-coverage=[func|bb|edge]" << true << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]"; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6298,12 +6298,14 @@ options::OPT_fno_assume_sane_operator_new)) CmdArgs.push_back("-fno-assume-sane-operator-new"); - // -frelaxed-template-template-args is off by default, as it is a severe - // breaking change until a corresponding change to template partial ordering - // is provided. - if (Args.hasFlag(options::OPT_frelaxed_template_template_args, - options::OPT_fno_relaxed_template_template_args, false)) - CmdArgs.push_back("-frelaxed-template-template-args"); + // -frelaxed-template-template-args is deprecated and on by default. + if (Arg *A = + Args.getLastArg(options::OPT_frelaxed_template_template_args, + options::OPT_fno_relaxed_template_template_args)) { + D.Diag(diag::warn_drv_deprecated_arg) << A->getAsString(Args) << false; + if (A->getOption().matches(options::OPT_fno_relaxed_template_template_args)) + CmdArgs.push_back("-fno-relaxed-template-template-args"); + } // -fsized-deallocation is off by default, as it is an ABI-breaking change for // most platforms. diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1608,12 +1608,12 @@ // Emit warnings for legacy options even if they are overridden. if (Args.hasArg(options::OPT_mno_code_object_v3_legacy)) - D.Diag(diag::warn_drv_deprecated_arg) << "-mno-code-object-v3" - << "-mcode-object-version=2"; + D.Diag(diag::warn_drv_deprecated_arg) + << "-mno-code-object-v3" << true << "-mcode-object-version=2"; if (Args.hasArg(options::OPT_mcode_object_v3_legacy)) - D.Diag(diag::warn_drv_deprecated_arg) << "-mcode-object-v3" - << "-mcode-object-version=3"; + D.Diag(diag::warn_drv_deprecated_arg) + << "-mcode-object-v3" << true << "-mcode-object-version=3"; if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) { if (CodeObjArg->getOption().getID() == diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7420,9 +7420,7 @@ // C++1z [temp.arg.template]p3: (DR 150) // A template-argument matches a template template-parameter P when P // is at least as specialized as the template-argument A. - // FIXME: We should enable RelaxedTemplateTemplateArgs by default as it is a - // defect report resolution from C++17 and shouldn't be introduced by - // concepts. + // FIXME: RelaxedTemplateTemplateArgs is deprecated, should be always on. if (getLangOpts().RelaxedTemplateTemplateArgs) { // Quick check for the common case: // If P contains a parameter pack, then A [...] matches P if each of A's diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s +// RUN: %clang_cc1 -std=c++2a -verify %s template concept C = T::f(); // expected-note@-1{{similar constraint}} diff --git a/clang/test/Driver/frelaxed-template-template-args.cpp b/clang/test/Driver/frelaxed-template-template-args.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/frelaxed-template-template-args.cpp @@ -0,0 +1,5 @@ +// RUN: %clang -fsyntax-only -frelaxed-template-template-args %s 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: %clang -fsyntax-only -fno-relaxed-template-template-args %s 2>&1 | FileCheck --check-prefix=CHECK-OFF %s + +// CHECK-ON: warning: argument '-frelaxed-template-template-args' is deprecated [-Wdeprecated] +// CHECK-OFF: warning: argument '-fno-relaxed-template-template-args' is deprecated [-Wdeprecated] diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -5,7 +5,7 @@ // RUN: %clang_cc1 -std=c++20 -fcxx-exceptions -fsized-deallocation -verify %s // RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -fsized-deallocation -verify %s // -// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -frelaxed-template-template-args -DRELAXED_TEMPLATE_TEMPLATE_ARGS=1 -verify %s +// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -fno-relaxed-template-template-args -DNO_RELAXED_TEMPLATE_TEMPLATE_ARGS=1 -verify %s // RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -DCONCEPTS_TS=1 -verify %s // RUN: %clang_cc1 -std=c++14 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation // RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify -fsized-deallocation %s @@ -195,9 +195,9 @@ #error "wrong value for __cpp_nontype_template_args" #endif -#if defined(RELAXED_TEMPLATE_TEMPLATE_ARGS) \ - ? check(template_template_args, 0, 0, 0, 201611, 201611, 201611) \ - : check(template_template_args, 0, 0, 0, 0, 0, 0) +#if defined(NO_RELAXED_TEMPLATE_TEMPLATE_ARGS) \ + ? check(template_template_args, 0, 0, 0, 0, 0, 0) \ + : check(template_template_args, 0, 0, 0, 201611, 201611, 201611) #error "wrong value for __cpp_template_template_args" #endif diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -60,12 +60,14 @@ // Replacement of templates template class TT, typename T1, typename Arg1, typename Arg2> struct Replace, Arg1, Arg2> { +// expected-note@-1 2 {{partial specialization matches}} typedef TT::type> type; }; template class TT, typename T1, typename T2, typename Arg1, typename Arg2> struct Replace, Arg1, Arg2> { +// expected-note@-1 2 {{partial specialization matches}} typedef TT::type, typename Replace::type> type; }; @@ -79,8 +81,19 @@ int array0[is_same::type, int>::value? 1 : -1]; int array1[is_same::type, const int>::value? 1 : -1]; + int array2[is_same, int, float>::type, vector >::value? 1 : -1]; +// expected-error@-1 {{ambiguous partial specializations of 'Replace, int, float>'}} +// FIXME: Some bad error recovery from the parser here: +// expected-error@-3 {{expected '(' for function-style cast or type construction}} +// expected-error@-4 {{no member named 'value' in the global namespace}} + int array3[is_same, int, float>::type, vector >::value? 1 : -1]; +// expected-error@-1 {{ambiguous partial specializations of 'Replace, int, float>'}} +// FIXME: Some bad error recovery from the parser here: +// expected-error@-3 {{expected '(' for function-style cast or type construction}} +// expected-error@-4 {{no member named 'value' in the global namespace}} + int array4[is_same, double, float>::type, vector >::value? 1 : -1]; // PR5911 diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -112,15 +112,14 @@ int array4[is_same, X4 >::value? 1 : -1]; -template struct X5 {}; // expected-note{{has a different type 'int'}} +template struct X5 {}; template struct X5b {}; template class B = X5> // expected-error{{template template argument has different}} \ - // expected-note{{previous non-type template parameter}} + template class B = X5> struct X6 {}; X6 x6a; -X6 x6b; // expected-note{{while checking a default template argument}} +X6 x6b; X6 x6c; diff --git a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp --- a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp +++ b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp @@ -20,30 +20,29 @@ apply::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}} // Template template parameters -template struct B; // expected-note{{has a different type 'int'}} +template struct B; template class X> // expected-error{{cannot have type 'float'}} \ - // expected-note{{with type 'long'}} + template class X> // expected-error{{cannot have type 'float'}} struct X0 { }; X0 x0b1; X0 x0b2; // expected-note{{while substituting}} -X0 x0b3; // expected-error{{template template argument has different template parameters}} +X0 x0b3; -template class TT> // expected-note{{parameter with type 'int'}} +template class TT> struct X1 { }; template class TT> struct X2 { - X1 x1; // expected-error{{has different template parameters}} + X1 x1; }; template struct X3i { }; -template struct X3l { }; // expected-note{{different type 'long'}} +template struct X3l { }; X2 x2okay; -X2 x2bad; // expected-note{{instantiation}} +X2 x2bad; template class TT, class R = TT<1, 2> > struct Comp { diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp --- a/clang/test/SemaTemplate/nested-template.cpp +++ b/clang/test/SemaTemplate/nested-template.cpp @@ -112,18 +112,16 @@ // Template template parameters template struct X2 { - template class> // expected-error{{cannot have type 'float'}} \ - // expected-note{{previous non-type template}} + template class> // expected-error{{cannot have type 'float'}} struct Inner { }; }; -template // expected-note{{template non-type parameter}} +template struct X2_arg; X2::Inner x2i1; X2 x2a; // expected-note{{instantiation}} -X2::Inner x2i3; // expected-error{{template template argument has different}} +X2::Inner x2i3; namespace PR10896 { template diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -6,11 +6,11 @@ template class X> struct B; // expected-note{{previous template template parameter is here}} -template class X> struct C; // expected-note 2{{previous non-type template parameter with type 'int' is here}} +template class X> struct C; // expected-note {{previous non-type template parameter with type 'int' is here}} template struct X; // expected-note{{too few template parameters in template template argument}} template struct Y; // expected-note{{template parameter has a different kind in template argument}} -template struct Ylong; // expected-note{{template non-type parameter has a different type 'long' in template argument}} +template struct Ylong; template struct Yref; // expected-note{{template non-type parameter has a different type 'const int &' in template argument}} namespace N { @@ -27,7 +27,7 @@ A *a5; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}} B *a6; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}} C *a7; -C *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}} +C *a8; C *a9; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}} template void f(int); diff --git a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp --- a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp +++ b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -frelaxed-template-template-args %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s // expected-note@temp_arg_template_cxx1z.cpp:* 1+{{}} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -814,7 +814,7 @@ Matching template template parameters to compatible arguments P0522R0 - Partial (10) + Clang 14 Removing deprecated dynamic exception specifications @@ -841,14 +841,6 @@ functions using expression syntax are no longer guaranteed to be destroyed in reverse construction order in that ABI. This is not fully supported during constant expression evaluation until Clang 12. -
-(10): Despite being the resolution to a Defect Report, this -feature is disabled by default in all language versions, and can be enabled -explicitly with the flag -frelaxed-template-template-args in Clang 4 -onwards. -The change to the standard lacks a corresponding change for template partial -ordering, resulting in ambiguity errors for reasonable and previously-valid -code. This issue is expected to be rectified soon.