mizvekov updated this revision to Diff 384929.
mizvekov added a comment.

.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109496/new/

https://reviews.llvm.org/D109496

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/Driver/frelaxed-template-template-args.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaTemplate/default-arguments.cpp
  clang/test/SemaTemplate/instantiate-template-template-parm.cpp
  clang/test/SemaTemplate/nested-template.cpp
  clang/test/SemaTemplate/temp_arg_template.cpp
  clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -596,7 +596,7 @@
 <p>You can use Clang in C++17 mode with the <code>-std=c++17</code> option
 (use <code>-std=c++1z</code> in Clang 4 and earlier).</p>
 
-<details open>
+<details>
 <summary>List of features and minimum Clang version with support</summary>
 
 <table width="689" border="1" cellspacing="0">
@@ -813,8 +813,8 @@
     <!-- Issaquah 2016 papers -->
     <tr>
       <td>Matching template template parameters to compatible arguments</td>
-      <td><a href="https://wg21.link/p0522r0";>P0522R0</a></td>
-      <td class="partial" align="center">Partial <a href="#p0522">(10)</a></td>
+      <td><a href="https://wg21.link/p0522r0";>P0522R0</a> (<a href="#dr">DR</a>)</td>
+      <td class="full" align="center">Clang 4 <a href="#p0522">(10)</a></td>
     </tr>
     <tr>
       <td>Removing deprecated dynamic exception specifications</td>
@@ -842,13 +842,10 @@
 reverse construction order in that ABI.
 This is not fully supported during constant expression evaluation until Clang 12.
 </span><br>
-<span id="p0522">(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 <tt>-frelaxed-template-template-args</tt> 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.
+<span id="p0522">(10): Prior to Clang 14, this feature is not enabled by
+default, but can be enabled with <tt>-frelaxed-template-template-args</tt>.
+Starting from Clang 14, the flag is deprecated and will be removed in a future
+version.
 </span>
 </p>
 </details>
Index: clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
===================================================================
--- clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
+++ 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+{{}}
 
Index: clang/test/SemaTemplate/temp_arg_template.cpp
===================================================================
--- clang/test/SemaTemplate/temp_arg_template.cpp
+++ clang/test/SemaTemplate/temp_arg_template.cpp
@@ -6,11 +6,11 @@
 
 template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
 
-template<template<int I> class X> struct C;  // expected-note 2{{previous non-type template parameter with type 'int' is here}}
+template<template<int I> class X> struct C;  // expected-note {{previous non-type template parameter with type 'int' is here}}
 
 template<class> struct X; // expected-note{{too few template parameters in template template argument}}
 template<int N> struct Y; // expected-note{{template parameter has a different kind in template argument}}
-template<long N> struct Ylong; // expected-note{{template non-type parameter has a different type 'long' in template argument}}
+template<long N> struct Ylong;
 template<const int &N> struct Yref; // expected-note{{template non-type parameter has a different type 'const int &' in template argument}}
 
 namespace N {
@@ -27,7 +27,7 @@
 A<TooMany> *a5; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
 B<X> *a6; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
 C<Y> *a7;
-C<Ylong> *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+C<Ylong> *a8;
 C<Yref> *a9; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
 
 template<typename T> void f(int);
Index: clang/test/SemaTemplate/nested-template.cpp
===================================================================
--- clang/test/SemaTemplate/nested-template.cpp
+++ clang/test/SemaTemplate/nested-template.cpp
@@ -112,18 +112,16 @@
 // Template template parameters
 template<typename T>
 struct X2 {
-  template<template<class U, T Value> class>  // expected-error{{cannot have type 'float'}} \
-                                              // expected-note{{previous non-type template}}
+  template<template<class U, T Value> class>  // expected-error{{cannot have type 'float'}}
     struct Inner { };
 };
 
-template<typename T, 
-         int Value> // expected-note{{template non-type parameter}}
+template<typename T, int Value>
   struct X2_arg;
 
 X2<int>::Inner<X2_arg> x2i1;
 X2<float> x2a; // expected-note{{instantiation}}
-X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
+X2<long>::Inner<X2_arg> x2i3;
 
 namespace PR10896 {
   template<typename TN>
Index: clang/test/SemaTemplate/instantiate-template-template-parm.cpp
===================================================================
--- clang/test/SemaTemplate/instantiate-template-template-parm.cpp
+++ clang/test/SemaTemplate/instantiate-template-template-parm.cpp
@@ -20,30 +20,29 @@
 apply<add_reference, float>::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<int> struct B; // expected-note{{has a different type 'int'}}
+template<int> struct B;
 
 template<typename T, 
-         template<T Value> class X> // expected-error{{cannot have type 'float'}} \
-                                    // expected-note{{with type 'long'}}
+         template<T Value> class X> // expected-error{{cannot have type 'float'}}
 struct X0 { };
 
 X0<int, B> x0b1;
 X0<float, B> x0b2; // expected-note{{while substituting}}
-X0<long, B> x0b3; // expected-error{{template template argument has different template parameters}}
+X0<long, B> x0b3;
 
-template<template<int V> class TT> // expected-note{{parameter with type 'int'}}
+template<template<int V> class TT>
 struct X1 { };
 
 template<typename T, template<T V> class TT>
 struct X2 {
-  X1<TT> x1; // expected-error{{has different template parameters}}
+  X1<TT> x1;
 };
 
 template<int V> struct X3i { };
-template<long V> struct X3l { }; // expected-note{{different type 'long'}}
+template<long V> struct X3l { };
 
 X2<int, X3i> x2okay;
-X2<long, X3l> x2bad; // expected-note{{instantiation}}
+X2<long, X3l> x2bad;
 
 template <typename T, template <T, T> class TT, class R = TT<1, 2> >
 struct Comp {
Index: clang/test/SemaTemplate/default-arguments.cpp
===================================================================
--- clang/test/SemaTemplate/default-arguments.cpp
+++ clang/test/SemaTemplate/default-arguments.cpp
@@ -112,15 +112,14 @@
 int array4[is_same<X4<add_pointer>, 
                    X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
 
-template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
+template<int> struct X5 {};
 template<long> struct X5b {};
 template<typename T, 
-         template<T> class B = X5> // expected-error{{template template argument has different}} \
-                                   // expected-note{{previous non-type template parameter}}
+         template<T> class B = X5>
   struct X6 {};
 
 X6<int> x6a;
-X6<long> x6b; // expected-note{{while checking a default template argument}}
+X6<long> x6b;
 X6<long, X5b> x6c;
 
 
Index: clang/test/Lexer/cxx-features.cpp
===================================================================
--- clang/test/Lexer/cxx-features.cpp
+++ clang/test/Lexer/cxx-features.cpp
@@ -5,7 +5,6 @@
 // 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 -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 +194,7 @@
 #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 check(template_template_args, 201611, 201611, 201611, 201611, 201611, 201611)
 #error "wrong value for __cpp_template_template_args"
 #endif
 
Index: clang/test/Driver/frelaxed-template-template-args.cpp
===================================================================
--- /dev/null
+++ 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]
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===================================================================
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ 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<typename T> concept C = T::f();
 // expected-note@-1{{similar constraint}}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5514,33 +5514,52 @@
 /// neither partial specialization is more specialized, returns NULL.
 ClassTemplatePartialSpecializationDecl *
 Sema::getMoreSpecializedPartialSpecialization(
-                                  ClassTemplatePartialSpecializationDecl *PS1,
-                                  ClassTemplatePartialSpecializationDecl *PS2,
-                                              SourceLocation Loc) {
-  QualType PT1 = PS1->getInjectedSpecializationType();
-  QualType PT2 = PS2->getInjectedSpecializationType();
-
-  TemplateDeductionInfo Info(Loc);
-  bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info);
-  bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info);
-
-  if (!Better1 && !Better2)
-      return nullptr;
-  if (Better1 && Better2) {
+    ClassTemplatePartialSpecializationDecl *PS1,
+    ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc) {
+  {
+    QualType PT1 = PS1->getInjectedSpecializationType(),
+             PT2 = PS2->getInjectedSpecializationType();
+    TemplateDeductionInfo Info(Loc);
+    bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info),
+         Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info);
+    if (Better1 != Better2)
+      return Better1 ? PS1 : PS2;
+  }
+  {
     llvm::SmallVector<const Expr *, 3> AC1, AC2;
     PS1->getAssociatedConstraints(AC1);
     PS2->getAssociatedConstraints(AC2);
-    bool AtLeastAsConstrained1, AtLeastAsConstrained2;
-    if (IsAtLeastAsConstrained(PS1, AC1, PS2, AC2, AtLeastAsConstrained1))
-      return nullptr;
-    if (IsAtLeastAsConstrained(PS2, AC2, PS1, AC1, AtLeastAsConstrained2))
+    bool Better1, Better2;
+    if (IsAtLeastAsConstrained(PS1, AC1, PS2, AC2, Better1))
       return nullptr;
-    if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
+    if (IsAtLeastAsConstrained(PS2, AC2, PS1, AC1, Better2))
       return nullptr;
-    return AtLeastAsConstrained1 ? PS1 : PS2;
+    if (Better1 != Better2)
+      return Better1 ? PS1 : PS2;
   }
-
-  return Better1 ? PS1 : PS2;
+  {
+    // This is a workaround for the ambiguity issues created by
+    // P0522, which is the resolution of CWG 150.
+    // Pick as the more specialized partial specialization the one
+    // which has the first template argument of template specialization type
+    // with a smaller number of arguments.
+    auto As1 = PS1->getTemplateArgs().asArray(),
+         As2 = PS2->getTemplateArgs().asArray();
+    assert(As1.size() == As2.size());
+    for (int I = 0; I < As1.size(); ++I) {
+      const auto &A1 = As1[I], &A2 = As2[I];
+      if (A1.getKind() == TemplateArgument::ArgKind::Type &&
+          A2.getKind() == TemplateArgument::ArgKind::Type) {
+        const auto *AT1 = dyn_cast<TemplateSpecializationType>(
+                       A1.getAsType()->getCanonicalTypeInternal()),
+                   *AT2 = dyn_cast<TemplateSpecializationType>(
+                       A2.getAsType()->getCanonicalTypeInternal());
+        if (AT1 && AT2 && AT1->getNumArgs() != AT2->getNumArgs())
+          return AT1->getNumArgs() < AT2->getNumArgs() ? PS1 : PS2;
+      }
+    }
+  }
+  return nullptr;
 }
 
 bool Sema::isMoreSpecializedThanPrimary(
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -7407,56 +7407,50 @@
   // 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.
-  if (getLangOpts().RelaxedTemplateTemplateArgs) {
-    // Quick check for the common case:
-    //   If P contains a parameter pack, then A [...] matches P if each of A's
-    //   template parameters matches the corresponding template parameter in
-    //   the template-parameter-list of P.
-    if (TemplateParameterListsAreEqual(
-            Template->getTemplateParameters(), Params, false,
-            TPL_TemplateTemplateArgumentMatch, Arg.getLocation()) &&
-        // If the argument has no associated constraints, then the parameter is
-        // definitely at least as specialized as the argument.
-        // Otherwise - we need a more thorough check.
-        !Template->hasAssociatedConstraints())
-      return false;
+  // Quick check for the common case:
+  //   If P contains a parameter pack, then A [...] matches P if each of A's
+  //   template parameters matches the corresponding template parameter in
+  //   the template-parameter-list of P.
+  if (TemplateParameterListsAreEqual(Template->getTemplateParameters(), Params,
+                                     false, TPL_TemplateTemplateArgumentMatch,
+                                     Arg.getLocation()) &&
+      // If the argument has no associated constraints, then the parameter is
+      // definitely at least as specialized as the argument.
+      // Otherwise - we need a more thorough check.
+      !Template->hasAssociatedConstraints())
+    return false;
 
-    if (isTemplateTemplateParameterAtLeastAsSpecializedAs(Params, Template,
-                                                          Arg.getLocation())) {
-      // C++2a[temp.func.order]p2
-      //   [...] If both deductions succeed, the partial ordering selects the
-      //   more constrained template as described by the rules in
-      //   [temp.constr.order].
-      SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
-      Params->getAssociatedConstraints(ParamsAC);
-      // C++2a[temp.arg.template]p3
-      //   [...] In this comparison, if P is unconstrained, the constraints on A
-      //   are not considered.
-      if (ParamsAC.empty())
-        return false;
-      Template->getAssociatedConstraints(TemplateAC);
-      bool IsParamAtLeastAsConstrained;
-      if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
-                                 IsParamAtLeastAsConstrained))
-        return true;
-      if (!IsParamAtLeastAsConstrained) {
-        Diag(Arg.getLocation(),
-             diag::err_template_template_parameter_not_at_least_as_constrained)
-            << Template << Param << Arg.getSourceRange();
-        Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
-        Diag(Template->getLocation(), diag::note_entity_declared_at)
-            << Template;
-        MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
-                                                      TemplateAC);
-        return true;
-      }
+  if (isTemplateTemplateParameterAtLeastAsSpecializedAs(Params, Template,
+                                                        Arg.getLocation())) {
+    // C++2a[temp.func.order]p2
+    //   [...] If both deductions succeed, the partial ordering selects the
+    //   more constrained template as described by the rules in
+    //   [temp.constr.order].
+    SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
+    Params->getAssociatedConstraints(ParamsAC);
+    // C++2a[temp.arg.template]p3
+    //   [...] In this comparison, if P is unconstrained, the constraints on A
+    //   are not considered.
+    if (ParamsAC.empty())
       return false;
+    Template->getAssociatedConstraints(TemplateAC);
+    bool IsParamAtLeastAsConstrained;
+    if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
+                               IsParamAtLeastAsConstrained))
+      return true;
+    if (!IsParamAtLeastAsConstrained) {
+      Diag(Arg.getLocation(),
+           diag::err_template_template_parameter_not_at_least_as_constrained)
+          << Template << Param << Arg.getSourceRange();
+      Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
+      Diag(Template->getLocation(), diag::note_entity_declared_at) << Template;
+      MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
+                                                    TemplateAC);
+      return true;
     }
-    // FIXME: Produce better diagnostics for deduction failures.
+    return false;
   }
+  // FIXME: Produce better diagnostics for deduction failures.
 
   return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
                                          Params,
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -589,8 +589,8 @@
   }
   if (LangOpts.AlignedAllocation && !LangOpts.AlignedAllocationUnavailable)
     Builder.defineMacro("__cpp_aligned_new", "201606L");
-  if (LangOpts.RelaxedTemplateTemplateArgs)
-    Builder.defineMacro("__cpp_template_template_args", "201611L");
+
+  Builder.defineMacro("__cpp_template_template_args", "201611L");
 
   // C++20 features.
   if (LangOpts.CPlusPlus20) {
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1890,12 +1890,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() ==
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -6391,12 +6391,10 @@
                     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, with no effect.
+  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;
 
   // -fsized-deallocation is off by default, as it is an ABI-breaking change for
   // most platforms.
Index: clang/lib/Driver/SanitizerArgs.cpp
===================================================================
--- clang/lib/Driver/SanitizerArgs.cpp
+++ 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]";
   }
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2334,10 +2334,8 @@
   LangOpts<"AppExt">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Restrict code to those available for App Extensions">,
   NegFlag<SetFalse>>;
-defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-args",
-  LangOpts<"RelaxedTemplateTemplateArgs">, DefaultFalse,
-  PosFlag<SetTrue, [CC1Option], "Enable C++17 relaxed template template argument matching">,
-  NegFlag<SetFalse>>;
+def frelaxed_template_template_args : Flag<["-"], "frelaxed-template-template-args">, Flags<[]>;
+def fno_relaxed_template_template_args : Flag<["-"], "fno-relaxed-template-template-args">, Flags<[]>;
 defm sized_deallocation : BoolFOption<"sized-deallocation",
   LangOpts<"SizedDeallocation">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Enable C++14 sized global deallocation functions">,
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -149,7 +149,6 @@
 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(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
 
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -355,7 +355,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<Deprecated>;
+  "argument '%0' is deprecated%select{|, use '%2' instead}1">, InGroup<Deprecated>;
 def warn_drv_assuming_mfloat_abi_is : Warning<
   "unknown platform, assuming -mfloat-abi=%0">;
 def warn_ignoring_ftabstop_value : Warning<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to