aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
AgeCommit message (Collapse)AuthorFilesLines
2021-09-13Merged current trunk to branch.Thomas Koenig1-146/+434
2020-12-23c++: Fix constexpr array ICE [PR98332]Jason Merrill1-2/+2
The element initializer was non-constant, so its CONSTRUCTOR element ended up NULL, so unshare_constructor crashed trying to look at it. This patch fixes this in two places: First, by returning when we see a non-constant initializer; second, by not crashing on NULL. gcc/cp/ChangeLog: PR c++/98332 * constexpr.c (unshare_constructor): Check for NULL. (cxx_eval_vec_init_1): Always exit early if non-constant. gcc/testsuite/ChangeLog: PR c++/98332 * g++.dg/cpp0x/constexpr-overflow3.C: New test.
2020-12-08c++: ICE with -fsanitize=vptr and constexpr dynamic_cast [PR98103]Marek Polacek1-1/+10
-fsanitize=vptr initializes all vtable pointers to null so that it can catch invalid calls; see cp_ubsan_maybe_initialize_vtbl_ptrs. That means that evaluating a vtable reference can produce a null pointer in this mode, so cxx_eval_dynamic_cast_fn should check that and give and error. gcc/cp/ChangeLog: PR c++/98103 * constexpr.c (cxx_eval_dynamic_cast_fn): If the evaluating of vtable yields a null pointer, give an error and return. Use objtype. gcc/testsuite/ChangeLog: PR c++/98103 * g++.dg/ubsan/vptr-18.C: New test.
2020-12-08c++: Fix defaulted <=> fallback to < and == [PR96299]Jason Merrill1-1/+1
I thought I had implemented P1186R3, but apparently I didn't read it closely enough to understand the point of the paper, namely that for a defaulted operator<=>, if a member type doesn't have a viable operator<=>, we will use its operator< and operator== if the defaulted operator has an specific comparison category as its return type; the compiler can't guess if it should be strong_ordering or something else, but the user can make that choice explicit. The libstdc++ test change was necessary because of the change in genericize_spaceship from op0 > op1 to op1 < op0; this should be equivalent, but isn't because of PR88173. gcc/cp/ChangeLog: PR c++/96299 * cp-tree.h (build_new_op): Add overload that omits some parms. (genericize_spaceship): Add location_t parm. * constexpr.c (cxx_eval_binary_expression): Pass it. * cp-gimplify.c (genericize_spaceship): Pass it. * method.c (genericize_spaceship): Handle class-type arguments. (build_comparison_op): Fall back to op</== when appropriate. gcc/testsuite/ChangeLog: PR c++/96299 * g++.dg/cpp2a/spaceship-synth-neg2.C: Move error. * g++.dg/cpp2a/spaceship-p1186.C: New test. libstdc++-v3/ChangeLog: PR c++/96299 * testsuite/18_support/comparisons/algorithms/partial_order.cc: One more line needs to use VERIFY instead of static_assert.
2020-12-05c++: Fix constexpr access to union member through pointer-to-member [PR98122]Jakub Jelinek1-13/+51
We currently incorrectly reject the first testcase, because cxx_fold_indirect_ref_1 doesn't attempt to handle UNION_TYPEs. As the second testcase shows, it isn't that easy, because I believe we need to take into account the active member and prefer that active member over other members, because if we pick a non-active one, we might reject valid programs. 2020-12-05 Jakub Jelinek <jakub@redhat.com> PR c++/98122 * constexpr.c (cxx_union_active_member): New function. (cxx_fold_indirect_ref_1): Add ctx argument, pass it through to recursive call. Handle UNION_TYPE. (cxx_fold_indirect_ref): Add ctx argument, pass it to recursive calls and cxx_fold_indirect_ref_1. (cxx_eval_indirect_ref): Adjust cxx_fold_indirect_ref calls. * g++.dg/cpp1y/constexpr-98122.C: New test. * g++.dg/cpp2a/constexpr-98122.C: New test.
2020-12-03c++: Add __builtin_bit_cast to implement std::bit_cast [PR93121]Jakub Jelinek1-0/+206
The following patch adds __builtin_bit_cast builtin, similarly to clang or MSVC which implement std::bit_cast using such an builtin too. It checks the various std::bit_cast requirements, when not constexpr evaluated acts pretty much like VIEW_CONVERT_EXPR of the source argument to the destination type and the hardest part is obviously the constexpr evaluation. I've left out PDP11 handling of those, couldn't figure out how exactly are bitfields laid out there 2020-12-03 Jakub Jelinek <jakub@redhat.com> PR libstdc++/93121 * fold-const.h (native_encode_initializer): Add mask argument defaulted to nullptr. (find_bitfield_repr_type): Declare. (native_interpret_aggregate): Declare. * fold-const.c (find_bitfield_repr_type): New function. (native_encode_initializer): Add mask argument and support for filling it. Handle also some bitfields without integral DECL_BIT_FIELD_REPRESENTATIVE. (native_interpret_aggregate): New function. * gimple-fold.h (clear_type_padding_in_mask): Declare. * gimple-fold.c (struct clear_padding_struct): Add clear_in_mask member. (clear_padding_flush): Handle buf->clear_in_mask. (clear_padding_union): Copy clear_in_mask. Don't error if buf->clear_in_mask is set. (clear_padding_type): Don't error if buf->clear_in_mask is set. (clear_type_padding_in_mask): New function. (gimple_fold_builtin_clear_padding): Set buf.clear_in_mask to false. * doc/extend.texi (__builtin_bit_cast): Document. * c-common.h (enum rid): Add RID_BUILTIN_BIT_CAST. * c-common.c (c_common_reswords): Add __builtin_bit_cast. * cp-tree.h (cp_build_bit_cast): Declare. * cp-tree.def (BIT_CAST_EXPR): New tree code. * cp-objcp-common.c (names_builtin_p): Handle RID_BUILTIN_BIT_CAST. (cp_common_init_ts): Handle BIT_CAST_EXPR. * cxx-pretty-print.c (cxx_pretty_printer::postfix_expression): Likewise. * parser.c (cp_parser_postfix_expression): Handle RID_BUILTIN_BIT_CAST. * semantics.c (cp_build_bit_cast): New function. * tree.c (cp_tree_equal): Handle BIT_CAST_EXPR. (cp_walk_subtrees): Likewise. * pt.c (tsubst_copy): Likewise. * constexpr.c (check_bit_cast_type, cxx_eval_bit_cast): New functions. (cxx_eval_constant_expression): Handle BIT_CAST_EXPR. (potential_constant_expression_1): Likewise. * cp-gimplify.c (cp_genericize_r): Likewise. * g++.dg/cpp2a/bit-cast1.C: New test. * g++.dg/cpp2a/bit-cast2.C: New test. * g++.dg/cpp2a/bit-cast3.C: New test. * g++.dg/cpp2a/bit-cast4.C: New test. * g++.dg/cpp2a/bit-cast5.C: New test.
2020-12-03c++: Implement LWG3396 Clarify point of reference for ↵Jakub Jelinek1-1/+6
source_location::current() [PR80780, PR93093] While std::source_location::current () is static consteval source_location current() noexcept; in the standard, it also says with LWG3396: "Any call to current that appears as a default member initializer ([class.mem]), or as a subexpression thereof, should correspond to the location of the constructor definition or aggregate initialization that uses the default member initializer. Any call to current that appears as a default argument ([dcl.fct.default]), or as a subexpression thereof, should correspond to the location of the invocation of the function that uses the default argument ([expr.call])." so it must work as compiler magic rather than normal immediate functions, in particular we need to defer its evaluation when parsing default arguments or nsdmis. This patch actually defers evaluation of all the calls to std::source_location::current () until genericization (or constant expression evaluation when called from constant expression contexts). I had to change constexpr.c too so that it temporarily adjusts current_function_decl from the constexpr evaluation context, but we do the same already from __builtin_FUNCTION (). 2020-12-03 Jakub Jelinek <jakub@redhat.com> PR c++/80780 PR c++/93093 * cp-tree.h (source_location_current_p): Declare. * tree.c (source_location_current_p): New function. * call.c (immediate_invocation_p): New function. (build_over_call): Use it to resolve LWG3396. * constexpr.c (cxx_eval_builtin_function_call): Temporarily set current_function_decl from ctx->call->fundef->decl if any. * cp-gimplify.c (cp_genericize_r) <case CALL_EXPR>: Fold calls to immediate function std::source_location::current (). * g++.dg/cpp2a/srcloc15.C: New test. * g++.dg/cpp2a/srcloc16.C: New test. * g++.dg/cpp2a/srcloc17.C: New test. * g++.dg/cpp2a/srcloc18.C: New test.
2020-12-02c++: Fix ICE with inline variable in template [PR97975]Marek Polacek1-3/+4
In this test, we have static inline const int c = b; in a class template, and we call store_init_value as usual. There, the value is IMPLICIT_CONV_EXPR<const float>(b) which is is_nondependent_static_init_expression but isn't is_nondependent_constant_expression (they only differ in STRICT). We call fold_non_dependent_expr, but that just returns the expression because it only instantiates is_nondependent_constant_expression expressions. Since we're not checking the initializer of a constexpr variable, we go on to call maybe_constant_init, whereupon we crash because it tries to evaluate all is_nondependent_static_init_expression expressions, which our value is, but it still contains a template code. I think the fix is to call fold_non_dependent_init instead of maybe_constant_init, and only call fold_non_dependent_expr on the "this is a constexpr variable" path so as to avoid instantiating twice in a row. Outside a template this should also avoid evaluating the value twice. gcc/cp/ChangeLog: PR c++/97975 * constexpr.c (fold_non_dependent_init): Add a tree parameter. Use it. * cp-tree.h (fold_non_dependent_init): Add a tree parameter with a default value. * typeck2.c (store_init_value): Call fold_non_dependent_expr only when checking the initializer for constexpr variables. Call fold_non_dependent_init instead of maybe_constant_init. gcc/testsuite/ChangeLog: PR c++/97975 * g++.dg/cpp1z/inline-var8.C: New test.
2020-11-24middle-end, c++: Treat shifts by negative as undefined [PR96929]Jakub Jelinek1-0/+15
The PR38359 change made the -1 >> x to -1 optimization less useful by requiring that the x must be non-negative. Shifts by negative amount are UB, but we for historic reasons had in some (but not all) places some hack to treat shifts by negative value as the other direction shifts by the negated amount. The following patch just removes that special handling, instead we punt on optimizing those (and ideally path isolation should catch that up and turn those into __builtin_unreachable, perhaps with __builtin_warning next to it). Folding the shifts in some places as if they were rotates and in other as if they were saturating just leads to inconsistencies. For C++ constexpr diagnostics and -fpermissive, I've added code to pretend fold-const.c has not changed, without -fpermissive it will be an error anyway and I think it is better not to change all the diagnostics. During x86_64-linux and i686-linux bootstrap/regtest, my statistics gathering patch noted 185 unique -m32/-m64 x TU x function_name x shift_kind x fold-const/tree-ssa-ccp cases. I have investigated the 64 ../../gcc/config/i386/i386.c x86_output_aligned_bss LSHIFT_EXPR wide_int_bitop 64 ../../gcc/config/i386/i386-expand.c emit_memmov LSHIFT_EXPR wide_int_bitop 64 ../../gcc/config/i386/i386-expand.c ix86_expand_carry_flag_compare LSHIFT_EXPR wide_int_bitop 64 ../../gcc/expmed.c expand_divmod LSHIFT_EXPR wide_int_bitop 64 ../../gcc/lra-lives.c process_bb_lives LSHIFT_EXPR wide_int_bitop 64 ../../gcc/rtlanal.c nonzero_bits1 LSHIFT_EXPR wide_int_bitop 64 ../../gcc/varasm.c optimize_constant_pool.isra LSHIFT_EXPR wide_int_bitop cases and all of them are either during jump threading (dom) or during PRE. For jump threading, the most common case is 1 << floor_log2 (whatever) where floor_log2 is return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x); and clz_hwi is if (x == 0) return HOST_BITS_PER_WIDE_INT; return __builtin_clz* (x); and so has range [-1, 63] and a comparison against == 0 which makes the threader think it might be nice to jump thread the case leading to 1 << -1. I think it is better to keep the 1 << -1 s in the IL for this and let path isolation turn that into __builtin_unreachable () if the user wishes so. 2020-11-24 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/96929 * fold-const.c (wide_int_binop) <case LSHIFT_EXPR, case RSHIFT_EXPR>: Return false on negative second argument rather than trying to handle it as shift in the other direction. * tree-ssa-ccp.c (bit_value_binop) <case LSHIFT_EXPR, case RSHIFT_EXPR>: Punt on negative shift count rather than trying to handle it as shift in the other direction. * match.pd (-1 >> x to -1): Remove tree_expr_nonnegative_p check. * constexpr.c (cxx_eval_binary_expression): For shifts by constant with MSB set, emulate older wide_int_binop behavior to preserve diagnostics and -fpermissive behavior. * gcc.dg/tree-ssa/pr96929.c: New test.
2020-11-21c++: Reject identifier label in constexpr [PR97846]Marek Polacek1-1/+8
[dcl.constexpr]/3 says that the function-body of a constexpr function shall not contain an identifier label, but we aren't enforcing that. This patch implements that. Of course, we can't reject artificial labels. gcc/cp/ChangeLog: PR c++/97846 * constexpr.c (potential_constant_expression_1): Reject LABEL_EXPRs that use non-artifical LABEL_DECLs. gcc/testsuite/ChangeLog: PR c++/97846 * g++.dg/cpp1y/constexpr-label.C: New test.
2020-11-21c++: Fix wrong error with constexpr destructor [PR97427]Marek Polacek1-16/+33
When I implemented the code to detect modifying const objects in constexpr contexts, we couldn't have constexpr destructors, so I didn't consider them. But now we can and that caused a bogus error in this testcase: [class.dtor]p5 says that "const and volatile semantics are not applied on an object under destruction. They stop being in effect when the destructor for the most derived object starts." so we have to clear the TREE_READONLY flag we set on the object after the constructors have been called to mark it as no-longer-under-construction. In the ~Foo call it's now an object under destruction, so don't report those errors. gcc/cp/ChangeLog: PR c++/97427 * constexpr.c (cxx_set_object_constness): New function. (cxx_eval_call_expression): Set new_obj for destructors too. Call cxx_set_object_constness to set/unset TREE_READONLY of the object under construction/destruction. gcc/testsuite/ChangeLog: PR c++/97427 * g++.dg/cpp2a/constexpr-dtor10.C: New test.
2020-11-19c++: Expose constexpr hash tableNathan Sidwell1-44/+45
This patch exposes the constexpr hash table so that the modules machinery can save and load constexpr bodies. While there I noticed that we could do a little constification of the hasher and comparator functions. Also combine the saving machinery to a single function returning void -- nothing ever looked at its return value. gcc/cp/ * cp-tree.h (struct constexpr_fundef): Moved from constexpr.c. (maybe_save_constexpr_fundef): Declare. (register_constexpr_fundef): Take constexpr_fundef object, return void. * decl.c (mabe_save_function_definition): Delete, functionality moved to maybe_save_constexpr_fundef. (emit_coro_helper, finish_function): Adjust. * constexpr.c (struct constexpr_fundef): Moved to cp-tree.h. (constexpr_fundef_hasher::equal): Constify. (constexpr_fundef_hasher::hash): Constify. (retrieve_constexpr_fundef): Make non-static. (maybe_save_constexpr_fundef): Break out checking and duplication from ... (register_constexpr_fundef): ... here. Just register the constexpr.
2020-11-12c++: Fix up constexpr CLEANUP_POINT_EXPR and TRY_FINALLY_EXPR handling [PR97790]Jakub Jelinek1-22/+12
As the testcase shows, CLEANUP_POINT_EXPR (and I think TRY_FINALLY_EXPR too) suffer from the same problem that I was trying to fix in r10-3597-g1006c9d4395a939820df76f37c7b085a4a1a003f for CLEANUP_STMT, namely that if in the middle of the body expression of those stmts is e.g. return stmt, goto, break or continue (something that changes *jump_target and makes it start skipping stmts), we then skip the cleanups too, which is not appropriate - the cleanups were either queued up during the non-skipping execution of the body (for CLEANUP_POINT_EXPR), or for TRY_FINALLY_EXPR are relevant already after entering the body block. > Would it make sense to always use a NULL jump_target when evaluating > cleanups? I was afraid of that, especially for TRY_FINALLY_EXPR, but it seems that during constexpr evaluation the cleanups will most often be just very simple destructor calls (or calls to cleanup attribute functions). Furthermore, for neither of these 3 tree codes we'll reach that code if jump_target && *jump_target initially (there is a return NULL_TREE much earlier for those except for trees that could embed labels etc. in it and clearly these 3 don't count in that). 2020-11-12 Jakub Jelinek <jakub@redhat.com> PR c++/97790 * constexpr.c (cxx_eval_constant_expression) <case CLEANUP_POINT_EXPR, case TRY_FINALLY_EXPR, case CLEANUP_STMT>: Don't pass jump_target to cxx_eval_constant_expression when evaluating the cleanups. * g++.dg/cpp2a/constexpr-dtor9.C: New test.
2020-11-04Objective-C++ : Fix ICE in potential_constant_expression_1.Iain Sandoe1-1/+1
We cannot, as things stand, handle Objective-C tree codes in the switch and deal with this by calling out to a function that has a dummy version when Objective-C is not enabled. Because of the way the logic works (with a fall through to a 'sorry' in case of unhandled expressions), the function reports cases that are known to be unsuitable for constant exprs. The dummy function always reports 'false' and thus will fall through to the 'sorry'. gcc/c-family/ChangeLog: * c-objc.h (objc_non_constant_expr_p): New. * stub-objc.c (objc_non_constant_expr_p): New. gcc/cp/ChangeLog: * constexpr.c (potential_constant_expression_1): Handle expressions known to be non-constant for Objective-C. gcc/objc/ChangeLog: * objc-act.c (objc_non_constant_expr_p): New.
2020-11-03c++: Tweaks for value_dependent_expression_p.Marek Polacek1-0/+5
We may not call value_dependent_expression_p on expressions that are not potential constant expressions, otherwise value_d could crash, as I saw recently (in C++98). So beef up the checking in i_d_e_p. This revealed a curious issue: when we have __PRETTY_FUNCTION__ in a template function, we set its DECL_VALUE_EXPR to error_mark_node (cp_make_fname_decl), so potential_c_e returns false when it gets it, but value_dependent_expression_p handles it specially and says true. This broke lambda-generic-pretty1.C. So take care of that. And then also tweak uses_template_parms. gcc/cp/ChangeLog: * constexpr.c (potential_constant_expression_1): Treat __PRETTY_FUNCTION__ inside a template function as potentially-constant. * pt.c (uses_template_parms): Call instantiation_dependent_expression_p instead of value_dependent_expression_p. (instantiation_dependent_expression_p): Check potential_constant_expression before calling value_dependent_expression_p.
2020-11-02c++: Don't purge the satisfaction cachesPatrick Palka1-4/+2
The adoption of P2104 ("Disallow changing concept values") means we can memoize the result of satisfaction indefinitely and no longer have to clear the satisfaction caches on various events that would affect satisfaction. To that end, this patch removes the invalidation routine clear_satisfaction_cache and adjusts its callers appropriately. This provides a large reduction in compile time and memory use in some cases. For example, on the libstdc++ test std/ranges/adaptor/join.cc, compile time and memory usage drops nearly 75%, from 7.5s/770MB to 2s/230MB, with a --enable-checking=release compiler. gcc/cp/ChangeLog: * class.c (finish_struct_1): Don't call clear_satisfaction_cache. * constexpr.c (clear_cv_and_fold_caches): Likewise. Remove bool parameter. * constraint.cc (clear_satisfaction_cache): Remove definition. * cp-tree.h (clear_satisfaction_cache): Remove declaration. (clear_cv_and_fold_caches): Remove bool parameter. * typeck2.c (store_init_value): Remove argument to clear_cv_and_fold_caches. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-complete1.C: Delete test that became ill-formed after P2104.
2020-10-29c++: Fix constexpr cleanup error handling.Jason Merrill1-6/+4
In this testcase, the primary evaluation successfully produces 'true', and then running one of the cleanups hits a double delete, making the whole thing not a valid constant expression. So we were returning 'true' wrapped in a NOP_EXPR to indicate its non-constancy, but evaluating that again is a perfectly acceptable constant expression, so we weren't getting the verbose diagnostic we were looking for. So if non_constant_p gets set other than for overflow, go back to the original expression. With this change, we should never hit the manifestly_const_eval test, and the is-constant-evaluated1.C test passes without it. gcc/cp/ChangeLog: PR c++/97388 * constexpr.c (cxx_eval_outermost_constant_expr): Revert to original expression if evaluation sets non_constant_p. gcc/testsuite/ChangeLog: PR c++/97388 * g++.dg/cpp2a/constexpr-dtor8.C: New test.
2020-10-29c++: Fix constexpr dtors vs invisible ref [PR97388]Jakub Jelinek1-7/+12
For arguments passed by invisible reference, in the IL until genericization we have the source types on the callee side and while on the caller side we already pass references to the actual argument slot in the caller, we undo that in cxx_bind_parameters_in_call's if (TREE_ADDRESSABLE (type)) /* Undo convert_for_arg_passing work here. */ x = convert_from_reference (x); This works fine most of the time, except when the type also has constexpr destructor; in that case the destructor is invoked in the caller and thus the unsharing we do to make sure that the callee doesn't modify caller's values is in that case undesirable, it prevents the changes done in the callee propagating to the caller which should see them for the constexpr dtor evaluation. The following patch fixes that. While it could be perhaps done for all TREE_ADDRESSABLE types, I don't see the need to change the behavior if there is no constexpr non-trivial dtor. Jason: And we need to avoid memoizing the call, because a later equivalent call also needs to modify its argument. And we don't need to unshare constructors when we aren't memoizing the call, because we already unshared them when evaluating the TARGET_EXPR representing the copy-initialization of the argument. 2020-10-20 Jakub Jelinek <jakub@redhat.com> Jason Merrill <jason@redhat.com> PR c++/97388 * constexpr.c (cxx_bind_parameters_in_call): Set non_constant_args if the parameter type has a non-trivial destructor. (cxx_eval_call_expression): Only unshare arguments if we're memoizing this evaluation. * g++.dg/cpp2a/constexpr-dtor5.C: New test. * g++.dg/cpp2a/constexpr-dtor6.C: New test. * g++.dg/cpp2a/constexpr-dtor7.C: New test.
2020-10-29c++: Diagnose constexpr delete [] new int; and delete new int[N]; [PR95808]Jakub Jelinek1-5/+53
This patch diagnoses delete [] new int; and delete new int[1]; in constexpr contexts by remembering IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun)) & OVL_OP_FLAG_VEC from the operator new and checking it at operator delete time. 2020-10-29 Jakub Jelinek <jakub@redhat.com> PR c++/95808 * cp-tree.h (enum cp_tree_index): Add CPTI_HEAP_VEC_UNINIT_IDENTIFIER and CPTI_HEAP_VEC_IDENTIFIER. (heap_vec_uninit_identifier, heap_vec_identifier): Define. * decl.c (initialize_predefined_identifiers): Initialize those identifiers. * constexpr.c (cxx_eval_call_expression): Reject array allocations deallocated with non-array deallocation or non-array allocations deallocated with array deallocation. (non_const_var_error): Handle heap_vec_uninit_identifier and heap_vec_identifier too. (cxx_eval_constant_expression): Handle also heap_vec_uninit_identifier and in that case during initialization replace it with heap_vec_identifier. (find_heap_var_refs): Handle heap_vec_uninit_identifier and heap_vec_identifier too. * g++.dg/cpp2a/constexpr-new15.C: New test.
2020-10-24c++: Fix verify_ctor_sanity ICE [PR96241]Marek Polacek1-2/+9
The code added in r10-6437 caused us to create a CONSTRUCTOR when we're {}-initializing an aggregate. Then we pass this new CONSTRUCTOR down to cxx_eval_constant_expression which, if the CONSTRUCTOR isn't TREE_CONSTANT or reduced_constant_expression_p, calls cxx_eval_bare_aggregate. In this case the CONSTRUCTOR wasn't reduced_constant_expression_p because for r_c_e_p a CONST_DECL isn't good enough so it returns false. So we go to cxx_eval_bare_aggregate where we crash, because ctx->ctor wasn't set up properly. So my fix is to do so. Since we're value-initializing, I'm not setting CONSTRUCTOR_NO_CLEARING. To avoid keeping a garbage constructor around, I call free_constructor in case the evaluation did not use it. gcc/cp/ChangeLog: PR c++/96241 * constexpr.c (cxx_eval_array_reference): Set up ctx->ctor if we are initializing an aggregate. Call free_constructor on the new CONSTRUCTOR if it isn't returned from cxx_eval_constant_expression. gcc/testsuite/ChangeLog: PR c++/96241 * g++.dg/cpp0x/constexpr-96241.C: New test. * g++.dg/cpp1y/constexpr-96241.C: New test.
2020-10-22c++: Handle RANGE_EXPR index in init_subob_ctx [PR97328]Patrick Palka1-2/+9
In the testcase below, we're ICEing during constexpr evaluation of the CONSTRUCTOR {.data={{}, [1 ... 7]={}}} of type 'vector'. The interesting thing about this CONSTRUCTOR is that it has a RANGE_EXPR index for an element initializer which doesn't satisfy reduced_constant_expression_p (because the field 't' is uninitialized). This is a problem because init_subob_ctx currently punts on setting up a sub-aggregate initialization context when given a RANGE_EXPR index, so we later trip over the asserts in verify_ctor_sanity when recursing into cxx_eval_bare_aggregate on this element initializer. Fix this by making init_subob_ctx set up an appropriate initialization context when supplied a RANGE_EXPR index. gcc/cp/ChangeLog: PR c++/97328 * constexpr.c (init_subob_ctx): Don't punt on RANGE_EXPR indexes, instead build a sub-aggregate initialization context with no subobject. gcc/testsuite/ChangeLog: PR c++/97328 * g++.dg/cpp2a/constexpr-init19.C: New test. * g++.dg/cpp2a/constexpr-init20.C: New test.
2020-10-22c++: constexpr evaluation and bare EMPTY_CLASS_EXPR [PR96575]Patrick Palka1-8/+6
In the testcase below, folding of the initializer for 'ret' inside the instantiated f<lambda>::lambda ends up yielding an initializer for which potential_constant_expression returns false. This causes finish_function to mark the lambda as non-constexpr, which ultimately causes us to reject 'f(g)' as a call to a non-constexpr function. The initializer for 'ret' inside f<lambda>::lambda, prior to folding, is the CALL_EXPR <lambda(S)>::operator() (&cb, ({}, <<< Unknown tree: empty_class_expr >>>;)) where the second argument is a COMPOUND_EXPR whose second operand is an EMPTY_CLASS_EXPR that was formed by build_class_a. cp_fully_fold_init is able to only partially fold this initializer: it gets rid of the side-effectless COMPOUND_EXPR to obtain <lambda(S)>::operator() (&cb, <<< Unknown tree: empty_class_expr >>>) as the final initializer for 'ret'. This initializer no longer satifies potential_constant_expression due to the bare EMPTY_CLASS_EXPR which is not wrapped in a COMPOUND_EXPR. (cp_fully_fold_init first tries maybe_constant_value on the original CALL_EXPR, but constexpr evaluation punts upon seeing __builtin_is_constant_evaluated, since manifestly_const_eval is false.) To fix this, it seems we could either make cp_fold preserve the COMPOUND_EXPR trees produced by build_call_a, or we could improve the constexpr machinery to treat EMPTY_CLASS_EXPR trees as first-class citizens. Assuming it's safe to continue folding away these COMPOUND_EXPRs, the second approach seems cleaner, so this patch implements the second approach. gcc/cp/ChangeLog: PR c++/96575 * constexpr.c (cxx_eval_constant_expression) <case EMPTY_CLASS_EXPR>: Lower it to a CONSTRUCTOR. (potential_constant_expression_1) <case COMPOUND_EXPR>: Remove now-redundant handling of COMPOUND_EXPR with EMPTY_CLASS_EXPR second operand. <case EMPTY_CLASS_EXPR>: Return true instead of false. gcc/testsuite/ChangeLog: PR c++/96575 * g++.dg/cpp1z/constexpr-96575.C: New test.
2020-10-01c++: Handle std::construct_at on automatic vars during constant evaluation ↵Jakub Jelinek1-1/+2
[PR97195] As mentioned in the PR, we only support due to a bug in constant expressions std::construct_at on non-automatic variables, because we VERIFY_CONSTANT the second argument of placement new, which fails verification if it is an address of an automatic variable. The following patch fixes it by not performing that verification, the placement new evaluation later on will verify it after it is dereferenced. 2020-10-01 Jakub Jelinek <jakub@redhat.com> PR c++/97195 * constexpr.c (cxx_eval_call_expression): Don't VERIFY_CONSTANT the second argument. * g++.dg/cpp2a/constexpr-new14.C: New test.
2020-09-22c++: Ignore __sanitizer_ptr_{sub,cmp} builtin calls during constant ↵Jakub Jelinek1-0/+6
expression evaluation [PR97145] These two builtin calls are added already during parsing before pointer subtractions or comparisons, normally they perform runtime verification of whether the pointers point to the same object or different objects, but during constant expressione valuation we don't really need those builtins for anything. 2020-09-22 Jakub Jelinek <jakub@redhat.com> PR c++/97145 * constexpr.c (cxx_eval_builtin_function_call): Return void_node for calls to __sanitize_ptr_{sub,cmp} builtins. * g++.dg/asan/pr97145.C: New test.
2020-09-03c++: Fix another PCH hash_map issue [PR96901]Jakub Jelinek1-1/+1
The recent libstdc++ changes caused lots of libstdc++-v3 tests FAILs on i686-linux, all of them in the same spot during constexpr evaluation of a recursive _S_gcd call. The problem is yet another hash_map that used the default hasing of tree keys through pointer hashing which is preserved across PCH write/read. During PCH handling, the addresses of GC objects are changed, which means that the hash values of the keys in such hash tables change without those hash tables being rehashed. Which in the fundef_copies_table case usually means we just don't find a copy of a FUNCTION_DECL body for recursive uses and start from scratch. But when the hash table keeps growing, the "dead" elements in the hash table can sometimes reappear and break things. In particular what I saw under the debugger is when the fundef_copies_table hash map has been used on the outer _S_gcd call, it didn't find an entry for it, so returned a slot with *slot == NULL, which is treated as that the function itself is used directly (i.e. no recursion), but that addition of a hash table slot caused the recursive _S_gcd call to actually find something in the hash table, unfortunately not the new *slot == NULL spot, but a different one from the pre-PCH streaming which contained the returned toplevel (non-recursive) call entry for it, which means that for the recursive _S_gcd call we actually used the same trees as for the outer ones rather than a copy of those, which breaks constexpr evaluation. 2020-09-03 Jakub Jelinek <jakub@redhat.com> PR c++/96901 * tree.h (struct decl_tree_traits): New type. (decl_tree_map): New typedef. * constexpr.c (fundef_copies_table): Change type from hash_map<tree, tree> * to decl_tree_map *.
2020-09-03c++: Disable -frounding-math during manifestly constant evaluation [PR96862]Jakub Jelinek1-0/+2
As discussed in the PR, fold-const.c punts on floating point constant evaluation if the result is inexact and -frounding-math is turned on. /* Don't constant fold this floating point operation if the result may dependent upon the run-time rounding mode and flag_rounding_math is set, or if GCC's software emulation is unable to accurately represent the result. */ if ((flag_rounding_math || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations)) && (inexact || !real_identical (&result, &value))) return NULL_TREE; Jonathan said that we should be evaluating them anyway, e.g. conceptually as if they are done with the default rounding mode before user had a chance to change that, and e.g. in C in initializers it is also ignored. In fact, fold-const.c for C initializers turns off various other options: /* Perform constant folding and related simplification of initializer expression EXPR. These behave identically to "fold_buildN" but ignore potential run-time traps and exceptions that fold must preserve. */ int saved_signaling_nans = flag_signaling_nans;\ int saved_trapping_math = flag_trapping_math;\ int saved_rounding_math = flag_rounding_math;\ int saved_trapv = flag_trapv;\ int saved_folding_initializer = folding_initializer;\ flag_signaling_nans = 0;\ flag_trapping_math = 0;\ flag_rounding_math = 0;\ flag_trapv = 0;\ folding_initializer = 1; flag_signaling_nans = saved_signaling_nans;\ flag_trapping_math = saved_trapping_math;\ flag_rounding_math = saved_rounding_math;\ flag_trapv = saved_trapv;\ folding_initializer = saved_folding_initializer; So, shall cxx_eval_outermost_constant_expr instead turn off all those options (then warning_sentinel wouldn't be the right thing to use, but given the 8 or how many return stmts in cxx_eval_outermost_constant_expr, we'd need a RAII class for this. Not sure about the folding_initializer, that one is affecting complex multiplication and division constant evaluation somehow. 2020-09-03 Jakub Jelinek <jakub@redhat.com> PR c++/96862 * constexpr.c (cxx_eval_outermost_constant_expr): Temporarily disable flag_rounding_math during manifestly constant evaluation. * g++.dg/cpp1z/constexpr-96862.C: New test.
2020-08-10c++: Fix constexpr evaluation of SPACESHIP_EXPR [PR96497]Jakub Jelinek1-2/+2
The following valid testcase is rejected, because cxx_eval_binary_expression is called on the SPACESHIP_EXPR with lval = true, as the address of the spaceship needs to be passed to a method call. After recursing on the operands and calling genericize_spaceship which turns it into a TARGET_EXPR with initialization, we call cxx_eval_constant_expression on it which succeeds, but then we fall through into code that will VERIFY_CONSTANT (r) which FAILs because it is an address of a variable. Rather than avoiding that for lval = true and SPACESHIP_EXPR, the patch just tail calls cxx_eval_constant_expression - I believe that call should perform all the needed verifications. 2020-08-10 Jakub Jelinek <jakub@redhat.com> PR c++/96497 * constexpr.c (cxx_eval_binary_expression): For SPACESHIP_EXPR, tail call cxx_eval_constant_expression after genericize_spaceship to avoid undesirable further VERIFY_CONSTANT. * g++.dg/cpp2a/spaceship-constexpr3.C: New test.
2020-08-05c++: cxx_eval_vec_init after zero-initialization [PR96282]Patrick Palka1-1/+17
In the first testcase below, expand_aggr_init_1 sets up t's default constructor such that the ctor first zero-initializes the entire base b, followed by calling b's default constructor, the latter of which just default-initializes the array member b::m via a VEC_INIT_EXPR. So upon constexpr evaluation of this latter VEC_INIT_EXPR, ctx->ctor is nonempty due to the prior zero-initialization, and we proceed in cxx_eval_vec_init to append new constructor_elts to the end of ctx->ctor without first checking if a matching constructor_elt already exists. This leads to ctx->ctor having two matching constructor_elts for each index. This patch fixes this issue by truncating a zero-initialized array CONSTRUCTOR in cxx_eval_vec_init_1 before we begin appending array elements to it. We propagate its zeroed out state during evaluation by clearing CONSTRUCTOR_NO_CLEARING on each new appended aggregate element. gcc/cp/ChangeLog: PR c++/96282 * constexpr.c (cxx_eval_vec_init_1): Truncate ctx->ctor and then clear CONSTRUCTOR_NO_CLEARING on each appended element initializer if we're initializing a previously zero-initialized array object. gcc/testsuite/ChangeLog: PR c++/96282 * g++.dg/cpp0x/constexpr-array26.C: New test. * g++.dg/cpp0x/constexpr-array27.C: New test. * g++.dg/cpp2a/constexpr-init18.C: New test. Co-authored-by: Jason Merrill <jason@redhat.com>
2020-07-30c++: decl_constant_value and unsharing [PR96197]Patrick Palka1-2/+2
In the testcase from the PR we're seeing excessive memory use (> 5GB) during constexpr evaluation, almost all of which is due to the call to decl_constant_value in the VAR_DECL/CONST_DECL branch of cxx_eval_constant_expression. We reach here every time we evaluate an ARRAY_REF of a constexpr VAR_DECL, and from there decl_constant_value makes an unshared copy of the VAR_DECL's initializer. But unsharing here is unnecessary because callers of cxx_eval_constant_expression already unshare its result when necessary. To fix this excessive unsharing, this patch adds a new defaulted parameter unshare_p to decl_really_constant_value and decl_constant_value so that callers can control whether to unshare. As a simplification, we can also move the call to unshare_expr in constant_value_1 outside of the loop, since doing unshare_expr on a DECL_P is a no-op. Now that we no longer unshare the result of decl_constant_value and decl_really_constant_value from cxx_eval_constant_expression, memory use during constexpr evaluation for the testcase from the PR falls from ~5GB to 15MB according to -ftime-report. gcc/cp/ChangeLog: PR c++/96197 * constexpr.c (cxx_eval_constant_expression) <case CONST_DECL>: Pass false to decl_constant_value and decl_really_constant_value so that they don't unshare their result. * cp-tree.h (decl_constant_value): New declaration with an added bool parameter. (decl_really_constant_value): Add bool parameter defaulting to true to existing declaration. * init.c (constant_value_1): Add bool parameter which controls whether to unshare the initializer before returning. Call unshare_expr at most once. (scalar_constant_value): Pass true to constant_value_1's new bool parameter. (decl_really_constant_value): Add bool parameter and forward it to constant_value_1. (decl_constant_value): Likewise, but instead define a new overload with an added bool parameter. gcc/testsuite/ChangeLog: PR c++/96197 * g++.dg/cpp1y/constexpr-array8.C: New test.
2020-07-09c++: Partially revert fix for PR c++/95497 [PR96132]Patrick Palka1-0/+1
I was mistaken to assume that a dependent type is necessarily incomplete, and indeed there are multiple places in the frontend where we check a type for both dependency and completeness. So this patch partially reverts the fix for PR95497, restoring the dependent_type_p check that guarded the call to is_really_empty_class below. gcc/cp/ChangeLog: PR c++/96132 * constexpr.c (potential_constant_expression_1) <case PARM_DECL>: Restore dependent_type_p check that guarded the call to is_really_empty_class. gcc/testsuite/ChangeLog: PR c++/96132 * g++.dg/template/incomplete12.C: New test.
2020-07-08c++: ICE in is_really_empty_class [PR95497]Patrick Palka1-1/+1
We are ICEing in the testcase below because we pass the yet-uninstantiated class type A<int> of the PARM_DECL b to is_really_empty_class from is_rvalue_constant_expression when parsing the requirement t += b. This patch fixes the ICE by guarding the problematic call to is_really_empty_class with a COMPLETE_TYPE_P check, which should also subsume the existing dependent_type_p check. gcc/cp/ChangeLog: PR c++/95497 * constexpr.c (potential_constant_expression_1) <case PARM_DECL>: When processing_template_decl, check COMPLETE_TYPE_P before calling is_really_empty_class. Don't check dependent_type_p. gcc/testsuite/ChangeLog: PR c++/95497 * g++.dg/cpp2a/concepts-pr95497.C: New test.
2020-07-02c++: Support C++20 virtual consteval functions. [PR88335]Jason Merrill1-0/+48
Jakub's partial implementation of consteval virtual had trouble with the current ABI requirement that we omit the vtable slot for a consteval virtual function; it's difficult to use the normal code for constant evaluation and also magically make the slots disappear if the vtables get written out. I notice that Clang trunk also doesn't implement that requirement, and it seems unnecessary to me; I expect consteval virtual functions to be extremely rare, so it should be fine to just give them a vtable slot as normal but put zero in it if the vtable gets emitted. I've commented as much to the ABI committee. One of Jakub's testcases points out that we weren't handling thunks in our constexpr virtual handling; that is fixed here as well. Incidentally, being able to use C++11 range-for definitely simplified clear_consteval_vfns. gcc/c-family/ChangeLog: * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_consteval. gcc/cp/ChangeLog: * decl.c (grokfndecl): Allow consteval virtual. * search.c (check_final_overrider): Check consteval mismatch. * constexpr.c (cxx_eval_thunk_call): New. (cxx_eval_call_expression): Call it. * cvt.c (cp_get_fndecl_from_callee): Handle FDESC_EXPR. * decl2.c (mark_vtable_entries): Track vtables with consteval. (maybe_emit_vtables): Pass consteval_vtables through. (clear_consteval_vfns): Replace consteval with nullptr. (c_parse_final_cleanups): Call it. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval-virtual1.C: New test. * g++.dg/cpp2a/consteval-virtual2.C: New test. * g++.dg/cpp2a/consteval-virtual3.C: New test. * g++.dg/cpp2a/consteval-virtual4.C: New test. * g++.dg/cpp2a/consteval-virtual5.C: New test. Co-authored-by: Jakub Jelinek <jakub@redhat.com>
2020-06-17c++: ICE with IMPLICIT_CONV_EXPR in array subscript [PR95508]Marek Polacek1-0/+13
Since r10-7096 convert_like, when called in a template, creates an IMPLICIT_CONV_EXPR when we're converting to/from array type. In this test, we have e[f], and we're converting f (of type class A) to int, so convert_like in build_new_op_1 created the IMPLICIT_CONV_EXPR that got into cp_build_array_ref which calls maybe_constant_value. My patch above failed to adjust this spot to call fold_non_dependent_expr instead, which can handle codes like I_C_E in a template. Fixed by using a new function maybe_fold_non_dependent_expr, which, if the expr can't be evaluated to a constant, returns the original expression. gcc/cp/ChangeLog: PR c++/95508 * constexpr.c (maybe_fold_non_dependent_expr): New. * cp-tree.h (maybe_fold_non_dependent_expr): Declare. * typeck.c (cp_build_array_ref): Call maybe_fold_non_dependent_expr instead of maybe_constant_value. gcc/testsuite/ChangeLog: PR c++/95508 * g++.dg/template/conv16.C: New test.
2020-06-04c++: Fix complex constexpr virtual cases [PR93310].Jason Merrill1-41/+3
The code in constexpr for looking up the actual type of the object and then getting the virtual function from there broke for both of these tests: for 16, it assumed incorrectly that the DECL_VINDEX would apply to the most derived type's vtable; for 17, it failed to consider that during construction the base subobject is treated as being of the base type. Fixed by just doing constant evaluation of the expression that looks up the function in the vtable. This means that a virtual call will involve loading the vptr, so we will reject some calls through non-constexpr variables that we previously accepted, but this seems appropriate to me. None of our testcases were affected. gcc/cp/ChangeLog: PR c++/93310 * constexpr.c (cxx_eval_constant_expression) [OBJ_TYPE_REF]: Evaluate OBJ_TYPE_REF_EXPR. gcc/testsuite/ChangeLog: PR c++/93310 * g++.dg/cpp2a/constexpr-virtual16.C: New test. * g++.dg/cpp2a/constexpr-virtual17.C: New test. * g++.dg/cpp2a/constexpr-new12.C: Adjust diagnostic.
2020-06-04c++: Reject some further reinterpret casts in constexpr [PR82304, PR95307]Jakub Jelinek1-13/+12
cxx_eval_outermost_constant_expr had a check for reinterpret_casts from pointers (well, it checked from ADDR_EXPRs) to integral type, but that only caught such cases at the toplevel of expressions. As the comment said, it should be done even inside of the expressions, but at the point of the writing e.g. pointer differences used to be a problem. We now have POINTER_DIFF_EXPR, so this is no longer an issue. Had to do it just for CONVERT_EXPR, because the FE emits NOP_EXPR casts from pointers to integrals in various spots, e.g. for the PMR & 1 tests, though on NOP_EXPR we have the REINTERPRET_CAST_P bit that we do check, while on CONVERT_EXPR we don't. 2020-06-04 Jakub Jelinek <jakub@redhat.com> PR c++/82304 PR c++/95307 * constexpr.c (cxx_eval_constant_expression): Diagnose CONVERT_EXPR conversions from pointer types to arithmetic types here... (cxx_eval_outermost_constant_expr): ... instead of here. * g++.dg/template/pr79650.C: Expect different diagnostics and expect it on all lines that do pointer to integer casts. * g++.dg/cpp1y/constexpr-shift1.C: Expect different diagnostics. * g++.dg/cpp1y/constexpr-82304.C: New test. * g++.dg/cpp0x/constexpr-95307.C: New test.
2020-05-29c++: constexpr ctor with RANGE_EXPR index [PR95241]Patrick Palka1-0/+16
In the testcase below, the CONSTRUCTOR for 'field' contains a RANGE_EXPR index: {{aggr_init_expr<...>, [1...2]={.off=1}}} but get_or_insert_ctor_field isn't prepared to handle looking up a RANGE_EXPR index. This patch adds limited support to get_or_insert_ctor_field for looking up a RANGE_EXPR index. The limited scope of this patch should make it more suitable for backporting, and more extensive support would be needed only to handle self-modifying CONSTRUCTORs that contain a RANGE_EXPR index, but I haven't yet been able to come up with a testcase that actually creates such a CONSTRUCTOR. gcc/cp/ChangeLog: PR c++/95241 * constexpr.c (get_or_insert_ctor_field): Add limited support for RANGE_EXPR index lookups. gcc/testsuite/ChangeLog: PR c++/95241 * g++.dg/cpp0x/constexpr-array25.C: New test.
2020-05-28c++: Immediately deduce auto member [PR94926].Jason Merrill1-2/+0
In r9-297 I was trying to be more flexible and treat static data members of class templates more like variable templates, where the type need not be determined until the variable is instantiated, but I suppose that in a class the types of all the non-template members need to be determined at the time of class instantiation. gcc/cp/ChangeLog: PR c++/94926 * decl.c (cp_finish_decl): Revert r9-297 change. (check_static_variable_definition): Likewise. * constexpr.c (ensure_literal_type_for_constexpr_object): Likewise. * pt.c (instantiate_decl): Return early on type error. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/pr86648.C: Expect error. * g++.dg/cpp1z/static2.C: Expect error. * g++.dg/cpp0x/nsdmi16.C: New test.
2020-05-23c++: Avoid concept evaluation when uid-sensitive [PR94038]Patrick Palka1-1/+2
Concept evaluation may entail DECL_UID generation and/or template instantiation, so in general we can't perform it during uid-sensitive constexpr evaluation. gcc/cp/ChangeLog: PR c++/94038 * constexpr.c (cxx_eval_constant_expression) <case TEMPLATE_ID_EXPR>: Don't evaluate the concept when constexpr evaluation is uid-sensitive. gcc/testsuite/ChangeLog: PR c++/94038 * g++.dg/warn/pr94038-3.C: New test.
2020-05-21c++: Constant expression parsing and parameters.Jason Merrill1-0/+8
The difference between a "potential" constant-expression and a regular constant-expression is the treatment of parameters; in a constexpr function, a parameter is potentially constant when evaluating a call to that function, but it is not constant during parsing of the function. cp_parser_constant_expression should check the latter rather than the former. gcc/cp/ChangeLog: * cp-tree.h (is_rvalue_constant_expression): Declare. * constexpr.c (is_rvalue_constant_expression): New. * parser.c (cp_parser_constant_expression): Use it. * decl.c (cp_finish_decl): Try to treat a constexpr initializer in a template as constant.
2020-05-21c++: template instantiation during fold_for_warn [PR94038]Patrick Palka1-24/+76
Unfortunately, the previous fix to PR94038 is fragile. When the argument to fold_for_warn is a bare CALL_EXPR, then all is well: the result of maybe_constant_value from fold_for_warn (with uid_sensitive=true) is reused via the cv_cache in the subsequent call to maybe_constant_value from cp_fold (with uid_sensitive=false), so we avoid instantiating bar<int>. But when the argument to fold_for_warn is more complex, e.g. an INDIRECT_REF of a CALL_EXPR, as in the testcase below (due to bar<int>() returning const int& which we need to decay to int) then from fold_for_warn we call maybe_constant_value on the INDIRECT_REF, and from cp_fold we call it on the CALL_EXPR, so there is no reuse via the cv_cache and we therefore end up instantiating bar<int>. So for a more robust solution to this general issue of warning flags affecting code generation, it seems that we need a way to globally avoid template instantiation during constexpr evaluation whenever we're performing warning-dependent folding. To that end, this patch replaces the flag constexpr_ctx::uid_sensitive with a global flag uid_sensitive_constexpr_evaluation_p, and enables it during fold_for_warn using an RAII helper. The patch also adds a counter that keeps track of the number of times uid_sensitive_constexpr_evaluation_p is called and returned true, and we use this to determine whether the result of constexpr evaluation was restricted by the flag. This lets us safely update the cv_cache and fold_cache from fold_for_warn in the most common case where the flag did not restrict constexpr evaluation. gcc/cp/ChangeLog: PR c++/94038 * constexpr.c (constexpr_ctx::uid_sensitive): Remove field. (uid_sensitive_constexpr_evaluation_value): Define. (uid_sensitive_constexpr_evaluation_true_counter): Define. (uid_sensitive_constexpr_evaluation_p): Define. (uid_sensitive_constexpr_evaluation_sentinel): Define its constructor. (uid_sensitive_constexpr_evaluation_checker): Define its constructor and its evaluation_restricted_p method. (get_fundef_copy): Remove 'ctx' parameter. Use u_s_c_e_p instead of constexpr_ctx::uid_sensitive. (cxx_eval_call_expression): Use u_s_c_e_p instead, and test it last. Adjust call to get_fundef_copy. (instantiate_cx_fn_r): Test u_s_c_e_p so that we increment the counter if necessary. (cxx_eval_outermost_constant_expr): Remove 'uid_sensitive' parameter. Adjust function body accordingly. (maybe_constant_value): Remove 'uid_sensitive' parameter and adjust function body accordingly. Set up a uid_sensitive_constexpr_evaluation_checker, and use it to conditionally update the cv_cache. * cp-gimplify.c (cp_fold): Set up a uid_sensitive_constexpr_evaluation_checker, and use it to conditionally update the fold_cache. * cp-tree.h (maybe_constant_value): Update declaration. (struct uid_sensitive_constexpr_evaluation_sentinel): Define. (struct sensitive_constexpr_evaluation_checker): Define. * expr.c (fold_for_warn): Set up a uid_sensitive_constexpr_evaluation_sentinel before calling the folding subroutines. Drop all but the first argument to maybe_constant_value. gcc/testsuite/ChangeLog: PR c++/94038 * g++.dg/warn/pr94038-2.C: New test.
2020-05-13c++: Replace "C++2a" with "C++20".Jason Merrill1-19/+19
C++20 isn't final quite yet, but all that remains is formalities, so let's go ahead and change all the references. I think for the next C++ standard we can just call it C++23 rather than C++2b, since the committee has been consistent about time-based releases rather than feature-based. gcc/c-family/ChangeLog 2020-05-13 Jason Merrill <jason@redhat.com> * c.opt (std=c++20): Make c++2a the alias. (std=gnu++20): Likewise. * c-common.h (cxx_dialect): Change cxx2a to cxx20. * c-opts.c: Adjust. * c-cppbuiltin.c: Adjust. * c-ubsan.c: Adjust. * c-warn.c: Adjust. gcc/cp/ChangeLog 2020-05-13 Jason Merrill <jason@redhat.com> * call.c, class.c, constexpr.c, constraint.cc, decl.c, init.c, lambda.c, lex.c, method.c, name-lookup.c, parser.c, pt.c, tree.c, typeck2.c: Change cxx2a to cxx20. libcpp/ChangeLog 2020-05-13 Jason Merrill <jason@redhat.com> * include/cpplib.h (enum c_lang): Change CXX2A to CXX20. * init.c, lex.c: Adjust.
2020-05-05c++: constexpr and lambda capture [PR90212]Jason Merrill1-1/+7
This is the same issue as PR86429, just in potential_constant_expression_1 rather than cxx_eval_constant_expression. As in that case, when we're trying to evaluate a constant expression within a lambda, we don't have a constant closure object to refer to, but we can try to refer directly to the captured variable. gcc/cp/ChangeLog 2020-05-05 Jason Merrill <jason@redhat.com> PR c++/90212 * constexpr.c (potential_constant_expression_1): In a lambda function, consider a captured variable directly.
2020-04-27c++: Delegating constructor in constexpr init [PR94772]Patrick Palka1-1/+27
In the first testcase below, the call to the target constructor foo{} from foo's delegating constructor is encoded as the INIT_EXPR *(struct foo *) this = AGGR_INIT_EXPR <4, __ct_comp, D.2140, ...>; During initialization of the variable 'bar', we prematurely set TREE_READONLY on bar's CONSTRUCTOR in two places before the outer delegating constructor has returned: first, at the end of cxx_eval_call_expression after evaluating the RHS of the above INIT_EXPR, and second, at the end of cxx_eval_store_expression after having finished evaluating the above INIT_EXPR. This then prevents the rest of the outer delegating constructor from mutating 'bar'. This (hopefully minimally risky) patch makes cxx_eval_call_expression refrain from setting TREE_READONLY when evaluating the target constructor of a delegating constructor. It also makes cxx_eval_store_expression refrain from setting TREE_READONLY when the object being initialized is "*this', on the basis that it should be the responsibility of the routine that set 'this' in the first place to set the object's TREE_READONLY appropriately. gcc/cp/ChangeLog: PR c++/94772 * constexpr.c (cxx_eval_call_expression): Don't set new_obj if we're evaluating the target constructor of a delegating constructor. (cxx_eval_store_expression): Don't set TREE_READONLY if the LHS of the INIT_EXPR is '*this'. gcc/testsuite/ChangeLog: PR c++/94772 * g++.dg/cpp1y/constexpr-tracking-const23.C: New test. * g++.dg/cpp1y/constexpr-tracking-const24.C: New test. * g++.dg/cpp1y/constexpr-tracking-const25.C: New test.
2020-04-20c++: Fix ICE with { } as template argument [PR94592]Marek Polacek1-2/+6
As an extension (there should be a CWG about this though), we support braced-init-list as a template argument, but convert_nontype_argument had trouble digesting them. We ICEd because of the double coercion we perform for template arguments: convert_nontype_argument called from finish_template_type got a { }, and since a class type was involved and we were in a template, convert_like created an IMPLICIT_CONV_EXPR. Then the second conversion of the same argument crashed in constexpr.c because the IMPLICIT_CONV_EXPR had gotten wrapped in a TARGET_EXPR. Another issue was that an IMPLICIT_CONV_EXPR leaked to constexpr.c when building an aggregate init. We should have instantiated the IMPLICIT_CONV_EXPR in the first call to convert_nontype_argument, but we didn't, because the call to is_nondependent_constant_expression returned false because it checks !BRACE_ENCLOSED_INITIALIZER_P. Then non_dep was false even though the expression didn't contain anything dependent and we didn't instantiate it in convert_nontype_argument. To fix this, check BRACE_ENCLOSED_INITIALIZER_P in cxx_eval_outermost_constant_expr rather than in is_nondependent_*. PR c++/94592 * constexpr.c (cxx_eval_outermost_constant_expr): Return when T is a BRACE_ENCLOSED_INITIALIZER_P. (is_nondependent_constant_expression): Don't check BRACE_ENCLOSED_INITIALIZER_P. (is_nondependent_static_init_expression): Likewise. * g++.dg/cpp2a/nontype-class34.C: New test. * g++.dg/cpp2a/nontype-class35.C: New test.
2020-04-14c++: Stray RESULT_DECLs in result of constexpr call [PR94034]Patrick Palka1-0/+54
When evaluating the initializer of 'a' in the following example struct A { A() = default; A(const A&); A *p = this; }; constexpr A foo() { return {}; } constexpr A a = foo(); the PLACEHOLDER_EXPR for 'this' in the aggregate initializer returned by foo gets resolved to the RESULT_DECL of foo. But due to guaranteed RVO, the 'this' should really be resolved to '&a'. Fixing this properly by immediately resolving 'this' and PLACEHOLDER_EXPRs to the ultimate object under construction would in general mean that we would no longer be able to cache constexpr calls for which RVO possibly applies, because the result of the call may now depend on the ultimate object under construction. So as a mostly correct stopgap solution that retains cachability of RVO'd constexpr calls, this patch fixes this issue by rewriting all occurrences of the RESULT_DECL in the result of a constexpr function call with the current object under construction, after the call returns. This means the 'this' pointer during construction of the temporary will still point to the temporary object instead of the ultimate object, but besides that this approach seems functionally equivalent to the proper approach. gcc/cp/ChangeLog: PR c++/94034 * constexpr.c (replace_result_decl_data): New struct. (replace_result_decl_data_r): New function. (replace_result_decl): New function. (cxx_eval_call_expression): Use it. * tree.c (build_aggr_init_expr): Set the location of the AGGR_INIT_EXPR to that of its initializer. gcc/testsuite/ChangeLog: PR c++/94034 * g++.dg/cpp0x/constexpr-empty15.C: New test. * g++.dg/cpp1y/constexpr-nsdmi6a.C: New test. * g++.dg/cpp1y/constexpr-nsdmi6b.C: New test. * g++.dg/cpp1y/constexpr-nsdmi7a.C: New test. * g++.dg/cpp1y/constexpr-nsdmi7b.C: New test.
2020-04-13c++: More self-modifying constexpr init [PR94470]Patrick Palka1-12/+7
In this PR we're incorrectly rejecting a self-modifying constexpr initializer as a consequence of the fix for PR78572. It looks like however that the fix for PR78572 is obsoleted by the fix for PR89336: the testcase from the former PR successfully compiles even with its fix reverted. But then further testing showed that the analogous testcase of PR78572 where the array has an aggregate element type is still problematic (i.e. we ICE) even with the fix for PR78572 applied. The reason is that in cxx_eval_bare_aggregate we attach a constructor_elt of aggregate type always to the end of the new CONSTRUCTOR, but that's not necessarily correct if the CONSTRUCTOR is self-modifying. We should instead be using get_or_insert_ctor_field to insert the constructor_elt in the right place. So this patch reverts the PR78572 fix and makes the appropriate changes to cxx_eval_bare_aggregate. This fixes PR94470, and we now are also able to fully reduce the initializers of 'arr' and 'arr2' in the new test array57.C to constant initializers. gcc/cp/ChangeLog: PR c++/94470 * constexpr.c (get_or_insert_ctor_field): Set default value of parameter 'pos_hint' to -1. (cxx_eval_bare_aggregate): Use get_or_insert_ctor_field instead of assuming the the next index belongs at the end of the new CONSTRUCTOR. (cxx_eval_store_expression): Revert PR c++/78572 fix. gcc/testsuite/ChangeLog: PR c++/94470 * g++.dg/cpp1y/constexpr-nsdmi8.C: New test. * g++.dg/cpp1y/constexpr-nsdmi9.C: New test. * g++.dg/init/array57.C: New test.
2020-04-09c++: constexpr static data member instantiation [PR94523]Jason Merrill1-4/+9
Here due to my recent change to store_init_value we were expanding the initializer of aw knowing that we were initializing aw. When cxx_eval_call_expression finished the constructor, it wanted to look up the value of aw to set TREE_READONLY on it, but we haven't set DECL_INITIAL yet, so decl_constant_value tried to instantiate the initializer again. And infinite recursion. Stopped by optimizing the case of asking for the value of ctx->object, which is ctx->value. It also would have worked to look in the values hash table, so let's move that up before decl_constant_value as well. gcc/cp/ChangeLog 2020-04-09 Jason Merrill <jason@redhat.com> PR c++/94523 * constexpr.c (cxx_eval_constant_expression) [VAR_DECL]: Look at ctx->object and ctx->global->values first.
2020-04-04c++: Refrain from using replace_placeholders in constexpr evaluation [PR94205]Patrick Palka1-8/+17
This removes the use of replace_placeholders in cxx_eval_constant_expression (which is causing the new test lambda-this6.C to ICE due to replace_placeholders mutating the shared TARGET_EXPR_INITIAL tree which then trips up the gimplifier). In its place, this patch adds a 'parent' field to constexpr_ctx which is used to store a pointer to an outer constexpr_ctx that refers to another object under construction. With this new field, we can beef up lookup_placeholder to resolve PLACEHOLDER_EXPRs which refer to former objects under construction, which fixes PR94205 without needing to do replace_placeholders. Also we can now respect the CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag when resolving PLACEHOLDER_EXPRs, and doing so fixes the constexpr analogue of PR79937. gcc/cp/ChangeLog: PR c++/94205 PR c++/79937 * constexpr.c (struct constexpr_ctx): New field 'parent'. (cxx_eval_bare_aggregate): Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag from the original constructor to the reduced constructor. (lookup_placeholder): Prefer to return the outermost matching object by recursively calling lookup_placeholder on the 'parent' context, but don't cross CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors. (cxx_eval_constant_expression): Link the 'ctx' context to the 'new_ctx' context via 'new_ctx.parent' when being expanded without an explicit target. Don't call replace_placeholders. (cxx_eval_outermost_constant_expr): Initialize 'ctx.parent' to NULL. gcc/testsuite/ChangeLog: PR c++/94205 PR c++/79937 * g++.dg/cpp1y/pr79937-5.C: New test. * g++.dg/cpp1z/lambda-this6.C: New test.
2020-04-04c++: Fix constexpr evaluation of self-modifying CONSTRUCTORs [PR94219]Patrick Palka1-97/+153
This PR reveals that cxx_eval_bare_aggregate and cxx_eval_store_expression do not anticipate that a constructor element's initializer could mutate the underlying CONSTRUCTOR. Evaluation of the initializer could add new elements to the underlying CONSTRUCTOR, thereby potentially invalidating any pointers to or assumptions about the CONSTRUCTOR's elements, and so these routines should be prepared for that. To fix this problem, this patch makes cxx_eval_bare_aggregate and cxx_eval_store_expression recompute the constructor_elt pointers through which we're assigning, after it evaluates the initializer. Care is taken to to not slow down the common case where the initializer does not modify the underlying CONSTRUCTOR. gcc/cp/ChangeLog: PR c++/94219 PR c++/94205 * constexpr.c (get_or_insert_ctor_field): Split out (while adding support for VECTOR_TYPEs, and optimizations for the common case) from ... (cxx_eval_store_expression): ... here. Rename local variable 'changed_active_union_member_p' to 'activated_union_member_p'. Record the sequence of indexes into 'indexes' that yields the subobject we're assigning to. Record the integer offsets of the constructor indexes we're assigning through into 'index_pos_hints'. After evaluating the initializer of the store expression, recompute 'valp' using 'indexes' and using 'index_pos_hints' as hints. (cxx_eval_bare_aggregate): Tweak comments. Use get_or_insert_ctor_field to recompute the constructor_elt pointer we're assigning through after evaluating each initializer. gcc/testsuite/ChangeLog: PR c++/94219 PR c++/94205 * g++.dg/cpp1y/constexpr-nsdmi3.C: New test. * g++.dg/cpp1y/constexpr-nsdmi4.C: New test. * g++.dg/cpp1y/constexpr-nsdmi5.C: New test. * g++.dg/cpp1z/lambda-this5.C: New test.
2020-04-04c++: Fix reuse of class constants [PR94453]Jason Merrill1-1/+1
The testcase hit an ICE trying to expand a TARGET_EXPR temporary cached from the other lambda-expression. This patch fixes this in two ways: 1) Avoid reusing a TARGET_EXPR from another function. 2) Avoid ending up with a TARGET_EXPR at all; the use of 'p' had become <TARGET_EXPR<NON_LVALUE_EXPR<TARGET_EXPR ...>>>, which doesn't make any sense. gcc/cp/ChangeLog 2020-04-04 Jason Merrill <jason@redhat.com> PR c++/94453 * constexpr.c (maybe_constant_value): Use break_out_target_exprs. * expr.c (mark_use) [VIEW_CONVERT_EXPR]: Don't wrap a TARGET_EXPR in NON_LVALUE_EXPR.