Author: Sirraide
Date: 2025-05-08T01:41:57+02:00
New Revision: 45b5cc08e5823c59802f88ec3f27108ab98c1eb9

URL: 
https://github.com/llvm/llvm-project/commit/45b5cc08e5823c59802f88ec3f27108ab98c1eb9
DIFF: 
https://github.com/llvm/llvm-project/commit/45b5cc08e5823c59802f88ec3f27108ab98c1eb9.diff

LOG: [Clang] Fix the warning group of several compatibilty diagnostics (#138872)

There are a few diagnostics that are incorrectly grouped under
`-Wc++20-compat` instead of `-Wpre-c++20-compat`.

I grepped for any remaining `-Wc++xy-compat` diagnostics, but they all
seem to actually be about compatibility with C++XY.

Fixes #138775.

Added: 
    clang/test/SemaCXX/gh138775.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticCommonKinds.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/CXX/drs/cwg1xx.cpp
    clang/test/CXX/drs/cwg2xx.cpp
    clang/test/CXX/drs/cwg4xx.cpp
    clang/test/CXX/drs/cwg5xx.cpp
    clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
    clang/test/FixIt/fixit.cpp
    clang/test/SemaCXX/MicrosoftCompatibility.cpp
    clang/test/SemaCXX/MicrosoftExtensions.cpp
    clang/test/SemaCXX/MicrosoftSuper.cpp
    clang/test/SemaCXX/rounding-math-crash.cpp
    clang/test/SemaCXX/unknown-type-name.cpp
    clang/test/SemaTemplate/typename-specifier-3.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9c4ab80537ac9..4c25d6d4d515a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -505,6 +505,9 @@ Improvements to Clang's diagnostics
 - ``-Wreserved-identifier`` now fires on reserved parameter names in a function
   declaration which is not a definition.
 
+- Several compatibility diagnostics that were incorrectly being grouped under
+  ``-Wpre-c++20-compat`` are now part of ``-Wc++20-compat``. (#GH138775)
+
 Improvements to Clang's time-trace
 ----------------------------------
 

diff  --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f26c906b46447..e4d94fefbbf3d 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -130,9 +130,11 @@ def err_attribute_not_type_attr : Error<
   "%0%select{ attribute|}1 cannot be applied to types">;
 def err_enum_template : Error<"enumeration cannot be a template">;
 
-def warn_cxx20_compat_consteval : Warning<
-  "'consteval' specifier is incompatible with C++ standards before C++20">,
-  InGroup<CXX20Compat>, DefaultIgnore;
+def warn_cxx20_compat_consteval
+    : Warning<"'consteval' specifier is incompatible with C++ standards before 
"
+              "C++20">,
+      InGroup<CXXPre20Compat>,
+      DefaultIgnore;
 def warn_missing_type_specifier : Warning<
   "type specifier missing, defaults to 'int'">,
   InGroup<ImplicitInt>, DefaultIgnore;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 195e1202880b9..e1b9ed0647bb9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -51,6 +51,8 @@ defm adl_only_template_id : CXX20Compat<
   "with explicit template arguments is">;
 defm ctad_for_alias_templates
     : CXX20Compat<"class template argument deduction for alias templates is">;
+defm implicit_typename
+    : CXX20Compat<"missing 'typename' prior to dependent type name %0 is">;
 
 // C++23 compatibility with C++20 and earlier.
 defm constexpr_static_var : CXX23Compat<
@@ -5867,16 +5869,8 @@ def ext_typename_missing
 def err_typename_refers_to_using_value_decl : Error<
   "typename specifier refers to a dependent using declaration for a value "
   "%0 in %1">;
-def note_using_value_decl_missing_typename : Note<
-  "add 'typename' to treat this using declaration as a type">;
-def warn_cxx17_compat_implicit_typename : Warning<"use of implicit 'typename' 
is "
-  "incompatible with C++ standards before C++20">, InGroup<CXX20Compat>,
-  DefaultIgnore;
-def ext_implicit_typename
-    : ExtWarn<"missing 'typename' prior to dependent "
-              "type name %0; implicit 'typename' is a C++20 extension">,
-      InGroup<CXX20>;
-
+def note_using_value_decl_missing_typename
+    : Note<"add 'typename' to treat this using declaration as a type">;
 def err_template_kw_refers_to_non_template : Error<
   "%0%select{| following the 'template' keyword}1 "
   "does not refer to a template">;
@@ -9572,9 +9566,11 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
   "incomplete type %0 used in type trait expression">, NoSFINAE;
 
 // C++20 constinit and require_constant_initialization attribute
-def warn_cxx20_compat_constinit : Warning<
-  "'constinit' specifier is incompatible with C++ standards before C++20">,
-  InGroup<CXX20Compat>, DefaultIgnore;
+def warn_cxx20_compat_constinit
+    : Warning<"'constinit' specifier is incompatible with C++ standards before 
"
+              "C++20">,
+      InGroup<CXXPre20Compat>,
+      DefaultIgnore;
 def err_constinit_local_variable : Error<
   "local variable cannot be declared 'constinit'">;
 def err_require_constant_init_failed : Error<

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6b561d7bfc6e7..5a45198a7ce02 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -349,12 +349,11 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, 
SourceLocation NameLoc,
           if (AllowImplicitTypename == ImplicitTypenameContext::No)
             return nullptr;
           SourceLocation QualifiedLoc = SS->getRange().getBegin();
-          if (getLangOpts().CPlusPlus20)
-            Diag(QualifiedLoc, diag::warn_cxx17_compat_implicit_typename);
-          else
-            Diag(QualifiedLoc, diag::ext_implicit_typename)
-                << NestedNameSpecifier::Create(Context, SS->getScopeRep(), &II)
-                << FixItHint::CreateInsertion(QualifiedLoc, "typename ");
+          auto DB =
+              DiagCompat(QualifiedLoc, diag_compat::implicit_typename)
+              << NestedNameSpecifier::Create(Context, SS->getScopeRep(), &II);
+          if (!getLangOpts().CPlusPlus20)
+            DB << FixItHint::CreateInsertion(QualifiedLoc, "typename ");
         }
 
         // We know from the grammar that this name refers to a type,

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 65706d4b15455..94f4c1c46c1fb 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3775,12 +3775,10 @@ TypeResult Sema::ActOnTemplateIdType(
       NestedNameSpecifier *NNS =
           NestedNameSpecifier::Create(Context, SS.getScopeRep(), TemplateII);
       if (AllowImplicitTypename == ImplicitTypenameContext::Yes) {
-        if (getLangOpts().CPlusPlus20)
-          Diag(SS.getBeginLoc(), diag::warn_cxx17_compat_implicit_typename);
-        else
-          Diag(SS.getBeginLoc(), diag::ext_implicit_typename)
-              << NNS
-              << FixItHint::CreateInsertion(SS.getBeginLoc(), "typename ");
+        auto DB = DiagCompat(SS.getBeginLoc(), diag_compat::implicit_typename)
+                  << NNS;
+        if (!getLangOpts().CPlusPlus20)
+          DB << FixItHint::CreateInsertion(SS.getBeginLoc(), "typename ");
       } else
         Diag(SS.getBeginLoc(), diag::err_typename_missing_template) << NNS;
 

diff  --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index 6b9ad31bffbcd..8b84de0ab5a9a 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -96,7 +96,7 @@ namespace cwg108 { // cwg108: 2.9
   template<typename T> struct A {
     struct B { typedef int X; };
     B::X x;
-    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B::X'; implicit 'typename' is a C++20 extension}}
+    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B::X' is a C++20 extension}}
     struct C : B { X x; };
     // expected-error@-1 {{unknown type name 'X'}}
   };
@@ -321,7 +321,7 @@ namespace cwg121 { // cwg121: 2.7
     X::Y<T> x;
     T::Y<T> y;
     // expected-error@-1 {{use 'template' keyword to treat 'Y' as a dependent 
template name}}
-    // cxx98-17-error@-2 {{missing 'typename' prior to dependent type name 
'T::Y'; implicit 'typename' is a C++20 extension}}
+    // cxx98-17-error@-2 {{missing 'typename' prior to dependent type name 
'T::Y' is a C++20 extension}}
   };
   Z<X> z;
 } // namespace cwg121

diff  --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index b2ae8f88ead74..a53a8d1ed64a8 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -426,7 +426,7 @@ namespace cwg224 { // cwg224: 16
       A::type a;
       A<T>::type b;
       A<T*>::type c;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::type' is a C++20 extension}}
       ::cwg224::example1::A<T>::type d;
 
       class B {
@@ -435,13 +435,13 @@ namespace cwg224 { // cwg224: 16
         A::type a;
         A<T>::type b;
         A<T*>::type c;
-        // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::type'; implicit 'typename' is a C++20 extension}}
+        // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::type' is a C++20 extension}}
         ::cwg224::example1::A<T>::type d;
 
         B::type e;
         A<T>::B::type f;
         A<T*>::B::type g;
-        // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::B::type'; implicit 'typename' is a C++20 extension}}
+        // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::B::type' is a C++20 extension}}
         typename A<T*>::B::type h;
       };
     };
@@ -450,25 +450,25 @@ namespace cwg224 { // cwg224: 16
       typedef int type;
       A<T*>::type a;
       A<T>::type b;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T>::type' is a C++20 extension}}
     };
 
     template <class T1, class T2, int I> struct B {
       typedef int type;
       B<T1, T2, I>::type b1;
       B<T2, T1, I>::type b2;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<T2, T1, I>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<T2, T1, I>::type' is a C++20 extension}}
 
       typedef T1 my_T1;
       static const int my_I = I;
       static const int my_I2 = I+0;
       static const int my_I3 = my_I;
       B<my_T1, T2, my_I>::type b3;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<my_T1, T2, my_I>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<my_T1, T2, my_I>::type' is a C++20 extension}}
       B<my_T1, T2, my_I2>::type b4;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<my_T1, T2, my_I2>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<my_T1, T2, my_I2>::type' is a C++20 extension}}
       B<my_T1, T2, my_I3>::type b5;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<my_T1, T2, my_I3>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'B<my_T1, T2, my_I3>::type' is a C++20 extension}}
     };
   }
 
@@ -480,7 +480,7 @@ namespace cwg224 { // cwg224: 16
       X<A::i, char>::type x;
       X<A<T>::i, double>::type y;
       X<A<T*>::i, long>::type z;
-      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'X<A<T *>::i, long>::type'; implicit 'typename' is a C++20 extension}}
+      // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'X<A<T *>::i, long>::type' is a C++20 extension}}
       int f();
     };
     template <class T> int A<T>::f() {

diff  --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index e8e2600870233..210f7ae71ec04 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -257,7 +257,7 @@ namespace cwg409 { // cwg409: 2.7
     A::B b2;
     A<T>::B b3;
     A<T*>::B b4;
-    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::B'; implicit 'typename' is a C++20 extension}}
+    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'A<T *>::B' is a C++20 extension}}
   };
 } // namespace cwg409
 

diff  --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp
index 0825b52653b4d..1d505adecfb27 100644
--- a/clang/test/CXX/drs/cwg5xx.cpp
+++ b/clang/test/CXX/drs/cwg5xx.cpp
@@ -254,9 +254,9 @@ namespace cwg526 { // cwg526: 2.7
     typedef int type;
     X<N>::type v1;
     X<(N)>::type v2;
-    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'X<(N)>::type'; implicit 'typename' is a C++20 extension}}
+    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'X<(N)>::type' is a C++20 extension}}
     X<+N>::type v3;
-    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'X<+N>::type'; implicit 'typename' is a C++20 extension}}
+    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'X<+N>::type' is a C++20 extension}}
   };
 } // namespace cwg526
 
@@ -783,7 +783,7 @@ struct Outer {
 };
 template <class T>
 Outer<T>::Inner* Outer<T>::Inner::self() { return this; }
-// cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'Outer<T>::Inner'; implicit 'typename' is a C++20 extension}}
+// cxx98-17-error@-1 {{missing 'typename' prior to dependent type name 
'Outer<T>::Inner' is a C++20 extension}}
 
 } // namespace cwg560
 

diff  --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp 
b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
index 910dab11ee5e1..acaeea9e70e3f 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
@@ -17,7 +17,7 @@ namespace Example1 {
 
   template<class T> struct A<A<A<T>>> {
     struct C {};
-    B<B<T>>::C bc; // expected-warning {{implicit 'typename' is a C++20 
extension}}
+    B<B<T>>::C bc; // expected-warning {{missing 'typename' prior to dependent 
type name 'B<B<T>>::C' is a C++20 extension}}
   };
 }
 

diff  --git a/clang/test/FixIt/fixit.cpp b/clang/test/FixIt/fixit.cpp
index 605c2d0bd0235..3e5040969c3ee 100644
--- a/clang/test/FixIt/fixit.cpp
+++ b/clang/test/FixIt/fixit.cpp
@@ -211,7 +211,7 @@ struct MoreAccidentalCommas {
 template<class T> struct Mystery;
 template<class T> typedef Mystery<T>::type getMysteriousThing() { // \
   expected-error {{function definition declared 'typedef'}} \
-  expected-warning {{implicit 'typename' is a C++20 extension}}
+  expected-warning {{missing 'typename' prior to dependent type name 
'Mystery<T>::type' is a C++20 extension}}
   return Mystery<T>::get();
 }
 

diff  --git a/clang/test/SemaCXX/MicrosoftCompatibility.cpp 
b/clang/test/SemaCXX/MicrosoftCompatibility.cpp
index a830883280173..b8cd22ad350a5 100644
--- a/clang/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/clang/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -211,14 +211,14 @@ class C : private A<T>, public B<U> {
    typedef B<U> Base2;
    typedef A<U> Base3;
 
-   A<T>::TYPE a1; // expected-warning {{implicit 'typename' is a C++20 
extension}}
-   Base1::TYPE a2; // expected-warning {{implicit 'typename' is a C++20 
extension}}
+   A<T>::TYPE a1; // expected-warning {{missing 'typename' prior to dependent 
type name 'A<T>::TYPE' is a C++20 extension}}
+   Base1::TYPE a2; // expected-warning {{missing 'typename' prior to dependent 
type name 'Base1::TYPE' is a C++20 extension}}
 
-   B<U>::TYPE a3; // expected-warning {{implicit 'typename' is a C++20 
extension}}
-   Base2::TYPE a4; // expected-warning {{implicit 'typename' is a C++20 
extension}}
+   B<U>::TYPE a3; // expected-warning {{missing 'typename' prior to dependent 
type name 'B<U>::TYPE' is a C++20 extension}}
+   Base2::TYPE a4; // expected-warning {{missing 'typename' prior to dependent 
type name 'Base2::TYPE' is a C++20 extension}}
 
-   A<U>::TYPE a5; // expected-warning {{implicit 'typename' is a C++20 
extension}}
-   Base3::TYPE a6; // expected-warning {{implicit 'typename' is a C++20 
extension}}
+   A<U>::TYPE a5; // expected-warning {{missing 'typename' prior to dependent 
type name 'A<U>::TYPE' is a C++20 extension}}
+   Base3::TYPE a6; // expected-warning {{missing 'typename' prior to dependent 
type name 'Base3::TYPE' is a C++20 extension}}
  };
 
 class D {

diff  --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp 
b/clang/test/SemaCXX/MicrosoftExtensions.cpp
index 7454a01158f6b..4dff2b1c362a7 100644
--- a/clang/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp
@@ -613,7 +613,7 @@ typedef char __unaligned *aligned_type; // expected-error 
{{expected ';' after t
 
 namespace PR32750 {
 template<typename T> struct A {};
-template<typename T> struct B : A<A<T>> { A<T>::C::D d; }; // expected-warning 
{{implicit 'typename' is a C++20 extension}}
+template<typename T> struct B : A<A<T>> { A<T>::C::D d; }; // expected-warning 
{{missing 'typename' prior to dependent type name 'A<T>::C::D' is a C++20 
extension}}
 }
 
 #endif

diff  --git a/clang/test/SemaCXX/MicrosoftSuper.cpp 
b/clang/test/SemaCXX/MicrosoftSuper.cpp
index 94e29b23ef11c..d117b93523363 100644
--- a/clang/test/SemaCXX/MicrosoftSuper.cpp
+++ b/clang/test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@ struct DerivedFromDependentBase : BaseTemplate<T> {
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c;         // expected-warning {{implicit 'typename' is a C++20 
extension}}
-  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++20 
extension}}
+  __super::XXX c;         // expected-warning {{missing 'typename'}}
+  typedef __super::XXX d; // expected-warning {{missing 'typename'}}
 
   void foo() {
     typename __super::XXX e;
@@ -127,8 +127,8 @@ struct DerivedFromTemplateParameter : T {
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c;         // expected-warning {{implicit 'typename' is a C++20 
extension}}
-  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++20 
extension}}
+  __super::XXX c;         // expected-warning {{missing 'typename'}}
+  typedef __super::XXX d; // expected-warning {{missing 'typename'}}
 
   void foo() {
     typename __super::XXX e;

diff  --git a/clang/test/SemaCXX/gh138775.cpp b/clang/test/SemaCXX/gh138775.cpp
new file mode 100644
index 0000000000000..854e25f84fe49
--- /dev/null
+++ b/clang/test/SemaCXX/gh138775.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=cxx17 %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=pre-cxx20-compat 
-Wpre-c++20-compat %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=cxx20-compat 
-Wc++20-compat %s
+// cxx20-compat-no-diagnostics
+
+// cxx17-error@+4 {{unknown type name 'consteval'; did you mean 'constexpr'}}
+// cxx17-warning@+3 {{missing 'typename' prior to dependent type name 
'T::type' is a C++20 extension}}
+// pre-cxx20-compat-warning@+2 {{'consteval' specifier is incompatible with 
C++ standards before C++20}}
+// pre-cxx20-compat-warning@+1 {{missing 'typename' prior to dependent type 
name 'T::type' is incompatible with C++ standards before C++20}}
+template<typename T> consteval T::type f();
+
+// cxx17-error@+2 {{unknown type name 'constinit'}}
+// pre-cxx20-compat-warning@+1 {{'constinit' specifier is incompatible with 
C++ standards before C++20}}
+constinit int x = 4;

diff  --git a/clang/test/SemaCXX/rounding-math-crash.cpp 
b/clang/test/SemaCXX/rounding-math-crash.cpp
index 2a09b02fe9cef..f9c5ada2a403e 100644
--- a/clang/test/SemaCXX/rounding-math-crash.cpp
+++ b/clang/test/SemaCXX/rounding-math-crash.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -frounding-math -verify 
%s
 
 template <class b> b::a() {}
-// expected-warning@-1 {{implicit 'typename' is a C++20 extension}}
+// expected-warning@-1 {{missing 'typename' prior to dependent type name 
'b::a' is a C++20 extension}}
 // expected-error@-2 {{expected unqualified-id}}

diff  --git a/clang/test/SemaCXX/unknown-type-name.cpp 
b/clang/test/SemaCXX/unknown-type-name.cpp
index 602f8f9ec7d29..9ce8b69c5bd22 100644
--- a/clang/test/SemaCXX/unknown-type-name.cpp
+++ b/clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@ struct A {
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-warning{{implicit 'typename' is a 
C++20 extension}}
-  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a 
C++20 extension}}
+  static int h(T::type, int); // expected-warning{{missing 'typename'}}
+  static int h(T::type x, char); // expected-warning{{missing 'typename'}}
 };
 
 template<typename T>
-A<T>::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a 
C++20 extension}}
+A<T>::type g(T t) { return t; } // expected-warning{{missing 'typename'}}
 
 template<typename T>
-A<T>::type A<T>::f() { return type(); } // expected-warning{{implicit 
'typename' is a C++20 extension}}
+A<T>::type A<T>::f() { return type(); } // expected-warning{{missing 
'typename'}}
 
 template<typename T>
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@ int *test(UnknownType *fool) { return 0; } // 
expected-error{{unknown type name
 
 template<typename T> int A<T>::n(T::value); // ok
 template<typename T>
-A<T>::type // expected-warning {{implicit 'typename' is a C++20 extension}}
+A<T>::type // expected-warning {{missing 'typename'}}
 A<T>::m(T::value, 0); // ok
 
-template<typename T> int A<T>::h(T::type, int) {} // 
expected-warning{{implicit 'typename' is a C++20 extension}}
-template<typename T> int A<T>::h(T::type x, char) {} // 
expected-warning{{implicit 'typename' is a C++20 extension}}
+template<typename T> int A<T>::h(T::type, int) {} // expected-warning{{missing 
'typename'}}
+template<typename T> int A<T>::h(T::type x, char) {} // 
expected-warning{{missing 'typename'}}
 
 template<typename T> int h(T::type, int); // expected-error{{missing 
'typename'}}
 template<typename T> int h(T::type x, char); // expected-error{{missing 
'typename'}}
@@ -117,4 +117,4 @@ template<typename T> int i(T::type, int());
 //        a fix-it to add 'typename A<T>::type'
 template<typename T>
 A<T>::g() { } // expected-error{{expected unqualified-id}}
-// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
+// expected-warning@-1{{missing 'typename'}}

diff  --git a/clang/test/SemaTemplate/typename-specifier-3.cpp 
b/clang/test/SemaTemplate/typename-specifier-3.cpp
index cdd065c98bb0a..6e09012a86e6a 100644
--- a/clang/test/SemaTemplate/typename-specifier-3.cpp
+++ b/clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@ namespace PR12884_original {
       typedef int arg;
     };
     struct C {
-      typedef B::X<typename B::arg> x; // precxx17-warning{{missing 'typename' 
prior to dependent type name 'B::X'; implicit 'typename' is a C++20 extension}}
+      typedef B::X<typename B::arg> x; // precxx17-warning{{missing 'typename' 
prior to dependent type name 'B::X' is a C++20 extension}}
     };
   };
 


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to