aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
AgeCommit message (Collapse)AuthorFilesLines
6 daysc++: pack indexing is a non-deduced context [PR121795]Patrick Palka1-2/+2
We weren't explicitly treating a pack index specifier as a non-deduced context (as per [temp.deduct.type]/5), leading to an ICE for the first testcase below. PR c++/121795 gcc/cp/ChangeLog: * pt.cc (unify) <case PACK_INDEX_TYPE>: New non-deduced context case. gcc/testsuite/ChangeLog: * g++.dg/cpp26/pack-indexing17.C: New test. * g++.dg/cpp26/pack-indexing17a.C: New test. Reviewed-by: Marek Polacek <polacek@redhat.com> Reviewed-by: Jason Merrill <jason@redhat.com>
11 daysc++: Update TLS model after processing a TLS variableH.J. Lu1-3/+5
Set a tentative TLS model in grokvardecl and update TLS mode with the default TLS access model after a TLS variable has been fully processed if the default TLS access model is stronger. gcc/cp/ PR c++/107393 * decl.cc (grokvardecl): Set a tentative TLS model which will be updated by cplus_decl_attributes later. * decl2.cc (cplus_decl_attributes): Update TLS model with the default TLS access model if the default TLS access model is stronger. * pt.cc (tsubst_decl): Set TLS model only after processing a variable. gcc/testsuite/ PR c++/107393 * g++.dg/tls/pr107393-1.C: New test. * g++.dg/tls/pr107393-2.C: Likewise. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2025-09-03c++: constant non-dep init folding vs FIELD_DECL access [PR97740]Patrick Palka1-0/+6
Here although the local templated variables x and y have the same reduced constant value, only x's initializer {a.get()} is well-formed as written since A::m has private access. We correctly reject y's initializer {&a.m} (at instantiation time), but we also reject x's initializer because we happen to constant fold it ahead of time, which means at instantiation time it's already represented as a COMPONENT_REF to a FIELD_DECL, and so when substituting this COMPONENT_REF we naively double check that the given FIELD_DECL is accessible, which fails. This patch sidesteps around this particular issue by not checking access when substituting a COMPONENT_REF to a FIELD_DECL. If the target of a COMPONENT_REF is already a FIELD_DECL (i.e. before substitution), then I think we can assume access has been already checked appropriately. PR c++/97740 gcc/cp/ChangeLog: * pt.cc (tsubst_expr) <case COMPONENT_REF>: Don't check access when the given member is already a FIELD_DECL. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-97740a.C: New test. * g++.dg/cpp0x/constexpr-97740b.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-09-02c++, contracts: Simplify contracts headers [NFC].Iain Sandoe1-0/+1
We have contracts-related declarations and macros split between contracts.h and cp-tree.h, and then contracts.h is included in the latter, which means that it is included in all c++ front end files. This patch: - moves all the contracts-related material to contracts.h. - makes some functions that are only used in contracts.cc static. - tries to group the external API for contracts into related topics. - includes contracts.h in the front end sources that need it. gcc/cp/ChangeLog: * constexpr.cc: Include contracts.h * coroutines.cc: Likewise. * cp-gimplify.cc: Likewise. * decl.cc: Likewise. * decl2.cc: Likewise. * mangle.cc: Likewise. * module.cc: Likewise. * pt.cc: Likewise. * search.cc: Likewise. * semantics.cc: Likewise. * contracts.cc (validate_contract_role, setup_default_contract_role, add_contract_role, get_concrete_axiom_semantic, get_default_contract_role): Make static. * cp-tree.h (make_postcondition_variable, grok_contract, finish_contract_condition, find_contract, set_decl_contracts, get_contract_semantic, set_contract_semantic): Move to contracts.h. * contracts.h (get_contract_role, add_contract_role, validate_contract_role, setup_default_contract_role, lookup_concrete_semantic, get_default_contract_role): Remove. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
2025-08-28c++: Fix ICE with parameter uses in expansion stmts [PR121575]Jakub Jelinek1-0/+5
The following testcase shows an ICE when a parameter of a non-template function is referenced in expansion stmt body. tsubst_expr in that case assumes that either the PARM_DECL has registered local specialization, or is this argument or it is in unevaluated context. Parameters are always defined outside of the expansion statement for-range-declaration or body, so for the instantiation of the body outside of templates should always map to themselves. It could be fixed by registering local self-specializations for all the function parameters, but just handling it in tsubst_expr seems to be easier and less costly. Some PARM_DECLs, e.g. from concepts, have NULL DECL_CONTEXT, those are handled like before (and assert it is unevaluated operand), for others this checks if the PARM_DECL is from a non-template and in that case it will just return t. 2025-08-28 Jakub Jelinek <jakub@redhat.com> Jason Merrill <jason@redhat.com> PR c++/121575 * pt.cc (tsubst_expr) <case PARM_DECL>: If DECL_CONTEXT (t) isn't a template return t for PARM_DECLs without local specialization. * g++.dg/cpp26/expansion-stmt20.C: New test.
2025-08-25c++: Implement C++ CWG3048 - Empty destructuring expansion statementsJakub Jelinek1-7/+3
The following patch implements the proposed resolution of https://cplusplus.github.io/CWG/issues/3048.html Instead of rejecting structured binding size it just builds a normal decl rather than structured binding declaration. 2025-08-25 Jakub Jelinek <jakub@redhat.com> * pt.cc (finish_expansion_stmt): Implement C++ CWG3048 - Empty destructuring expansion statements. Don't error for destructuring expansion stmts if sz is 0, don't call fit_decomposition_lang_decl if n is 0 and pass NULL rather than this_decomp to cp_finish_decl. * g++.dg/cpp26/expansion-stmt15.C: Don't expect error on destructuring expansion stmts with structured binding size 0. * g++.dg/cpp26/expansion-stmt21.C: New test. * g++.dg/cpp26/expansion-stmt22.C: New test.
2025-08-20c++: pointer to auto member function [PR120757]Jason Merrill1-2/+6
Here r13-1210 correctly changed &A<int>::foo to not be considered type-dependent, but tsubst_expr of the OFFSET_REF got confused trying to tsubst a type that involved auto. Fixed by getting the type from the member rather than tsubst. PR c++/120757 gcc/cp/ChangeLog: * pt.cc (tsubst_expr) [OFFSET_REF]: Don't tsubst the type. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/auto-fn66.C: New test.
2025-08-15c++: Implement __builtin_structured_binding_size traitJakub Jelinek1-0/+7
clang++ apparently added a SFINAE-friendly __builtin_structured_binding_size trait to return the structured binding size (or error if not in SFINAE contexts if a type doesn't have a structured binding size). The expansion statement patch already anticipated this through adding complain argument to cp_finish_decomp. The following patch implements it. 2025-08-15 Jakub Jelinek <jakub@redhat.com> gcc/ * doc/extend.texi (Type Traits): Document __builtin_structured_binding_size. gcc/cp/ * cp-trait.def (STRUCTURED_BINDING_SIZE): New unary trait. * cp-tree.h (finish_structured_binding_size): Declare. * semantics.cc (trait_expr_value): Handle CPTK_STRUCTURED_BINDING_SIZE. (finish_structured_binding_size): New function. (finish_trait_expr): Handle CPTK_RANK and CPTK_TYPE_ORDER in the switch instead of just doing break; for those and ifs at the end to handle them. Handle CPTK_STRUCTURED_BINDING_SIZE. * pt.cc (tsubst_expr): Likewise. * constraint.cc (diagnose_trait_expr): Likewise. * decl.cc (get_tuple_size): Use mce_true for maybe_const_value. (cp_decomp_size): Diagnose incomplete types not just if processing_template_decl, and use error_at instead of pedwarn. If btype is NULL, just return 0 instead of diagnosing an error. gcc/testsuite/ * g++.dg/cpp26/expansion-stmt15.C: Expect different diagnostics for zero size destructuring expansion statement. * g++.dg/ext/builtin-structured-binding-size1.C: New test. * g++.dg/ext/builtin-structured-binding-size2.C: New test. * g++.dg/ext/builtin-structured-binding-size3.C: New test. * g++.dg/ext/builtin-structured-binding-size4.C: New test.
2025-08-13c++: P2036R3 - Change scope of lambda trailing-return-type [PR102610]Marek Polacek1-0/+21
This patch is an attempt to implement P2036R3 along with P2579R0, fixing build breakages caused by P2036R3. The simplest example is: auto counter1 = [j=0]() mutable -> decltype(j) { return j++; }; which currently doesn't compile because the 'j' in the capture isn't visible in the trailing return type. With these proposals, the 'j' will be in a lambda scope which spans the trailing return type, so this test will compile. This oughtn't be difficult but decltype and other issues made this patch much more challenging. We have to push the explicit captures before going into _lambda_declarator_opt because that is what parses the trailing return type. Yet we can't build any captures until after _lambda_body -> start_lambda_function which creates the lambda's operator(), without which we can't build a proxy, but _lambda_body happens only after parsing the declarator. This patch works around it by creating a fake operator() and adding it to the capture and then removing it when we have the real operator(). Another thing is that in "-> decltype(j)" we don't have the right current_function_decl yet. If current_lambda_expr gives us a lambda, we know this decltype appertains to a lambda. But we have to know if we are in a parameter-declaration-clause: as per [expr.prim.id.unqual]/4.4, if we are, we shouldn't be adding "const". The new LAMBDA_EXPR_CONST_QUAL_P flag tracks this. But it doesn't handle nested lambdas yet, specifically, [expr.prim.id.unqual]/14. I don't think this patch changes behavior for the tests in "capture-default with [=]" as the paper promises; clang++ behaves the same as gcc with this patch. PR c++/102610 gcc/cp/ChangeLog: * cp-tree.h (LAMBDA_EXPR_CONST_QUAL_P): Define. (maybe_add_dummy_lambda_op): Declare. (remove_dummy_lambda_op): Declare. (push_capture_proxies): Adjust. * lambda.cc (build_capture_proxy): No longer static. New early_p parameter. Use it. (add_capture): Adjust the call to build_capture_proxy. (resolvable_dummy_lambda): Check DECL_LAMBDA_FUNCTION_P. (push_capture_proxies): New. (start_lambda_function): Use it. * name-lookup.cc (check_local_shadow): Give an error for is_capture_proxy. (cp_binding_level_descriptor): Add lambda-scope. (begin_scope) <case sk_lambda>: New case. * name-lookup.h (enum scope_kind): Add sk_lambda. (struct cp_binding_level): Widen kind. * parser.cc (cp_parser_lambda_expression): Create a new (lambda) scope after the lambda-introducer. (cp_parser_lambda_declarator_opt): Set LAMBDA_EXPR_CONST_QUAL_P. Create a dummy operator() if needed. Inject the captures into the lambda scope. Remove the dummy operator(). (make_dummy_lambda_op): New. (maybe_add_dummy_lambda_op): New. (remove_dummy_lambda_op): New. * pt.cc (tsubst_lambda_expr): Begin/end a lambda scope. Push the capture proxies. Build/remove a dummy operator() if needed. Set LAMBDA_EXPR_CONST_QUAL_P. * semantics.cc (parsing_lambda_declarator): New. (outer_var_p): Also consider captures as outer variables if in a lambda declarator. (process_outer_var_ref): Reset containing_function when parsing_lambda_declarator. (finish_decltype_type): Process decls in the lambda-declarator as well. Look at LAMBDA_EXPR_CONST_QUAL_P unless we have an xobj function. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-decltype3.C: Remove xfail. * g++.dg/warn/Wshadow-19.C: Add -Wpedantic. Adjust a dg-warning. * g++.dg/warn/Wshadow-6.C: Adjust expected diagnostics. * g++.dg/cpp23/lambda-scope1.C: New test. * g++.dg/cpp23/lambda-scope2.C: New test. * g++.dg/cpp23/lambda-scope3.C: New test. * g++.dg/cpp23/lambda-scope4.C: New test. * g++.dg/cpp23/lambda-scope4b.C: New test. * g++.dg/cpp23/lambda-scope5.C: New test. * g++.dg/cpp23/lambda-scope6.C: New test. * g++.dg/cpp23/lambda-scope7.C: New test. * g++.dg/cpp23/lambda-scope8.C: New test. * g++.dg/cpp23/lambda-scope9.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-08-13c++: Implement C++26 P1306R5 - Expansion statements [PR120776]Jakub Jelinek1-3/+463
The following patch implements the C++26 P1306R5 - Expansion statements paper. When expansion statements are used outside of templates, the lowering of the statement uses push_tinst_level_loc and instantiates the body multiple times, otherwise when the new TEMPLATE_FOR_STMT statement is being instantiated and !processing_template_decl, it instantiates the body several times with just local_specialization_stack around each iteration but with the original args. Because the lowering of these statements is mostly about instantiation, I've put the lowering code into pt.cc rather than semantics.cc. Only destructuring expansion statements currently use in the patch temporary lifetime extension which matches the proposed resolution of https://cplusplus.github.io/CWG/issues/3043.html I'm not sure what will CWG decide about that if there will be some temporary lifetime extension for enumerating expansion statements and if yes, under what exact rules (e.g. whether it extends all the temporaries across one iteration of the body, or only if a reference is initialized or nothing at all). And for iterating expansion statements, I think I don't understand the P2686R4 rules well yet, I think if the expansion-initializer is used in static constexpr rvalue reference, then it isn't needed, but not sure if it won't be needed if static would be dropped (whether struct S { constexpr S () : s (0) {} constexpr ~S () {} int s; }; struct T { const S &t, &u; }; void foo () { constexpr T t = { S {}, S {} }; use (t.t, t.u); } is ok under P2686R4; though without constexpr before T I see S::~S () being called after use, not at the end of the t declaration, so maybe it is fine also without static). As per https://cplusplus.github.io/CWG/issues/3044.html the patch uses build_int_cst (ptrdiff_type_node, i) to create second operand of begin + i and doesn't lookup overloaded comma operator (note, I'm actually not even creating a lambda there, just using TARGET_EXPRs). I guess my preference would be dropping those 4 static keywords from [stmt.expand] but the patch does use those for now and it won't be possible to change that until the rest of P2686R4 is implemented. As per https://cplusplus.github.io/CWG/issues/3045.html it treats sk_template_for like sk_for for the purpose of redeclaration of vars in the body but doesn't yet reject [[fallthrough]]; in the expansion stmt body (when not nested in another switch). I'm not sure if cp_perform_range_for_lookup used in the patch is exactly what we want for the https://eel.is/c++draft/stmt.expand#3.2 - it does finish_call_expr on the perform_koenig_lookup as well, shouldn't for the decision whether it is iterating or destructing (i.e. tf_none) just call perform_koenig_lookup and check if it found some FUNCTION_DECL/OVERLOAD/TEMPLATE_DECL? cp_decomp_size in the patch has tsubst_flags_t argument and attempts to be SFINAE friendly, even when it isn't needed strictly for this patch. This is with PR96185 __builtin_structured_binding_size implementation in mind (to follow clang). The new TEMPLATE_FOR_STMT statement is expected to be lowered to something that doesn't use the statement at all, I've implemented break/continue discovery in the body, so all I needed was to punt on TEMPLATE_FOR_STMT in potential_constant_expression_1 so that we don't try to constant evaluate it when it is still dependent (and cxx_eval_constant_expression rejects it without any extra code). I think only enumerating and iterating expansion statements can have zero iteration, because for destructuring ones it doesn't use a structured binding pack and so valid structured binding has to have at least one iteration. Though https://cplusplus.github.io/CWG/issues/3048.html could change that, this patch currently rejects it though. 2025-08-13 Jakub Jelinek <jakub@redhat.com> PR c++/120776 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_expansion_statements=202506L for C++26. gcc/cp/ * cp-tree.def: Implement C++26 P1306R5 - Expansion statements. (TEMPLATE_FOR_STMT): New tree code. * cp-tree.h (struct saved_scope): Add expansion_stmt. (in_expansion_stmt): Define. (TEMPLATE_FOR_DECL, TEMPLATE_FOR_EXPR, TEMPLATE_FOR_BODY, TEMPLATE_FOR_SCOPE, TEMPLATE_FOR_INIT_STMT): Define. (struct tinst_level): Adjust comment. (cp_decomp_size, finish_expansion_stmt, do_pushlevel, cp_build_range_for_decls, build_range_temp, cp_perform_range_for_lookup, begin_template_for_scope): Declare. (finish_range_for_stmt): Remove declaration. * cp-objcp-common.cc (cp_common_init_ts): Handle TEMPLATE_FOR_STMT. * name-lookup.h (enum scope_kind): Add sk_template_for enumerator. (struct cp_binding_level): Enlarge kind bitfield from 4 to 5 bits. Adjust comment with remaining space bits. * name-lookup.cc (check_local_shadow): Handle sk_template_for like sk_for. (cp_binding_level_descriptor): Add entry for sk_template_for. (begin_scope): Handle sk_template_for. * parser.h (IN_EXPANSION_STMT): Define. * parser.cc (cp_debug_parser): Print IN_EXPANSION_STMT bit. (cp_parser_lambda_expression): Temporarily clear in_expansion_stmt. (cp_parser_statement): Handle RID_TEMPLATE followed by RID_FOR for C++11. (cp_parser_label_for_labeled_statement): Complain about named labels inside of expansion stmt body. (cp_hide_range_decl): New function. (cp_parser_range_for): Use it. Adjust do_range_for_auto_deduction caller. Remove second template argument from auto_vecs bindings and names. (build_range_temp): No longer static. (do_range_for_auto_deduction): Add expansion_stmt argument. (cp_build_range_for_decls): New function. (cp_convert_range_for): Use it. Call cp_perform_range_for_lookup rather than cp_parser_perform_range_for_lookup. (cp_parser_perform_range_for_lookup): Rename to ... (cp_perform_range_for_lookup): ... this. No longer static. Add complain argument and handle it. (cp_parser_range_for_member_function): Rename to ... (cp_range_for_member_function): ... this. (cp_parser_expansion_statement): New function. (cp_parser_jump_statement): Handle IN_EXPANSION_STMT. (cp_convert_omp_range_for): Adjust do_range_for_auto_deduction caller. Call cp_perform_range_for_lookup rather than cp_parser_perform_range_for_lookup. * error.cc (print_instantiation_full_context): Handle tldcl being TEMPLATE_FOR_STMT. (print_instantiation_partial_context_line): Likewise. * constexpr.cc (potential_constant_expression_1): Handle TEMPLATE_FOR_STMT. * decl.cc (poplevel_named_label_1): Use obl instead of bl->level_chain. (finish_case_label): Diagnose case labels inside of template for. (find_decomp_class_base): Add complain argument, don't diagnose anything and just return error_mark_node if tf_none, adjust recursive call. (cp_decomp_size): New function. (cp_finish_decomp): Adjust find_decomp_class_base caller. * semantics.cc (do_pushlevel): No longer static. (begin_template_for_scope): New function. * pt.cc (push_tinst_level_loc): Handle TEMPLATE_FOR_STMT. (reopen_tinst_level): Likewise. (tsubst_stmt): Handle TEMPLATE_FOR_STMT. (struct expansion_stmt_bc): New type. (expansion_stmt_find_bc_r, finish_expansion_stmt): New functions. * decl2.cc (decl_dependent_p): Return true for current function's decl if in_expansion_stmt. * call.cc (extend_ref_init_temps): Don't extend_all_temps if TREE_STATIC (decl). * cxx-pretty-print.cc (cxx_pretty_printer::statement): Handle TEMPLATE_FOR_STMT. gcc/testsuite/ * g++.dg/cpp1z/decomp64.C: New test. * g++.dg/cpp26/expansion-stmt1.C: New test. * g++.dg/cpp26/expansion-stmt2.C: New test. * g++.dg/cpp26/expansion-stmt3.C: New test. * g++.dg/cpp26/expansion-stmt4.C: New test. * g++.dg/cpp26/expansion-stmt5.C: New test. * g++.dg/cpp26/expansion-stmt6.C: New test. * g++.dg/cpp26/expansion-stmt7.C: New test. * g++.dg/cpp26/expansion-stmt8.C: New test. * g++.dg/cpp26/expansion-stmt9.C: New test. * g++.dg/cpp26/expansion-stmt10.C: New test. * g++.dg/cpp26/expansion-stmt11.C: New test. * g++.dg/cpp26/expansion-stmt12.C: New test. * g++.dg/cpp26/expansion-stmt13.C: New test. * g++.dg/cpp26/expansion-stmt14.C: New test. * g++.dg/cpp26/expansion-stmt15.C: New test. * g++.dg/cpp26/expansion-stmt16.C: New test. * g++.dg/cpp26/expansion-stmt17.C: New test. * g++.dg/cpp26/expansion-stmt18.C: New test. * g++.dg/cpp26/expansion-stmt19.C: New test. * g++.dg/cpp26/feat-cxx26.C: Add __cpp_expansion_statements tests.
2025-08-07c++: Implement C++26 P1061R10 - Structured Bindings can introduce a Pack ↵Jakub Jelinek1-11/+106
[PR117783] The following patch implements the C++26 P1061R10 - Structured Bindings can introduce a Pack paper. One thing unresolved in the patch is mangling, I've raised https://github.com/itanium-cxx-abi/cxx-abi/issues/200 for that but no comments there yet. One question is if it is ok not to mention the fact that there is a structured binding pack in the mangling of the structured bindings but more important is in case of std::tuple* we might need to mangle individual structured binding pack elements separately (each might need an exported name for the var itself and perhaps its guard variable as well). The patch just uses the normal mangling for the whole structured bindings and emits sorry if we need to mangle the structured binding pack elements. The patch just marks the structured binding pack specially (considered e.g. using some bit on it, but in the end I'm identifying it using a made up type which causes DECL_PACK_P to be true; it is kind of self-referential solution, because the type on the pack mentions the DECL_DECOMPOSITION_P VAR_DECL on which the type is attached as its pack, so it needs to be handled carefully during instantiation to avoid infinite recursion, but it is the type that should be used if something else actually needs to use the same type as the structured binding pack, e.g. a capture proxy), and stores the pack elements when actually processed through cp_finish_decomp with non-dependent initializer into a TREE_VEC used as DECL_VALUE_EXPR of the pack; though because several spots use the DECL_VALUE_EXPR and assume it is ARRAY_REF from which they can find out the base variable and the index, it stores the base variable and index in the first 2 TREE_VEC elts and has the structured binding elements only after that. https://eel.is/c++draft/temp.dep.expr#3.6 says the packs are type dependent regardless of whether the initializer of the structured binding is type dependent or not, so I hope having a dependent type on the structured binding VAR_DECL is ok. The paper also has an exception for sizeof... which is then not value dependent when the structured bindings are initialized with non-dependent initializer: https://eel.is/c++draft/temp.dep.constexpr#4 The patch special cases that in 3 spots (I've been wondering if e.g. during parsing I couldn't just fold the sizeof... to the INTEGER_CST right away, but guess I'd need to repeat that also during partial instantiation). And one thing still unresolved is debug info, I've just added DECL_IGNORED_P on the structured binding pack VAR_DECL because there were ICEs with -g for now, hope it can be fixed incrementally but am not sure what exactly we should emit in the debug info for that. Speaking of which, I see DW_TAG_GNU_template_parameter_pack DW_TAG_GNU_formal_parameter_pack etc. DIEs emitted regardless of DWARF version, shouldn't we try to upstream those into DWARF 6 or check what other compilers emit for the packs? And bet we'd need DW_TAG_GNU_structured_binding_pack as well. 2025-08-07 Jakub Jelinek <jakub@redhat.com> PR c++/117783 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Change __cpp_structured_bindings predefined value for C++26 from 202403L to 202411L. gcc/cp/ * parser.cc: Implement C++26 P1061R10 - Structured Bindings can introduce a Pack. (cp_parser_range_for): Also handle TREE_VEC as DECL_VALUE_EXPR instead of ARRAY_REF. (cp_parser_decomposition_declaration): Use sb-identifier-list instead of identifier-list in comments. Parse structured bindings with structured binding pack. Don't emit pedwarn about structured binding attributes in structured bindings inside of a condition. (cp_convert_omp_range_for): Also handle TREE_VEC as DECL_VALUE_EXPR instead of ARRAY_REF. * decl.cc (get_tuple_element_type): Change i argument type from unsigned to unsigned HOST_WIDE_INT. (get_tuple_decomp_init): Likewise. (set_sb_pack_name): New function. (cp_finish_decomp): Handle structured binding packs. * pt.cc (tsubst_pack_expansion): Handle structured binding packs and capture proxies for them. Formatting fixes. (tsubst_decl): For structured binding packs don't tsubst TREE_TYPE first, instead recreate the type after r is created. (tsubst_omp_for_iterator): Also handle TREE_VEC as DECL_VALUE_EXPR instead of ARRAY_REF. (tsubst_expr): Handle sizeof... on non-dependent structure binding packs. (value_dependent_expression_p): Return false for sizeof... on non-dependent structure binding packs. (instantiation_dependent_r): Don't recurse on sizeof... on non-dependent structure binding packs. * constexpr.cc (potential_constant_expression_1): Also handle TREE_VEC on DECL_VALUE_EXPR of structure binding packs. gcc/testsuite/ * g++.dg/cpp26/decomp13.C: New test. * g++.dg/cpp26/decomp14.C: New test. * g++.dg/cpp26/decomp15.C: New test. * g++.dg/cpp26/decomp16.C: New test. * g++.dg/cpp26/decomp17.C: New test. * g++.dg/cpp26/decomp18.C: New test. * g++.dg/cpp26/decomp19.C: New test. * g++.dg/cpp26/decomp20.C: New test. * g++.dg/cpp26/decomp21.C: New test. * g++.dg/cpp26/feat-cxx26.C (__cpp_structured_bindings): Expect 202411 rather than 202403.
2025-07-31c++: consteval blocksMarek Polacek1-1/+2
This patch implements consteval blocks, as specified by P2996. They aren't very useful without define_aggregate, but having a reviewed implementation on trunk would be great. consteval {} can be anywhere where a member-declaration or block-declaration can be. The expression corresponding to it is: [] -> void static consteval compound-statement () and it must be a constant expression. I've used cp_parser_lambda_expression to take care of most of the parsing. Since a consteval block can find itself in a template, we need a vehicle to carry the block for instantiation. Rather than inventing a new tree, I'm using STATIC_ASSERT. A consteval block can't return a value but that is checked by virtue of the lambda having a void return type. PR c++/120775 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Use extract_call_expr. * cp-tree.h (CONSTEVAL_BLOCK_P, LAMBDA_EXPR_CONSTEVAL_BLOCK_P): Define. (finish_static_assert): Adjust declaration. (current_nonlambda_function): Likewise. * lambda.cc (current_nonlambda_function): New parameter. Only keep iterating if the function represents a consteval block. * parser.cc (cp_parser_lambda_expression): New parameter for consteval blocks. Use it. Set LAMBDA_EXPR_CONSTEVAL_BLOCK_P. (cp_parser_lambda_declarator_opt): Likewise. (build_empty_string): New. (cp_parser_next_tokens_are_consteval_block_p): New. (cp_parser_consteval_block): New. (cp_parser_block_declaration): Handle consteval blocks. (cp_parser_static_assert): Use build_empty_string. (cp_parser_member_declaration): Handle consteval blocks. * pt.cc (tsubst_stmt): Adjust a call to finish_static_assert. * semantics.cc (finish_fname): Warn for consteval blocks. (finish_static_assert): New parameter for consteval blocks. Set CONSTEVAL_BLOCK_P. Evaluate consteval blocks specially. gcc/testsuite/ChangeLog: * g++.dg/cpp26/consteval-block1.C: New test. * g++.dg/cpp26/consteval-block2.C: New test. * g++.dg/cpp26/consteval-block3.C: New test. * g++.dg/cpp26/consteval-block4.C: New test. * g++.dg/cpp26/consteval-block5.C: New test. * g++.dg/cpp26/consteval-block6.C: New test. * g++.dg/cpp26/consteval-block7.C: New test. * g++.dg/cpp26/consteval-block8.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-07-30c++: improve non-constant template arg diagnosticJason Merrill1-22/+30
A conversation today pointed out that the current diagnostic for this case doesn't mention the constant evaluation failure, it just says e.g. "'p' is not a valid template argument for 'int*' because it is not the address of a variable" This patch improves the diagnostic in C++17 and above (post-N4268) to diagnose failed constant-evaluation. gcc/cp/ChangeLog: * pt.cc (convert_nontype_argument_function): Check cxx_constant_value on failure. (invalid_tparm_referent_p): Likewise. gcc/testsuite/ChangeLog: * g++.dg/tc1/dr49.C: Adjust diagnostic. * g++.dg/template/func2.C: Likewise. * g++.dg/cpp1z/nontype8.C: New test.
2025-07-25diagnostics: convert diagnostic_t to enum class diagnostics::kindDavid Malcolm1-1/+3
No functional change intended. gcc/ChangeLog: * Makefile.in: Replace diagnostic.def with diagnostics/kinds.def. * config/aarch64/aarch64.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * config/i386/i386-options.cc: Likewise. * config/s390/s390.cc: Likewise. * diagnostic-core.h: Replace typedef diagnostic_t with enum class diagnostics::kind in diagnostics/kinds.h and include it. * diagnostic-global-context.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * diagnostic.cc: Likewise. * diagnostic.h: Likewise. * diagnostics/buffering.cc: Likewise. * diagnostics/buffering.h: Likewise. * diagnostics/context.h: Likewise. * diagnostics/diagnostic-info.h: Likewise. * diagnostics/html-sink.cc: Likewise. * diagnostic.def: Move to... * diagnostics/kinds.def: ...here and update for diagnostic_t becoming enum class diagnostics::kind. * diagnostics/kinds.h: New file, based on material in diagnostic-core.h. * diagnostics/lazy-paths.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * diagnostics/option-classifier.cc: Likewise. * diagnostics/option-classifier.h: Likewise. * diagnostics/output-spec.h: Likewise. * diagnostics/paths-output.cc: Likewise. * diagnostics/sarif-sink.cc: Likewise. * diagnostics/selftest-context.cc: Likewise. * diagnostics/selftest-context.h: Likewise. * diagnostics/sink.h: Likewise. * diagnostics/source-printing.cc: Likewise. * diagnostics/text-sink.cc: Likewise. * diagnostics/text-sink.h: Likewise. * gcc.cc: Likewise. * libgdiagnostics.cc: Likewise. * lto-wrapper.cc: Likewise. * opts-common.cc: Likewise. * opts-diagnostic.h: Likewise. * opts.cc: Likewise. * rtl-error.cc: Likewise. * substring-locations.cc: Likewise. * toplev.cc: Likewise. gcc/ada/ChangeLog: * gcc-interface/trans.cc: Update for diagnostic_t becoming enum class diagnostics::kind. gcc/analyzer/ChangeLog: * pending-diagnostic.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * program-point.cc: Likewise. gcc/c-family/ChangeLog: * c-common.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * c-format.cc: Likewise. * c-lex.cc: Likewise. * c-opts.cc: Likewise. * c-pragma.cc: Likewise. * c-warn.cc: Likewise. gcc/c/ChangeLog: * c-errors.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * c-parser.cc: Likewise. * c-typeck.cc: Likewise. gcc/cobol/ChangeLog: * util.cc: Update for diagnostic_t becoming enum class diagnostics::kind. gcc/cp/ChangeLog: * call.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * constexpr.cc: Likewise. * cp-tree.h: Likewise. * decl.cc: Likewise. * error.cc: Likewise. * init.cc: Likewise. * method.cc: Likewise. * module.cc: Likewise. * parser.cc: Likewise. * pt.cc: Likewise. * semantics.cc: Likewise. * typeck.cc: Likewise. * typeck2.cc: Likewise. gcc/d/ChangeLog: * d-diagnostic.cc: Update for diagnostic_t becoming enum class diagnostics::kind. gcc/fortran/ChangeLog: * cpp.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * error.cc: Likewise. * options.cc: Likewise. gcc/jit/ChangeLog: * dummy-frontend.cc: Update for diagnostic_t becoming enum class diagnostics::kind. gcc/m2/ChangeLog: * gm2-gcc/m2linemap.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * gm2-gcc/rtegraph.cc: Likewise. gcc/rust/ChangeLog: * backend/rust-tree.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * backend/rust-tree.h: Likewise. * resolve/rust-ast-resolve-expr.cc: Likewise. * resolve/rust-ice-finalizer.cc: Likewise. * resolve/rust-ice-finalizer.h: Likewise. * resolve/rust-late-name-resolver-2.0.cc: Likewise. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic_plugin_test_show_locus.cc: Update for diagnostic_t becoming enum class diagnostics::kind. * gcc.dg/plugin/expensive_selftests_plugin.cc: Likewise. * gcc.dg/plugin/location_overflow_plugin.cc: Likewise. * lib/gcc-dg.exp: Likewise. libcpp/ChangeLog: * internal.h: Update comment for diagnostic_t becoming enum class diagnostics::kind. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2025-07-24c++: one more PR114632 tweakJason Merrill1-5/+4
Patrick points out that after the PR114632 fix we can also rever the change that moved cp_evaluated higher in tsubst_lambda_expr. gcc/cp/ChangeLog: * pt.cc (tsubst_lambda_expr): Revert r9-5971 change.
2025-07-24c++: lambda convop in C++23 [PR114632]Jason Merrill1-7/+4
The lambda conversion was ICEing for two C++23 features, static op() and explicit object parameters. The issue with the former seems like a more general issue: tsubst_function_decl recursing to substitute the parameters was affected by cp_unevaluated_operand from the decltype that refers to the declaration. Various places already make a point of clearing cp_unevaluated_operand ahead of PARM_DECL tsubsting; doing it here makes the PR101233 fix redundant. For explicit object lambdas, we want to implement CWG2561 and just not declare the conversion. PR c++/114632 PR c++/101233 gcc/cp/ChangeLog: * lambda.cc (maybe_add_lambda_conv_op): Not for xobj lambda. * pt.cc (tsubst_function_decl): Add cp_evaluated. (alias_ctad_tweaks): Revert PR101233 fix. gcc/testsuite/ChangeLog: * g++.dg/cpp23/explicit-obj-lambda18.C: New test. * g++.dg/cpp23/static-operator-call7.C: New test.
2025-07-16openmp: Refactor handling of iteratorsKwok Cheung Yeung1-3/+1
Move code to calculate the iteration size and to generate the iterator expansion loop into separate functions. Use OMP_ITERATOR_DECL_P to check for iterators in clause declarations. gcc/c-family/ * c-omp.cc (c_finish_omp_depobj): Use OMP_ITERATOR_DECL_P. gcc/c/ * c-typeck.cc (handle_omp_array_sections): Use OMP_ITERATOR_DECL_P. (c_finish_omp_clauses): Likewise. gcc/cp/ * pt.cc (tsubst_omp_clause_decl): Use OMP_ITERATOR_DECL_P. * semantics.cc (handle_omp_array_sections): Likewise. (finish_omp_clauses): Likewise. gcc/ * gimplify.cc (gimplify_omp_affinity): Use OMP_ITERATOR_DECL_P. (compute_omp_iterator_count): New. (build_omp_iterator_loop): New. (gimplify_omp_depend): Use OMP_ITERATOR_DECL_P, compute_omp_iterator_count and build_omp_iterator_loop. * tree-inline.cc (copy_tree_body_r): Use OMP_ITERATOR_DECL_P. * tree-pretty-print.cc (dump_omp_clause): Likewise. * tree.h (OMP_ITERATOR_DECL_P): New macro.
2025-07-11c++: Implement C++26 P2786R13 - Trivial Relocatability [PR119064]Jakub Jelinek1-1/+11
The following patch implements the compiler side of the C++26 paper. Based on the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119064#c3 feedback, the patch enables the new conditional keywords trivially_relocatable_if_eligible and replaceable_if_eligible only for C++26, for older versions those conditional keywords yield -Wc++26-compat warning and are treated as normal identifiers. Plus __trivially_relocatable_if_eligible and __replaceable_if_eligible are handled as conditional keywords always without diagnostics (similarly to __final in C++98). The patch uses __builtin_ prefix on the new traits (but unlike clang which for some weird reason chose to name one __builtin_is_replaceable and another __builtin_is_cpp_trivially_relocatable this one uses __builtin_is_replaceable and __builtin_is_trivially_relocatable. I'll try to convince clang to change, they've only implemented it recently. The patch computes these properties on demand, only when something needs them (at the expense of eating 2 more bits per lang_type, but I've recently saved 64 bits and a patch to save another 64 bits is pending; and even 4 bits wouldn't fit). The patch doesn't add __builtin_trivially_relocate builtin that clang has, std::trivially_relocate is not constexpr and I think we don't need it for now at least until we implement some kind of vtable pointer signing __builtin_memmove should do the job. Especially if libstdc++ will for clang compatibility use the builtin if available and __builtin_memmove otherwise, we can switch any time. I've cross-tested all testcases also against the clang++ trunk implementation, and both compilers agreed in everything except for https://github.com/llvm/llvm-project/issues/143599 where clang++ was changed already and https://github.com/llvm/llvm-project/issues/144232 where I believe clang++ got it wrong too. The first testcase comes from https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2786r13.html#simple-worked-examples just tweaked so that the classes are named differently each time and that it compiles. There are 3 differences from the paper vs. the g++ as well as clang++ implementation, I've added comments into trivially-relocatable1.C but I think either that part of the paper wasn't updated through the later changes or it got it wrong. 2025-07-11 Jakub Jelinek <jakub@redhat.com> PR c++/119064 gcc/ * doc/invoke.texi (Wc++26-compat): Document. gcc/c-family/ * c.opt (Wc++26-compat): New option. * c.opt.urls: Regenerate. * c-opts.cc (c_common_post_options): Clear warn_cxx26_compat for C++26 or later. * c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine __cpp_trivial_relocatability=202502L. gcc/cp/ * cp-tree.h: Implement C++26 P2786R13 - Trivial Relocatability. (struct lang_type): Add trivially_relocatable, trivially_relocatable_computed, replaceable and replaceable_computed bitfields. Change width of dummy from 2 to 30. (CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT, CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, CLASSTYPE_REPLACEABLE_BIT, CLASSTYPE_REPLACEABLE_COMPUTED): Define. (enum virt_specifier): Add VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE and VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE enumerators. (trivially_relocatable_type_p, replaceable_type_p): Declare. * cp-trait.def (IS_NOTHROW_RELOCATABLE, IS_REPLACEABLE, IS_TRIVIALLY_RELOCATABLE): New traits. * parser.cc (cp_parser_class_property_specifier_seq_opt): Handle trivially_relocatable_if_eligible, __trivially_relocatable_if_eligible, replaceable_if_eligible and __replaceable_if_eligible. (cp_parser_class_head): Set CLASSTYPE_REPLACEABLE_BIT and/or CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT if corresponding conditional keywords were parsed and assert corresponding *_COMPUTED macro is false. * pt.cc (instantiate_class_template): Copy over also CLASSTYPE_TRIVIALLY_RELOCATABLE_{BIT,COMPUTED} and CLASSTYPE_REPLACEABLE_{BIT,COMPUTED} bits. * semantics.cc (referenceable_type_p): Move definition earlier. (trait_expr_value): Handle CPTK_IS_NOTHROW_RELOCATABLE, CPTK_IS_REPLACEABLE and CPTK_IS_TRIVIALLY_RELOCATABLE. (finish_trait_expr): Likewise. * tree.cc (default_movable_type_p): New function. (union_with_no_declared_special_member_fns): Likewise. (trivially_relocatable_type_p): Likewise. (replaceable_type_p): Likewise. * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_NOTHROW_RELOCATABLE, CPTK_IS_REPLACEABLE and CPTK_IS_TRIVIALLY_RELOCATABLE. gcc/testsuite/ * g++.dg/cpp26/feat-cxx26.C: Add test for __cpp_trivial_relocatability. * g++.dg/cpp26/trivially-relocatable1.C: New test. * g++.dg/cpp26/trivially-relocatable2.C: New test. * g++.dg/cpp26/trivially-relocatable3.C: New test. * g++.dg/cpp26/trivially-relocatable4.C: New test. * g++.dg/cpp26/trivially-relocatable5.C: New test. * g++.dg/cpp26/trivially-relocatable6.C: New test. * g++.dg/cpp26/trivially-relocatable7.C: New test. * g++.dg/cpp26/trivially-relocatable8.C: New test. * g++.dg/cpp26/trivially-relocatable9.C: New test. * g++.dg/cpp26/trivially-relocatable10.C: New test. * g++.dg/cpp26/trivially-relocatable11.C: New test.
2025-07-10c++, libstdc++: Implement C++26 P3068R5 - constexpr exceptions [PR117785]Jakub Jelinek1-1/+8
The following patch implements the C++26 P3068R5 - constexpr exceptions paper. As the IL cxx_eval_constant* functions process already contains the low level calls like __cxa_{allocate,free}_exception, __cxa_{,re}throw etc., the patch just makes 10 extern "C" __cxa_* functions magic builtins which during constant evaluation pretend to be constexpr even when not declared so and handle them directly, plus does the same for 3 std namespace functions - std::uncaught_exceptions, std::current_exception and std::rethrow_exception and adds one new FE builtin - __builtin_eh_ptr_adjust_ref which the library can use instead of the _M_addref and _M_release out of line methods (this one instead of recognizing _M_* as magic too because those are clearly specific to libstdc++ and e.g. libc++ could use something else). The patch uses magic VAR_DECLs with heap_{uninit_,,deleted_}identifier DECL_NAME like for operator new/delete for objects allocated with __cxa_allocate_exception, just sets their DECL_LANG_SPECIFIC so that we can track their reference count as well (with std::exception_ptr the same exception object can be referenced multiple times and we want to destruct and free only when it reaches zero refcount). For uncaught exceptions being propagated, the patch uses new kind of *jump_target, which is that magic VAR_DECL described above. The largest change in the patch is making jump_target argument non-optional in cxa_eval_constant_exception and all functions it calls that need it. This is because exceptions can be thrown from pretty much everywhere, e.g. binary expression can throw in either operand. And the patch also adds if (*jump_target) return NULL_TREE; or similar in many spots, so that we don't crash because cxx_eval_constant_expression returned NULL_TREE somewhere before actually trying to use it and so that we don't uselessly dive into other operands etc. Note, with statement expressions actually this was something we just didn't handle correctly before, one can validly have: a = ({ if (x) return 42; 12; }) + b; or in the other operand, or break/continue instead of return if it is somewhere in a loop/switch; and it isn't ok to branch from one operand to another one through some kind of goto. On the potential_constant_expression_1 side, important change was to set *jump_target conservatively on calls that could throw for C++26 (the patch uses magic void_node for potential_constant_expression* instead of VAR_DECL, so that we don't have to create new VAR_DECLs there uselessly). Without that change, several methods in libstdc++ wouldn't work correctly. I'm not sure what exactly potential_constant_expression_1 maps to in the C++26 standard wording now and whether doing that is ok, because basically after the first call to non-noexcept function it stops checking stuff. And, in some spots where I know potential_constant_expression_1 didn't check some subexpressions (e.g. the EH only cleanups or TRY_BLOCK handlers) I've added *potential_constant_expression* calls during cxx_eval_constant*, not sure if I need to do that because potential_constant_expression_1 is very conservative and just doesn't recurse on subexpressions in many cases. 2025-07-10 Jakub Jelinek <jakub@redhat.com> PR c++/117785 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_constexpr_exceptions=202411L for C++26. gcc/cp/ * constexpr.cc: Implement C++26 P3068R5 - constexpr exceptions. (class constexpr_global_ctx): Add caught_exceptions and uncaught_exceptions members. (constexpr_global_ctx::constexpr_global_ctx): Initialize uncaught_exceptions. (returns, breaks, continues, switches): Move earlier. (throws): New function. (exception_what_str, diagnose_std_terminate, diagnose_uncaught_exception): New functions. (enum cxa_builtin): New type. (cxx_cxa_builtin_fn_p, cxx_eval_cxa_builtin_fn): New functions. (cxx_eval_builtin_function_call): Add jump_target argument. Call cxx_eval_cxa_builtin_fn for __builtin_eh_ptr_adjust_ref. Adjust cxx_eval_constant_expression calls, if it results in jmp_target, set *jump_target to it and return. (cxx_bind_parameters_in_call): Add jump_target argument. Pass it through to cxx_eval_constant_expression. If it sets *jump_target, break. (fold_operand): Adjust cxx_eval_constant_expression caller. (cxx_eval_assert): Likewise. If it set jmp_target, return true. (cxx_eval_internal_function): Add jump_target argument. Pass it through to cxx_eval_constant_expression. Return early if *jump_target after recursing on args. (cxx_eval_dynamic_cast_fn): Likewise. Don't set reference_p for C++26 with -fexceptions. (cxx_eval_thunk_call): Add jump_target argument. Pass it through to cxx_eval_constant_expression. (cxx_set_object_constness): Likewise. Don't set TREE_READONLY if throws (jump_target). (cxx_eval_call_expression): Add jump_target argument. Pass it through to cxx_eval_internal_function, cxx_eval_builtin_function_call, cxx_eval_thunk_call, cxx_eval_dynamic_cast_fn and cxx_set_object_constness. Pass it through also cxx_eval_constant_expression on arguments, cxx_bind_parameters_in_call and cxx_fold_indirect_ref and for those cases return early if *jump_target. Call cxx_eval_cxa_builtin_fn for cxx_cxa_builtin_fn_p functions. For cxx_eval_constant_expression on body, pass address of cleared jmp_target automatic variable, if it throws propagate to *jump_target and make it non-cacheable. For C++26 don't diagnose calls to non-constexpr functions before cxx_bind_parameters_in_call could report some argument throwing an exception. (cxx_eval_unary_expression): Add jump_target argument. Pass it through to cxx_eval_constant_expression and return early if *jump_target after the call. (cxx_fold_pointer_plus_expression): Likewise. (cxx_eval_binary_expression): Likewise and similarly for cxx_fold_pointer_plus_expression call. (cxx_eval_conditional_expression): Pass jump_target to cxx_eval_constant_expression on first operand and return early if *jump_target after the call. (cxx_eval_vector_conditional_expression): Add jump_target argument. Pass it through to cxx_eval_constant_expression for all 3 arguments and return early if *jump_target after any of those calls. (get_array_or_vector_nelts): Add jump_target argument. Pass it through to cxx_eval_constant_expression. (eval_and_check_array_index): Add jump_target argument. Pass it through to cxx_eval_constant_expression calls and return early after each of them if *jump_target. (cxx_eval_array_reference): Likewise. (cxx_eval_component_reference): Likewise. (cxx_eval_bit_field_ref): Likewise. (cxx_eval_bit_cast): Likewise. Assert CHECKING_P call doesn't throw or return. (cxx_eval_logical_expression): Add jump_target argument. Pass it through to cxx_eval_constant_expression calls and return early after each of them if *jump_target. (cxx_eval_bare_aggregate): Likewise. (cxx_eval_vec_init_1): Add jump_target argument. Pass it through to cxx_eval_bare_aggregate and recursive call. Pass it through to get_array_or_vector_nelts and cxx_eval_constant_expression and return early after it if *jump_target. (cxx_eval_vec_init): Add jump_target argument. Pass it through to cxx_eval_constant_expression and cxx_eval_vec_init_1. (cxx_union_active_member): Add jump_target argument. Pass it through to cxx_eval_constant_expression and return early after it if *jump_target. (cxx_fold_indirect_ref_1): Add jump_target argument. Pass it through to cxx_union_active_member and recursive calls. (cxx_eval_indirect_ref): Add jump_target argument. Pass it through to cxx_fold_indirect_ref_1 calls and to recursive call, in which case return early after it if *jump_target. (cxx_fold_indirect_ref): Add jump_target argument. Pass it through to cxx_fold_indirect_ref and cxx_eval_constant_expression calls and return early after those if *jump_target. (cxx_eval_trinary_expression): Add jump_target argument. Pass it through to cxx_eval_constant_expression calls and return early after those if *jump_target. (cxx_eval_store_expression): Add jump_target argument. Pass it through to cxx_eval_constant_expression and eval_and_check_array_index calls and return early after those if *jump_target. (cxx_eval_increment_expression): Add jump_target argument. Pass it through to cxx_eval_constant_expression calls and return early after those if *jump_target. (label_matches): Handle VAR_DECL case. (cxx_eval_statement_list): Remove local_target variable and !jump_target handling. Handle throws (jump_target) like returns or breaks. (cxx_eval_loop_expr): Remove local_target variable and !jump_target handling. Pass it through to cxx_eval_constant_expression. Handle throws (jump_target) like returns. (cxx_eval_switch_expr): Pass jump_target through to cxx_eval_constant_expression on cond, return early after it if *jump_target. (build_new_constexpr_heap_type): Add jump_target argument. Pass it through to cxx_eval_constant_expression calls, return early after those if *jump_target. (merge_jump_target): New function. (cxx_eval_constant_expression): Make jump_target argument no longer defaulted, don't test jump_target for NULL. Pass jump_target through to recursive calls, cxx_eval_call_expression, cxx_eval_store_expression, cxx_eval_indirect_ref, cxx_eval_unary_expression, cxx_eval_binary_expression, cxx_eval_logical_expression, cxx_eval_array_reference, cxx_eval_component_reference, cxx_eval_bit_field_ref, cxx_eval_vector_conditional_expression, cxx_eval_bare_aggregate, cxx_eval_vec_init, cxx_eval_trinary_expression, cxx_fold_indirect_ref, build_new_constexpr_heap_type, cxx_eval_increment_expression, cxx_eval_bit_cast and return earlyu after some of those if *jump_target as needed. (cxx_eval_constant_expression) <case TARGET_EXPR>: For C++26 push also CLEANUP_EH_ONLY cleanups, with NULL_TREE marker after them. (cxx_eval_constant_expression) <case RETURN_EXPR>: Don't override *jump_target if throws (jump_target). (cxx_eval_constant_expression) <case TRY_CATCH_EXPR, case TRY_BLOCK, case MUST_NOT_THROW_EXPR, case TRY_FINALLY_EXPR, case CLEANUP_STMT>: Handle C++26 constant expressions. (cxx_eval_constant_expression) <case CLEANUP_POINT_EXPR>: For C++26 with throws (jump_target) evaluate the CLEANUP_EH_ONLY cleanups as well, and if not throws (jump_target) skip those. Set *jump_target if some of the cleanups threw. (cxx_eval_constant_expression) <case THROW_EXPR>: Recurse on operand for C++26. (cxx_eval_outermost_constant_expr): Diagnose uncaught exceptions both from main expression and cleanups, diagnose also break/continue/returns from the main expression. Handle CLEANUP_EH_ONLY cleanup markers. Don't diagnose mutable poison stuff if non_constant_p. Use different diagnostics for non-deleted heap allocations if they were allocated by __cxa_allocate_exception. (callee_might_throw): New function. (struct check_for_return_continue_data): Add could_throw field. (check_for_return_continue): Handle AGGR_INIT_EXPR and CALL_EXPR and set d->could_throw if they could throw. (potential_constant_expression_1): For CALL_EXPR allow cxx_dynamic_cast_fn_p calls. For C++26 set *jump_target to void_node for calls that could throw. For C++26 if call to non-constexpr call is seen, try to evaluate arguments first and if they could throw, don't diagnose call to non-constexpr function nor return false. Adjust check_for_return_continue_data initializers and set *jump_target to void_node if data.could_throw_p. For C++26 recurse on THROW_EXPR argument. Add comment explaining TRY_BLOCK handling with C++26 exceptions. Handle throws like returns in some cases. * cp-tree.h (MUST_NOT_THROW_NOEXCEPT_P, MUST_NOT_THROW_THROW_P, MUST_NOT_THROW_CATCH_P, DECL_EXCEPTION_REFCOUNT): Define. (DECL_LOCAL_DECL_P): Fix comment typo, VARIABLE_DECL -> VAR_DECL. (enum cp_built_in_function): Add CP_BUILT_IN_EH_PTR_ADJUST_REF, (handler_match_for_exception_type): Declare. * call.cc (handler_match_for_exception_type): New function. * except.cc (initialize_handler_parm): Set MUST_NOT_THROW_CATCH_P on newly created MUST_NOT_THROW_EXPR. (begin_eh_spec_block): Set MUST_NOT_THROW_NOEXCEPT_P. (wrap_cleanups_r): Set MUST_NOT_THROW_THROW_P. (build_throw): Add another TARGET_EXPR whose scope spans until after the __cxa_throw call and copy pointer value from ptr to it and use it in __cxa_throw argument. * tree.cc (builtin_valid_in_constant_expr_p): Handle CP_BUILT_IN_EH_PTR_ADJUST_REF. * decl.cc (cxx_init_decl_processing): Initialize __builtin_eh_ptr_adjust_ref FE builtin. * pt.cc (tsubst_stmt) <case MUST_NOT_THROW_EXPR>: Copy the MUST_NOT_THROW_NOEXCEPT_P, MUST_NOT_THROW_THROW_P and MUST_NOT_THROW_CATCH_P flags. * cp-gimplify.cc (cp_gimplify_expr) <case CALL_EXPR>: Error on non-folded CP_BUILT_IN_EH_PTR_ADJUST_REF calls. gcc/testsuite/ * g++.dg/cpp0x/constexpr-ellipsis2.C: Expect different diagnostics for C++26. * g++.dg/cpp0x/constexpr-throw.C: Likewise. * g++.dg/cpp1y/constexpr-84192.C: Expect different diagnostics. * g++.dg/cpp1y/constexpr-throw.C: Expect different diagnostics for C++26. * g++.dg/cpp1z/constexpr-asm-5.C: Likewise. * g++.dg/cpp26/constexpr-eh1.C: New test. * g++.dg/cpp26/constexpr-eh2.C: New test. * g++.dg/cpp26/constexpr-eh3.C: New test. * g++.dg/cpp26/constexpr-eh4.C: New test. * g++.dg/cpp26/constexpr-eh5.C: New test. * g++.dg/cpp26/constexpr-eh6.C: New test. * g++.dg/cpp26/constexpr-eh7.C: New test. * g++.dg/cpp26/constexpr-eh8.C: New test. * g++.dg/cpp26/constexpr-eh9.C: New test. * g++.dg/cpp26/constexpr-eh10.C: New test. * g++.dg/cpp26/constexpr-eh11.C: New test. * g++.dg/cpp26/constexpr-eh12.C: New test. * g++.dg/cpp26/constexpr-eh13.C: New test. * g++.dg/cpp26/constexpr-eh14.C: New test. * g++.dg/cpp26/constexpr-eh15.C: New test. * g++.dg/cpp26/feat-cxx26.C: Change formatting in __cpp_pack_indexing and __cpp_pp_embed test. Add __cpp_constexpr_exceptions test. * g++.dg/cpp26/static_assert1.C: Expect different diagnostics for C++26. * g++.dg/cpp2a/consteval34.C: Likewise. * g++.dg/cpp2a/consteval-memfn1.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic4.C: For C++26 add std::exception and std::bad_cast definitions and expect different diagnostics. * g++.dg/cpp2a/constexpr-dynamic6.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic7.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic8.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic9.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic11.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic14.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic18.C: Likewise. * g++.dg/cpp2a/constexpr-new27.C: New test. * g++.dg/cpp2a/constexpr-typeid5.C: New test. libstdc++-v3/ * include/bits/version.def (constexpr_exceptions): New. * include/bits/version.h: Regenerate. * libsupc++/exception (std::bad_exception::bad_exception): Add _GLIBCXX26_CONSTEXPR. (std::bad_exception::~bad_exception, std::bad_exception::what): For C++26 add constexpr and define inline. * libsupc++/exception.h (std::exception::exception, std::exception::operator=): Add _GLIBCXX26_CONSTEXPR. (std::exception::~exception, std::exception::what): For C++26 add constexpr and define inline. * libsupc++/exception_ptr.h (std::make_exception_ptr): Add _GLIBCXX26_CONSTEXPR. For if consteval use just throw with current_exception() in catch. (std::exception_ptr::exception_ptr(void*)): For C++26 add constexpr and define inline. (std::exception_ptr::exception_ptr()): Add _GLIBCXX26_CONSTEXPR. (std::exception_ptr::exception_ptr(const exception_ptr&)): Likewise. Use __builtin_eh_ptr_adjust_ref if consteval and compiler has it instead of _M_addref. (std::exception_ptr::exception_ptr(nullptr_t)): Add _GLIBCXX26_CONSTEXPR. (std::exception_ptr::exception_ptr(exception_ptr&&)): Likewise. (std::exception_ptr::operator=): Likewise. (std::exception_ptr::~exception_ptr): Likewise. Use __builtin_eh_ptr_adjust_ref if consteval and compiler has it instead of _M_release. (std::exception_ptr::swap): Add _GLIBCXX26_CONSTEXPR. (std::exception_ptr::operator bool): Likewise. (std::exception_ptr::operator==): Likewise. * libsupc++/nested_exception.h (std::nested_exception::nested_exception): Add _GLIBCXX26_CONSTEXPR. (std::nested_exception::operator=): Likewise. (std::nested_exception::~nested_exception): For C++26 add constexpr and define inline. (std::nested_exception::rethrow_if_nested): Add _GLIBCXX26_CONSTEXPR. (std::nested_exception::nested_ptr): Likewise. (std::_Nested_exception::_Nested_exception): Likewise. (std::throw_with_nested, std::rethrow_if_nested): Likewise. * libsupc++/new (std::bad_alloc::bad_alloc): Likewise. (std::bad_alloc::operator=): Likewise. (std::bad_alloc::~bad_alloc): For C++26 add constexpr and define inline. (std::bad_alloc::what): Likewise. (std::bad_array_new_length::bad_array_new_length): Add _GLIBCXX26_CONSTEXPR. (std::bad_array_new_length::~bad_array_new_length): For C++26 add constexpr and define inline. (std::bad_array_new_length::what): Likewise. * libsupc++/typeinfo (std::bad_cast::bad_cast): Add _GLIBCXX26_CONSTEXPR. (std::bad_cast::~bad_cast): For C++26 add constexpr and define inline. (std::bad_cast::what): Likewise. (std::bad_typeid::bad_typeid): Add _GLIBCXX26_CONSTEXPR. (std::bad_typeid::~bad_typeid): For C++26 add constexpr and define inline. (std::bad_typeid::what): Likewise.
2025-07-08c++: bogus error with union in qualified name [PR83469]Marek Polacek1-8/+17
While working on Reflection I noticed that we reject: union U { int i; }; constexpr auto r = ^^typename ::U; which is due to PR83469. Andrew P. posted a patch in 2021: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586344.html for which I had some comments but an updated patch never came. ~~ There are a few issues here with typenames and unions (and even struct keywords with unions). First in cp_parser_check_class_key, we need to allow typenames to name union types and union key to be able to use with typenames. The next issue is we need to record if we had a union key, right now we just record it was a struct/class/typename one which is wrong. ~~ This patch is an updated and cleaned up version; I've also addressed a missing bit in pt.cc. PR c++/83469 PR c++/93809 gcc/cp/ChangeLog: * cp-tree.h (UNION_TYPE_P): Define. (TYPENAME_IS_UNION_P): Define. * decl.cc (struct typename_info): Add union_p field. (struct typename_hasher::equal): Compare union_p field. (build_typename_type): Use ti.union_p for union_type. Set TYPENAME_IS_UNION_P. * error.cc (dump_type) <case TYPENAME_TYPE>: Handle TYPENAME_IS_UNION_P. * module.cc (trees_out::type_node): Likewise. * parser.cc (cp_parser_check_class_key): Allow typename key for union types and allow union keyword for typename types. * pt.cc (tsubst) <case TYPENAME_TYPE>: Don't conflate unions with class_type. For TYPENAME_IS_CLASS_P, check NON_UNION_CLASS_TYPE_P rather than CLASS_TYPE_P. Add TYPENAME_IS_UNION_P handling. gcc/testsuite/ChangeLog: * g++.dg/template/error45.C: Adjust dg-error. * g++.dg/warn/Wredundant-tags-3.C: Remove xfail. * g++.dg/parse/union1.C: New test. * g++.dg/parse/union2.C: New test. * g++.dg/parse/union3.C: New test. * g++.dg/parse/union4.C: New test. * g++.dg/parse/union5.C: New test. * g++.dg/parse/union6.C: New test. Co-authored-by: Andrew Pinski <quic_apinski@quicinc.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2025-06-29c++/modules: Ensure type of partial spec VAR_DECL is consistent with its ↵Nathaniel Shead1-0/+4
template [PR120644] We were erroring because the TEMPLATE_DECL of the existing partial specialisation has an undeduced return type, but the imported declaration did not. The root cause is similar to what was fixed in r13-2744-g4fac53d6522189, where modules streaming code assumes that a TEMPLATE_DECL and its DECL_TEMPLATE_RESULT will always have the same TREE_TYPE. That commit fixed the issue by ensuring that when the type of a variable is deduced the TEMPLATE_DECL is updated as well, but missed handling partial specialisations. This patch ensures that the same adjustment is made there as well. PR c++/120644 gcc/cp/ChangeLog: * decl.cc (cp_finish_decl): Also propagate type to partial templates. * module.cc (trees_out::decl_value): Add assertion that the TREE_TYPE of a streamed template decl matches its inner. (trees_in::is_matching_decl): Clarify function return type deduction should only occur for non-TEMPLATE_DECL. * pt.cc (template_for_substitution): Handle partial specs. gcc/testsuite/ChangeLog: * g++.dg/modules/auto-7.h: New test. * g++.dg/modules/auto-7_a.H: New test. * g++.dg/modules/auto-7_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> Reviewed-by: Patrick Palka <ppalka@redhat.com>
2025-06-27c++: fix ICE with [[deprecated]] [PR120756]Marek Polacek1-1/+2
Here we end up with "error reporting routines re-entered" because resolve_nondeduced_context isn't passing complain to mark_used. PR c++/120756 gcc/cp/ChangeLog: * pt.cc (resolve_nondeduced_context): Pass complain to mark_used. gcc/testsuite/ChangeLog: * g++.dg/warn/deprecated-22.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-06-16c++: add -Wsfinae-incompleteJason Merrill1-1/+0
We already error about a type or function definition causing a concept check to change value, but it would be useful to diagnose this for other SFINAE contexts as well; the memoization problem also affects templates. So -Wsfinae-incomplete remembers if we've failed a requirement for a complete type/deduced return type in a non-tf_error context, and later warns if the type/function becomes complete. This warning is enabled by default; I think the signal-to-noise ratio is high enough to warrant that, and it catches things that are likely to make the program "ill-formed, no diagnostic required". friend87.C is an interesting case; this could be considered a false positive because it is using friend injection to define the auto function to implement a compile-time counter. I think this is sufficiently pathological that it's fine to expect people who want to play this sort of game to suppress the warning. The data for this warning uses GTY((cache)) to persist through GC, but allow entries to be discarded if the key is not otherwise marked. I don't think it's desirable to export/import this information in modules, it makes sense for it to be local to a single TU. -Wsfinae-incomplete=2 adds a warning at the point of failure, which is primarily intended to help with debugging warnings from the default mode. gcc/ChangeLog: * doc/invoke.texi: Document -Wsfinae-incomplete. gcc/c-family/ChangeLog: * c.opt: Add -Wsfinae-incomplete. * c.opt.urls: Regenerate. gcc/cp/ChangeLog: * constraint.cc (failed_completions_map): New. (note_failed_type_completion): Rename from note_failed_type_completion_for_satisfaction. Add -Wsfinae-incomplete handling. (failed_completion_location): New. * class.cc (finish_struct_1): Add -Wsfinae-incomplete warning. * decl.cc (require_deduced_type): Adjust. (finish_function): Add -Wsfinae-incomplete warning. * typeck.cc (complete_type_or_maybe_complain): Adjust. (cxx_sizeof_or_alignof_type): Call note_failed_type_completion. * pt.cc (dependent_template_arg_p): No longer static. * cp-tree.h: Adjust. libstdc++-v3/ChangeLog: * testsuite/20_util/is_complete_or_unbounded/memoization.cc * testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: Expect -Wsfinae-incomplete. gcc/testsuite/ChangeLog: * g++.dg/template/friend87.C * g++.dg/cpp2a/concepts-complete1.C * g++.dg/cpp2a/concepts-complete2.C * g++.dg/cpp2a/concepts-complete3.C * g++.dg/cpp2a/concepts-complete4.C: Expect -Wsfinae-incomplete.
2025-06-09c++: Fix template class lookup [PR120495, PR115605].Iain Sandoe1-11/+19
In the reported issues, using lookup_template_class () directly on (for example) the coroutine_handle identifier fails because a class-local TYPE_DECL is found. This is because, in the existing code, lookup is called with default parameters which means that class contexts are examined first. Fix this, when a context is provided by the caller, by doing lookup in namespace provided. PR c++/120495 PR c++/115605 gcc/cp/ChangeLog: * pt.cc (lookup_template_class): Honour provided namespace contexts when looking up class templates. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr120495.C: New test. * g++.dg/pr115605.C: New test. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
2025-06-05c++: substituting fn parm redeclared with dep alias tmpl [PR120224]Patrick Palka1-2/+12
Here we declare f twice, the second time around using a dependent alias template. Due to alias template transparency these are logically the same overload. But now the function type of f (produced from the first declaration) diverges from the type of its formal parameter (produced from the subsequent redefinition) in that substituting T=int succeeds for the function type but not for the formal parameter type. This eventually causes us to produce an undiagnosed error_mark_node in the AST of the function call, leading to failure of the sanity check check added in r14-6343-g0c018a74eb1aff. Before r14-6343 we would still go on to reject the testcase later at instantiation time, from regenerate_decl_from_template, making this a regression. To fix this, it seems we just need to propagate error_mark_node upon substitution failure into the type of a PARM_DECL. PR c++/120224 gcc/cp/ChangeLog: * pt.cc (tsubst_function_decl): Return error_mark_node if substituting into the formal parameter list failed. (tsubst_decl) <case PARM_DECL>: Return error_mark_node upon TREE_TYPE substitution failure, when in a SFINAE context. Return error_mark_node upon DECL_CHAIN substitution failure. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-80.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-06-02OpenMP: Handle more cases in user/condition selectorSandra Loosemore1-7/+23
Tobias had noted that the C front end was not treating C23 constexprs as constant in the user/condition selector property, which led to missed opportunities to resolve metadirectives at parse time. Additionally neither C nor C++ was permitting the expression to have pointer or floating-point type -- the former being a common idiom in other C/C++ conditional expressions. By using the existing front-end hooks for the implicit conversion to bool in conditional expressions, we also get free support for using a C++ class object that has a bool conversion operator in the user/condition selector. gcc/c/ChangeLog * c-parser.cc (c_parser_omp_context_selector): Call convert_lvalue_to_rvalue and c_objc_common_truthvalue_conversion on the expression for OMP_TRAIT_PROPERTY_BOOL_EXPR. gcc/cp/ChangeLog * cp-tree.h (maybe_convert_cond): Declare. * parser.cc (cp_parser_omp_context_selector): Call maybe_convert_cond and fold_build_cleanup_point_expr on the expression for OMP_TRAIT_PROPERTY_BOOL_EXPR. * pt.cc (tsubst_omp_context_selector): Likewise. * semantics.cc (maybe_convert_cond): Remove static declaration. gcc/testsuite/ChangeLog * c-c++-common/gomp/declare-variant-2.c: Update expected output. * c-c++-common/gomp/metadirective-condition-constexpr.c: New. * c-c++-common/gomp/metadirective-condition.c: New. * c-c++-common/gomp/metadirective-error-recovery.c: Update expected output. * g++.dg/gomp/metadirective-condition-class.C: New. * g++.dg/gomp/metadirective-condition-template.C: New.
2025-05-30OpenMP: C++ "declare mapper" supportJulian Brown1-3/+50
This patch adds support for OpenMP 5.0 "declare mapper" functionality for C++. I've merged it to og13 based on the last version posted upstream, with some minor changes due to the newly-added 'present' map modifier support. There's also a fix to splay-tree traversal in gimplify.cc:omp_instantiate_implicit_mappers, and this patch omits the rearrangement of gimplify.cc:gimplify_{scan,adjust}_omp_clauses that I separated out into its own patch and applied (to og13) already. gcc/c-family/ * c-common.h (c_omp_region_type): Add C_ORT_DECLARE_MAPPER and C_ORT_OMP_DECLARE_MAPPER codes. (omp_mapper_list): Add forward declaration. (c_omp_find_nested_mappers, c_omp_instantiate_mappers): Add prototypes. * c-omp.cc (c_omp_find_nested_mappers): New function. (remap_mapper_decl_info): New struct. (remap_mapper_decl_1, omp_instantiate_mapper, c_omp_instantiate_mappers): New functions. gcc/cp/ * constexpr.cc (reduced_constant_expression_p): Add OMP_DECLARE_MAPPER case. (cxx_eval_constant_expression, potential_constant_expression_1): Likewise. * cp-gimplify.cc (cxx_omp_finish_mapper_clauses): New function. * cp-objcp-common.h (LANG_HOOKS_OMP_FINISH_MAPPER_CLAUSES, LANG_HOOKS_OMP_MAPPER_LOOKUP, LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE, LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define langhooks. * cp-tree.h (lang_decl_base): Add omp_declare_mapper_p field. Recount spare bits comment. (DECL_OMP_DECLARE_MAPPER_P): New macro. (omp_mapper_id): Add prototype. (cp_check_omp_declare_mapper): Add prototype. (omp_instantiate_mappers): Add prototype. (cxx_omp_finish_mapper_clauses): Add prototype. (cxx_omp_mapper_lookup): Add prototype. (cxx_omp_extract_mapper_directive): Add prototype. (cxx_omp_map_array_section): Add prototype. * decl.cc (check_initializer): Add OpenMP declare mapper support. (cp_finish_decl): Set DECL_INITIAL for OpenMP declare mapper var decls as appropriate. * decl2.cc (mark_used): Instantiate OpenMP "declare mapper" magic var decls. * error.cc (dump_omp_declare_mapper): New function. (dump_simple_decl): Use above. * parser.cc (cp_parser_omp_clause_map): Add KIND parameter. Support "mapper" modifier. (cp_parser_omp_all_clauses): Add KIND argument to cp_parser_omp_clause_map call. (cp_parser_omp_target): Call omp_instantiate_mappers before finish_omp_clauses. (cp_parser_omp_declare_mapper): New function. (cp_parser_omp_declare): Add "declare mapper" support. * pt.cc (tsubst_decl): Adjust name of "declare mapper" magic var decls once we know their type. (tsubst_omp_clauses): Call omp_instantiate_mappers before finish_omp_clauses, for target regions. (tsubst_expr): Support OMP_DECLARE_MAPPER nodes. (instantiate_decl): Instantiate initialiser (i.e definition) for OpenMP declare mappers. * semantics.cc (gimplify.h): Include. (omp_mapper_id, omp_mapper_lookup, omp_extract_mapper_directive, cxx_omp_map_array_section, cp_check_omp_declare_mapper): New functions. (finish_omp_clauses): Delete GOMP_MAP_PUSH_MAPPER_NAME and GOMP_MAP_POP_MAPPER_NAME artificial clauses. (omp_target_walk_data): Add MAPPERS field. (finish_omp_target_clauses_r): Scan for uses of struct/union/class type variables. (finish_omp_target_clauses): Create artificial mapper binding clauses for used structs/unions/classes in offload region. gcc/fortran/ * parse.cc (tree.h, fold-const.h, tree-hash-traits.h): Add includes (for additions to omp-general.h). gcc/ * gimplify.cc (gimplify_omp_ctx): Add IMPLICIT_MAPPERS field. (new_omp_context): Initialise IMPLICIT_MAPPERS hash map. (delete_omp_context): Delete IMPLICIT_MAPPERS hash map. (instantiate_mapper_info): New structs. (remap_mapper_decl_1, omp_mapper_copy_decl, omp_instantiate_mapper, omp_instantiate_implicit_mappers): New functions. (gimplify_scan_omp_clauses): Handle MAPPER_BINDING clauses. (gimplify_adjust_omp_clauses): Instantiate implicit declared mappers. (gimplify_omp_declare_mapper): New function. (gimplify_expr): Call above function. * langhooks-def.h (lhd_omp_mapper_lookup, lhd_omp_extract_mapper_directive, lhd_omp_map_array_section): Add prototypes. (LANG_HOOKS_OMP_FINISH_MAPPER_CLAUSES, LANG_HOOKS_OMP_MAPPER_LOOKUP, LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE, LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define macros. (LANG_HOOK_DECLS): Add above macros. * langhooks.cc (lhd_omp_mapper_lookup, lhd_omp_extract_mapper_directive, lhd_omp_map_array_section): New dummy functions. * langhooks.h (lang_hooks_for_decls): Add OMP_FINISH_MAPPER_CLAUSES, OMP_MAPPER_LOOKUP, OMP_EXTRACT_MAPPER_DIRECTIVE, OMP_MAP_ARRAY_SECTION hooks. * omp-general.h (omp_name_type<T>): Add templatized struct, hash type traits (for omp_name_type<tree> specialization). (omp_mapper_list<T>): Add struct. * tree-core.h (omp_clause_code): Add OMP_CLAUSE__MAPPER_BINDING_. * tree-pretty-print.cc (dump_omp_clause): Support GOMP_MAP_UNSET, GOMP_MAP_PUSH_MAPPER_NAME, GOMP_MAP_POP_MAPPER_NAME artificial mapping clauses. Support OMP_CLAUSE__MAPPER_BINDING_ and OMP_DECLARE_MAPPER. * tree.cc (omp_clause_num_ops, omp_clause_code_name): Add OMP_CLAUSE__MAPPER_BINDING_. * tree.def (OMP_DECLARE_MAPPER): New tree code. * tree.h (OMP_DECLARE_MAPPER_ID, OMP_DECLARE_MAPPER_DECL, OMP_DECLARE_MAPPER_CLAUSES): New defines. (OMP_CLAUSE__MAPPER_BINDING__ID, OMP_CLAUSE__MAPPER_BINDING__DECL, OMP_CLAUSE__MAPPER_BINDING__MAPPER): New defines. include/ * gomp-constants.h (gomp_map_kind): Add GOMP_MAP_UNSET, GOMP_MAP_PUSH_MAPPER_NAME, GOMP_MAP_POP_MAPPER_NAME artificial mapping clause types. gcc/testsuite/ * c-c++-common/gomp/map-6.c: Update error scan output. * c-c++-common/gomp/declare-mapper-3.c: New test (only enabled for C++ for now). * c-c++-common/gomp/declare-mapper-4.c: Likewise. * c-c++-common/gomp/declare-mapper-5.c: Likewise. * c-c++-common/gomp/declare-mapper-6.c: Likewise. * c-c++-common/gomp/declare-mapper-7.c: Likewise. * c-c++-common/gomp/declare-mapper-8.c: Likewise. * c-c++-common/gomp/declare-mapper-9.c: Likewise. * c-c++-common/gomp/declare-mapper-10.c: Likewise. * c-c++-common/gomp/declare-mapper-12.c: Likewise. * g++.dg/gomp/declare-mapper-1.C: New test. * g++.dg/gomp/declare-mapper-2.C: New test. * g++.dg/gomp/declare-mapper-3.C: New test. libgomp/ * testsuite/libgomp.c++/declare-mapper-1.C: New test. * testsuite/libgomp.c++/declare-mapper-2.C: New test. * testsuite/libgomp.c++/declare-mapper-3.C: New test. * testsuite/libgomp.c++/declare-mapper-4.C: New test. * testsuite/libgomp.c++/declare-mapper-5.C: New test. * testsuite/libgomp.c++/declare-mapper-6.C: New test. * testsuite/libgomp.c++/declare-mapper-7.C: New test. * testsuite/libgomp.c++/declare-mapper-8.C: New test. * testsuite/libgomp.c-c++-common/declare-mapper-9.c: New test (only enabled for C++ for now). * testsuite/libgomp.c-c++-common/declare-mapper-10.c: Likewise. * testsuite/libgomp.c-c++-common/declare-mapper-11.c: Likewise. * testsuite/libgomp.c-c++-common/declare-mapper-12.c: Likewise. * testsuite/libgomp.c-c++-common/declare-mapper-13.c: Likewise. * testsuite/libgomp.c-c++-common/declare-mapper-14.c: Likewise. Co-authored-by: Tobias Burnus <tburnus@baylibre.com>
2025-05-26c++: add -fdump-lang-tinstJason Merrill1-17/+94
This patch adds a dump with a trace of template instantiations, indented based on the depth of recursive instantiation. -lineno adds the location that triggered the instantiation, -details adds non-instantiation sbustitutions. The instantiate_pending_templates change is to avoid a bunch of entries for reopening tinst scopes that we then don't instantiate anything with; it also seems a bit cleaner this way. gcc/cp/ChangeLog: * cp-tree.h: Declare tinst_dump_id. * cp-objcp-common.cc (cp_register_dumps): Set it. * pt.cc (push_tinst_level_loc): Dump it. (reopen_tinst_level): Here too. (tinst_complete_p): New. (instantiate_pending_templates): Don't reopen_tinst_level for already-complete instantiations. gcc/ChangeLog: * doc/invoke.texi: Move C++ -fdump-lang to C++ section. Add -fdump-lang-tinst.
2025-05-15c++: unifying specializations of non-primary tmpls [PR120161]Patrick Palka1-3/+3
Here unification of P=Wrap<int>::type, A=Wrap<long>::type wrongly succeeds ever since r14-4112 which made the RECORD_TYPE case of unify no longer recurse into template arguments for non-primary templates (since they're a non-deduced context) and so the int/long mismatch that makes the two types distinct goes unnoticed. In the case of (comparing specializations of) a non-primary template, unify should still go on to compare the types directly before returning success. PR c++/120161 gcc/cp/ChangeLog: * pt.cc (unify) <case RECORD_TYPE>: When comparing specializations of a non-primary template, still perform a type comparison. gcc/testsuite/ChangeLog: * g++.dg/template/unify13.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-05-15c++: one more PR99599 tweakJason Merrill1-2/+2
Patrick pointed out that if the parm/arg types aren't complete yet at this point, it would affect the type_has_converting_constructor and TYPE_HAS_CONVERSION tests. I don't have a testcase, but it makes sense for safety. PR c++/99599 gcc/cp/ChangeLog: * pt.cc (conversion_may_instantiate_p): Make sure classes are complete.
2025-05-09c++: recursive instantiation diagnostic [PR120204]Jason Merrill1-4/+12
Here tsubst_baselink was returning error_mark_node silently despite tf_error; we need to actually give an error. PR c++/120204 gcc/cp/ChangeLog: * pt.cc (tsubst_baselink): Always error if lookup fails. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-recursion3.C: New test.
2025-05-09c++: CWG2369 workaround and ... [PR120185]Jason Merrill1-1/+1
My r16-479 adjustment to the PR99599 workaround broke on a class with a varargs constructor. It also occurred to me that we don't need to do non-dep conversion checking in two phases when concepts aren't supported. PR c++/99599 PR c++/120185 gcc/cp/ChangeLog: * class.cc (type_has_converting_constructor): Handle null parm. * pt.cc (fn_type_unification): Skip early non-dep checking if no concepts. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-nondep6.C: New test.
2025-05-08c++: adjust PR99599/CWG2369 workaroundJason Merrill1-29/+11
This tweak to CWG2369 has gotten more discussion lately in CWG, including in P3606. In those discussions, it occurred to me that having the check depend on whether a class has been instantiated yet is unstable, that it should only check for user-defined conversions. Also, one commenter was surprised that adding an explicitly-declared default constructor to a class changed things, so this patch also changes the aggregate check to more narrowly checking for one-argument constructors other than the copy/move constructors. As a result, this early filter resembles how LOOKUP_DEFAULTED rejects any candidate that would need a UDC: in both cases we want to avoid considering arbitrary UDCs. But here, rather than rejecting, we want the early filter to let the candidate past without considering the conversion. PR c++/99599 gcc/cp/ChangeLog: * cp-tree.h (type_has_converting_constructor): Declare. * class.cc (type_has_converting_constructor): New. * pt.cc (conversion_may_instantiate_p): Don't check completeness. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-recursive-sat4.C: Adjust again. * g++.dg/cpp2a/concepts-nondep5.C: New test.
2025-05-01c++: more overeager use of deleted function before ADL [PR119034]Patrick Palka1-7/+1
The PR68942 fix used the tf_conv flag to disable mark_used when substituting a FUNCTION_DECL callee of an ADL-enabled call. In this slightly more elaborate testcase, we end up prematurely calling mark_used anyway on the FUNCTION_DECL directly from the CALL_EXPR case of tsubst_expr during partial instantiation, leading to a bogus "use of deleted function" error. This patch fixes the general problem in a more robust way by ensuring the callee of an ADL-enabled call is wrapped in an OVERLOAD, so that tsubst_expr leaves it alone. PR c++/119034 PR c++/68942 gcc/cp/ChangeLog: * pt.cc (tsubst_expr) <case CALL_EXPR>: Revert PR68942 fix. * semantics.cc (finish_call_expr): Ensure the callee of an ADL-enabled call is wrapped in an OVERLOAD. gcc/testsuite/ChangeLog: * g++.dg/template/koenig13.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-05-01c++/modules: Fix imported CNTTPs being considered non-constant [PR119938]Nathaniel Shead1-1/+6
When importing a CNTTP object, since r15-3031-g0b7904e274fbd6 we shortcut the processing of the generated NTTP so that we don't attempt to recursively load pendings. However, due to an oversight we do not properly set TREE_CONSTANT or DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P on the decl, which confuses later processing. This patch ensures that this happens correctly. PR c++/119938 gcc/cp/ChangeLog: * pt.cc (get_template_parm_object): When !check_init, add assert that expr really is constant and mark decl as such. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-nttp-2_a.H: New test. * g++.dg/modules/tpl-nttp-2_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2025-04-30c++: UNBOUND_CLASS_TEMPLATE context substitution [PR119981]Patrick Palka1-7/+13
In r15-123 and r14-11434 we unconditionally set processing_template_decl when substituting the context of an UNBOUND_CLASS_TEMPLATE, in order to handle instantiation of the dependently scoped friend declaration template<int N> template<class T> friend class A<N>::B; where the scope A<N> remains dependent after instantiation. But this turns out to misbehave for the UNBOUND_CLASS_TEMPLATE in the below testcase representing g<[]{}>::template fn since with the flag set substituting the args of test3 into the lambda causes us to defer the substitution and yield a lambda that still looks dependent, which in turn makes g<[]{}> still dependent and not suitable for qualified name lookup. This patch restricts setting processing_template_decl during UNBOUND_CLASS_TEMPLATE substitution to the case where there are multiple levels of introduced template parameters, as in the friend declaration. (This means we need to substitute the template parameter list(s) first, which makes sense since they lexically appear first.) PR c++/119981 PR c++/119378 gcc/cp/ChangeLog: * pt.cc (tsubst) <case UNBOUND_CLASS_TEMPLATE>: Substitute into template parameter list first. When substituting the context, only set processing_template_decl if there's more than one level of introduced template parameters. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ15.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-04-25c++: bad pending_template recursionJason Merrill1-2/+8
limit_bad_template_recursion currently avoids immediate instantiation of templates from uses in an already ill-formed instantiation, but we still can get unnecessary recursive instantiation in pending_templates if the instantiation was queued before the error. Initially this regressed several libstdc++ tests which seemed to rely on a static_assert in a function called from another that is separately ill-formed. For instance, in the 48101_neg.cc tests, we first got an error in find(), then later instantiate _S_key() (called from find) and got the static_assert error from there. r16-131-g876d1a22dfaf87 and r16-132-g901900bc37566c changed the library code (and tests) to make the expected static_assert errors happen earlier. gcc/cp/ChangeLog: * cp-tree.h (struct tinst_level): Add had_errors bit. * pt.cc (push_tinst_level_loc): Clear it. (pop_tinst_level): Set it. (reopen_tinst_level): Check it. (instantiate_pending_templates): Call limit_bad_template_recursion. gcc/testsuite/ChangeLog: * g++.dg/template/recurse5.C: New test.
2025-04-16c++: ill-formed constexpr function [PR113360]Jason Merrill1-0/+5
If we already gave an error while parsing a function, we don't also need to try to explain what's wrong with it when we later try to use it in a constant-expression. In the new testcase explain_invalid_constexpr_fn couldn't find anything still in the function to complain about, so it said because: followed by nothing. We still try to constant-evaluate it to reduce error cascades, but we shouldn't complain if it doesn't work very well. This flag is similar to CLASSTYPE_ERRONEOUS that I added a while back. PR c++/113360 gcc/cp/ChangeLog: * cp-tree.h (struct language_function): Add erroneous bit. * constexpr.cc (explain_invalid_constexpr_fn): Return if set. (cxx_eval_call_expression): Quiet if set. * parser.cc (cp_parser_function_definition_after_declarator) * pt.cc (instantiate_body): Set it. gcc/testsuite/ChangeLog: * g++.dg/cpp23/constexpr-nonlit18.C: Remove redundant message. * g++.dg/cpp1y/constexpr-diag2.C: New test. * g++.dg/cpp1y/pr63996.C: Adjust expected errors. * g++.dg/template/explicit-args6.C: Likewise. * g++.dg/cpp0x/constexpr-ice21.C: Likewise.
2025-04-16c++: templates, attributes, #pragma target [PR114772]Jason Merrill1-0/+2
Since r12-5426 apply_late_template_attributes suppresses various global state to avoid applying active pragmas to earlier declarations; we also need to override target_option_current_node. PR c++/114772 PR c++/101180 gcc/cp/ChangeLog: * pt.cc (apply_late_template_attributes): Also override target_option_current_node. gcc/testsuite/ChangeLog: * g++.dg/ext/pragma-target2.C: New test.
2025-04-15c++: prev declared hidden tmpl friend inst, cont [PR119807]Patrick Palka1-0/+4
When remapping existing specializations of a hidden template friend from a previous declaration to the new definition, we must remap only those specializations that match this new definition, but currently we remap all specializations (since they all appear in the same DECL_TEMPLATE_INSTANTIATIONS list of the most general template). Concretely, in the first testcase below, we form two specializations of the friend A::f, one with arguments {{0},{bool}} and another with arguments {{1},{bool}}. Later when instantiating B, we need to remap these specializations. During the B<0> instantiation we only want to remap the first specialization, and during the B<1> instantiation only the second specialization, but currently we remap both specializations twice. tsubst_friend_function needs to determine if an existing specialization matches the shape of the new definition, which is tricky in general, e.g. if the outer template parameters may not match up. Fortunately we don't have to reinvent the wheel here since is_specialization_of_friend seems to do exactly what we need. We can check this unconditionally, but I think it's only necessary when dealing with specializations formed from a class template scope previous declaration, hence the TMPL_ARGS_HAVE_MULTIPLE_LEVELS check. PR c++/119807 PR c++/112288 gcc/cp/ChangeLog: * pt.cc (tsubst_friend_function): Skip remapping an existing specialization if it doesn't match the shape of the new friend definition. gcc/testsuite/ChangeLog: * g++.dg/template/friend86.C: New test. * g++.dg/template/friend87.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-04-10c++: nested lambda capture pack [PR119345]Jason Merrill1-0/+2
tsubst_stmt already registers a local capture proxy as a local_specialization of both an outer capture proxy and the captured variable; we also need to do that in add_extra_args. PR c++/119345 gcc/cp/ChangeLog: * pt.cc (add_extra_args): Also register a specialization of the captured variable. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ14.C: New test.
2025-04-10c++: alias_ctad_tweaks ICE w/ inherited CTAD [PR119687]Patrick Palka1-2/+1
With inherited CTAD the set of guides may be a two-dimensional overload set (i.e. OVERLOADs of OVERLOADs) so alias_ctad_tweaks (which also does the inherited CTAD transformation) needs to use the 2D-aware lkp_iterator instead of ovl_iterator, or better yet use the more idiomatic lkp_range. PR c++/119687 gcc/cp/ChangeLog: * pt.cc (alias_ctad_tweaks): Use lkp_range / lkp_iterator instead of ovl_iterator. gcc/testsuite/ChangeLog: * g++.dg/cpp23/class-deduction-inherited8.C: New test. Reviewed-by: Jason Merill <jason@redhat.com>
2025-04-09c++: ICE with nested default targ lambdas [PR119574]Patrick Palka1-1/+0
Here we substitute into the inner lambda twice, first during default argument substitution for the outer template parameters, then during that for the inner template parameters. For the second testcase (which is easier to follow/debug), the first substitution into the inner lambda is with the template arguments {0, NULL_TREE}, which we defer because it's an incremental substitution. For the second and final substitution we have the template arguments {1, NULL_TREE}, which we try combining via add_extra_args and ICE on the checking assert because TREE_STATIC isn't set on the deferred arguments but the template arguments are considered dependent. The template arguments aren't dependent however -- they're just incomplete because when we deferred them we were in the middle of deduction, and we consider a NULL_TREE template argument as dependent. If we remove this checking assert, we go on to correctly merge the template arguments into {{0, NULL_TREE}, {1, NULL_TREE}}. So this patch just removes this imprecise assert. PR c++/119574 gcc/cp/ChangeLog: * pt.cc (add_extra_args): Remove checking assert. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ13.C: New test. * g++.dg/cpp2a/lambda-targ13a.C: New test. * g++.dg/cpp2a/lambda-targ13b.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-04-08c++: lambda in concept [PR118698]Jason Merrill1-0/+12
When normalizing is_foo for <T>, we get to normalizing callable<decltype(...),T> for <T,foo>, which means substituting <T,foo> into <decltype(...),T>. Since r14-9938, because in_template_context is false we return the lambda unchanged, just with LAMBDA_EXPR_EXTRA_ARGS set, so the closure type still refers to the is_specialization_of tparms in its CLASSTYPE_TEMPLATE_INFO. So then in normalize_atom caching find_template_parameters walks over the parameter mapping; any_template_parm_r walks into the TREE_TYPE of a LAMBDA_EXPR without considering EXTRA_ARGS and finds a template parm from the wrong parameter list. But since r15-3530 we expect to set tf_partial when substituting with dependent arguments, so we should set that when normalizing. And then tf_partial causes TREE_STATIC to be set on the EXTRA_ARGS, meaning that those args will replace all the template parms in the rest of the lambda, so we can walk just the EXTRA_ARGS and ignore the rest. PR c++/118698 gcc/cp/ChangeLog: * constraint.cc (struct norm_info): Add tf_partial. * pt.cc (any_template_parm_r): Handle LAMBDA_EXPR_EXTRA_ARGS. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-lambda22.C: New test.
2025-04-08c++: self-dependent alias template [PR117530]Jason Merrill1-6/+8
Here, instantiating B<short> means instantiating A<short>, which means instantiating B<short>. And then when we go to register the initial instantiation, it conflicts with the inner one. Fixed by checking after tsubst whether there's already something in the hash table. We already did something much like this in tsubst_decl, but that doesn't handle this case. While I was here, I noticed that we had a pop_deferring_access_checks on one early exit but not another, and since I wanted to add yet another I switched to using deferring_access_check_sentinel. PR c++/117530 gcc/cp/ChangeLog: * pt.cc (instantiate_template): Check retrieve_specialization after tsubst. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-uneval27.C: New test.
2025-04-05c++: maybe_dependent_member_ref and typenames [PR118626]Patrick Palka1-1/+2
Here during maybe_dependent_member_ref for accepted_type<_Up>, we correctly don't strip the typedef because it's a complex one (its defaulted template parameter isn't used in its definition) and so we recurse to consider its corresponding TYPE_DECL. We then incorrectly decide to not rewrite this use because of the TYPENAME_TYPE shortcut. But I don't think this shortcut should apply to a typedef TYPE_DECL. PR c++/118626 gcc/cp/ChangeLog: * pt.cc (maybe_dependent_member_ref): Restrict TYPENAME_TYPE shortcut to non-typedef TYPE_DECL. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-alias25a.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-04-05c++: maybe_dependent_member_ref and stripped alias [PR118626]Patrick Palka1-3/+27
Here during maybe_dependent_member_ref (as part of CTAD rewriting for the variant constructor) for __accepted_type<_Up> we strip this alias all the way to type _Nth_type<__accepted_index<_Up>>, for which we return NULL since _Nth_type is at namespace scope and so no longer needs rewriting. Note that however the template argument __accepted_index<_Up> of this stripped type _does_ need rewriting (since it specializes a variable template from the current instantiation). We end up not rewriting this variable template reference at any point however because upon returning NULL, the caller (tsubst) proceeds to substitute the original form of the type __accepted_type<_Up>, which doesn't directly refer to __accepted_index. This later leads to an ICE during subsequent alias CTAD rewriting of this guide that contains a non-rewritten reference to __accepted_index. So when maybe_dependent_member_ref decides to not rewrite a class-scope alias that's been stripped, the caller needs to commit to substituting the stripped type rather than the original type. This patch essentially implements that by making maybe_dependent_member_ref call tsubst itself in that case. PR c++/118626 gcc/cp/ChangeLog: * pt.cc (maybe_dependent_member_ref): Substitute and return the stripped type if we decided to not rewrite it directly. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-alias25.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-03-31c++: lambda in function template signature [PR119401]Jason Merrill1-0/+13
Here we instantiate the lambda three times in producing A<0>::f: 1) in tsubst_function_type, substituting the type of A<>::f 2) in tsubst_function_decl, substituting the parameters of A<>::f 3) in regenerate_decl_from_template when instantiating A<>::f The first one gets thrown away by maybe_rebuild_function_decl_type. Before r15-7202, we happily built all of them and mangled the result wrongly as lambda #3. After r15-7202, we try to mangle #3 as #1, which breaks because #1 is already mangled as #1. This patch avoids building #3 by suppressing regenerate_decl_from_template if the template signature includes a lambda, fixing the ICE. We now mangle the lambda as #2, which is still wrong. Addressing that should involve not calling tsubst_function_type from tsubst_function_decl, and building the type from the parms types in the first place rather than fixing it up in maybe_rebuild_function_decl_type. PR c++/119401 gcc/cp/ChangeLog: * pt.cc (regenerate_decl_from_template): Don't regenerate if the signature involves a lambda. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ11.C: New test.
2025-03-29c++/modules: Fix modules and LTO with header units [PR118961]Nathaniel Shead1-9/+18
This patch makes some adjustments required to get a simple modules testcase working with LTO. There are two main issues fixed. Firstly, modules only streams the maybe-in-charge constructor, and any clones are recreated on stream-in. These clones are copied from the existing function decl and then adjusted. This caused issues because the clones were getting incorrectly marked as abstract, since after clones have been created (in the imported file) the maybe-in-charge decl gets marked as abstract. So this patch just ensures that clones are always created as non-abstract. The second issue is that we need to explicitly tell cgraph that explicit instantiations need to be emitted, otherwise LTO will elide them (as they don't necessarily appear to be used directly) and cause link errors. Additionally, expand_or_defer_fn doesn't setup comdat groups for explicit instantiations, so we need to do that here as well. Currently this is all handled in 'mark_decl_instantiated'; this patch splits out the linkage handling into a separate function that we can call from modules code, maybe in GCC16 we could move this somewhere more central. PR c++/118961 gcc/cp/ChangeLog: * class.cc (copy_fndecl_with_name): Mark clones as non-abstract. * cp-tree.h (setup_explicit_instantiation_definition_linkage): Declare new function. * module.cc (trees_in::read_var_def): Use it. (module_state::read_cluster): Likewise. * pt.cc (setup_explicit_instantiation_definition_linkage): New function. (mark_decl_instantiated): Use it. gcc/testsuite/ChangeLog: * g++.dg/modules/lto-1.h: New test. * g++.dg/modules/lto-1_a.H: New test. * g++.dg/modules/lto-1_b.C: New test. * g++.dg/modules/lto-1_c.C: New test. * g++.dg/modules/lto-2_a.H: New test. * g++.dg/modules/lto-2_b.C: New test. * g++.dg/modules/lto-3_a.H: New test. * g++.dg/modules/lto-3_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2025-03-27OpenMP: Fix C++ template handling with append_args' prefer_type modifierTobias Burnus1-2/+7
It is possible but not very sensible to use C++ templates with in the prefer_type modifier to the 'append_args' clause of 'declare variant'. The commit r15-6336-g12dd892b1a3ad7 added substitution support in pt.cc, but missed to update afterward the actual data in decl.cc. As gimplification support was only added in r15-8898-gf016ee89955ab4, this could not be tested back then. The latter commit added a sorry for it gimplify.cc and the existing testcase, which this commit now removes. gcc/cp/ChangeLog: * cp-tree.h (cp_finish_omp_init_prefer_type): Add. * decl.cc (omp_declare_variant_finalize_one): Call it. * pt.cc (tsubst_attribute): Minor rebustification for OpenMP append_args handling. * semantics.cc (cp_omp_init_prefer_type_update): Rename to ... (cp_finish_omp_init_prefer_type): ... this; remove static attribute and return modified tree. Move clause handling to ... (finish_omp_clauses): ... the caller. gcc/ChangeLog: * gimplify.cc (modify_call_for_omp_dispatch): Remove sorry. gcc/testsuite/ChangeLog: * g++.dg/gomp/append-args-1.C: Remove expected dg-sorry. * g++.dg/gomp/append-args-8.C: New test.