https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/66021
>From a3390c4ac8bba43e73ea41f4af85b37df97b1098 Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Mon, 11 Sep 2023 23:40:38 +0200 Subject: [PATCH 1/6] [Clang] Static member initializers are not immediate escalating context. Per CWG2760, default members initializers should be consider part the body of consstructors, which mean they are evaluated in an immediate escalating context. However, this does not apply to static members. This patch produces some extraneous diagnostics, unfortunately we do not have a good way to report an error back to the initializer and this is a preexisting issue Fixes #65985 --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/lib/Parse/ParseDeclCXX.cpp | 12 ++++++++-- .../SemaCXX/cxx2b-consteval-propagate.cpp | 23 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3cdad2f7b9f0e5a..8c8ec0e11e3dd7d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -281,6 +281,10 @@ Bug Fixes to C++ Support a non-template inner-class between the function and the class template. (`#65810 <https://github.com/llvm/llvm-project/issues/65810>`_) +- Fix a crash when calling a non-constant immediate function + in the initializer of a static data member. + (`#65985 <https://github.com/llvm/llvm-project/issues/65985>_`). + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 730b6e55246d6b7..b4a72d599da6655 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3230,13 +3230,21 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, assert(Tok.isOneOf(tok::equal, tok::l_brace) && "Data member initializer not starting with '=' or '{'"); + bool IsFieldInitialization = isa_and_present<FieldDecl>(D); + EnterExpressionEvaluationContext Context( Actions, - isa_and_present<FieldDecl>(D) + IsFieldInitialization ? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed : Sema::ExpressionEvaluationContext::PotentiallyEvaluated, D); - Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext = true; + + // CWG2760 + // Default member initializers used to initialize a base or member subobject + // [...] are considered to be part of the function body + Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext = + IsFieldInitialization; + if (TryConsumeToken(tok::equal, EqualLoc)) { if (Tok.is(tok::kw_delete)) { // In principle, an initializer of '= delete p;' is legal, but it will diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index c5eb7f139327505..f967ce6554d777c 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -330,3 +330,26 @@ struct S { S s(0); // expected-note {{in the default initializer of 'j'}} } + +namespace GH65985 { + +int consteval operator""_foo(unsigned long long V) { + return 0; +} +int consteval operator""_bar(unsigned long long V); // expected-note 3{{here}} + +struct C { + static const int a = 1_foo; + static constexpr int b = 1_foo; + static const int c = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ + // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ + // expected-error {{in-class initializer for static data member is not a constant expression}} + + // FIXME: remove duplicate diagnostics + static constexpr int d = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ + // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ + // expected-error {{constexpr variable 'd' must be initialized by a constant expression}} \ + // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} +}; + +} >From 12e04c8bd51d1f4e0d77969642f115b554b3a589 Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Wed, 13 Sep 2023 10:10:28 +0200 Subject: [PATCH 2/6] Add more tests --- clang/test/SemaCXX/cxx2a-consteval.cpp | 35 +++++++++++++++++++ .../SemaCXX/cxx2b-consteval-propagate.cpp | 23 ------------ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index d98ec8048c32466..82d3212ed8156b4 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1126,4 +1126,39 @@ int test2() { return h{nullptr}; } // expected-note@-2 {{subobject 'g' is not initialized}} +} + +namespace GH65985 { + +int consteval operator""_foo(unsigned long long V) { + return 0; +} +int consteval operator""_bar(unsigned long long V); // expected-note 3{{here}} + +int consteval f() { + return 0; +} + +int consteval g(); // expected-note {{here}} + + +struct C { + static const int a = 1_foo; + static constexpr int b = 1_foo; + static const int c = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ + // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ + // expected-error {{in-class initializer for static data member is not a constant expression}} + + // FIXME: remove duplicate diagnostics + static constexpr int d = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ + // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ + // expected-error {{constexpr variable 'd' must be initialized by a constant expression}} \ + // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} + + static const int e = f(); + static const int f = g(); // expected-error {{call to consteval function 'GH65985::g' is not a constant expression}} \ + // expected-error {{in-class initializer for static data member is not a constant expression}} \ + // expected-note {{undefined function 'g' cannot be used in a constant expression}} +}; + } diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index f967ce6554d777c..c5eb7f139327505 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -330,26 +330,3 @@ struct S { S s(0); // expected-note {{in the default initializer of 'j'}} } - -namespace GH65985 { - -int consteval operator""_foo(unsigned long long V) { - return 0; -} -int consteval operator""_bar(unsigned long long V); // expected-note 3{{here}} - -struct C { - static const int a = 1_foo; - static constexpr int b = 1_foo; - static const int c = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ - // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ - // expected-error {{in-class initializer for static data member is not a constant expression}} - - // FIXME: remove duplicate diagnostics - static constexpr int d = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ - // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ - // expected-error {{constexpr variable 'd' must be initialized by a constant expression}} \ - // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} -}; - -} >From 0ed89350391f75bb81db02a7051c4367a95a3abb Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Sat, 16 Sep 2023 12:06:54 +0200 Subject: [PATCH 3/6] Add tests for #66562 Fixes #66562 --- clang/test/SemaCXX/cxx2a-consteval.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 82d3212ed8156b4..12de744891406d9 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -8,7 +8,7 @@ consteval int f1(int i) { return i; } -consteval constexpr int f2(int i) { +consteval constexpr int f2(int i) { //expected-error@-1 {{cannot combine}} return i; } @@ -195,7 +195,7 @@ auto ptr = ret1(0); struct A { consteval int f(int) { // expected-note@-1+ {{declared here}} - return 0; + return 0; } }; @@ -239,7 +239,7 @@ constexpr int f_c(int i) { int t = f(i); // expected-error@-1 {{is not a constant expression}} // expected-note@-2 {{function parameter}} - return f(0); + return f(0); } consteval int f_eval(int i) { @@ -675,7 +675,7 @@ Bar<derp> a; // expected-note {{in instantiation of member function 'issue_55601 struct constantDerp { // Can be used in a constant expression. - consteval constantDerp(int) {} + consteval constantDerp(int) {} consteval operator int() const { return 5; } }; Bar<constantDerp> b; @@ -1162,3 +1162,17 @@ struct C { }; } + +namespace GH66562 { + +namespace ns +{ + consteval int foo(int x) { return 1; } // expected-note {{declared here}} +} + +template <class A> +struct T { + static constexpr auto xx = ns::foo(A{}); // expected-error {{cannot take address of consteval function 'foo' outside of an immediate invocation}} +}; + +} >From c78921103078476e2dfbf11742bdd2e7737a8016 Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Tue, 19 Sep 2023 20:20:06 +0200 Subject: [PATCH 4/6] fix whitespaces, add test for immediate calls --- clang/test/SemaCXX/cxx2a-consteval.cpp | 8 ++++---- clang/test/SemaCXX/cxx2b-consteval-propagate.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 12de744891406d9..a091fadfa3094bd 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -8,7 +8,7 @@ consteval int f1(int i) { return i; } -consteval constexpr int f2(int i) { +consteval constexpr int f2(int i) { //expected-error@-1 {{cannot combine}} return i; } @@ -195,7 +195,7 @@ auto ptr = ret1(0); struct A { consteval int f(int) { // expected-note@-1+ {{declared here}} - return 0; + return 0; } }; @@ -239,7 +239,7 @@ constexpr int f_c(int i) { int t = f(i); // expected-error@-1 {{is not a constant expression}} // expected-note@-2 {{function parameter}} - return f(0); + return f(0); } consteval int f_eval(int i) { @@ -675,7 +675,7 @@ Bar<derp> a; // expected-note {{in instantiation of member function 'issue_55601 struct constantDerp { // Can be used in a constant expression. - consteval constantDerp(int) {} + consteval constantDerp(int) {} consteval operator int() const { return 5; } }; Bar<constantDerp> b; diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index c5eb7f139327505..f6032999112ae2f 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -330,3 +330,18 @@ struct S { S s(0); // expected-note {{in the default initializer of 'j'}} } + +namespace GH65985 { +consteval int invalid(); // expected-note 2{{declared here}} +constexpr int escalating(auto) { + return invalid(); + // expected-note@-1 {{'escalating<int>' is an immediate function because its body contains a call to a consteval function 'invalid' and that call is not a constant expression}} + // expected-note@-2 2{{undefined function 'invalid' cannot be used in a constant expression}} +} +struct S { + static constexpr int a = escalating(0); // expected-note 2{{in call to}} + // expected-error@-1 {{call to immediate function 'escalating<int>' is not a constant expression}} + // expected-error@-2 {{constexpr variable 'a' must be initialized by a constant expression}} +}; + +} >From 8139144f148ad5af829ea0e34861397105c3cf2c Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Tue, 19 Sep 2023 21:16:30 +0200 Subject: [PATCH 5/6] Fix test --- clang/test/SemaCXX/cxx2b-consteval-propagate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index 5cf5b69e4390a53..531a62622873357 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -340,10 +340,12 @@ constexpr int escalating(auto) { } struct S { static constexpr int a = escalating(0); // expected-note 2{{in call to}} - // expected-error@-1 {{call to immediate function 'escalating<int>' is not a constant expression}} + // expected-error@-1 {{call to immediate function 'GH65985::escalating<int>' is not a constant expression}} // expected-error@-2 {{constexpr variable 'a' must be initialized by a constant expression}} }; +} + namespace GH66324 { consteval int allocate(); // expected-note 2{{declared here}} >From 8f43822ecf07b1cf439c3fc07be3d217954e21f0 Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Tue, 19 Sep 2023 23:25:58 +0200 Subject: [PATCH 6/6] remove conflict markers from the release notes --- clang/docs/ReleaseNotes.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9f29bf87b2d53a7..44a5d5740dabef1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -287,11 +287,9 @@ Bug Fixes to C++ Support a non-template inner-class between the function and the class template. (`#65810 <https://github.com/llvm/llvm-project/issues/65810>`_) -<<<<<<< HEAD - Fix a crash when calling a non-constant immediate function in the initializer of a static data member. (`#65985 <https://github.com/llvm/llvm-project/issues/65985>_`). -======= - Clang now properly converts static lambda call operator to function pointers on win32. (`#62594 <https://github.com/llvm/llvm-project/issues/62594>`_) @@ -301,7 +299,6 @@ Bug Fixes to C++ Support the location of a non-defining declaration rather than the location of the definition the specialization was instantiated from. (`#26057 <https://github.com/llvm/llvm-project/issues/26057>`_`) ->>>>>>> llvm_be_very_careful/main - Fix a crash when a default member initializer of a base aggregate makes an invalid call to an immediate function. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits