aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
AgeCommit message (Collapse)AuthorFilesLines
2025-12-08c++: Document why TARGET_EXPR is not handled in tsubst_exprEgas Ribeiro1-0/+5
TARGET_EXPR represents semantic temporary objects and is deliberately not handled by tsubst routines, which expect syntactic templated trees. Add a comment and gcc_unreachable to make this explicit. gcc/cp/ChangeLog: * pt.cc (tsubst_expr): Add TARGET_EXPR case with explanatory comment and gcc_unreachable. Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt> Reviewed-by: Patrick Palka <ppalka@redhat.com>
2025-12-08c++: Fix SFINAE for deleted explicit specializations [PR119343]Egas Ribeiro1-2/+0
When checking a deleted explicit specialization in a SFINAE context, we were incorrectly selecting a partial specialization because resolve_nondeduced_context was calling mark_used. But resolving an overload to a single function (per DR 115) does not constitute ODR-use, so mark_used shouldn't be called there. Instead callers should call mark_used or mark_single_function on the result to uniformly handle all resolvable overloads (even non-template-id ones). This turns out to fix the below testcase because it causes convert_to_void for void(X::template g<0>) to properly propagate ODR-use failure (due to deleted g<0>) and return error_mark_node instead of returning void_node. PR c++/119343 gcc/cp/ChangeLog: * pt.cc (resolve_nondeduced_context): Remove mark_used call. gcc/testsuite/ChangeLog: * g++.dg/template/sfinae-deleted-pr119343.C: New test. Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt> Reviewed-by: Patrick Palka <ppalka@redhat.com>
2025-12-06c++: is_late_template_attribute and tsubst_attribute fixesJakub Jelinek1-1/+2
This has been discussed in the 1/9 Reflection thread, but doesn't depend on reglection in any way. cp_parser_std_attribute calls lookup_attribute_spec as: const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute)); so with TREE_LIST where TREE_VALUE is attribute name and TREE_PURPOSE attribute ns. Similarly c_parser_std_attribute. And for attribute_takes_identifier_p those do: else if (attr_ns == gnu_identifier && attribute_takes_identifier_p (attr_id)) and bool takes_identifier = (ns != NULL_TREE && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0 && attribute_takes_identifier_p (name)); when handling std attributes (for GNU attributes they just call those with the IDENTIFIER_NODE name. is_late_template_attribute and tsubst_attribute pass to these functions just get_attribute_name though, so handle attributes in all namespaces as GNU attributes only, which means that lookup_attribute_spec can return NULL or find a different attribute if it is not from gnu:: or say standard attribute mapped to gnu::, or attribute_takes_identifier_p can return true even for attributes for which it shouldn't. I thought about changing attribute_takes_identifier_p to take optionally TREE_LIST, but that would mean handling it in the target hooks too and they only care about GNU attributes right now, so given the above parser.cc/c-parser.cc snippets, the following patch just follow what they do. 2025-12-06 Jakub Jelinek <jakub@redhat.com> * decl2.cc (is_late_template_attribute): Call lookup_attribute_spec on TREE_PURPOSE (attr) rather than name. Only call attribute_takes_identifier_p if get_attribute_namespace (attr) is gnu_identifier. * pt.cc (tsubst_attribute): Only call attribute_takes_identifier_p if get_attribute_namespace (t) is gnu_identifier.
2025-12-05OpenMP: C/C++ parser support for dyn_groupprivateTobias Burnus1-0/+1
Follow-up to the Fortran patch r16-5633-g26d41e245dbba3, which (besides other changes) added parser support for the 'dyn_groupprivate' clause to the target directive. This commit adds now the parser support to C/C++ and moves the not-yet-implemented 'sorry' to the early middle end. gcc/c-family/ChangeLog: * c-omp.cc (c_omp_split_clauses): Handle OMP_CLAUSE_DYN_GROUPPRIVATE, sort target clauses alphabetically. * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_clause_dyn_groupprivate): New. (OMP_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE; sort clauses alphabetically. (c_parser_omp_clause_name, c_parser_omp_all_clauses): Handle 'dyn_groupprivate' clause. * c-typeck.cc (c_finish_omp_clauses): Likewise. gcc/cp/ChangeLog: * pt.cc (tsubst_omp_clauses): Handle OMP_CLAUSE_DYN_GROUPPRIVATE. * semantics.cc (finish_omp_clauses): Likewise. * parser.cc (cp_parser_omp_clause_dyn_groupprivate): New. (cp_parser_omp_clause_name, cp_parser_omp_all_clauses): Handle 'dyn_groupprivate' clause. (OMP_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE; sort clauses alphabetically. gcc/fortran/ChangeLog: * openmp.cc (resolve_omp_clauses): Permit zero with DYN_GROUPPRIVATE clause. * trans-openmp.cc (fallback): Generate TREE code for DYN_GROUPPRIVATE and remove 'sorry'. gcc/ChangeLog: * gimplify.cc (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_DYN_GROUPPRIVATE by printing 'sorry, unimplemented'. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DYN_GROUPPRIVATE. (enum omp_clause_fallback_kind): New. (struct tree_omp_clause): Add fallback_kind union member. * tree-nested.cc (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Handle OMP_CLAUSE_DYN_GROUPPRIVATE. * tree.cc (omp_clause_num_ops, omp_clause_code_name): Add OMP_CLAUSE_DYN_GROUPPRIVATE. * tree-pretty-print.cc (dump_omp_clause): Handle OMP_CLAUSE_DYN_GROUPPRIVATE. * tree.h (OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR, OMP_CLAUSE_DYN_GROUPPRIVATE_KIND): New #define. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/dyn_groupprivate-1.f90: Add scan-dump test. * gfortran.dg/gomp/dyn_groupprivate-2.f90: Extend and update. * c-c++-common/gomp/dyn_groupprivate-1.c: New test. * c-c++-common/gomp/dyn_groupprivate-2.c: New test.
2025-12-03c++: fix typoJason Merrill1-4/+4
Thanks to Marek for pointing out my misspelling. gcc/cp/ChangeLog: * pt.cc (dependent_implict_conv_p): Rename to... (dependent_implicit_conv_p): ...this.
2025-12-02c++: alias template parm conv and redecl [PR122171]Jason Merrill1-9/+26
Here when substituting BITS into poly_table convert_template_argument adds an IMPLICIT_CONV_EXPR to represent the conversion to the alias template parameter. In r16-4115 I extended that to value-dependent arguments as well as type-dependent, in case the conversion turns out to be narrowing. tsubst_expr needs the same change so maybe_update_decl_type doesn't replace the IMPLICIT_CONV_EXPR with a NOP_EXPR. The do_auto_deduction change is to avoid a regression in nontype-auto21.C when the first test is changed from uses_template_parms (as it was in convert_template_argument) to dependent_type_p; this mattered because we were failing to resolve the auto return type before deducing the auto non-type parameter type from helper<token>::c. Many other places that call resolve_nondeduced_context similarly then call mark_single_function. PR c++/122171 PR c++/112632 gcc/cp/ChangeLog: * pt.cc (dependent_implict_conv_p): Split out... (convert_template_argument): ...from here. (tsubst_expr) [IMPLICIT_CONV_EXPR]: Use it. (do_auto_deduction): Call mark_single_function. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-conv1.C: New test.
2025-11-26c++: fix crash with pack indexing in noexcept [PR121325]Marek Polacek1-1/+20
In my r15-6792 patch I added a call to tsubst in tsubst_pack_index to fully instantiate args#N in the pack. Here we are in an unevaluated context, but since the pack is a TREE_VEC, we call tsubst_template_args which has cp_evaluated at the beginning. That causes a crash because we trip on the assert in tsubst_expr/PARM_DECL: gcc_assert (cp_unevaluated_operand); because retrieve_local_specialization didn't find anything (becase there are no local_specializations yet). We can avoid the cp_evaluated by calling the new tsubst_tree_vec, which creates a new TREE_VEC and substitutes each element. PR c++/121325 gcc/cp/ChangeLog: * pt.cc (tsubst_tree_vec): New. (tsubst_pack_index): Call it. gcc/testsuite/ChangeLog: * g++.dg/cpp26/pack-indexing18.C: New test. Reviewed-by: Patrick Palka <ppalka@redhat.com>
2025-11-25c++/modules: Walk indirectly exposed namespaces [PR122699]Nathaniel Shead1-6/+5
In some situations, such as friend injection, we may add an entity to a namespace without ever explicitly opening that namespace in this TU. We currently have an additional loop to make sure the namespace is considered purview, but this isn't sufficient to make walk_module_binding find it, since the namspace itself is not in the current TU's symbol table. This patch ensures we still process the (hidden) binding for the injected friend in this TU. PR c++/122699 gcc/cp/ChangeLog: * name-lookup.h (expose_existing_namespace): Declare. * name-lookup.cc (expose_existing_namespace): New function. (push_namespace): Call it. * pt.cc (tsubst_friend_function): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-21_a.C: New test. * g++.dg/modules/tpl-friend-21_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2025-11-22c++: Fix up [[maybe_unused]] handling on expansion stmts [PR122788]Jakub Jelinek1-0/+4
This PR complains that [[maybe_unused]] attribute is ignored on the range-for-declaration of expansion-statement. We copy DECL_ATTRIBUTES and apply late attributes, but early attributes don't have their handlers called again, so some extra flags need to be copied as well. This copies TREE_USED and DECL_READ_P flags. 2025-11-22 Jakub Jelinek <jakub@redhat.com> PR c++/122788 * pt.cc (finish_expansion_stmt): Or in TREE_USED and DECL_READ_P flags from range_decl to decl or from corresponding structured binding to this_decl. * g++.dg/cpp26/expansion-stmt27.C: New test.
2025-11-20c++: Fix error recovery ICE in tsubst_baselink [PR120876]Jakub Jelinek1-13/+13
The following testcase ICEs since r12-6080. The problem is that lookup_fnfields can return NULL_TREE on failure, but the maybe_incomplete handling was added before the if (!baselink) handling and assumes that baselink is non-NULL (and BASELINK). The following patch reorders the if (maybe_incomplete) handling with if (!baselink). 2025-11-20 Jakub Jelinek <jakub@redhat.com> PR c++/120876 * pt.cc (tsubst_baselink): Move maybe_incomplete handling after !baselink handling. * g++.dg/parse/crash81.C: New test.
2025-11-19c++: fix ICE when comparing targs [PR119580]Marek Polacek1-0/+2
In r10-7816, cp_tree_equal/TEMPLATE_ID_EXPR was changed to use comp_template_args to compare the targs. This makes sense, but comp_template_args won't deal with an error_mark_node. We created a BASELINK for S::foo<T::value_type>, but since value_type couldn't be looked up, we ended up with an error_mark_node instead of a TREE_VEC of arguments for the TEMPLATE_ID_EXPR in the BASELINK. It seems reasonable not to create such a TEMPLATE_ID_EXPR by checking the result of tsubst_template_args like we do in so many other places. This changes the diagnostic in three tests, but it's only the followup error message after complaining about the type/value mismatch. PR c++/119580 gcc/cp/ChangeLog: * pt.cc (tsubst_baselink): Return error_mark_node if tsubst_template_args returned error_mark_node. gcc/testsuite/ChangeLog: * g++.dg/template/crash106.C: Adjust expected diagnostics. * g++.dg/template/crash112.C: Likewise. * g++.dg/template/dependent-args1.C: Likewise. * g++.dg/cpp0x/pr119580.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-11-19c++: current inst name lookup within noexcept-spec [PR122668]Patrick Palka1-1/+10
Since we don't implement deferred noexcept-spec parsing of a friend declaration, the r15-2117 change diagnosing name lookup failure for the current instantiation ahead of time needs to be suppressed in this case. PR c++/122668 PR c++/114764 gcc/cp/ChangeLog: * pt.cc (dependentish_scope_p): Return true for the current instantiation from within an immediately parsed noexcept-spec. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept91.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-11-15c++/modules: explicit inst of constructorJason Merrill1-5/+0
The extern template __shared_ptr<filesystem::_Dir> in bits/fs_dir.h was leading to an ICE in import_export_decl in 29_atomics/atomic_ref/address.cc because we had the nonsensical combination of DECL_REALLY_EXTERN and !DECL_INTERFACE_KNOWN. This turned out to be because mark_decl_instantiated was exiting early if TREE_ASM_WRITTEN since way back in the pre-cgraph days, and expand_or_defer_fn_1 sets TREE_ASM_WRITTEN on maybe-in-charge ctors. The mark_decl_instantiated code is long-obsolete, so let's just remove it. gcc/cp/ChangeLog: * module.cc (trees_out::write_function_def): Check flag consistency. * pt.cc (mark_decl_instantiated): Ignore TREE_ASM_WRITTEN.
2025-11-15c++/modules: friend void foo<bar>()Jason Merrill1-3/+1
23_containers/mdspan/layouts/padded.cc was failing because on load we were wrongly treating the __get_static_stride friends as equivalent between layout_left_padded and layout_right_padded. This happened because we were wrongly pushing these declarations into namespace scope even though we don't yet know what template they instantiate. Fixed by using the same MK_local_friend mechanism as template friends. gcc/cp/ChangeLog: * decl.cc (grokfndecl): Set DECL_CHAIN of a friend f<>. * module.cc (trees_out::get_merge_kind): Give it MK_local_friend. (trees_out::decl_container): Its container is the befriender. (trees_out::key_mergeable): Expand comment. * cp-tree.h (decl_specialization_friend_p): New. * friend.cc (do_friend): Use it. * pt.cc (tsubst_friend_function): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/friend-11_a.C: New test. * g++.dg/modules/friend-11_b.C: New test.
2025-11-11c++/modules: Propagate purviewness to all parent namespacesNathaniel Shead1-3/+4
In PR c++/100134, tsubst_friend_function was adjusted to ensure that instantiating a friend function in an unopened namespace still correctly marked the namespace as purview. This adjusts the fix to also apply to nested namespaces. gcc/cp/ChangeLog: * pt.cc (tsubst_friend_function): Mark all parent namespaces as purview if needed. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-8_a.H: Add testcase. * g++.dg/modules/tpl-friend-8_b.C: Add testcase. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2025-11-10c++: Implement C++26 P3920R0 - Wording for NB comment resolution on trivial ↵Jakub Jelinek1-11/+1
relocation Trivial relocation was voted out of C++26, the following patch removes it (note, the libstdc++ part was still waiting for patch review and so doesn't need to be removed). This isn't a mere revert of r16-2206; I've kept -Wc++26-compat option, from earlier patches the non-terminal stays to be class-property-specifier, and I had to partially revert also various follow-up changes, e.g. for modules to handle the new flags and test them, for -Wkeyword-macro etc. to diagnose the conditional keywords or the feature test macro etc. 2025-11-10 Jakub Jelinek <jakub@redhat.com> PR c++/119064 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Revert 2025-07-11 changes. gcc/cp/ * cp-tree.h (struct lang_type): Revert 2025-07-11 changes. (CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT): Remove. (CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED): Remove. (CLASSTYPE_REPLACEABLE_BIT): Remove. (CLASSTYPE_REPLACEABLE_COMPUTED): Remove. (enum virt_specifier): Revert 2025-07-11 changes. (trivially_relocatable_type_p): Remove. (replaceable_type_p): Remove. * cp-trait.def (IS_NOTHROW_RELOCATABLE): Remove. (IS_REPLACEABLE): Remove. (IS_TRIVIALLY_RELOCATABLE): Remove. * parser.cc (cp_parser_class_specifier, cp_parser_class_head): Revert 2025-07-11 changes. * pt.cc (instantiate_class_template): Likewise. * semantics.cc (trait_expr_value): Likewise. (finish_trait_expr): Likewise. * tree.cc (default_movable_type_p): Remove. (union_with_no_declared_special_member_fns): Remove. (trivially_relocatable_type_p): Remove. (replaceable_type_p): Remove. * constraint.cc (diagnose_trait_expr): Revert 2025-07-11 changes. * module.cc (trees_out::lang_type_bools): Revert part of 2025-07-26 changes related to trivial relocatability. (trees_in::lang_type_bools): Likewise. * lex.cc (cxx_init): Don't call cpp_warn on trivially_relocatable_if_eligible and replaceable_if_eligible. gcc/testsuite/ * g++.dg/cpp26/feat-cxx26.C: Revert 2025-07-11 changes. * g++.dg/DRs/dr2581-1.C (__cpp_trivial_relocatability): Remove test. * g++.dg/DRs/dr2581-2.C (__cpp_trivial_relocatability): Likewise. * g++.dg/warn/Wkeyword-macro-1.C: Don't expect any diagnostics on #define or #undef of trivially_relocatable_if_eligible or replaceable_if_eligible. * g++.dg/warn/Wkeyword-macro-2.C: Likewise. * g++.dg/warn/Wkeyword-macro-4.C: Likewise. * g++.dg/warn/Wkeyword-macro-5.C: Likewise. * g++.dg/warn/Wkeyword-macro-7.C: Likewise. * g++.dg/warn/Wkeyword-macro-8.C: Likewise. * g++.dg/cpp26/trivially-relocatable1.C: Remove. * g++.dg/cpp26/trivially-relocatable2.C: Remove. * g++.dg/cpp26/trivially-relocatable3.C: Remove. * g++.dg/cpp26/trivially-relocatable4.C: Remove. * g++.dg/cpp26/trivially-relocatable5.C: Remove. * g++.dg/cpp26/trivially-relocatable6.C: Remove. * g++.dg/cpp26/trivially-relocatable7.C: Remove. * g++.dg/cpp26/trivially-relocatable8.C: Remove. * g++.dg/cpp26/trivially-relocatable9.C: Remove. * g++.dg/cpp26/trivially-relocatable10.C: Remove. * g++.dg/cpp26/trivially-relocatable11.C: Remove. * g++.dg/modules/class-11_a.H: Remove trivial relocatability related parts. * g++.dg/modules/class-11_b.C: Likewise.
2025-11-06c++/modules: Complain on imported GMF TU-local entities in instantiation ↵Nathaniel Shead1-26/+8
[PR121574] An unfortunate side effect of the previous patch is that even with -pedantic-errors, unless the user specifies -Wtemplate-names-tu-local when building the module interface there will be no diagnostic at all from instantiating a template that exposes global TU-local entities, either when building the module or its importer. This patch solves this by recognising imported TU-local dependencies, even if they weren't streamed as TU_LOCAL_ENTITY nodes. The warnings here are deliberately conservative for when we can be sure this was actually an imported TU-local entity; in particular, we bail on any TU-local entity that originated from a header module, without attempting to determine if the entity came via a named module first. PR c++/121574 gcc/cp/ChangeLog: * cp-tree.h (instantiating_tu_local_entity): Declare. * module.cc (is_tu_local_entity): Extract from depset::hash. (is_tu_local_value): Likewise. (has_tu_local_tmpl_arg): Likewise. (depset::hash::is_tu_local_entity): Remove. (depset::hash::has_tu_local_tmpl_arg): Remove. (depset::hash::is_tu_local_value): Remove. (instantiating_tu_local_entity): New function. (depset::hash::add_binding_entity): No longer go through depset::hash to check is_tu_local_entity. * pt.cc (complain_about_tu_local_entity): Remove. (tsubst): Use instantiating_tu_local_entity. (tsubst_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-17_b.C: Check for diagnostics when instantiating imported TU-local entities. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2025-10-09c++: C++26 va_start - part of P3348R4 - C++26 should refer to C23 not C17Jakub Jelinek1-5/+5
The C++26 https://wg21.link/P3348R4 C++26 should refer to C23 not C17 paper among other things changes va_start macro in the similar way how C23 has changed it. Now, unlike C17 and older, C++ has since forever allowed int (...) but just one wasn't able to use va_start/va_arg/va_end in such functions. With the current C++26 draft wording, we'd have to #define va_start(V, ...) __builtin_va_start (V, 0) like we've used for C23 before the PR107980 change. But Jonathan has kindly filed https://cplusplus.github.io/LWG/issue4388 which similarly to C23 will if accepted allow to define it as #define va_start(...) __builtin_c23_va_start(__VA_ARGS__) and let the compiler diagnose undesirable cases (see stdarg6.C testcase in the patch for what it can diagnose, basically anything that isn't either va_start (ap) or va_start (ap, i) where i is the last argument's identifier). This patch implements what assumes LWG4388 will pass. It also defines #define __STDC_VERSION_STDARG_H__ 202311L also for C++26. The hardest part is actually something different. C23 had to differentiate between C99 void foo (); i.e. unspecified arguments (but not stdarg) and the new C23 void bar (...); which is stdarg, but in both cases TYPE_ARG_TYPES (fntype) is NULL. This has been implemented through the new TYPE_NO_NAMED_ARGS_STDARG_P flag, fntypes with that flag set are considered stdarg_p and allow va_start in those, while fntypes with NULL TYPE_ARG_TYPES but the flag cleared are not stdarg_p, can accept any number of arguments but can't use va_start. So, I had to change various places in the C++ FE to pass true as the third argument to build_function_type for calls which are meant to be (...) so that one can actually use va_start in those. Done only for C++26 in order not to disturb older versions too much. And there is a problem with some of the builtins and #pragma weak which are using (...) declarations more in the sense of C17 unspecified arguments rather than this call has variable arguments. So, structural_comptypes now considers the non-C++26 (...) used for selected builtins and #pragma weak incompatible with C++26 (...) to avoid ICEs. 2025-10-09 Jakub Jelinek <jakub@redhat.com> gcc/ * ginclude/stdarg.h (va_start): Use __builtin_c23_va_start also for C++26. (__STDC_VERSION_STDARG_H__): Also define for C++26. gcc/c-family/ * c-common.h (D_CXX26): Define. * c-common.cc (c_common_resword): Add D_CXX26 to __builtin_c23_va_start flags, mention D_CXX26 in comment. gcc/cp/ * cp-tree.h (cp_build_function_type): Declare. * lex.cc: Implement va_start changes from P3348R4 - C++26 should refer to C23 not C17 paper. (init_reswords): Set D_CXX26 in mask for C++23 and older. * parser.cc (cp_parser_primary_expression): Handle RID_C23_VA_START. (cp_parser_builtin_c23_va_start): New function. * cp-objcp-common.cc (names_builtin_p): Likewise. * decl.cc (grokfndecl, check_function_type): Pass TYPE_NO_NAMED_ARGS_STDARG_P as last arg to build_function_type. (grokdeclarator, static_fn_type): Use cp_build_function_type instead of build_function_type. * typeck.cc (merge_types): Likewise. (structural_comptypes): Return false for TYPE_NO_NAMED_ARGS_STDARG_P differences. * lambda.cc (maybe_add_lambda_conv_op): Use cp_build_function_type instead of build_function_type. * tree.cc (cp_build_function_type): New function. (strip_typedefs): Pass TYPE_NO_NAMED_ARGS_STDARG_P as last arg to build_function_type. * name-lookup.cc (push_local_extern_decl_alias): Likewise. * module.cc (trees_in::tree_node): Use cp_build_function_type instead of build_function_type. * pt.cc (copy_default_args_to_explicit_spec, rebuild_function_or_method_type, build_deduction_guide): Likewise. (alias_ctad_tweaks): Pass TYPE_NO_NAMED_ARGS_STDARG_P as last arg to build_function_type. * decl2.cc (change_return_type, cp_reconstruct_complex_type): Likewise. gcc/testsuite/ * c-c++-common/cpp/has-builtin-4.c: Expect __has_builtin (__builtin_c23_va_start) == 1 also for C++26. * c-c++-common/Wvarargs.c (foo3): Don't expect undefined behavior warning for C++26. * g++.dg/cpp26/stdarg1.C: New test. * g++.dg/cpp26/stdarg2.C: New test. * g++.dg/cpp26/stdarg3.C: New test. * g++.dg/cpp26/stdarg4.C: New test. * g++.dg/cpp26/stdarg5.C: New test. * g++.dg/cpp26/stdarg6.C: New test. * g++.dg/cpp26/stdarg7.C: New test. * g++.dg/cpp26/stdarg8.C: New test. * g++.dg/cpp26/stdarg9.C: New test. * g++.dg/opt/pr60849.C (foo): Add explicit cast.
2025-10-04c++: concepts and conversions, take 2 [PR122127]Jason Merrill1-2/+5
My r16-4115 changed convert_template_argument (when called from instantiate_alias_template) to take the maybe_convert_nontype_argument path rather than convert_nontype_argument for this testcase. This meant not folding the use of the by-ref capture in the template argument to constant 1. When we come back to convert_template_argument again when substituting into resize<_Np> we strip the IMPLICIT_CONV_EXPR (since the types are the same) and take the convert_nontype_argument path, but at this point we've pushed into the alias template context and trying to fold away the capture fails because current_lambda_expr() is now null. Taking the convert_nontype_argument path in the same-type case where we would later strip an IMPLICIT_CONV_EXPR fixes the problem. Note that maybe_convert_nontype_argument already shares the same-type check with the stripping, but that isn't enough; it still doesn't fold away the capture proxy. PR c++/122127 PR c++/112632 gcc/cp/ChangeLog: * pt.cc (convert_template_argument): Don't add redundant IMPLICIT_CONV_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-template18.C: New test.
2025-09-27c++: concepts and conversions [PR112632]Jason Merrill1-2/+3
One case missed in my fix for this PR: Here we were omitting the IMPLICIT_CONV_EXPR that expresses the conversion from int to char because the target type was non-dependent and the argument was not type-dependent. But we still need it if the argument is value-dependent. PR c++/112632 gcc/cp/ChangeLog: * pt.cc (convert_template_argument): Also force IMPLICIT_CONV_EXPR if the argument is value-dependent. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-conv4.C: New test.
2025-09-27c++: implicit 'this' in generic lambda [PR122048]Jason Merrill1-1/+2
Here template substitution was replacing a reference to the 'this' of X::f with the implicit closure parameter of the operator(), which is wrong. The closure parameter is never a suitable replacement for a 'this' parameter. PR c++/122048 gcc/cp/ChangeLog: * pt.cc (tsubst_expr): Don't use a lambda current_class_ptr. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/lambda-generic-this6.C: New test.
2025-09-23c++: Fix canonical type for lambda pack captures [PR122015]Nathaniel Shead1-0/+12
comp_template_parms_position uses whether a TEMPLATE_TYPE_PARM is a pack to determine equivalency. This in turn affects whether canonical_type_parameter finds a pre-existing auto type as equivalent. When generating the 'auto...' type for a lambda pack capture, we only mark it as a pack after generating the node (and calculating its canonical); this means that later when comparing a version streamed in from a module we think that two equivalent types have different TYPE_CANONICAL, because the latter already had TEMPLATE_PARM_PARAMETER_PACK set before calculating its canonical. This patch fixes this by using a new 'make_auto_pack' function to ensure that packness is set before the canonical is looked up. PR c++/122015 gcc/cp/ChangeLog: * cp-tree.h (make_auto_pack): Declare. * lambda.cc (lambda_capture_field_type): Use make_auto_pack to ensure TYPE_CANONICAL is set correctly. * pt.cc (make_auto_pack): New function. gcc/testsuite/ChangeLog: * g++.dg/modules/lambda-11.h: New test. * g++.dg/modules/lambda-11_a.H: New test. * g++.dg/modules/lambda-11_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Patrick Palka <ppalka@redhat.com>
2025-09-20c++: find_template_parameters and NTTPs [PR121981]Patrick Palka1-1/+4
Here the normal form of the two immediately-declared D<<placeholder>, V> constraints is the same, so we rightfully share the normal form between them. We first compute the normal form from the context of auto deduction for W in which case the placeholder has level 2 where the set of in-scope template parameters has depth 2 (a dummy level is added from normalize_placeholder_type_constraints). Naturally the atomic constraint only depends on the template parameter V of depth 1 index 0. The depth 2 of current_template_parms however means that find_template_parameters when it sees V within the atomic constraint will recurse into its TREE_TYPE, an auto of level 2, and mark the atomic constraint as also depending on the template parameter of depth 2 index 0, which is clearly wrong. Later during constraint checking for B we ICE within the satisfaction cache since we lack two levels of template arguments supposedly needed by the cached atomic constraint. I think when find_template_parameters sees an NTTP, it doesn't need to walk its TREE_TYPE because NTTP substitution is done obliviously with respect to its type -- only the corresponding NTTP argument matters, not other template arguments possibly used within its type. This is most clearly true for (unconstrained) auto NTTPs as in the testcase, but also true for other NTTPs. Doing so fixes the testcase because we no longer record any depth 2 when walking V within the atomic constraint. PR c++/121981 gcc/cp/ChangeLog: * pt.cc (any_template_parm_r) <case TEMPLATE_TYPE_PARM>: Don't walk TREE_TYPE. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-placeholder15.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2025-09-12c++: 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>
2025-09-07c++: 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>