Message ID | Y3DYxNPWpM23FCtj@tucnak |
---|---|
State | New |
Headers | show |
Series | c++, v2: Implement C++23 P2647R1 - Permitting static constexpr variables in constexpr functions | expand |
On 11/13/22 01:45, Jakub Jelinek wrote: > On Fri, Nov 11, 2022 at 06:07:04PM +0100, Jakub Jelinek wrote: >> The following patch on top of Marek's P2448 PR106649 patch >> (mainly because that patch implements the previous __cpp_constexpr >> feature test macro bump so this can't go in earlier; OT, >> P2280R4 doesn't have any feature test macro?) implements this >> simple paper. >> >> Ok for trunk if it passes bootstrap/regtest and is voted into C++23? > > Here is an updated patch that passed bootstrap/regtest, the only > change is another testcase tweak. > > 2022-11-13 Jakub Jelinek <jakub@redhat.com> > > gcc/c-family/ > * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr > value from 202207L to 202211L. > gcc/cp/ > * constexpr.cc (cxx_eval_constant_expression): Implement C++23 > P2647R1 - Permitting static constexpr variables in constexpr functions. > Allow decl_maybe_constant_var_p static or thread_local vars for > C++23. This was accepted as a DR, so it shouldn't be limited to C++23 mode. Certainly it should be allowed in C++20 mode; I don't have a strong opinion about C++14/17. Jonathan, do you? > (potential_constant_expression_1): Likewise. > gcc/testsuite/ > * g++.dg/cpp23/constexpr-nonlit17.C: New test. > * g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr > value. > * g++.dg/ext/stmtexpr19.C: Don't expect an error for C++23 or later. > > --- gcc/c-family/c-cppbuiltin.cc.jj 2022-11-11 17:14:52.021613271 +0100 > +++ gcc/c-family/c-cppbuiltin.cc 2022-11-11 17:17:45.065265246 +0100 > @@ -1074,7 +1074,7 @@ c_cpp_builtins (cpp_reader *pfile) > /* Set feature test macros for C++23. */ > cpp_define (pfile, "__cpp_size_t_suffix=202011L"); > cpp_define (pfile, "__cpp_if_consteval=202106L"); > - cpp_define (pfile, "__cpp_constexpr=202207L"); > + cpp_define (pfile, "__cpp_constexpr=202211L"); > cpp_define (pfile, "__cpp_multidimensional_subscript=202110L"); > cpp_define (pfile, "__cpp_named_character_escapes=202207L"); > cpp_define (pfile, "__cpp_static_call_operator=202207L"); > --- gcc/cp/constexpr.cc.jj 2022-11-11 17:14:52.024613231 +0100 > +++ gcc/cp/constexpr.cc 2022-11-11 17:16:54.384952917 +0100 > @@ -7085,7 +7085,8 @@ cxx_eval_constant_expression (const cons > && (TREE_STATIC (r) > || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r))) > /* Allow __FUNCTION__ etc. */ > - && !DECL_ARTIFICIAL (r)) > + && !DECL_ARTIFICIAL (r) > + && (cxx_dialect < cxx23 || !decl_maybe_constant_var_p (r))) > { > if (!ctx->quiet) > { > @@ -9577,7 +9578,10 @@ potential_constant_expression_1 (tree t, > tmp = DECL_EXPR_DECL (t); > if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)) > { > - if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp)) > + if (CP_DECL_THREAD_LOCAL_P (tmp) > + && !DECL_REALLY_EXTERN (tmp) > + && (cxx_dialect < cxx23 > + || !decl_maybe_constant_var_p (tmp))) > { > if (flags & tf_error) > constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p, > @@ -9585,7 +9589,9 @@ potential_constant_expression_1 (tree t, > "%<constexpr%> context", tmp); > return false; > } > - else if (TREE_STATIC (tmp)) > + else if (TREE_STATIC (tmp) > + && (cxx_dialect < cxx23 > + || !decl_maybe_constant_var_p (tmp))) > { > if (flags & tf_error) > constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p, > --- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C.jj 2022-11-11 17:59:59.972852793 +0100 > +++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C 2022-11-11 17:59:38.725141231 +0100 > @@ -0,0 +1,12 @@ > +// P2647R1 - Permitting static constexpr variables in constexpr functions > +// { dg-do compile { target c++23 } } > + > +constexpr char > +test () > +{ > + static const int x = 5; > + static constexpr char c[] = "Hello World"; > + return *(c + x); > +} > + > +static_assert (test () == ' '); > --- gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C.jj 2022-11-11 17:14:52.194610922 +0100 > +++ gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C 2022-11-11 17:48:56.038865825 +0100 > @@ -134,8 +134,8 @@ > > #ifndef __cpp_constexpr > # error "__cpp_constexpr" > -#elif __cpp_constexpr != 202207 > -# error "__cpp_constexpr != 202207" > +#elif __cpp_constexpr != 202211 > +# error "__cpp_constexpr != 202211" > #endif > > #ifndef __cpp_decltype_auto > --- gcc/testsuite/g++.dg/ext/stmtexpr19.C.jj 2020-01-14 20:02:46.839608995 +0100 > +++ gcc/testsuite/g++.dg/ext/stmtexpr19.C 2022-11-12 09:17:40.706245495 +0100 > @@ -8,7 +8,7 @@ const test* setup() > { > static constexpr test atest = > { > - ({ static const int inner = 123; &inner; }) // { dg-error "static" } > + ({ static const int inner = 123; &inner; }) // { dg-error "static" "" { target c++20_down } } > }; > > return &atest; > > > Jakub >
On Tue, Nov 15, 2022 at 06:36:38PM -0500, Jason Merrill wrote: > > Here is an updated patch that passed bootstrap/regtest, the only > > change is another testcase tweak. > > > > 2022-11-13 Jakub Jelinek <jakub@redhat.com> > > > > gcc/c-family/ > > * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr > > value from 202207L to 202211L. > > gcc/cp/ > > * constexpr.cc (cxx_eval_constant_expression): Implement C++23 > > P2647R1 - Permitting static constexpr variables in constexpr functions. > > Allow decl_maybe_constant_var_p static or thread_local vars for > > C++23. > > This was accepted as a DR, so it shouldn't be limited to C++23 mode. > Certainly it should be allowed in C++20 mode; I don't have a strong opinion > about C++14/17. Jonathan, do you? How will a feature with feature test macro with multiple values work as DR? Or will everything but the macro be treated as a DR (so __cpp_constexpr >= 202211L only for C++23)? Because __cpp_constexpr >= 202211L is >= 202207L too and that implies P2448R2 which wasn't a DR and >= 202110L which implies P2242R3 which wasn't a DR. And C++20 added other 2 non-DR papers that bumped the value. C++17 another one. > > (potential_constant_expression_1): Likewise. > > gcc/testsuite/ > > * g++.dg/cpp23/constexpr-nonlit17.C: New test. > > * g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr > > value. > > * g++.dg/ext/stmtexpr19.C: Don't expect an error for C++23 or later. Jakub
On Tue, 15 Nov 2022 at 23:36, Jason Merrill <jason@redhat.com> wrote: > > On 11/13/22 01:45, Jakub Jelinek wrote: > > On Fri, Nov 11, 2022 at 06:07:04PM +0100, Jakub Jelinek wrote: > >> The following patch on top of Marek's P2448 PR106649 patch > >> (mainly because that patch implements the previous __cpp_constexpr > >> feature test macro bump so this can't go in earlier; OT, > >> P2280R4 doesn't have any feature test macro?) implements this > >> simple paper. > >> > >> Ok for trunk if it passes bootstrap/regtest and is voted into C++23? > > > > Here is an updated patch that passed bootstrap/regtest, the only > > change is another testcase tweak. > > > > 2022-11-13 Jakub Jelinek <jakub@redhat.com> > > > > gcc/c-family/ > > * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr > > value from 202207L to 202211L. > > gcc/cp/ > > * constexpr.cc (cxx_eval_constant_expression): Implement C++23 > > P2647R1 - Permitting static constexpr variables in constexpr functions. > > Allow decl_maybe_constant_var_p static or thread_local vars for > > C++23. > > This was accepted as a DR, so it shouldn't be limited to C++23 mode. > Certainly it should be allowed in C++20 mode; I don't have a strong > opinion about C++14/17. Jonathan, do you? I don't. The lack of this feature caused some awkwardness implementing a C++23 library feature in <charconv>, but that means my desire for it was only in C++23 mode. And that has been mitigated by changes Patrick made to work around it anyway. I think it does make sense for C++20, where constexpr is pretty close to "normal" code, what with dynamic allocations, std::string etc. but I don't see a great need for it before C++20. > > > (potential_constant_expression_1): Likewise. > > gcc/testsuite/ > > * g++.dg/cpp23/constexpr-nonlit17.C: New test. > > * g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr > > value. > > * g++.dg/ext/stmtexpr19.C: Don't expect an error for C++23 or later. > > > > --- gcc/c-family/c-cppbuiltin.cc.jj 2022-11-11 17:14:52.021613271 +0100 > > +++ gcc/c-family/c-cppbuiltin.cc 2022-11-11 17:17:45.065265246 +0100 > > @@ -1074,7 +1074,7 @@ c_cpp_builtins (cpp_reader *pfile) > > /* Set feature test macros for C++23. */ > > cpp_define (pfile, "__cpp_size_t_suffix=202011L"); > > cpp_define (pfile, "__cpp_if_consteval=202106L"); > > - cpp_define (pfile, "__cpp_constexpr=202207L"); > > + cpp_define (pfile, "__cpp_constexpr=202211L"); > > cpp_define (pfile, "__cpp_multidimensional_subscript=202110L"); > > cpp_define (pfile, "__cpp_named_character_escapes=202207L"); > > cpp_define (pfile, "__cpp_static_call_operator=202207L"); > > --- gcc/cp/constexpr.cc.jj 2022-11-11 17:14:52.024613231 +0100 > > +++ gcc/cp/constexpr.cc 2022-11-11 17:16:54.384952917 +0100 > > @@ -7085,7 +7085,8 @@ cxx_eval_constant_expression (const cons > > && (TREE_STATIC (r) > > || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r))) > > /* Allow __FUNCTION__ etc. */ > > - && !DECL_ARTIFICIAL (r)) > > + && !DECL_ARTIFICIAL (r) > > + && (cxx_dialect < cxx23 || !decl_maybe_constant_var_p (r))) > > { > > if (!ctx->quiet) > > { > > @@ -9577,7 +9578,10 @@ potential_constant_expression_1 (tree t, > > tmp = DECL_EXPR_DECL (t); > > if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)) > > { > > - if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp)) > > + if (CP_DECL_THREAD_LOCAL_P (tmp) > > + && !DECL_REALLY_EXTERN (tmp) > > + && (cxx_dialect < cxx23 > > + || !decl_maybe_constant_var_p (tmp))) > > { > > if (flags & tf_error) > > constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p, > > @@ -9585,7 +9589,9 @@ potential_constant_expression_1 (tree t, > > "%<constexpr%> context", tmp); > > return false; > > } > > - else if (TREE_STATIC (tmp)) > > + else if (TREE_STATIC (tmp) > > + && (cxx_dialect < cxx23 > > + || !decl_maybe_constant_var_p (tmp))) > > { > > if (flags & tf_error) > > constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p, > > --- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C.jj 2022-11-11 17:59:59.972852793 +0100 > > +++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C 2022-11-11 17:59:38.725141231 +0100 > > @@ -0,0 +1,12 @@ > > +// P2647R1 - Permitting static constexpr variables in constexpr functions > > +// { dg-do compile { target c++23 } } > > + > > +constexpr char > > +test () > > +{ > > + static const int x = 5; > > + static constexpr char c[] = "Hello World"; > > + return *(c + x); > > +} > > + > > +static_assert (test () == ' '); > > --- gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C.jj 2022-11-11 17:14:52.194610922 +0100 > > +++ gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C 2022-11-11 17:48:56.038865825 +0100 > > @@ -134,8 +134,8 @@ > > > > #ifndef __cpp_constexpr > > # error "__cpp_constexpr" > > -#elif __cpp_constexpr != 202207 > > -# error "__cpp_constexpr != 202207" > > +#elif __cpp_constexpr != 202211 > > +# error "__cpp_constexpr != 202211" > > #endif > > > > #ifndef __cpp_decltype_auto > > --- gcc/testsuite/g++.dg/ext/stmtexpr19.C.jj 2020-01-14 20:02:46.839608995 +0100 > > +++ gcc/testsuite/g++.dg/ext/stmtexpr19.C 2022-11-12 09:17:40.706245495 +0100 > > @@ -8,7 +8,7 @@ const test* setup() > > { > > static constexpr test atest = > > { > > - ({ static const int inner = 123; &inner; }) // { dg-error "static" } > > + ({ static const int inner = 123; &inner; }) // { dg-error "static" "" { target c++20_down } } > > }; > > > > return &atest; > > > > > > Jakub > > >
On Tue, 15 Nov 2022 at 23:50, Jakub Jelinek <jakub@redhat.com> wrote: > > On Tue, Nov 15, 2022 at 06:36:38PM -0500, Jason Merrill wrote: > > > Here is an updated patch that passed bootstrap/regtest, the only > > > change is another testcase tweak. > > > > > > 2022-11-13 Jakub Jelinek <jakub@redhat.com> > > > > > > gcc/c-family/ > > > * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr > > > value from 202207L to 202211L. > > > gcc/cp/ > > > * constexpr.cc (cxx_eval_constant_expression): Implement C++23 > > > P2647R1 - Permitting static constexpr variables in constexpr functions. > > > Allow decl_maybe_constant_var_p static or thread_local vars for > > > C++23. > > > > This was accepted as a DR, so it shouldn't be limited to C++23 mode. > > Certainly it should be allowed in C++20 mode; I don't have a strong opinion > > about C++14/17. Jonathan, do you? > > How will a feature with feature test macro with multiple values work as DR? > Or will everything but the macro be treated as a DR (so __cpp_constexpr >= > 202211L only for C++23)? Yes, I think so. We just won't be able to advertise this feature as supported in C++20. > Because __cpp_constexpr >= 202211L is >= 202207L too and that implies > P2448R2 which wasn't a DR and >= 202110L which implies P2242R3 which wasn't a > DR. And C++20 added other 2 non-DR papers that bumped the value. > C++17 another one. > > > > (potential_constant_expression_1): Likewise. > > > gcc/testsuite/ > > > * g++.dg/cpp23/constexpr-nonlit17.C: New test. > > > * g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr > > > value. > > > * g++.dg/ext/stmtexpr19.C: Don't expect an error for C++23 or later. > > Jakub >
On Wed, Nov 16, 2022 at 12:27:02AM +0000, Jonathan Wakely wrote: > On Tue, 15 Nov 2022 at 23:50, Jakub Jelinek <jakub@redhat.com> wrote: > > > > On Tue, Nov 15, 2022 at 06:36:38PM -0500, Jason Merrill wrote: > > > > Here is an updated patch that passed bootstrap/regtest, the only > > > > change is another testcase tweak. > > > > > > > > 2022-11-13 Jakub Jelinek <jakub@redhat.com> > > > > > > > > gcc/c-family/ > > > > * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr > > > > value from 202207L to 202211L. > > > > gcc/cp/ > > > > * constexpr.cc (cxx_eval_constant_expression): Implement C++23 > > > > P2647R1 - Permitting static constexpr variables in constexpr functions. > > > > Allow decl_maybe_constant_var_p static or thread_local vars for > > > > C++23. > > > > > > This was accepted as a DR, so it shouldn't be limited to C++23 mode. > > > Certainly it should be allowed in C++20 mode; I don't have a strong opinion > > > about C++14/17. Jonathan, do you? > > > > How will a feature with feature test macro with multiple values work as DR? > > Or will everything but the macro be treated as a DR (so __cpp_constexpr >= > > 202211L only for C++23)? > > Yes, I think so. We just won't be able to advertise this feature as > supported in C++20. Ok. But there is another issue, the https://eel.is/c++draft/expr.const#5.2 spot that P2647R1 is changing didn't exist in C++20, it was only added with P2242R3. So, if one would treat P2647R1 as a DR for C++20, one has to come up with a different standard modification. Probably change the last bullet of: [dcl.constexpr]/3 its function-body shall not enclose a goto statement, an identifier label, a definition of a variable of non-literal type or of static or thread storage duration. to a definition of a variable of non-literal type or of a non-constexpr variable of static or thread storage duration. or so. Jakub
On 11/16/22 01:19, Jakub Jelinek wrote: > On Wed, Nov 16, 2022 at 12:27:02AM +0000, Jonathan Wakely wrote: >> On Tue, 15 Nov 2022 at 23:50, Jakub Jelinek <jakub@redhat.com> wrote: >>> >>> On Tue, Nov 15, 2022 at 06:36:38PM -0500, Jason Merrill wrote: >>>>> Here is an updated patch that passed bootstrap/regtest, the only >>>>> change is another testcase tweak. >>>>> >>>>> 2022-11-13 Jakub Jelinek <jakub@redhat.com> >>>>> >>>>> gcc/c-family/ >>>>> * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr >>>>> value from 202207L to 202211L. >>>>> gcc/cp/ >>>>> * constexpr.cc (cxx_eval_constant_expression): Implement C++23 >>>>> P2647R1 - Permitting static constexpr variables in constexpr functions. >>>>> Allow decl_maybe_constant_var_p static or thread_local vars for >>>>> C++23. >>>> >>>> This was accepted as a DR, so it shouldn't be limited to C++23 mode. >>>> Certainly it should be allowed in C++20 mode; I don't have a strong opinion >>>> about C++14/17. Jonathan, do you? >>> >>> How will a feature with feature test macro with multiple values work as DR? >>> Or will everything but the macro be treated as a DR (so __cpp_constexpr >= >>> 202211L only for C++23)? >> >> Yes, I think so. We just won't be able to advertise this feature as >> supported in C++20. > > Ok. But there is another issue, the > https://eel.is/c++draft/expr.const#5.2 > spot that P2647R1 is changing didn't exist in C++20, it was only added with > P2242R3. So, if one would treat P2647R1 as a DR for C++20, one has to come up with > a different standard modification. > Probably change the last bullet of: > [dcl.constexpr]/3 > its function-body shall not enclose > > a goto statement, > an identifier label, > a definition of a variable of non-literal type or of static or thread storage duration. > to > a definition of a variable of non-literal type or of a non-constexpr > variable of static or thread storage duration. > or so. Indeed, though the hypothetical C++20 change could still use the "usable in constant expressions" phrase. Jason
On Wed, Nov 16, 2022 at 08:20:34AM -0500, Jason Merrill wrote: > > Ok. But there is another issue, the > > https://eel.is/c++draft/expr.const#5.2 > > spot that P2647R1 is changing didn't exist in C++20, it was only added with > > P2242R3. So, if one would treat P2647R1 as a DR for C++20, one has to come up with > > a different standard modification. > > Probably change the last bullet of: > > [dcl.constexpr]/3 > > its function-body shall not enclose > > > > a goto statement, > > an identifier label, > > a definition of a variable of non-literal type or of static or thread storage duration. > > to > > a definition of a variable of non-literal type or of a non-constexpr > > variable of static or thread storage duration. > > or so. > > Indeed, though the hypothetical C++20 change could still use the "usable in > constant expressions" phrase. Yes. Though, with -std=c++20 we are rejected already in start_decl's if (current_function_decl && VAR_P (decl) && DECL_DECLARED_CONSTEXPR_P (current_function_decl) && cxx_dialect < cxx23) { bool ok = false; if (CP_DECL_THREAD_LOCAL_P (decl) && !DECL_REALLY_EXTERN (decl)) error_at (DECL_SOURCE_LOCATION (decl), "%qD defined %<thread_local%> in %qs function only " "available with %<-std=c++2b%> or %<-std=gnu++2b%>", decl, DECL_IMMEDIATE_FUNCTION_P (current_function_decl) ? "consteval" : "constexpr"); else if (TREE_STATIC (decl)) error_at (DECL_SOURCE_LOCATION (decl), "%qD defined %<static%> in %qs function only available " "with %<-std=c++2b%> or %<-std=gnu++2b%>", decl, DECL_IMMEDIATE_FUNCTION_P (current_function_decl) ? "consteval" : "constexpr"); else ok = true; if (!ok) cp_function_chain->invalid_constexpr = true; } and at that point I fear decl_maybe_constant_var_p will not work properly. Shall this hunk be moved somewhere else (cp_finish_decl?) where we can already call it, or do the above in start_decl for cxx_dialect < cxx20 and add a cxx_dialect == cxx20 hunk in cp_finish_decl? Jakub
On 11/16/22 09:08, Jakub Jelinek wrote: > On Wed, Nov 16, 2022 at 08:20:34AM -0500, Jason Merrill wrote: >>> Ok. But there is another issue, the >>> https://eel.is/c++draft/expr.const#5.2 >>> spot that P2647R1 is changing didn't exist in C++20, it was only added with >>> P2242R3. So, if one would treat P2647R1 as a DR for C++20, one has to come up with >>> a different standard modification. >>> Probably change the last bullet of: >>> [dcl.constexpr]/3 >>> its function-body shall not enclose >>> >>> a goto statement, >>> an identifier label, >>> a definition of a variable of non-literal type or of static or thread storage duration. >>> to >>> a definition of a variable of non-literal type or of a non-constexpr >>> variable of static or thread storage duration. >>> or so. >> >> Indeed, though the hypothetical C++20 change could still use the "usable in >> constant expressions" phrase. > > Yes. > Though, with -std=c++20 we are rejected already in start_decl's > if (current_function_decl && VAR_P (decl) > && DECL_DECLARED_CONSTEXPR_P (current_function_decl) > && cxx_dialect < cxx23) > { > bool ok = false; > if (CP_DECL_THREAD_LOCAL_P (decl) && !DECL_REALLY_EXTERN (decl)) > error_at (DECL_SOURCE_LOCATION (decl), > "%qD defined %<thread_local%> in %qs function only " > "available with %<-std=c++2b%> or %<-std=gnu++2b%>", decl, > DECL_IMMEDIATE_FUNCTION_P (current_function_decl) > ? "consteval" : "constexpr"); > else if (TREE_STATIC (decl)) > error_at (DECL_SOURCE_LOCATION (decl), > "%qD defined %<static%> in %qs function only available " > "with %<-std=c++2b%> or %<-std=gnu++2b%>", decl, > DECL_IMMEDIATE_FUNCTION_P (current_function_decl) > ? "consteval" : "constexpr"); > else > ok = true; > if (!ok) > cp_function_chain->invalid_constexpr = true; > } > and at that point I fear decl_maybe_constant_var_p will not work > properly. Shall this hunk be moved somewhere else (cp_finish_decl?) > where we can already call it, or do the above in start_decl for > cxx_dialect < cxx20 and add a cxx_dialect == cxx20 hunk in cp_finish_decl? Hmm, I'd expect decl_maybe_constant_var_p to work fine at this point. Jason
On Wed, Nov 16, 2022 at 09:33:27AM -0500, Jason Merrill wrote: > > and at that point I fear decl_maybe_constant_var_p will not work > > properly. Shall this hunk be moved somewhere else (cp_finish_decl?) > > where we can already call it, or do the above in start_decl for > > cxx_dialect < cxx20 and add a cxx_dialect == cxx20 hunk in cp_finish_decl? > > Hmm, I'd expect decl_maybe_constant_var_p to work fine at this point. For static constexpr vars sure, but what about static const where start_decl doesn't know the initializer? Sure, decl_maybe_constant_var_p will not crash in that case, but it will return true even if the static const var doesn't have a constant initializer. Sure, we'd catch that later on when actually trying to constexpr evaluate the function and hitting there the spots added for C++23 in potential_constant_expression*/cxx_eval_*, but it would mean that we don't reject it when nothing calls the functions. I meant something like: constexpr int bar (int x) { if (x) throw 1; return 0; } constexpr int foo () { static const int a = bar (1); return 0; } with -std=c++20 IMHO shouldn't be accepted, while in C++23 it should. With constexpr int a = foo (); added we reject it in C++23 (correct), but the diagnostics is too weird: test.C:3:23: in ‘constexpr’ expansion of ‘foo()’ test.C:3:24: error: ‘__atomic_load_1((& _ZGVZ3foovE1a), 2)’ is not a constant expression 3 | constexpr int a = foo (); | ^ Jakub
On 11/16/22 09:46, Jakub Jelinek wrote: > On Wed, Nov 16, 2022 at 09:33:27AM -0500, Jason Merrill wrote: >>> and at that point I fear decl_maybe_constant_var_p will not work >>> properly. Shall this hunk be moved somewhere else (cp_finish_decl?) >>> where we can already call it, or do the above in start_decl for >>> cxx_dialect < cxx20 and add a cxx_dialect == cxx20 hunk in cp_finish_decl? >> >> Hmm, I'd expect decl_maybe_constant_var_p to work fine at this point. > > For static constexpr vars sure, but what about > static const where start_decl doesn't know the initializer? > Sure, decl_maybe_constant_var_p will not crash in that case, but > it will return true even if the static const var doesn't have > a constant initializer. Sure, we'd catch that later on when actually > trying to constexpr evaluate the function and hitting there the > spots added for C++23 in potential_constant_expression*/cxx_eval_*, > but it would mean that we don't reject it when nothing calls the functions. > > I meant something like: > constexpr int bar (int x) { if (x) throw 1; return 0; } > constexpr int foo () { static const int a = bar (1); return 0; } > with -std=c++20 IMHO shouldn't be accepted, while in C++23 it should. I'd expect us to reject that in C++20 in potential_constant_expression, but it's a fair point; it is awkward that P2242 wasn't also accepted as a DR. Moving the check from start_decl to cp_finish_decl makes sense to me. Jason
--- gcc/c-family/c-cppbuiltin.cc.jj 2022-11-11 17:14:52.021613271 +0100 +++ gcc/c-family/c-cppbuiltin.cc 2022-11-11 17:17:45.065265246 +0100 @@ -1074,7 +1074,7 @@ c_cpp_builtins (cpp_reader *pfile) /* Set feature test macros for C++23. */ cpp_define (pfile, "__cpp_size_t_suffix=202011L"); cpp_define (pfile, "__cpp_if_consteval=202106L"); - cpp_define (pfile, "__cpp_constexpr=202207L"); + cpp_define (pfile, "__cpp_constexpr=202211L"); cpp_define (pfile, "__cpp_multidimensional_subscript=202110L"); cpp_define (pfile, "__cpp_named_character_escapes=202207L"); cpp_define (pfile, "__cpp_static_call_operator=202207L"); --- gcc/cp/constexpr.cc.jj 2022-11-11 17:14:52.024613231 +0100 +++ gcc/cp/constexpr.cc 2022-11-11 17:16:54.384952917 +0100 @@ -7085,7 +7085,8 @@ cxx_eval_constant_expression (const cons && (TREE_STATIC (r) || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r))) /* Allow __FUNCTION__ etc. */ - && !DECL_ARTIFICIAL (r)) + && !DECL_ARTIFICIAL (r) + && (cxx_dialect < cxx23 || !decl_maybe_constant_var_p (r))) { if (!ctx->quiet) { @@ -9577,7 +9578,10 @@ potential_constant_expression_1 (tree t, tmp = DECL_EXPR_DECL (t); if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)) { - if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp)) + if (CP_DECL_THREAD_LOCAL_P (tmp) + && !DECL_REALLY_EXTERN (tmp) + && (cxx_dialect < cxx23 + || !decl_maybe_constant_var_p (tmp))) { if (flags & tf_error) constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p, @@ -9585,7 +9589,9 @@ potential_constant_expression_1 (tree t, "%<constexpr%> context", tmp); return false; } - else if (TREE_STATIC (tmp)) + else if (TREE_STATIC (tmp) + && (cxx_dialect < cxx23 + || !decl_maybe_constant_var_p (tmp))) { if (flags & tf_error) constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p, --- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C.jj 2022-11-11 17:59:59.972852793 +0100 +++ gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C 2022-11-11 17:59:38.725141231 +0100 @@ -0,0 +1,12 @@ +// P2647R1 - Permitting static constexpr variables in constexpr functions +// { dg-do compile { target c++23 } } + +constexpr char +test () +{ + static const int x = 5; + static constexpr char c[] = "Hello World"; + return *(c + x); +} + +static_assert (test () == ' '); --- gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C.jj 2022-11-11 17:14:52.194610922 +0100 +++ gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C 2022-11-11 17:48:56.038865825 +0100 @@ -134,8 +134,8 @@ #ifndef __cpp_constexpr # error "__cpp_constexpr" -#elif __cpp_constexpr != 202207 -# error "__cpp_constexpr != 202207" +#elif __cpp_constexpr != 202211 +# error "__cpp_constexpr != 202211" #endif #ifndef __cpp_decltype_auto --- gcc/testsuite/g++.dg/ext/stmtexpr19.C.jj 2020-01-14 20:02:46.839608995 +0100 +++ gcc/testsuite/g++.dg/ext/stmtexpr19.C 2022-11-12 09:17:40.706245495 +0100 @@ -8,7 +8,7 @@ const test* setup() { static constexpr test atest = { - ({ static const int inner = 123; &inner; }) // { dg-error "static" } + ({ static const int inner = 123; &inner; }) // { dg-error "static" "" { target c++20_down } } }; return &atest;