[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-30 Thread Corentin Jabot via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0550601d1801: [Clang] Add a compatibiliy warning for 
non-literals in constexpr. (authored by cor3ntin).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++2b-extensions
 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
 
-struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}}
+struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}} \
+// cxx2b-note 2{{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
@@ -96,7 +97,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +165,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,7 +229,7 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
+constexpr auto dependent_var_def_lambda() {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
   T t;
@@ -237,4 +239,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -25,17 +25,18 @@
 label:; // expected-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
-struct NonLiteral {
+struct NonLiteral { // expected-note 2 {{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,11 +1901,17 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, 

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-30 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

I thing to support the template case, we would have to modify 
`TemplateDeclInstantiator::VisitVarDecl` - which seems the best way to have a 
diagnostic without running through the whole function AST twice.
However, there is currently no check of any sort there so it would be a bit 
novel and odd!

Thank you both for the review


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-30 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.

LGTM




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

hubert.reinterpretcast wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > aaron.ballman wrote:
> > > > cor3ntin wrote:
> > > > > hubert.reinterpretcast wrote:
> > > > > > This seems to trigger even when the type is dependent:
> > > > > > ```
> > > > > > :1:36: warning: definition of a variable of non-literal type 
> > > > > > in a constexpr function is incompatible with C++ standards before 
> > > > > > C++2b [-Wpre-c++2b-compat]
> > > > > > auto qq = [](auto x) { decltype(x) n; };
> > > > > >^
> > > > > > 1 warning generated.
> > > > > > ```
> > > > > > 
> > > > > > This also seems to emit even when `Kind` is not 
> > > > > > `Sema::CheckConstexprKind::Diagnose` (unlike the 
> > > > > > `static`/`thread_local` case above). Is the `CheckLiteralType` 
> > > > > > logic not reusable for this?
> > > > > You are right, thanks for noticing that, it was rather bogus.
> > > > > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > > > > diagnostics message, as CheckLiteralType doesn't allow us to pass 
> > > > > parameter to the diagnostic message.
> > > > > 
> > > > > It leaves us with an uncovered scenario though: We do not emit the 
> > > > > warning on template instantiation, and I don't think there is an  
> > > > > easy way to do that.
> > > > > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > > > > diagnostics message, as CheckLiteralType doesn't allow us to pass 
> > > > > parameter to the diagnostic message.
> > > > 
> > > > Huh?
> > > > 
> > > > ```
> > > > static bool CheckLiteralType(Sema , Sema::CheckConstexprKind 
> > > > Kind,
> > > >  SourceLocation Loc, QualType T, unsigned 
> > > > DiagID,
> > > >  Ts &&...DiagArgs) {
> > > >   ...
> > > > }
> > > > ```
> > > > I would hope `DiagArgs` should do exactly that? :-)
> > > > It leaves us with an uncovered scenario though: We do not emit the 
> > > > warning on template instantiation, and I don't think there is an easy 
> > > > way to do that.
> > > 
> > > I believe the code paths that lead us here all come from 
> > > `Sema::CheckConstexprFunctionDefinition()` which is called from 
> > > `Sema::ActOnFinishFunctionBody()` which seems to be called when 
> > > instantiating templates in `Sema::InstantiateFunctionDefinition()`, so 
> > > perhaps some more investigation is needed as to why we're not reaching 
> > > this for template instantiations.
> > We could add something in addition of 
> > `Sema::CheckConstexprKind::CheckValid` and 
> > `Sema::CheckConstexprKind::Diagnose`, but 
> > 
> > * not for implicit lambdas, because we should not warn on lambdas that 
> > won't be constexpr
> > * for explicit constexpr lambdas / functions, it would force us to call 
> > CheckConstexprFunctionDefinition  on instanciation, which we currently 
> > don't do, and is not free for that one warning - and we would have to 
> > not-reemit the other warnings. It seems like quite a fair amount of work 
> > for a diagnostic not enabled by default.
> > so perhaps some more investigation is needed as to why we're not reaching 
> > this for template instantiations.
> 
> @aaron.ballman, do you have any position on whether we want this 
> investigation before moving forward with this patch?
>>so perhaps some more investigation is needed as to why we're not reaching 
>>this for template instantiations.
> @aaron.ballman, do you have any position on whether we want this 
> investigation before moving forward with this patch?

@hubert.reinterpretcast -- I think @cor3ntin did that investigation and found 
that we don't make it to this code path because of 
https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaDecl.cpp#L14961.

I think this is incremental progress, and we can handle the template 
instantiation cases in a follow-up.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-30 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419158.
cor3ntin added a comment.

Add braces


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++2b-extensions
 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
 
-struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}}
+struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}} \
+// cxx2b-note 2{{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
@@ -96,7 +97,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +165,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,7 +229,7 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
+constexpr auto dependent_var_def_lambda() {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
   T t;
@@ -237,4 +239,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -25,17 +25,18 @@
 label:; // expected-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
-struct NonLiteral {
+struct NonLiteral { // expected-note 2 {{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,11 +1901,17 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
- diag::err_constexpr_local_var_non_literal_type,
- isa(Dcl)))
+if 

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-30 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast accepted this revision.
hubert.reinterpretcast added a comment.
This revision is now accepted and ready to land.

This LGTM (with minor comment). Please wait for Aaron to respond re: the 
handling of template instantiations.




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1912-1913
+   diag::err_constexpr_local_var_non_literal_type,
+   isa(Dcl)))
   return false;
 if (!VD->getType()->isDependentType() &&

Minor nit: The coding standards were updated (some time ago now) to recommend 
keeping if-else chains consistently braced or not-braced.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

cor3ntin wrote:
> aaron.ballman wrote:
> > aaron.ballman wrote:
> > > cor3ntin wrote:
> > > > hubert.reinterpretcast wrote:
> > > > > This seems to trigger even when the type is dependent:
> > > > > ```
> > > > > :1:36: warning: definition of a variable of non-literal type 
> > > > > in a constexpr function is incompatible with C++ standards before 
> > > > > C++2b [-Wpre-c++2b-compat]
> > > > > auto qq = [](auto x) { decltype(x) n; };
> > > > >^
> > > > > 1 warning generated.
> > > > > ```
> > > > > 
> > > > > This also seems to emit even when `Kind` is not 
> > > > > `Sema::CheckConstexprKind::Diagnose` (unlike the 
> > > > > `static`/`thread_local` case above). Is the `CheckLiteralType` logic 
> > > > > not reusable for this?
> > > > You are right, thanks for noticing that, it was rather bogus.
> > > > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > > > diagnostics message, as CheckLiteralType doesn't allow us to pass 
> > > > parameter to the diagnostic message.
> > > > 
> > > > It leaves us with an uncovered scenario though: We do not emit the 
> > > > warning on template instantiation, and I don't think there is an  easy 
> > > > way to do that.
> > > > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > > > diagnostics message, as CheckLiteralType doesn't allow us to pass 
> > > > parameter to the diagnostic message.
> > > 
> > > Huh?
> > > 
> > > ```
> > > static bool CheckLiteralType(Sema , Sema::CheckConstexprKind Kind,
> > >  SourceLocation Loc, QualType T, unsigned 
> > > DiagID,
> > >  Ts &&...DiagArgs) {
> > >   ...
> > > }
> > > ```
> > > I would hope `DiagArgs` should do exactly that? :-)
> > > It leaves us with an uncovered scenario though: We do not emit the 
> > > warning on template instantiation, and I don't think there is an easy way 
> > > to do that.
> > 
> > I believe the code paths that lead us here all come from 
> > `Sema::CheckConstexprFunctionDefinition()` which is called from 
> > `Sema::ActOnFinishFunctionBody()` which seems to be called when 
> > instantiating templates in `Sema::InstantiateFunctionDefinition()`, so 
> > perhaps some more investigation is needed as to why we're not reaching this 
> > for template instantiations.
> We could add something in addition of `Sema::CheckConstexprKind::CheckValid` 
> and `Sema::CheckConstexprKind::Diagnose`, but 
> 
> * not for implicit lambdas, because we should not warn on lambdas that won't 
> be constexpr
> * for explicit constexpr lambdas / functions, it would force us to call 
> CheckConstexprFunctionDefinition  on instanciation, which we currently don't 
> do, and is not free for that one warning - and we would have to not-reemit 
> the other warnings. It seems like quite a fair amount of work for a 
> diagnostic not enabled by default.
> so perhaps some more investigation is needed as to why we're not reaching 
> this for template instantiations.

@aaron.ballman, do you have any position on whether we want this investigation 
before moving forward with this patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-30 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419120.
cor3ntin added a comment.

- Add a commebt to clarify which diagnostic message is being printed,

as per Aaron suggestion.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++2b-extensions
 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
 
-struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}}
+struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}} \
+// cxx2b-note 2{{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
@@ -96,7 +97,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +165,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,7 +229,7 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
+constexpr auto dependent_var_def_lambda() {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
   T t;
@@ -237,4 +239,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -25,17 +25,18 @@
 label:; // expected-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
-struct NonLiteral {
+struct NonLiteral { // expected-note 2 {{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,10 +1901,15 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
- 

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905-1907
+  CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
+   diag::warn_cxx20_compat_constexpr_var,
+   isa(Dcl), 2);

Apply Aaron's suggestion 
(https://reviews.llvm.org/D122249?id=417358#inline-1168823) to the updated code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 417640.
cor3ntin added a comment.

After talks with Aaron, I'm using CheckLiteralType
in all cases, which adds notes about why a type
is not literal.

We still need to branch on CPlusPlus2b because the
diagnostics take a variable number of arguments,
and I'd rather not have more diagnostics.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++2b-extensions
 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
 
-struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}}
+struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}} \
+// cxx2b-note 2{{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
@@ -96,7 +97,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +165,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,7 +229,7 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
+constexpr auto dependent_var_def_lambda() {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
   T t;
@@ -237,4 +239,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -25,17 +25,18 @@
 label:; // expected-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
-struct NonLiteral {
+struct NonLiteral { // expected-note 2 {{'NonLiteral' is not literal}}
   NonLiteral() {}
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,10 +1901,14 @@
 return false;
   }
 }
-if 

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

aaron.ballman wrote:
> aaron.ballman wrote:
> > cor3ntin wrote:
> > > hubert.reinterpretcast wrote:
> > > > This seems to trigger even when the type is dependent:
> > > > ```
> > > > :1:36: warning: definition of a variable of non-literal type in 
> > > > a constexpr function is incompatible with C++ standards before C++2b 
> > > > [-Wpre-c++2b-compat]
> > > > auto qq = [](auto x) { decltype(x) n; };
> > > >^
> > > > 1 warning generated.
> > > > ```
> > > > 
> > > > This also seems to emit even when `Kind` is not 
> > > > `Sema::CheckConstexprKind::Diagnose` (unlike the 
> > > > `static`/`thread_local` case above). Is the `CheckLiteralType` logic 
> > > > not reusable for this?
> > > You are right, thanks for noticing that, it was rather bogus.
> > > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > > diagnostics message, as CheckLiteralType doesn't allow us to pass 
> > > parameter to the diagnostic message.
> > > 
> > > It leaves us with an uncovered scenario though: We do not emit the 
> > > warning on template instantiation, and I don't think there is an  easy 
> > > way to do that.
> > > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > > diagnostics message, as CheckLiteralType doesn't allow us to pass 
> > > parameter to the diagnostic message.
> > 
> > Huh?
> > 
> > ```
> > static bool CheckLiteralType(Sema , Sema::CheckConstexprKind Kind,
> >  SourceLocation Loc, QualType T, unsigned 
> > DiagID,
> >  Ts &&...DiagArgs) {
> >   ...
> > }
> > ```
> > I would hope `DiagArgs` should do exactly that? :-)
> > It leaves us with an uncovered scenario though: We do not emit the warning 
> > on template instantiation, and I don't think there is an easy way to do 
> > that.
> 
> I believe the code paths that lead us here all come from 
> `Sema::CheckConstexprFunctionDefinition()` which is called from 
> `Sema::ActOnFinishFunctionBody()` which seems to be called when instantiating 
> templates in `Sema::InstantiateFunctionDefinition()`, so perhaps some more 
> investigation is needed as to why we're not reaching this for template 
> instantiations.
We could add something in addition of `Sema::CheckConstexprKind::CheckValid` 
and `Sema::CheckConstexprKind::Diagnose`, but 

* not for implicit lambdas, because we should not warn on lambdas that won't be 
constexpr
* for explicit constexpr lambdas / functions, it would force us to call 
CheckConstexprFunctionDefinition  on instanciation, which we currently don't 
do, and is not free for that one warning - and we would have to not-reemit the 
other warnings. It seems like quite a fair amount of work for a diagnostic not 
enabled by default.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D122249#3402331 , @cor3ntin wrote:

> - Fix test
> - Add a comment explaining why we do not use CheckLiteralType
>
> @aaron,ballman I completely missed that...!

No worries!

> However, CheckLiteralType does a bunch of tests that we do not need
> to diagnose *why* a type is not literal, which we do not care about here.

I think those kinds of diagnostics could be useful to a developer who has 
enabled this compat warning. It may not be immediately clear why the type is 
not a literal, and those notes can help some folks get to that answer much more 
quickly. Do you have some examples of whether the diagnostics clearly are 
distracting or useless?




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

aaron.ballman wrote:
> cor3ntin wrote:
> > hubert.reinterpretcast wrote:
> > > This seems to trigger even when the type is dependent:
> > > ```
> > > :1:36: warning: definition of a variable of non-literal type in a 
> > > constexpr function is incompatible with C++ standards before C++2b 
> > > [-Wpre-c++2b-compat]
> > > auto qq = [](auto x) { decltype(x) n; };
> > >^
> > > 1 warning generated.
> > > ```
> > > 
> > > This also seems to emit even when `Kind` is not 
> > > `Sema::CheckConstexprKind::Diagnose` (unlike the `static`/`thread_local` 
> > > case above). Is the `CheckLiteralType` logic not reusable for this?
> > You are right, thanks for noticing that, it was rather bogus.
> > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > diagnostics message, as CheckLiteralType doesn't allow us to pass parameter 
> > to the diagnostic message.
> > 
> > It leaves us with an uncovered scenario though: We do not emit the warning 
> > on template instantiation, and I don't think there is an  easy way to do 
> > that.
> > The reason I'm not using CheckLiteralType is to avoid duplicating a 
> > diagnostics message, as CheckLiteralType doesn't allow us to pass parameter 
> > to the diagnostic message.
> 
> Huh?
> 
> ```
> static bool CheckLiteralType(Sema , Sema::CheckConstexprKind Kind,
>  SourceLocation Loc, QualType T, unsigned DiagID,
>  Ts &&...DiagArgs) {
>   ...
> }
> ```
> I would hope `DiagArgs` should do exactly that? :-)
> It leaves us with an uncovered scenario though: We do not emit the warning on 
> template instantiation, and I don't think there is an easy way to do that.

I believe the code paths that lead us here all come from 
`Sema::CheckConstexprFunctionDefinition()` which is called from 
`Sema::ActOnFinishFunctionBody()` which seems to be called when instantiating 
templates in `Sema::InstantiateFunctionDefinition()`, so perhaps some more 
investigation is needed as to why we're not reaching this for template 
instantiations.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 417586.
cor3ntin added a comment.

- Fix test
- Add a comment explaining why we do not use CheckLiteralType

@aaron,ballman I completely missed that...!

However, CheckLiteralType does a bunch of tests that we do not need
to diagnose *why* a type is not literal, which we do not care about here.

I tried to play around with the code and trying to use CheckLiteralType, or to 
modify
it for this scenario does not appear to me an improvenent, so I rather keep the 
change as is.

I also fixed the fail test, i think i accidentally removed a line from the test 
file...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -96,7 +96,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +164,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,7 +228,7 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
+constexpr auto dependent_var_def_lambda() {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
   T t;
@@ -237,4 +238,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -30,12 +30,13 @@
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,10 +1901,19 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
- diag::err_constexpr_local_var_non_literal_type,
- isa(Dcl)))
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  // We do not use CheckLiteralType here because we want to
+  // emit a warning but no notes explaining why the type is not literal.
+  if (Kind == Sema::CheckConstexprKind::Diagnose &&
+   

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

I'm seeing precommit CI failures:

Failed Tests (1):

  Clang :: SemaCXX/constant-expression-cxx2b.cpp




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

cor3ntin wrote:
> hubert.reinterpretcast wrote:
> > This seems to trigger even when the type is dependent:
> > ```
> > :1:36: warning: definition of a variable of non-literal type in a 
> > constexpr function is incompatible with C++ standards before C++2b 
> > [-Wpre-c++2b-compat]
> > auto qq = [](auto x) { decltype(x) n; };
> >^
> > 1 warning generated.
> > ```
> > 
> > This also seems to emit even when `Kind` is not 
> > `Sema::CheckConstexprKind::Diagnose` (unlike the `static`/`thread_local` 
> > case above). Is the `CheckLiteralType` logic not reusable for this?
> You are right, thanks for noticing that, it was rather bogus.
> The reason I'm not using CheckLiteralType is to avoid duplicating a 
> diagnostics message, as CheckLiteralType doesn't allow us to pass parameter 
> to the diagnostic message.
> 
> It leaves us with an uncovered scenario though: We do not emit the warning on 
> template instantiation, and I don't think there is an  easy way to do that.
> The reason I'm not using CheckLiteralType is to avoid duplicating a 
> diagnostics message, as CheckLiteralType doesn't allow us to pass parameter 
> to the diagnostic message.

Huh?

```
static bool CheckLiteralType(Sema , Sema::CheckConstexprKind Kind,
 SourceLocation Loc, QualType T, unsigned DiagID,
 Ts &&...DiagArgs) {
  ...
}
```
I would hope `DiagArgs` should do exactly that? :-)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

hubert.reinterpretcast wrote:
> This seems to trigger even when the type is dependent:
> ```
> :1:36: warning: definition of a variable of non-literal type in a 
> constexpr function is incompatible with C++ standards before C++2b 
> [-Wpre-c++2b-compat]
> auto qq = [](auto x) { decltype(x) n; };
>^
> 1 warning generated.
> ```
> 
> This also seems to emit even when `Kind` is not 
> `Sema::CheckConstexprKind::Diagnose` (unlike the `static`/`thread_local` case 
> above). Is the `CheckLiteralType` logic not reusable for this?
You are right, thanks for noticing that, it was rather bogus.
The reason I'm not using CheckLiteralType is to avoid duplicating a diagnostics 
message, as CheckLiteralType doesn't allow us to pass parameter to the 
diagnostic message.

It leaves us with an uncovered scenario though: We do not emit the warning on 
template instantiation, and I don't think there is an  easy way to do that.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 417535.
cor3ntin added a comment.

Formatting


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -96,7 +96,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +164,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,8 +228,8 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
-  return [](bool b) { // cxx2a-note {{declared here}}
+constexpr auto dependent_var_def_lambda() {
+  return [](bool b) {
 if (!b)
   T t;
 return 0;
@@ -237,4 +238,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -30,12 +30,13 @@
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,10 +1901,17 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
- diag::err_constexpr_local_var_non_literal_type,
- isa(Dcl)))
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (Kind == Sema::CheckConstexprKind::Diagnose &&
+  !VD->getType()->isDependentType() &&
+  !VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),
+ diag::warn_cxx20_compat_constexpr_var)
+<< isa(Dcl) << 2;
+} else if (CheckLiteralType(
+   SemaRef, Kind, VD->getLocation(), VD->getType(),
+   diag::err_constexpr_local_var_non_literal_type,
+   isa(Dcl)))
   return false;
 if (!VD->getType()->isDependentType() &&
 !VD->hasInit() && !VD->isCXXForRangeDecl()) {
Index: 

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 417534.
cor3ntin added a comment.

- Check That the type is dependant
- Only emit the warning when Kind == Sema::CheckConstexprKind::Diagnose


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -96,7 +96,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +164,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -227,8 +228,8 @@
 }
 
 template 
-constexpr auto dependent_var_def_lambda(void) {
-  return [](bool b) { // cxx2a-note {{declared here}}
+constexpr auto dependent_var_def_lambda() {
+  return [](bool b) {
 if (!b)
   T t;
 return 0;
@@ -237,4 +238,4 @@
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -30,12 +30,13 @@
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,10 +1901,16 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
- diag::err_constexpr_local_var_non_literal_type,
- isa(Dcl)))
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (Kind == Sema::CheckConstexprKind::Diagnose &&
+  !VD->getType()->isDependentType() && !VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),
+ diag::warn_cxx20_compat_constexpr_var)
+<< isa(Dcl) << 2;
+} else if (CheckLiteralType(
+   SemaRef, Kind, VD->getLocation(), VD->getType(),
+   diag::err_constexpr_local_var_non_literal_type,
+   isa(Dcl)))
   return false;
 if (!VD->getType()->isDependentType() &&
  

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:219
+  NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be 
used in a constant expression}} \
+// cxx2b-warning {{definition of a variable of non-literal 
type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;

Not sure how much we want the message in this case. The lambda is not marked 
`constexpr` (although it is implicitly `constexpr` in C++2b).

Note that we don't get a message for this:
```
auto qq = [] { return 0; static int x = 42; };
constexpr int qx = qq();
```

I am not sure how difficult it would be to come at this from the 
used-in-constant-evaluation side, but there is probably a larger class of 
messages in the same situation (so it would probably be a separate endeavour).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-23 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1905
+if (SemaRef.LangOpts.CPlusPlus2b) {
+  if (!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),

This seems to trigger even when the type is dependent:
```
:1:36: warning: definition of a variable of non-literal type in a 
constexpr function is incompatible with C++ standards before C++2b 
[-Wpre-c++2b-compat]
auto qq = [](auto x) { decltype(x) n; };
   ^
1 warning generated.
```

This also seems to emit even when `Kind` is not 
`Sema::CheckConstexprKind::Diagnose` (unlike the `static`/`thread_local` case 
above). Is the `CheckLiteralType` logic not reusable for this?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-22 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 417376.
cor3ntin added a comment.

- fix formatting

- use cxx2b in the test as per aaron request. This doesn't really matter as 
this part

of the test file is only executed in c++2b mode though.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -96,7 +96,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +164,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -214,7 +215,8 @@
 
   auto non_literal = [](bool b) { // cxx2a-note 2{{declared here}}
 if (b)
-  NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -230,11 +232,12 @@
 constexpr auto dependent_var_def_lambda(void) {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
-  T t;
+  T t; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 }
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}} \
+// cxx2b-note {{in instantiation}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -30,12 +30,13 @@
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,10 +1901,15 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
- diag::err_constexpr_local_var_non_literal_type,
- 

[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2725
+def warn_cxx20_compat_constexpr_var : Warning<
+  "definition of a %select{static variable|thread_local variable|variable of 
non-literal type}1 "
   "in a constexpr %select{function|constructor}0 "

You should re-flow the whole diagnostic to the usual 80-col limit.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1904-1912
+if(SemaRef.LangOpts.CPlusPlus2b) {
+if(!VD->getType()->isLiteralType(SemaRef.Context))
+
SemaRef.Diag(VD->getLocation(),diag::warn_cxx20_compat_constexpr_var)
+<< isa(Dcl)
+<< 2;
+}
+else if (CheckLiteralType(SemaRef, Kind, VD->getLocation(), 
VD->getType(),

Formatting looks off here (I was expecting the `else if` on the same line as 
the curly brace, but maybe clang-format is being weird?)



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1908
+<< isa(Dcl)
+<< 2;
+}





Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:99
 return 0;
-  NonLiteral n;
+  NonLiteral n; // expected-warning {{definition of a variable of non-literal 
type in a constexpr function is incompatible with C++ standards before C++2b}}
 }

Shouldn't this be a `cxx2b-warning` instead?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122249

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


[PATCH] D122249: [Clang] Add a compatibiliy warning for non-literals in constexpr.

2022-03-22 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin created this revision.
Herald added a project: All.
cor3ntin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122249

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp

Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx2b.cpp
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -96,7 +96,7 @@
 constexpr int non_literal(bool b) {
   if (!b)
 return 0;
-  NonLiteral n;
+  NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int non_literal_1 = non_literal(false);
@@ -164,7 +164,8 @@
   auto non_literal = [](bool b) constexpr {
 if (!b)
   NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
-// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
+// cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -214,7 +215,8 @@
 
   auto non_literal = [](bool b) { // cxx2a-note 2{{declared here}}
 if (b)
-  NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+// cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 
@@ -230,11 +232,12 @@
 constexpr auto dependent_var_def_lambda(void) {
   return [](bool b) { // cxx2a-note {{declared here}}
 if (!b)
-  T t;
+  T t; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 return 0;
   };
 }
 
 constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda()(true); // \
 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
-// cxx2a-note  {{non-constexpr function}}
+// cxx2a-note {{non-constexpr function}} \
+// cxx2b-note {{in instantiation}}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
===
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
@@ -30,12 +30,13 @@
 };
 
 constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}}
-  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
+  NonLiteral n;// expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
+   // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr void non_literal2(bool b) {
   if (!b)
-NonLiteral n;
+NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}}
 }
 
 constexpr int c_thread_local(int n) {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1893,7 +1893,7 @@
   if (Kind == Sema::CheckConstexprKind::Diagnose) {
 SemaRef.Diag(VD->getLocation(),
  SemaRef.getLangOpts().CPlusPlus2b
- ? diag::warn_cxx20_compat_constexpr_static_var
+ ? diag::warn_cxx20_compat_constexpr_var
  : diag::ext_constexpr_static_var)
 << isa(Dcl)
 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
@@ -1901,8 +1901,13 @@
 return false;
   }
 }
-if (!SemaRef.LangOpts.CPlusPlus2b &&
-CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
+if(SemaRef.LangOpts.CPlusPlus2b) {
+if(!VD->getType()->isLiteralType(SemaRef.Context))
+SemaRef.Diag(VD->getLocation(),diag::warn_cxx20_compat_constexpr_var)
+<< isa(Dcl)
+