aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
AgeCommit message (Collapse)AuthorFilesLines
2023-11-16c++: constantness of call to function pointer [PR111703]Patrick Palka1-1/+6
potential_constant_expression for CALL_EXPR tests FUNCTION_POINTER_TYPE_P on the callee rather than on the type of the callee, which means we always pass want_rval=any when recursing and so may fail to identify a non-constant function pointer callee as such. Fixing this turns out to further work around PR111703. PR c++/111703 PR c++/107939 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Fix FUNCTION_POINTER_TYPE_P test. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-fn8.C: Extend test. * g++.dg/diagnostic/constexpr4.C: New test.
2023-11-15c++: constantness of local var in constexpr fn [PR111703, PR112269]Patrick Palka1-2/+2
potential_constant_expression was incorrectly treating most local variables from a constexpr function as constant because it wasn't considering the 'now' parameter. This patch fixes this by relaxing its var_in_maybe_constexpr_fn checks accordingly, which turns out to partially fix two recently reported regressions: PR111703 is a regression caused by r11-550-gf65a3299a521a4 for restricting constexpr evaluation during warning-dependent folding. The mechanism is intended to restrict only constant evaluation of the instantiated non-dependent expression, but it also ends up restricting constant evaluation occurring during instantiation of the expression, in particular when instantiating the converted argument 'x' (a VIEW_CONVERT_EXPR) into a copy constructor call. This seems like a flaw in the mechanism, though I don't know if we want to fix the mechanism or get rid of it completely since the original testcases which motivated the mechanism are fixed more simply by r13-1225-gb00b95198e6720. In any case, this patch partially fixes this by making us correctly treat 'x' as non-constant which prevents the problematic warning-dependent folding from occurring at all. PR112269 is caused by r14-4796-g3e3d73ed5e85e7 for merging tsubst_copy into tsubst_copy_and_build. tsubst_copy used to exit early when 'args' was empty, behavior which that commit deliberately didn't preserve. This early exit masked the fact that COMPLEX_EXPR wasn't handled by tsubst at all, and is a tree code that apparently we could see during warning-dependent folding on some targets. A complete fix is to add handling for this tree code in tsubst_expr, but this patch should fix the reported testsuite failures since the COMPLEX_EXPRs that crop up in <complex> are considered non-constant expressions after this patch. PR c++/111703 PR c++/112269 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case VAR_DECL>: Only consider var_in_maybe_constexpr_fn if 'now' is false. <case INDIRECT_REF>: Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-fn8.C: New test.
2023-10-20c++: remove NON_DEPENDENT_EXPR, part 1Patrick Palka1-9/+0
This tree code dates all the way back to r69130[1] which implemented typing of non-dependent expressions. Its motivation was never clear (to me at least) since its documentation in e.g. cp-tree.def doesn't seem accurate anymore. build_non_dependent_expr has since gained a bunch of edge cases about whether or how to wrap certain templated trees, making it hard to reason about in general. So this patch removes this tree code, and temporarily turns build_non_dependent_expr into the identity function. The subsequent patch will remove build_non_dependent_expr and adjust its callers appropriately. We now need to more thoroughly handle templated (sub)trees in a couple of places which previously didn't need to since they didn't look through NON_DEPENDENT_EXPR. [1]: https://gcc.gnu.org/pipermail/gcc-patches/2003-July/109355.html gcc/c-family/ChangeLog: * c-warn.cc (check_address_or_pointer_of_packed_member): Handle type-dependent callee of CALL_EXPR. gcc/cp/ChangeLog: * class.cc (instantiate_type): Remove NON_DEPENDENT_EXPR handling. * constexpr.cc (cxx_eval_constant_expression): Likewise. (potential_constant_expression_1): Likewise. * coroutines.cc (coro_validate_builtin_call): Don't expect ALIGNOF_EXPR to be wrapped in NON_DEPENDENT_EXPR. * cp-objcp-common.cc (cp_common_init_ts): Remove NON_DEPENDENT_EXPR handling. * cp-tree.def (NON_DEPENDENT_EXPR): Remove. * cp-tree.h (build_non_dependent_expr): Temporarily redefine as the identity function. * cvt.cc (maybe_warn_nodiscard): Handle type-dependent and variable callee of CALL_EXPR. * cxx-pretty-print.cc (cxx_pretty_printer::expression): Remove NON_DEPENDENT_EXPR handling. * error.cc (dump_decl): Likewise. (dump_expr): Likewise. * expr.cc (mark_use): Likewise. (mark_exp_read): Likewise. * pt.cc (build_non_dependent_expr): Remove. * tree.cc (lvalue_kind): Remove NON_DEPENDENT_EXPR handling. (cp_stabilize_reference): Likewise. * typeck.cc (warn_for_null_address): Likewise. (cp_build_binary_op): Handle type-dependent SIZEOF_EXPR operands. (cp_build_unary_op) <case TRUTH_NOT_EXPR>: Don't fold inside a template. gcc/testsuite/ChangeLog: * g++.dg/concepts/var-concept3.C: Adjust expected diagnostic for attempting to call a variable concept. Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-19c++: indirect change of active union member in constexpr [PR101631,PR102286]Nathaniel Shead1-47/+119
This patch adds checks for attempting to change the active member of a union by methods other than a member access expression. To be able to properly distinguish `*(&u.a) = ` from `u.a = `, this patch redoes the solution for c++/59950 to avoid extranneous *&; it seems that the only case that needed the workaround was when copying empty classes. This patch also ensures that constructors for a union field mark that field as the active member before entering the call itself; this ensures that modifications of the field within the constructor's body don't cause false positives (as these will not appear to be member access expressions). This means that we no longer need to start the lifetime of empty union members after the constructor body completes. As a drive-by fix, this patch also ensures that value-initialised unions are considered to have activated their initial member for the purpose of checking stores and accesses, which catches some additional mistakes pre-C++20. PR c++/101631 PR c++/102286 gcc/cp/ChangeLog: * call.cc (build_over_call): Fold more indirect refs for trivial assignment op. * class.cc (type_has_non_deleted_trivial_default_ctor): Create. * constexpr.cc (cxx_eval_call_expression): Start lifetime of union member before entering constructor. (cxx_eval_component_reference): Check against first member of value-initialised union. (cxx_eval_store_expression): Activate member for value-initialised union. Check for accessing inactive union member indirectly. * cp-tree.h (type_has_non_deleted_trivial_default_ctor): Forward declare. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-89336-3.C: Fix union initialisation. * g++.dg/cpp1y/constexpr-union6.C: New test. * g++.dg/cpp1y/constexpr-union7.C: New test. * g++.dg/cpp2a/constexpr-union2.C: New test. * g++.dg/cpp2a/constexpr-union3.C: New test. * g++.dg/cpp2a/constexpr-union4.C: New test. * g++.dg/cpp2a/constexpr-union5.C: New test. * g++.dg/cpp2a/constexpr-union6.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-19c++: Improve diagnostics for constexpr cast from void*Nathaniel Shead1-12/+79
This patch improves the errors given when casting from void* in C++26 to include the expected type if the types of the pointed-to objects were not similar. It also ensures (for all standard modes) that void* casts are checked even for DECL_ARTIFICIAL declarations, such as lifetime-extended temporaries, and is only ignored for cases where we know it's OK (e.g. source_location::current) or have no other choice (heap-allocated data). gcc/cp/ChangeLog: * constexpr.cc (is_std_source_location_current): New. (cxx_eval_constant_expression): Only ignore cast from void* for specific cases and improve other diagnostics. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-cast4.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Marek Polacek <polacek@redhat.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-17c++: Add missing auto_diagnostic_groups to constexpr.ccNathaniel Shead1-0/+9
gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_dynamic_cast_fn): Add missing auto_diagnostic_group. (cxx_eval_call_expression): Likewise. (diag_array_subscript): Likewise. (outside_lifetime_error): Likewise. (potential_constant_expression_1): Likewise. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Marek Polacek <polacek@redhat.com>
2023-10-16c++: fix truncated diagnostic in C++23 [PR111272]Marek Polacek1-1/+9
In C++23, since P2448, a constexpr function F that calls a non-constexpr function N is OK as long as we don't actually call F in a constexpr context. So instead of giving an error in maybe_save_constexpr_fundef, we only give an error when evaluating the call. Unfortunately, as shown in this PR, the diagnostic can be truncated: z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function because: 10 | constexpr Jam() { ft(); } | ^~~ ...because what? With this patch, we say: z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function because: 10 | constexpr Jam() { ft(); } | ^~~ z.C:10:23: error: call to non-'constexpr' function 'int Jam::ft()' 10 | constexpr Jam() { ft(); } | ~~^~ z.C:8:7: note: 'int Jam::ft()' declared here 8 | int ft() { return 42; } | ^~ Like maybe_save_constexpr_fundef, explain_invalid_constexpr_fn should also check the body of a constructor, not just the mem-initializer. PR c++/111272 gcc/cp/ChangeLog: * constexpr.cc (explain_invalid_constexpr_fn): Also check the body of a constructor in C++14 and up. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-diag1.C: New test.
2023-09-28Remove some unused poly_int variablesRichard Sandiford1-1/+0
Switching to default constructors for poly_int exposed some unused variables that weren't previously diagnosed. gcc/ * dwarf2out.cc (mem_loc_descriptor): Remove unused variables. * tree-affine.cc (expr_to_aff_combination): Likewise. gcc/cp/ * constexpr.cc (cxx_fold_indirect_ref): Remove unused variables. gcc/rust/ * backend/rust-constexpr.cc (rs_fold_indirect_ref): Remove unused variables.
2023-09-22c++: constexpr and designated initializerJason Merrill1-1/+1
The change of active member being non-constant (before C++20) results in a CONSTRUCTOR with a null value for the first field, don't crash. gcc/cp/ChangeLog: * constexpr.cc (free_constructor): Handle null ce->value. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-union7.C: New test.
2023-09-19c++: Move consteval folding to cp_fold_rMarek Polacek1-3/+20
In the review of P2564: <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628747.html> it turned out that in order to correctly handle an example in the paper, we should stop doing immediate evaluation in build_over_call and bot_replace, and instead do it in cp_fold_r. This patch does that. Another benefit is that this is a pretty significant simplification, at least in my opinion. Also, this fixes the c++/110997 ICE (but the test doesn't compile yet). The main drawback seems to be that cp_fold_r doesn't process uninstantiated templates. We still have to handle things like "false ? foo () : 1". To that end, I've added cp_fold_immediate, called on dead branches in cxx_eval_conditional_expression. You'll see that I've reintroduced ADDR_EXPR_DENOTES_CALL_P here. This is to detect *(&foo)) () (s.*&S::foo) () which were deemed ill-formed. gcc/cp/ChangeLog: * call.cc (build_over_call): Set ADDR_EXPR_DENOTES_CALL_P. Don't handle immediate_invocation_p here. * constexpr.cc (cxx_eval_call_expression): Use mce_true for DECL_IMMEDIATE_FUNCTION_P. (cxx_eval_conditional_expression): Call cp_fold_immediate. * cp-gimplify.cc (enum fold_flags): Add ff_fold_immediate. (maybe_replace_decl): Make static. (cp_fold_r): Expand immediate invocations. (cp_fold_immediate_r): New. (cp_fold_immediate): New. * cp-tree.h (ADDR_EXPR_DENOTES_CALL_P): Define. (cp_fold_immediate): Declare. * tree.cc (bot_replace): Don't handle immediate invocations here. libstdc++-v3/ChangeLog: * testsuite/20_util/allocator/105975.cc: Add dg-error. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if2.C: Add xfail. * g++.dg/cpp2a/consteval-memfn1.C: Adjust. * g++.dg/cpp2a/consteval11.C: Remove dg-message. * g++.dg/cpp2a/consteval3.C: Remove dg-message and dg-error. * g++.dg/cpp2a/consteval9.C: Remove dg-message. * g++.dg/cpp2a/consteval32.C: New test. * g++.dg/cpp2a/consteval33.C: New test. * g++.dg/cpp2a/consteval34.C: New test. * g++.dg/cpp2a/consteval35.C: New test.
2023-09-05c++: improve verify_constant diagnostic [PR91483]Marek Polacek1-1/+62
When verify_constant complains, it's pretty terse. Consider void test () { constexpr int i = 42; constexpr const int *p = &i; } where it says "'& i' is not a constant expression". OK, but why? With this patch, we say: b.C:5:28: error: '& i' is not a constant expression 5 | constexpr const int *p = &i; | ^~ b.C:5:28: note: pointer to 'i' is not a constant expression b.C:4:17: note: address of non-static constexpr variable 'i' may differ on each invocation of the enclosing function; add 'static' to give it a constant address 4 | constexpr int i = 42; | ^ | static which brings g++ on par with clang++. PR c++/91483 gcc/cp/ChangeLog: * constexpr.cc (verify_constant_explain_r): New. (verify_constant): Call it. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/constexpr3.C: New test.
2023-08-25OpenMP: Add OMP_STRUCTURED_BLOCK and GIMPLE_OMP_STRUCTURED_BLOCK.Sandra Loosemore1-0/+1
In order to detect invalid jumps in and out of intervening code in imperfectly-nested loops, the front ends need to insert some sort of marker to identify the structured block sequences that they push into the inner body of the loop. The error checking happens in the diagnose_omp_blocks pass, between gimplification and OMP lowering, so we need both GENERIC and GIMPLE representations of these markers. They are removed in OMP lowering so no subsequent passes need to know about them. This patch doesn't include any front-end changes to generate the new data structures. gcc/cp/ChangeLog * constexpr.cc (cxx_eval_constant_expression): Handle OMP_STRUCTURED_BLOCK. * pt.cc (tsubst_expr): Likewise. gcc/ChangeLog * doc/generic.texi (OpenMP): Document OMP_STRUCTURED_BLOCK. * doc/gimple.texi (GIMPLE instruction set): Add GIMPLE_OMP_STRUCTURED_BLOCK. (GIMPLE_OMP_STRUCTURED_BLOCK): New subsection. * gimple-low.cc (lower_stmt): Error on GIMPLE_OMP_STRUCTURED_BLOCK. * gimple-pretty-print.cc (dump_gimple_omp_block): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (pp_gimple_stmt_1): Likewise. * gimple-walk.cc (walk_gimple_stmt): Likewise. * gimple.cc (gimple_build_omp_structured_block): New. * gimple.def (GIMPLE_OMP_STRUCTURED_BLOCK): New. * gimple.h (gimple_build_omp_structured_block): Declare. (gimple_has_substatements): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (CASE_GIMPLE_OMP): Likewise. * gimplify.cc (is_gimple_stmt): Handle OMP_STRUCTURED_BLOCK. (gimplify_expr): Likewise. * omp-expand.cc (GIMPLE_OMP_STRUCTURED_BLOCK): Error on GIMPLE_OMP_STRUCTURED_BLOCK. * omp-low.cc (scan_omp_1_stmt): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (lower_omp_1): Likewise. (diagnose_sb_1): Likewise. (diagnose_sb_2): Likewise. * tree-inline.cc (remap_gimple_stmt): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (estimate_num_insns): Likewise. * tree-nested.cc (convert_nonlocal_reference_stmt): Likewise. (convert_local_reference_stmt): Likewise. (convert_gimple_call): Likewise. * tree-pretty-print.cc (dump_generic_node): Handle OMP_STRUCTURED_BLOCK. * tree.def (OMP_STRUCTURED_BLOCK): New. * tree.h (OMP_STRUCTURED_BLOCK_BODY): New.
2023-07-27c++: constexpr empty subobject elision [PR110197]Patrick Palka1-7/+16
Now that init_subob_ctx no longer sets new_ctx.ctor for a subobject of empty type, it seems we need to ensure its callers also consistently omit entries in the parent ctx->ctor for such subobjects. We also need to allow cxx_eval_array_reference to synthesize an empty subobject even if the array CONSTRUCTOR has CONSTRUCTOR_NO_CLEARING set. PR c++/110197 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_array_reference): Allow synthesizing an empty subobject even if CONSTRUCTOR_NO_CLEARING is set. (cxx_eval_bare_aggregate): Set 'no_slot' to true more generally whenever new_ctx.ctor is set to NULL_TREE by init_subob_ctx, i.e. whenever initializing an subobject of empty type. (cxx_eval_vec_init_1): Define 'no_slot' as above and use it accordingly. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-empty18.C: New test. * g++.dg/cpp0x/constexpr-empty19.C: New test.
2023-07-25c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]Nathaniel Shead1-42/+86
This adds rudimentary lifetime tracking in C++ constexpr contexts, allowing the compiler to report errors with using values after their backing has gone out of scope. We don't yet handle other ways of accessing values outside their lifetime (e.g. following explicit destructor calls). PR c++/96630 PR c++/98675 PR c++/70331 gcc/cp/ChangeLog: * constexpr.cc (constexpr_global_ctx::is_outside_lifetime): New function. (constexpr_global_ctx::get_value): Don't return expired values. (constexpr_global_ctx::get_value_ptr): Likewise. (constexpr_global_ctx::remove_value): Mark value outside lifetime. (outside_lifetime_error): New function. (cxx_eval_call_expression): No longer track save_exprs. (cxx_eval_loop_expr): Likewise. (cxx_eval_constant_expression): Add checks for outside lifetime values. Remove local variables at end of bind exprs, and temporaries after cleanup points. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-lifetime1.C: New test. * g++.dg/cpp1y/constexpr-lifetime2.C: New test. * g++.dg/cpp1y/constexpr-lifetime3.C: New test. * g++.dg/cpp1y/constexpr-lifetime4.C: New test. * g++.dg/cpp1y/constexpr-lifetime5.C: New test. * g++.dg/cpp1y/constexpr-lifetime6.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-07-25c++: Improve location information in constant evaluationNathaniel Shead1-1/+30
This patch updates 'input_location' during constant evaluation to ensure that errors in subexpressions that lack location information still provide accurate diagnostics. By itself this change causes some small regressions in diagnostic quality for circumstances where errors used 'input_location' but the location of the parent subexpression doesn't make sense, so this patch also includes a small diagnostic improvement to fix the most egregious case. gcc/cp/ChangeLog: * constexpr.cc (modifying_const_object_error): Find the source location of the const object's declaration. (cxx_eval_constant_expression): Update input_location to the location of the currently evaluated expression, if possible. libstdc++-v3/ChangeLog: * testsuite/25_algorithms/equal/constexpr_neg.cc: Update diagnostic locations. * testsuite/26_numerics/gcd/105844.cc: Likewise. * testsuite/26_numerics/lcm/105844.cc: Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-48089.C: Update diagnostic locations. * g++.dg/cpp0x/constexpr-70323.C: Likewise. * g++.dg/cpp0x/constexpr-70323a.C: Likewise. * g++.dg/cpp0x/constexpr-delete2.C: Likewise. * g++.dg/cpp0x/constexpr-diag3.C: Likewise. * g++.dg/cpp0x/constexpr-ice20.C: Likewise. * g++.dg/cpp0x/constexpr-mutable3.C: Likewise. * g++.dg/cpp0x/constexpr-recursion.C: Likewise. * g++.dg/cpp0x/overflow1.C: Likewise. * g++.dg/cpp1y/constexpr-89285.C: Likewise. * g++.dg/cpp1y/constexpr-89481.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const14.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const16.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const18.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const19.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const21.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const22.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const3.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const4.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const7.C: Likewise. * g++.dg/cpp1y/constexpr-union5.C: Likewise. * g++.dg/cpp1y/pr68180.C: Likewise. * g++.dg/cpp1z/constexpr-lambda6.C: Likewise. * g++.dg/cpp1z/constexpr-lambda8.C: Likewise. * g++.dg/cpp2a/bit-cast11.C: Likewise. * g++.dg/cpp2a/bit-cast12.C: Likewise. * g++.dg/cpp2a/bit-cast14.C: Likewise. * g++.dg/cpp2a/constexpr-98122.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic17.C: Likewise. * g++.dg/cpp2a/constexpr-init1.C: Likewise. * g++.dg/cpp2a/constexpr-new12.C: Likewise. * g++.dg/cpp2a/constexpr-new3.C: Likewise. * g++.dg/cpp2a/constinit10.C: Likewise. * g++.dg/cpp2a/is-corresponding-member4.C: Likewise. * g++.dg/ext/constexpr-vla2.C: Likewise. * g++.dg/ext/constexpr-vla3.C: Likewise. * g++.dg/ubsan/pr63956.C: Likewise. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-07-25c++: fix ICE with constexpr ARRAY_REF [PR110382]Marek Polacek1-2/+11
This code in cxx_eval_array_reference has been hard to get right. In r12-2304 I added some code; in r13-5693 I removed some of it. Here the problematic line is "S s = arr[0];" which causes a crash on the assert in verify_ctor_sanity: gcc_assert (!ctx->object || !DECL_P (ctx->object) || ctx->global->get_value (ctx->object) == ctx->ctor); ctx->object is the VAR_DECL 's', which is correct here. The second line points to the problem: we replaced ctx->ctor in cxx_eval_array_reference: new_ctx.ctor = build_constructor (elem_type, NULL); // #1 which I think we shouldn't have; the CONSTRUCTOR we created in cxx_eval_constant_expression/DECL_EXPR new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL); had the right type. We still need #1 though. E.g., in constexpr-96241.C, we never set ctx.ctor/object before calling cxx_eval_array_reference, so we have to build a CONSTRUCTOR there. And in constexpr-101371-2.C we have a ctx.ctor, but it has the wrong type, so we need a new one. We can fix the problem by always clearing the object, and, as an optimization, only create/free a new ctor when actually needed. PR c++/110382 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_array_reference): Create a new constructor only when we don't already have a matching one. Clear the object when the type is non-scalar. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-110382.C: New test.
2023-07-21c++: fix ICE with is_really_empty_class [PR110106]Marek Polacek1-2/+3
is_really_empty_class is liable to crash when it gets an incomplete or dependent type. Since r11-557, we pass the yet-uninstantiated class type S<0> of the PARM_DECL s to is_really_empty_class -- because of the potential_rvalue_constant_expression -> is_rvalue_constant_expression change in cp_parser_constant_expression. Here we're not parsing a template so we did not check COMPLETE_TYPE_P as we should. It should work to complete the type before checking COMPLETE_TYPE_P. PR c++/110106 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1): Try to complete the type when !processing_template_decl. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept80.C: New test.
2023-07-18c++: constexpr bit_cast with empty fieldJason Merrill1-0/+9
The change to only cache constexpr calls that are reduced_constant_expression_p tripped on bit-cast3.C, which failed that predicate due to the presence of an empty field in the result of native_interpret_aggregate, which reduced_constant_expression_p rejects to avoid confusing output_constructor. This patch proposes to skip such fields in native_interpret_aggregate, since they aren't actually involved in the value representation. gcc/ChangeLog: * fold-const.cc (native_interpret_aggregate): Skip empty fields. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_bit_cast): Check that the result of native_interpret_aggregate doesn't need more evaluation.
2023-07-17c++: only cache constexpr calls that are constant exprsJason Merrill1-8/+9
In reviewing Nathaniel's patch for PR70331, it occurred to me that instead of looking for various specific problematic things in the result of a constexpr call to decide whether to cache it, we should use reduced_constant_expression_p. The change to that function is to avoid crashing on uninitialized objects of non-class type. In a trial version of this patch I checked to see what cases this stopped caching; most were instances of partially-initialized return values, which seem fine to not cache. Some were returning pointers to expiring local variables, which we definitely want not to cache. And one was bit-cast3.C, which will be handled in a follow-up patch. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Only cache reduced_constant_expression_p results. (reduced_constant_expression_p): Handle CONSTRUCTOR of scalar type. (cxx_eval_constant_expression): Fold vectors here. (cxx_eval_bare_aggregate): Not here.
2023-07-14c++: style tweakNathaniel Shead1-1/+1
At this point r == t, but it makes more sense to refer to t like all the other cases do. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Pass t to get_value. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-07-14c++: c++26 regression fixesJason Merrill1-11/+10
Apparently I wasn't actually running the testsuite in C++26 mode like I thought I was, so there were some failures I wasn't seeing. The constexpr hunk fixes regressions with the P2738 implementation; we still need to use the old handling for casting from void pointers to heap variables. PR c++/110344 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Move P2738 handling after heap handling. * name-lookup.cc (get_cxx_dialect_name): Add C++26. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-cast2.C: Adjust for P2738. * g++.dg/ipa/devirt-45.C: Handle -fimplicit-constexpr.
2023-06-27c++: C++26 constexpr cast from void* [PR110344]Jason Merrill1-0/+11
P2768 allows static_cast from void* to ob* in constant evaluation if the pointer does in fact point to an object of the appropriate type. cxx_fold_indirect_ref already does the work of finding such an object if it happens to be a subobject rather than the outermost object at that address, as in constexpr-voidptr2.C. P2768 PR c++/110344 gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Update __cpp_constexpr. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): In C++26, allow cast from void* to the type of a pointed-to object. gcc/testsuite/ChangeLog: * g++.dg/cpp26/constexpr-voidptr1.C: New test. * g++.dg/cpp26/constexpr-voidptr2.C: New test. * g++.dg/cpp26/feat-cxx26.C: New test.
2023-06-12c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-3/+3
I previously applied this change in r13-4565 but reverted it due to PR108071. That PR was then fixed by r13-4712, but I didn't re-apply this change then because we weren't making the array static; since r14-1500 for PR110070 we now make the initializer array static, so let's bring this back. In situations where the maybe_init_list_as_range optimization isn't viable, we can build an initializer_list<string> with a loop over a constant array of string literals. This is represented using a VEC_INIT_EXPR, which required adjusting a couple of places that expected the initializer array to have the same type as the target array and fixing build_vec_init not to undo our efforts. PR c++/105838 gcc/cp/ChangeLog: * call.cc (convert_like_internal) [ck_list]: Use maybe_init_list_as_array. * constexpr.cc (cxx_eval_vec_init_1): Init might have a different type. * tree.cc (build_vec_init_elt): Likewise. * init.cc (build_vec_init): Handle from_array from a TARGET_EXPR. Retain TARGET_EXPR of a different type. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt5.C: New test.
2023-06-11c++: unsynthesized defaulted constexpr fn [PR110122]Patrick Palka1-4/+10
In this other testcase from PR110122, during regeneration of the generic lambda with V=Bar{}, substitution followed by coerce_template_parms for A<V>'s template argument naturally yields a copy of V in terms of Bar's (implicitly) defaulted copy constructor. This however happens inside a template context so although we introduced a use of the copy constructor, mark_used didn't actually synthesize it, which causes subsequent constant evaluation of the template argument to fail with: nontype-class59.C: In instantiation of ‘void f() [with Bar V = Bar{Foo()}]’: nontype-class59.C:22:11: required from here nontype-class59.C:18:18: error: ‘constexpr Bar::Bar(const Bar&)’ used before its definition We already make sure to instantiate templated constexpr functions needed for constant evaluation (as per P0859R0). So this patch fixes this by making us synthesize defaulted constexpr functions needed for constant evaluation as well. PR c++/110122 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Synthesize defaulted functions needed for constant evaluation. (instantiate_cx_fn_r): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/nontype-class59.C: New test.
2023-05-10c++: be stricter about constinit [CWG2543]Jason Merrill1-0/+12
DR 2543 clarifies that constinit variables should follow the language, and diagnose non-constant initializers (according to [expr.const]) even if they can actually initialize the variables statically. DR 2543 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Preserve TARGET_EXPR flags. (potential_constant_expression_1): Check TARGET_EXPR_ELIDING_P. * typeck2.cc (store_init_value): Diagnose constinit sooner. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2543.C: New test.
2023-05-10c++: always check consteval addressJason Merrill1-7/+15
The restriction on the "permitted result of a constant expression" to not refer to an immediate function applies regardless of context. The previous code tried to only check in cases where we wouldn't get the check in cp_fold_r, but with the next patch I would need to add another case and it shouldn't be a problem to always check. We also shouldn't talk about immediate evaluation when we aren't dealing with one. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Always check for address of immediate fn. (maybe_constant_init_1): Evaluate PTRMEM_CST. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2478.C: Handle -fimplicit-constexpr. * g++.dg/cpp23/consteval-if12.C: Adjust diagnostics. * g++.dg/cpp2a/consteval20.C: Likewise. * g++.dg/cpp2a/consteval24.C: Likewise. * g++.dg/cpp2a/srcloc20.C: Likewise.
2023-05-07c++: potentiality of templated memfn call [PR109480]Patrick Palka1-26/+6
Here we're incorrectly deeming the templated call a.g() inside b's initializer as potentially constant, despite g being non-constexpr, which leads to us needlessly instantiating the initializer ahead of time and which subsequently triggers a bug in access checking deferral (to be fixed by the follow-up patch). This patch fixes this by calling get_fns earlier during CALL_EXPR potentiality checking so that when we extract a FUNCTION_DECL out of a templated member function call (whose overall callee is typically a COMPONENT_REF) we do the usual constexpr-eligibility checking for it. In passing, I noticed the nearby special handling of the object argument of a non-static member function call is effectively the same as the generic argument handling a few lines below. So this patch just gets rid of this special handling; otherwise we'd have to adapt it to handle templated versions of such calls. PR c++/109480 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Reorganize to call get_fns sooner. Remove special handling of the object argument of a non-static member function call. Remove dead store to 'fun'. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept59.C: Make e() constexpr so that the expected "without object" diagnostic isn't replaced by a "call to non-constexpr function" diagnostic. * g++.dg/template/non-dependent25.C: New test.
2023-05-02c++: look for empty base at specific offset [PR109678]Jason Merrill1-1/+1
While looking at the empty base handling for 109678, it occurred to me that we ought to be able to look for an empty base at a specific offset, not just in general. PR c++/109678 gcc/cp/ChangeLog: * cp-tree.h (lookup_base): Add offset parm. * constexpr.cc (cxx_fold_indirect_ref_1): Pass it. * search.cc (struct lookup_base_data_s): Add offset. (dfs_lookup_base): Handle it. (lookup_base): Pass it.
2023-05-02c++: std::variant slow to compile [PR109678]Jason Merrill1-10/+13
Here, when dealing with a class with a complex subobject structure, we would try and fail to find the relevant FIELD_DECL for an empty base before giving up. And we would do this at each level, in a combinatorially problematic way. Instead, we should check for an empty base first. PR c++/109678 gcc/cp/ChangeLog: * constexpr.cc (cxx_fold_indirect_ref_1): Handle empty base first. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/variant1.C: New test.
2023-04-15c++: constexpr aggregate destruction [PR109357]Jason Merrill1-4/+11
We were assuming that the result of evaluation of TARGET_EXPR_INITIAL would always be the new value of the temporary, but that's not necessarily true when the initializer is complex (i.e. target_expr_needs_replace). In that case evaluating the initializer initializes the temporary as a side-effect. PR c++/109357 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression) [TARGET_EXPR]: Check for complex initializer. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-dtor15.C: New test.
2023-03-16c++: maybe_constant_init and unevaluated operands [PR109030]Patrick Palka1-0/+4
This testcase in this PR (already fixed by r13-6526-ge4692319fd5fc7) demonstrates that maybe_constant_init can be called on an unevaluated operand (e.g. from massage_init_elt) so this entry point should also limit constant evaluation in that case, like maybe_constant_value does. PR c++/109030 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_init_1): For an unevaluated non-manifestly-constant operand, don't constant evaluate and instead call fold_to_constant as in maybe_constant_value. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-inst2.C: New test.
2023-03-15c++: ICE with constexpr lambda [PR107280]Marek Polacek1-1/+2
We crash here since r10-3661, the store_init_value hunk in particular. Before, we called cp_fully_fold_init, so e.g. {.str=VIEW_CONVERT_EXPR<char[8]>("")} was folded into {.str=""} but now we don't fold and keep the VCE around, and it causes trouble in cxx_eval_store_expression: in the !refs->is_empty () loop we descend on .str's initializer but since it's wrapped in a VCE, we skip the STRING_CST check and then crash on the CONSTRUCTOR_NO_CLEARING. PR c++/107280 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_store_expression): Strip location wrappers. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-lambda28.C: New test.
2023-03-07c++: noexcept and copy elision [PR109030]Marek Polacek1-1/+5
When processing a noexcept, constructors aren't elided: build_over_call has /* It's unsafe to elide the constructor when handling a noexcept-expression, it may evaluate to the wrong value (c++/53025). */ && (force_elide || cp_noexcept_operand == 0)) so the assert I added recently needs to be relaxed a little bit. PR c++/109030 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Relax assert. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept77.C: New test.
2023-03-07c++: error with constexpr operator() [PR107939]Marek Polacek1-2/+6
Similarly to PR107938, this also started with r11-557, whereby cp_finish_decl can call check_initializer even in a template for a constexpr initializer. Here we are rejecting extern const Q q; template<int> constexpr auto p = q(0); even though q has a constexpr operator(). It's deemed non-const by decl_maybe_constant_var_p because even though 'q' is const it is not of integral/enum type. If fun is not a function pointer, we don't know if we're using it as an lvalue or rvalue, so with this patch we pass 'any' for want_rval. With that, p_c_e/VAR_DECL doesn't flat out reject the underlying VAR_DECL. PR c++/107939 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Pass 'any' when recursing on a VAR_DECL and not a pointer to function. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/var-templ74.C: Remove dg-error. * g++.dg/cpp1y/var-templ77.C: New test.
2023-03-04c++: Don't defer local statics initialized with constant expressions [PR108702]Jakub Jelinek1-0/+19
The stmtexpr19.C testcase used to be rejected as it has a static variable in statement expression in constexpr context, but as that static variable is initialized by constant expression, when P2647R1 was implemented we agreed to make it valid. Now, as reported, the testcase compiles fine, but doesn't actually link because the static variable isn't defined anywhere, and with -flto ICEs because of this problem. This is because we never varpool_node::finalize_decl those vars, the constant expression in which the DECL_EXPR is present for the static VAR_DECL is folded (constant evaluated) into just the address of the VAR_DECL. Now, similar testcase included below (do we want to include it in the testsuite too?) works fine, because in cp_finish_decl -> make_rtl_for_nonlocal_decl we have since PR70353 fix: /* We defer emission of local statics until the corresponding DECL_EXPR is expanded. But with constexpr its function might never be expanded, so go ahead and tell cgraph about the variable now. */ defer_p = ((DECL_FUNCTION_SCOPE_P (decl) && !var_in_maybe_constexpr_fn (decl)) || DECL_VIRTUAL_P (decl)); and so don't defer them in constexpr/consteval functions. The following patch calls rest_of_decl_compilation which make_rtl_for_nonlocal_decl didn't call when encountering DECL_EXPRs of such vars during constant evaluation if they weren't finalized yet. 2023-03-04 Jakub Jelinek <jakub@redhat.com> PR c++/108702 * constexpr.cc: Include toplev.h. (cxx_eval_constant_expression) <case DECL_EXPR>: When seeing a local static initialized by constant expression outside of a constexpr function which has been deferred by make_rtl_for_nonlocal_decl, call rest_of_decl_compilation on it. * g++.dg/ext/stmtexpr19.C: Use dg-do link rather than dg-do compile.
2023-03-02c++: constant non-copy-init is manifestly constant [PR108243]Patrick Palka1-0/+2
According to [basic.start.static]/2 and [expr.const]/2, a variable with static storage duration initialized with a constant initializer has constant initialization, and such an initializer is manifestly constant-evaluated. For copy initialization, we're already getting this right because in that case check_initializer would consistently call store_init_value, which for TREE_STATIC variables calls fold_non_dependent_init with m_c_e=true. But for direct (or default) initialization, check_initializer doesn't always call store_init_value. We instead however always call maybe_constant_init from expand_default_init[1], albeit with m_c_e=false which means we don't get the "manifestly constant-evaluated" part right for non-copy-init. This patch fixes this by setting m_c_e=true in maybe_constant_init for static storage duration variables, mainly for benefit of the call to maybe_constant_init from expand_default_init. [1]: this maybe_constant_init call isn't reached in the copy-init case because there init is a CONSTRUCTOR rather than a TREE_LIST, and so we exit early from expand_default_init, returning an INIT_EXPR. This INIT_EXPR is ultimately what causes us to consistently hit the store_init_value code path from check_initializer in the copy-init case. PR c++/108243 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_init_1): Override manifestly_const_eval to true if is_static. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/is-constant-evaluated14.C: New test.
2023-03-01c++: can't eval PTRMEM_CST in incomplete class [PR107574]Marek Polacek1-1/+12
Here we're attempting to evaluate a PTRMEM_CST in a class that hasn't been completed yet, but that doesn't work: /* We can't lower this until the class is complete. */ if (!COMPLETE_TYPE_P (DECL_CONTEXT (member))) return cst; and then this unlowered PTRMEM_CST is used as EXPR in tree op1 = build_nop (ptrdiff_type_node, expr); and we crash in a subsequent cp_fold_convert which gets type=ptrdiff_type_node, expr=PTRMEM_CST and does else if (TREE_CODE (expr) == PTRMEM_CST && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type), PTRMEM_CST_CLASS (expr))) where TYPE_PTRMEM_CLASS_TYPE (type) is going to crash since the type is ptrdiff_type_node. We could just add a TYPE_PTRMEM_P check before accessing TYPE_PTRMEM_CLASS_TYPE but I think it's nicer to explain why we couldn't evaluate the expression. PR c++/107574 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Emit an error when a PTRMEM_CST cannot be evaluated. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/ptrmem-cst1.C: New test.
2023-03-01c++: unevaluated array new-expr size constantness [PR108219]Patrick Palka1-5/+24
Here we're mishandling the unevaluated array new-expressions due to a supposed non-constant array size ever since r12-5253-g4df7f8c79835d569 made us no longer perform constant evaluation of non-manifestly-constant expressions within unevaluated contexts. This shouldn't make a difference here since the array sizes are constant literals, except they're expressed as NON_LVALUE_EXPR location wrappers around INTEGER_CST, wrappers which used to get stripped as part of constant evaluation and now no longer do. Moreover it means build_vec_init can't constant fold the MINUS_EXPR 'maxindex' passed from build_new_1 when in an unevaluated context (since it tries reducing it via maybe_constant_value called with mce_unknown). This patch fixes these issues by making maybe_constant_value (and fold_non_dependent_expr) try folding an unevaluated non-manifestly-constant operand via fold(), as long as it simplifies to a simple constant, rather than doing no simplification at all. This covers e.g. simple arithmetic and casts including stripping of location wrappers around INTEGER_CST. In passing, this patch also fixes maybe_constant_value to avoid constant evaluating an unevaluated operand when called with mce_false, by adjusting the early exit test appropriately. Co-authored-by: Jason Merrill <jason@redhat.com> PR c++/108219 PR c++/108218 gcc/cp/ChangeLog: * constexpr.cc (fold_to_constant): Define. (maybe_constant_value): Move up early exit test for unevaluated operands. Try reducing an unevaluated operand to a constant via fold_to_constant. (fold_non_dependent_expr_template): Add early exit test for CONSTANT_CLASS_P nodes. Try reducing an unevaluated operand to a constant via fold_to_constant. * cp-tree.h (fold_to_constant): Declare. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/new6.C: New test. * g++.dg/cpp2a/concepts-new1.C: New test.
2023-03-01c++: Don't recurse on DECL_INITIAL for DECL_EXPR on non-VAR_DECLs [PR108606]Jakub Jelinek1-1/+3
The r13-2965-g73d9b0e5947e16 change changed the line touched in this patch from return RECUR (tmp, want_rval); to return RECUR (DECL_INITIAL (tmp), want_rval); This is on DECL_EXPR handling code, where tmp can be lots of different trees and DECL_INITIAL unfortunately also means different things on different trees. It is the initializer on VAR_DECL, DECL_ARG_TYPE on PARM_DECLs (though those are unlikely to have DECL_EXPRs), for FUNCTION_DECLs the body, ..., USING_DECL_DECLS on USING_DECLs and DECL_FRIENDLIST on TYPE_DECLs. The testcase below ICEs because we have a DECL_EXPR for TYPE_DECL which has non-NULL DECL_FRIENDLIST and we certainly can't recurse on the friend list. The following patch will RECUR on DECL_INITIAL only for VAR_DECLs and for anything else just return true. 2023-03-01 Jakub Jelinek <jakub@redhat.com> PR c++/108606 * constexpr.cc (potential_constant_expression_1) <case DECL_EXPR>: Only recurse on DECL_INITIAL (tmp) if tmp is a VAR_DECL, otherwise just return true. * g++.dg/cpp1y/pr108606.C: New test.
2023-02-20c++: ICE with -fno-elide-constructors and trivial fn [PR101073]Marek Polacek1-22/+3
In constexpr-nsdmi3.C, with -fno-elide-constructors, we don't elide the Y::Y(const Y&) call used to initialize o.c. So store_init_value -> cxx_constant_init must constexpr-evaluate the call to Y::Y(const Y&) in cxx_eval_call_expression. It's a trivial function, so we do the "Shortcut trivial constructor/op=" code and rather than evaluating the function, we just create an assignment o.c = *(const struct Y &) (const struct Y *) &(&<PLACEHOLDER_EXPR struct X>)->b which is a MODIFY_EXPR, so the preeval code in cxx_eval_store_expression clears .ctor and .object, therefore we can't replace the PLACEHOLDER_EXPR whereupon we crash at /* A placeholder without a referent. We can get here when checking whether NSDMIs are noexcept, or in massage_init_elt; just say it's non-constant for now. */ gcc_assert (ctx->quiet); The PLACEHOLDER_EXPR can also be on the LHS as in constexpr-nsdmi10.C. I don't think we can do much here, but I noticed that the whole trivial_fn_p (fun) block is only entered when -fno-elide-constructors. This is true since GCC 9; it wasn't easy to bisect what changes made it so, but r240845 is probably one of them. -fno-elide-constructors is an option for experiments only so it's not clear to me why we'd still want to shortcut trivial constructor/op=. I propose to remove the code and add a checking assert to make sure we're not getting a trivial_fn_p unless -fno-elide-constructors. PR c++/101073 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Replace shortcutting trivial constructor/op= with a checking assert. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-nsdmi3.C: New test. * g++.dg/cpp1y/constexpr-nsdmi10.C: New test.
2023-02-17c++: make manifestly_const_eval tri-statePatrick Palka1-27/+32
This patch converts the constexpr machinery's manifestly_const_eval flag into a tri-state enum to allow us to express wanting to fold __builtin_is_constant_evaluated to false via speculative constexpr evaluation. For now, only the maybe_constant_value entry point is changed to take this enum; the others continue to take bool. The subsequent patch will teach cp_fold (which uses maybe_constant_value) to fold the builtin to false when called from cp_fold_function and cp_fully_fold_init. gcc/cp/ChangeLog: * constexpr.cc (constexpr_call::manifestly_const_eval): Give it type int instead of bool. (constexpr_ctx::manifestly_const_eval): Give it type mce_value instead of bool. (cxx_eval_builtin_function_call): Adjust after making manifestly_const_eval tri-state. (cxx_eval_call_expression): Likewise. (cxx_eval_binary_expression): Likewise. (cxx_eval_conditional_expression): Likewise. (cxx_eval_constant_expression): Likewise. (cxx_eval_outermost_constant_expr): Likewise. (cxx_constant_value): Likewise. (cxx_constant_dtor): Likewise. (maybe_constant_value): Give manifestly_const_eval parameter type mce_value instead of bool and adjust accordingly. (fold_non_dependent_expr_template): Adjust call to cxx_eval_outermost_constant_expr. (fold_non_dependent_expr): Likewise. (maybe_constant_init_1): Likewise. * constraint.cc (satisfy_atom): Adjust call to maybe_constant_value. * cp-tree.h (enum class mce_value): Define. (maybe_constant_value): Adjust manifestly_const_eval parameter type and default argument. * decl.cc (compute_array_index_type_loc): Adjust call to maybe_constant_value. * pt.cc (convert_nontype_argument): Likewise.
2023-02-03c++: wrong error with constexpr array and value-init [PR108158]Marek Polacek1-4/+0
In this test case, we find ourselves evaluating 't' which is ((const struct carray *) this)->data_[VIEW_CONVERT_EXPR<long int>(index)] in cxx_eval_array_reference. ctx->object is non-null, a RESULT_DECL, so we replace it with 't': new_ctx.object = t; // result_decl replaced and then we go to cxx_eval_constant_expression to evaluate an AGGR_INIT_EXPR, where we end up evaluating an INIT_EXPR (which is in the body of the constructor for seed_or_index): ((struct seed_or_index *) this)->value_ = NON_LVALUE_EXPR <0> whereupon in cxx_eval_store_expression we go to the probe loop where the 'this' is evaluated to ze_set.tables_.first_table_.data_[0] so the 'object' is ze_set, but that isn't in ctx->global->get_value_ptr so we fail with a bogus error. ze_set is not there because it comes from a different constexpr context (it's not in cv_cache either). The problem started with r12-2304 where I added the new_ctx.object replacement. That was to prevent a type mismatch: the type of 't' and ctx.object were different. It seems clear that we shouldn't have replaced ctx.object here. The cxx_eval_array_reference I mentioned earlier is called from cxx_eval_store_expression: 6257 init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue, 6258 non_constant_p, overflow_p); which already created a new context, whose .object we should be using unless, for instance, INIT contained a.b and we're evaluating the 'a' part, which I think was the case for r12-2304; in that case ctx.object has to be something different. It no longer seems necessary to replace new_ctx.object (likely due to changes in empty class handling). PR c++/108158 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_array_reference): Don't replace new_ctx.object. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-108158.C: New test.
2023-02-01c++, openmp: Handle some OMP_*/OACC_* constructs during constant expression ↵Jakub Jelinek1-0/+47
evaluation [PR108607] While potential_constant_expression_1 handled most of OMP_* codes (by saying that they aren't potential constant expressions), OMP_SCOPE was missing in that list. I've also added OMP_SCAN, though that is less important (similarly to OMP_SECTION it ought to appear solely inside of OMP_{FOR,SIMD} resp. OMP_SECTIONS). As the testcase shows, it isn't enough, potential_constant_expression_1 can catch only some cases, as soon as one uses switch or ifs where at least one of the possible paths could be constant expression, we can run into the same codes during cxx_eval_constant_expression, so this patch handles those there as well. 2023-02-01 Jakub Jelinek <jakub@redhat.com> PR c++/108607 * constexpr.cc (cxx_eval_constant_expression): Handle OMP_* and OACC_* constructs as non-constant. (potential_constant_expression_1): Handle OMP_SCAN and OMP_SCOPE. * g++.dg/gomp/pr108607.C: New test.
2023-01-16Update copyright years.Jakub Jelinek1-1/+1
2022-12-29[C++] constexpr: request insert iff depth is okAlexandre Oliva1-3/+5
cxx_eval_call_expression requests an INSERT even in cases when it would later decide not to insert. This could break double-hashing chains. Arrange for it to use NO_INSERT when the insertion would not be completed. for gcc/cp/ChangeLog * constexpr.cc (cxx_eval_call_expression): Do not request an INSERT that would not be completed.
2022-12-23c++: get_nsdmi in template context [PR108116]Patrick Palka1-0/+4
Here during ahead of time checking of C{}, we indirectly call get_nsdmi for C::m from finish_compound_literal, which in turn calls break_out_target_exprs for C::m's (non-templated) initializer, during which we build a call to A::~A and check expr_noexcept_p for it (from build_vec_delete_1). But this is all done with processing_template_decl set, so the built A::~A call is templated (whose form was recently changed by r12-6897-gdec8d0e5fa00ceb2) which expr_noexcept_p doesn't expect, and we crash. This patch fixes this by clearing processing_template_decl before the call to break_out_target_exprs from get_nsdmi. And since it more generally seems we shouldn't be seeing (or producing) non-templated trees in break_out_target_exprs, this patch also adds an assert to that effect. PR c++/108116 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_value): Clear processing_template_decl before calling break_out_target_exprs. * init.cc (get_nsdmi): Likewise. * tree.cc (break_out_target_exprs): Assert processing_template_decl is cleared. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template24.C: New test.
2022-12-19c++: modules and std::source_location::current() def arg [PR100881]Patrick Palka1-1/+1
We currently declare __builtin_source_location with a const void* return type instead of the actual type const std::source_location::__impl*, and later when folding this builtin we obtain the actual type via name lookup. But the below testcase demonstrates this approach seems to interact poorly with modules, since we may import an entity that uses std::source_location::current() in its default argument (or DMI) without necessarily importing <source_location>, and thus the name lookup for std::source_location will fail at the call site (when using the default argument) unless we also import <source_location>. This patch fixes this by instead initially declaring the builtin with an auto return type and updating it appropriately upon its first use (in standard code the first/only use would be in the definition of std::source_location). Thus when folding calls to this builtin we can get at its return type through the type of the CALL_EXPR and avoid needing to do a name lookup. PR c++/100881 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_builtin_function_call): Adjust calls to fold_builtin_source_location. * cp-gimplify.cc (cp_gimplify_expr): Likewise. (cp_fold): Likewise. (get_source_location_impl_type): Remove location_t parameter and adjust accordingly. No longer static. (fold_builtin_source_location): Take a CALL_EXPR tree instead of a location and obtain the impl type from its return type. * cp-tree.h (enum cp_tree_index): Remove CPTI_SOURCE_LOCATION_IMPL enumerator. (source_location_impl): Remove. (fold_builtin_source_location): Adjust parameter type. (get_source_location_impl_type): Declare. * decl.cc (cxx_init_decl_processing): Declare __builtin_source_location with auto return type instead of const void*. (require_deduced_type): Update the return type of __builtin_source_location. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/srcloc3.C: Adjust expected note s/evaluating/using. * g++.dg/cpp2a/srcloc4.C: Likewise. * g++.dg/cpp2a/srcloc5.C: Likewise. * g++.dg/cpp2a/srcloc6.C: Likewise. * g++.dg/cpp2a/srcloc7.C: Likewise. * g++.dg/cpp2a/srcloc8.C: Likewise. * g++.dg/cpp2a/srcloc9.C: Likewise. * g++.dg/cpp2a/srcloc10.C: Likewise. * g++.dg/cpp2a/srcloc11.C: Likewise. * g++.dg/cpp2a/srcloc12.C: Likewise. * g++.dg/cpp2a/srcloc13.C: Likewise. * g++.dg/modules/pr100881_a.C: New test. * g++.dg/modules/pr100881_b.C: New test.
2022-12-12Revert "c++: build initializer_list<string> in a loop [PR105838]"Jason Merrill1-3/+3
This patch broke a couple of different patterns; reverting while I work on a fix. PR c++/108701 This reverts commit bd0485f20f4794f9787237706a6308473a8e9415.
2022-12-08c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-3/+3
The previous patch avoided building an initializer_list<string> at all when building a vector<string>, but in situations where that isn't possible, we could still build the initializer_list with a loop over a constant array. This is represented using a VEC_INIT_EXPR, which required adjusting a couple of places that expected the initializer array to have the same type as the target array and fixing build_vec_init not to undo our efforts. PR c++/105838 gcc/cp/ChangeLog: * call.cc (convert_like_internal) [ck_list]: Use maybe_init_list_as_array. * constexpr.cc (cxx_eval_vec_init_1): Init might have a different type. * tree.cc (build_vec_init_elt): Likewise. * init.cc (build_vec_init): Handle from_array from a TARGET_EXPR. Retain TARGET_EXPR of a different type. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt2.C: New test.
2022-12-08c++: fewer allocator temps [PR105838]Jason Merrill1-10/+17
In this PR, initializing the array of std::string to pass to the vector initializer_list constructor gets very confusing to the optimizers as the number of elements increases, primarily because of all the std::allocator temporaries passed to all the string constructors. Instead of creating one for each string, let's share an allocator between all the strings; we can do this safely because we know that std::allocator is stateless and that string doesn't care about the object identity of its allocator parameter. PR c++/105838 gcc/cp/ChangeLog: * cp-tree.h (is_std_allocator): Declare. * constexpr.cc (is_std_allocator): Split out from... (is_std_allocator_allocate): ...here. * init.cc (find_temps_r): New. (find_allocator_temp): New. (build_vec_init): Use it. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/allocator-opt1.C: New test.