-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[Clang] Fix the warning group of several compatibilty diagnostics #138872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: None (Sirraide) ChangesThere are a few diagnostics that are incorrectly grouped under I grepped for any remaining Fixes #138775. Patch is 21.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138872.diff 18 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 55f774f5a672e..d828b679a4d4c 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..fd7cd77692a97 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -132,7 +132,7 @@ 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;
+ 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..d8f8ff5bbddec 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<
@@ -5869,14 +5871,6 @@ def err_typename_refers_to_using_value_decl : Error<
"%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 err_template_kw_refers_to_non_template : Error<
"%0%select{| following the 'template' keyword}1 "
"does not refer to a template">;
@@ -9574,7 +9568,7 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
// 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;
+ 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>::...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes to DR tests look good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you for the fix!
…vm#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 llvm#138775.
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.