aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/tree.cc
AgeCommit message (Collapse)AuthorFilesLines
2023-12-13c++: TARGET_EXPR location in default arg [PR96997]Jason Merrill1-0/+3
My r14-6505-g52b4b7d7f5c7c0 change to copy the location in build_aggr_init_expr reopened PR96997; let's fix it properly this time, by clearing the location like we do for other trees. PR c++/96997 gcc/cp/ChangeLog: * tree.cc (bot_manip): Check data.clear_location for TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/debug/cleanup2.C: New test.
2023-12-13c++: copy location to AGGR_INIT_EXPRJason Merrill1-0/+1
When building an AGGR_INIT_EXPR from a CALL_EXPR, we shouldn't lose location information. gcc/cp/ChangeLog: * tree.cc (build_aggr_init_expr): Copy EXPR_LOCATION. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-nsdmi7b.C: Adjust line. * g++.dg/template/copy1.C: Likewise.
2023-12-05Restore build with GCC 4.8 to GCC 5Richard Sandiford1-2/+5
GCC 5 and earlier applied array-to-pointer decay too early, which affected the new attribute namespace code. A reduced example of the construct that the attribute code uses is: struct S { template<__SIZE_TYPE__ N> S(int (&)[N]); }; struct T { int a; S b; }; int a[] = { 1 }; T t = { 1, a }; This was fixed by f85e1317f8ea933f5c615680353bd646f480f7d3 (PR 16333 et al). This patch tries to add a minimally-invasive workaround. gcc/ada/ * gcc-interface/utils.cc (gnat_internal_attribute_table): Add extra braces to work around PR 16333 in older compilers. gcc/ * attribs.cc (handle_ignored_attributes_option): Add extra braces to work around PR 16333 in older compilers. * config/aarch64/aarch64.cc (aarch64_gnu_attribute_table): Likewise. (aarch64_arm_attribute_table): Likewise. * config/arm/arm.cc (arm_gnu_attribute_table): Likewise. * config/i386/i386-options.cc (ix86_gnu_attribute_table): Likewise. * config/ia64/ia64.cc (ia64_gnu_attribute_table): Likewise. * config/rs6000/rs6000.cc (rs6000_gnu_attribute_table): Likewise. * target-def.h (TARGET_GNU_ATTRIBUTES): Likewise. * genhooks.cc (emit_init_macros): Likewise, when emitting the instantiation of TARGET_ATTRIBUTE_TABLE. * langhooks-def.h (LANG_HOOKS_INITIALIZER): Likewise, when instantiating LANG_HOOKS_ATTRIBUTE_TABLE. (LANG_HOOKS_ATTRIBUTE_TABLE): Define to be empty by default. * target.def (attribute_table): Likewise. gcc/c-family/ * c-attribs.cc (c_common_gnu_attribute_table): Add extra braces to work around PR 16333 in older compilers. gcc/c/ * c-decl.cc (std_attribute_table): Add extra braces to work around PR 16333 in older compilers. gcc/cp/ * tree.cc (cxx_gnu_attribute_table): Add extra braces to work around PR 16333 in older compilers. gcc/d/ * d-attribs.cc (d_langhook_common_attribute_table): Add extra braces to work around PR 16333 in older compilers. (d_langhook_gnu_attribute_table): Likewise. gcc/fortran/ * f95-lang.cc (gfc_gnu_attribute_table): Add extra braces to work around PR 16333 in older compilers. gcc/jit/ * dummy-frontend.cc (jit_gnu_attribute_table): Add extra braces to work around PR 16333 in older compilers. (jit_format_attribute_table): Likewise. gcc/lto/ * lto-lang.cc (lto_gnu_attribute_table): Add extra braces to work around PR 16333 in older compilers. (lto_format_attribute_table): Likewise.
2023-12-02Allow target attributes in non-gnu namespacesRichard Sandiford1-6/+10
Currently there are four static sources of attributes: - LANG_HOOKS_ATTRIBUTE_TABLE - LANG_HOOKS_COMMON_ATTRIBUTE_TABLE - LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE - TARGET_ATTRIBUTE_TABLE All of the attributes in these tables go in the "gnu" namespace. This means that they can use the traditional GNU __attribute__((...)) syntax and the standard [[gnu::...]] syntax. Standard attributes are registered dynamically with a null namespace. There are no supported attributes in other namespaces (clang, vendor namespaces, etc.). This patch tries to generalise things by making the namespace part of the attribute specification. It's usual for multiple attributes to be defined in the same namespace, so rather than adding the namespace to each individual definition, it seemed better to group attributes in the same namespace together. This would also allow us to reuse the same table for clang attributes that are written with the GNU syntax, or other similar situations where the attribute can be accessed via multiple "spellings". The patch therefore adds a scoped_attribute_specs that contains a namespace and a list of attributes in that namespace. It's still possible to have multiple scoped_attribute_specs for the same namespace. E.g. it makes sense to keep the C++-specific, C/C++-common, and format-related attributes in separate tables, even though they're all GNU attributes. Current lists of attributes are terminated by a null name. Rather than keep that for the new structure, it seemed neater to use an array_slice. This also makes the tables slighly more compact. In general, a target might want to support attributes in multiple namespaces. Rather than have a separate hook for each possibility (like the three langhooks above), it seemed better to make TARGET_ATTRIBUTE_TABLE a table of tables. Specifically, it's an array_slice of scoped_attribute_specs. We can do the same thing for langhooks, which allows the three hooks above to be merged into a single LANG_HOOKS_ATTRIBUTE_TABLE. It also allows the standard attributes to be registered statically and checked by the usual attribs.cc checks. The patch adds a TARGET_GNU_ATTRIBUTES helper for the common case in which a target wants a single table of gnu attributes. It can only be used if the table is free of preprocessor directives. There are probably other things we need to do to make vendor namespaces work smoothly. E.g. in principle it would be good to make exclusion sets namespace-aware. But to some extent we have that with standard vs. gnu attributes too. This patch is just supposed to be a first step. gcc/ * attribs.h (scoped_attribute_specs): New structure. (register_scoped_attributes): Take a reference to a scoped_attribute_specs instead of separate namespace and array parameters. * plugin.h (register_scoped_attributes): Likewise. * attribs.cc (register_scoped_attributes): Likewise. (attribute_tables): Change into an array of scoped_attribute_specs pointers. Reduce to 1 element for frontends and 1 element for targets. (empty_attribute_table): Delete. (check_attribute_tables): Update for changes to attribute_tables. Use a hash_set to identify duplicates. (handle_ignored_attributes_option): Update for above changes. (init_attributes): Likewise. (excl_pair): Delete. (test_attribute_exclusions): Update for above changes. Don't enforce symmetry for standard attributes in the top-level namespace. * langhooks-def.h (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE): Likewise. (LANG_HOOKS_INITIALIZER): Update accordingly. (LANG_HOOKS_ATTRIBUTE_TABLE): Define to an empty constructor. * langhooks.h (lang_hooks::common_attribute_table): Delete. (lang_hooks::format_attribute_table): Likewise. (lang_hooks::attribute_table): Redefine to an array of scoped_attribute_specs pointers. * target-def.h (TARGET_GNU_ATTRIBUTES): New macro. * target.def (attribute_spec): Redefine to return an array of scoped_attribute_specs pointers. * tree-inline.cc (function_attribute_inlinable_p): Update accordingly. * doc/tm.texi: Regenerate. * config/aarch64/aarch64.cc (aarch64_attribute_table): Define using TARGET_GNU_ATTRIBUTES. * config/alpha/alpha.cc (vms_attribute_table): Likewise. * config/avr/avr.cc (avr_attribute_table): Likewise. * config/bfin/bfin.cc (bfin_attribute_table): Likewise. * config/bpf/bpf.cc (bpf_attribute_table): Likewise. * config/csky/csky.cc (csky_attribute_table): Likewise. * config/epiphany/epiphany.cc (epiphany_attribute_table): Likewise. * config/gcn/gcn.cc (gcn_attribute_table): Likewise. * config/h8300/h8300.cc (h8300_attribute_table): Likewise. * config/loongarch/loongarch.cc (loongarch_attribute_table): Likewise. * config/m32c/m32c.cc (m32c_attribute_table): Likewise. * config/m32r/m32r.cc (m32r_attribute_table): Likewise. * config/m68k/m68k.cc (m68k_attribute_table): Likewise. * config/mcore/mcore.cc (mcore_attribute_table): Likewise. * config/microblaze/microblaze.cc (microblaze_attribute_table): Likewise. * config/mips/mips.cc (mips_attribute_table): Likewise. * config/msp430/msp430.cc (msp430_attribute_table): Likewise. * config/nds32/nds32.cc (nds32_attribute_table): Likewise. * config/nvptx/nvptx.cc (nvptx_attribute_table): Likewise. * config/riscv/riscv.cc (riscv_attribute_table): Likewise. * config/rl78/rl78.cc (rl78_attribute_table): Likewise. * config/rx/rx.cc (rx_attribute_table): Likewise. * config/s390/s390.cc (s390_attribute_table): Likewise. * config/sh/sh.cc (sh_attribute_table): Likewise. * config/sparc/sparc.cc (sparc_attribute_table): Likewise. * config/stormy16/stormy16.cc (xstormy16_attribute_table): Likewise. * config/v850/v850.cc (v850_attribute_table): Likewise. * config/visium/visium.cc (visium_attribute_table): Likewise. * config/arc/arc.cc (arc_attribute_table): Likewise. Move further down file. * config/arm/arm.cc (arm_attribute_table): Update for above changes, using... (arm_gnu_attributes, arm_gnu_attribute_table): ...these new globals. * config/i386/i386-options.h (ix86_attribute_table): Delete. (ix86_gnu_attribute_table): Declare. * config/i386/i386-options.cc (ix86_attribute_table): Replace with... (ix86_gnu_attributes, ix86_gnu_attribute_table): ...these two globals. * config/i386/i386.cc (ix86_attribute_table): Define as an array of scoped_attribute_specs pointers. * config/ia64/ia64.cc (ia64_attribute_table): Update for above changes, using... (ia64_gnu_attributes, ia64_gnu_attribute_table): ...these new globals. * config/rs6000/rs6000.cc (rs6000_attribute_table): Update for above changes, using... (rs6000_gnu_attributes, rs6000_gnu_attribute_table): ...these new globals. gcc/ada/ * gcc-interface/gigi.h (gnat_internal_attribute_table): Change type to scoped_attribute_specs. * gcc-interface/utils.cc (gnat_internal_attribute_table): Likewise, using... (gnat_internal_attributes): ...this as the underlying array. * gcc-interface/misc.cc (gnat_attribute_table): New global. (LANG_HOOKS_ATTRIBUTE_TABLE): Use it. gcc/c-family/ * c-common.h (c_common_attribute_table): Replace with... (c_common_gnu_attribute_table): ...this. (c_common_format_attribute_table): Change type to scoped_attribute_specs. * c-attribs.cc (c_common_attribute_table): Replace with... (c_common_gnu_attributes, c_common_gnu_attribute_table): ...these new globals. (c_common_format_attribute_table): Change type to scoped_attribute_specs, using... (c_common_format_attributes): ...this as the underlying array. gcc/c/ * c-tree.h (std_attribute_table): Declare. * c-decl.cc (std_attribute_table): Change type to scoped_attribute_specs, using... (std_attributes): ...this as the underlying array. (c_init_decl_processing): Remove call to register_scoped_attributes. * c-objc-common.h (c_objc_attribute_table): New global. (LANG_HOOKS_ATTRIBUTE_TABLE): Use it. (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE): Delete. gcc/cp/ * cp-tree.h (cxx_attribute_table): Delete. (cxx_gnu_attribute_table, std_attribute_table): Declare. * cp-objcp-common.h (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE): Delete. (cp_objcp_attribute_table): New table. (LANG_HOOKS_ATTRIBUTE_TABLE): Redefine. * tree.cc (cxx_attribute_table): Replace with... (cxx_gnu_attributes, cxx_gnu_attribute_table): ...these globals. (std_attribute_table): Change type to scoped_attribute_specs, using... (std_attributes): ...this as the underlying array. (init_tree): Remove call to register_scoped_attributes. gcc/d/ * d-tree.h (d_langhook_attribute_table): Replace with... (d_langhook_gnu_attribute_table): ...this. (d_langhook_common_attribute_table): Change type to scoped_attribute_specs. * d-attribs.cc (d_langhook_common_attribute_table): Change type to scoped_attribute_specs, using... (d_langhook_common_attributes): ...this as the underlying array. (d_langhook_attribute_table): Replace with... (d_langhook_gnu_attributes, d_langhook_gnu_attribute_table): ...these new globals. (uda_attribute_p): Update accordingly, and update for new targetm.attribute_table type. * d-lang.cc (d_langhook_attribute_table): New global. (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Delete. gcc/fortran/ * f95-lang.cc: Include attribs.h. (gfc_attribute_table): Change to an array of scoped_attribute_specs pointers, using... (gfc_gnu_attributes, gfc_gnu_attribute_table): ...these new globals. gcc/jit/ * dummy-frontend.cc (jit_format_attribute_table): Change type to scoped_attribute_specs, using... (jit_format_attributes): ...this as the underlying array. (jit_attribute_table): Change to an array of scoped_attribute_specs pointers, using... (jit_gnu_attributes, jit_gnu_attribute_table): ...these new globals for the original array. Include the format attributes. (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_ATTRIBUTE_TABLE): Define. gcc/lto/ * lto-lang.cc (lto_format_attribute_table): Change type to scoped_attribute_specs, using... (lto_format_attributes): ...this as the underlying array. (lto_attribute_table): Change to an array of scoped_attribute_specs pointers, using... (lto_gnu_attributes, lto_gnu_attribute_table): ...these new globals for the original array. Include the format attributes. (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE): Delete. (LANG_HOOKS_ATTRIBUTE_TABLE): Define.
2023-11-15c++, analyzer: Expand CAN_HAVE_LOCATION_P macro.Bernhard Reutner-Fischer1-1/+1
r14-985-gca2007a9bb3074 used the collapsed macro definition CAN_HAVE_LOCATION_P in gcc-rich-location.cc and r14-977-g8861c80733da5c in c++'s build_cplus_array_type (). However, although otherwise correct, the usage of CAN_HAVE_LOCATION_P in these two spots is misleading, so this patch reverts aforementioned two hunks. gcc/cp/ChangeLog: * tree.cc (build_cplus_array_type): Revert using the macro CAN_HAVE_LOCATION_P. gcc/ChangeLog: * gcc-rich-location.cc (maybe_range_label_for_tree_type_mismatch::get_text): Revert using the macro CAN_HAVE_LOCATION_P.
2023-11-15c++: partially inst requires-expr in noexcept-spec [PR101043]Patrick Palka1-7/+12
Here we're ICEing from strip_typedefs for the partially instantiated requires-expression when walking its REQUIRES_EXPR_EXTRA_ARGS which in this case is a TREE_LIST with non-empty TREE_PURPOSE (to hold the captured local specialization 't' as per build_extra_args) which strip_typedefs doesn't expect. We can probably skip walking REQUIRES_EXPR_EXTRA_ARGS at all since it shouldn't contain any typedefs in the first place, but it seems safer and more generally useful to just teach strip_typedefs to handle non-empty TREE_PURPOSE the obvious way. (The code asserts TREE_PURPOSE was empty even since since its inception i.e. r189298.) PR c++/101043 gcc/cp/ChangeLog: * tree.cc (strip_typedefs_expr) <case TREE_LIST>: Handle non-empty TREE_PURPOSE. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires37.C: New test.
2023-11-15c++: non-dependent .* operand folding [PR112427]Patrick Palka1-1/+10
Here when building up the non-dependent .* expression, we crash from fold_convert on 'b.a' due to this (templated) COMPONENT_REF having an IDENTIFIER_NODE instead of FIELD_DECL operand that middle-end routines expect. Like in r14-4899-gd80a26cca02587, this patch fixes this by replacing the problematic piecemeal folding with a single call to cp_fully_fold. Also, don't bother building the POINTER_PLUS_EXPR in a template context. This means the returned non-dependent tree might not have TREE_SIDE_EFFECTS set when it used to, so we need to compensate by making build_min_non_dep propagate TREE_SIDE_EFFECTS from the original arguments like buildN and build_min do. PR c++/112427 gcc/cp/ChangeLog: * tree.cc (build_min_non_dep): Propagate TREE_SIDE_EFFECTS from the original arguments. (build_min_non_dep_call_vec): Likewise. * typeck2.cc (build_m_component_ref): Use cp_convert, build2 and cp_fully_fold instead of fold_build_pointer_plus and fold_convert. Don't build the POINTER_PLUS_EXPR in a template context. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent29.C: New test.
2023-10-24c++: cp_stabilize_reference and non-dep exprs [PR111919]Patrick Palka1-0/+4
After the removal of NON_DEPENDENT_EXPR, cp_stabilize_reference (which used to just exit early for NON_DEPENDENT_EXPR) is now more prone to passing a weird templated tree to middle-end routines, which for the testcase below leads to a crash from contains_placeholder_p. It seems the best fix is to just exit early when in a template context, like we do in the closely related function cp_save_expr. PR c++/111919 gcc/cp/ChangeLog: * tree.cc (cp_stabilize_reference): Do nothing when processing_template_decl. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent27.C: New test.
2023-10-20c++: remove NON_DEPENDENT_EXPR, part 1Patrick Palka1-5/+0
This tree code dates all the way back to r69130[1] which implemented typing of non-dependent expressions. Its motivation was never clear (to me at least) since its documentation in e.g. cp-tree.def doesn't seem accurate anymore. build_non_dependent_expr has since gained a bunch of edge cases about whether or how to wrap certain templated trees, making it hard to reason about in general. So this patch removes this tree code, and temporarily turns build_non_dependent_expr into the identity function. The subsequent patch will remove build_non_dependent_expr and adjust its callers appropriately. We now need to more thoroughly handle templated (sub)trees in a couple of places which previously didn't need to since they didn't look through NON_DEPENDENT_EXPR. [1]: https://gcc.gnu.org/pipermail/gcc-patches/2003-July/109355.html gcc/c-family/ChangeLog: * c-warn.cc (check_address_or_pointer_of_packed_member): Handle type-dependent callee of CALL_EXPR. gcc/cp/ChangeLog: * class.cc (instantiate_type): Remove NON_DEPENDENT_EXPR handling. * constexpr.cc (cxx_eval_constant_expression): Likewise. (potential_constant_expression_1): Likewise. * coroutines.cc (coro_validate_builtin_call): Don't expect ALIGNOF_EXPR to be wrapped in NON_DEPENDENT_EXPR. * cp-objcp-common.cc (cp_common_init_ts): Remove NON_DEPENDENT_EXPR handling. * cp-tree.def (NON_DEPENDENT_EXPR): Remove. * cp-tree.h (build_non_dependent_expr): Temporarily redefine as the identity function. * cvt.cc (maybe_warn_nodiscard): Handle type-dependent and variable callee of CALL_EXPR. * cxx-pretty-print.cc (cxx_pretty_printer::expression): Remove NON_DEPENDENT_EXPR handling. * error.cc (dump_decl): Likewise. (dump_expr): Likewise. * expr.cc (mark_use): Likewise. (mark_exp_read): Likewise. * pt.cc (build_non_dependent_expr): Remove. * tree.cc (lvalue_kind): Remove NON_DEPENDENT_EXPR handling. (cp_stabilize_reference): Likewise. * typeck.cc (warn_for_null_address): Likewise. (cp_build_binary_op): Handle type-dependent SIZEOF_EXPR operands. (cp_build_unary_op) <case TRUTH_NOT_EXPR>: Don't fold inside a template. gcc/testsuite/ChangeLog: * g++.dg/concepts/var-concept3.C: Adjust expected diagnostic for attempting to call a variable concept. Reviewed-by: Jason Merrill <jason@redhat.com>
2023-09-19c++: Move consteval folding to cp_fold_rMarek Polacek1-22/+1
In the review of P2564: <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628747.html> it turned out that in order to correctly handle an example in the paper, we should stop doing immediate evaluation in build_over_call and bot_replace, and instead do it in cp_fold_r. This patch does that. Another benefit is that this is a pretty significant simplification, at least in my opinion. Also, this fixes the c++/110997 ICE (but the test doesn't compile yet). The main drawback seems to be that cp_fold_r doesn't process uninstantiated templates. We still have to handle things like "false ? foo () : 1". To that end, I've added cp_fold_immediate, called on dead branches in cxx_eval_conditional_expression. You'll see that I've reintroduced ADDR_EXPR_DENOTES_CALL_P here. This is to detect *(&foo)) () (s.*&S::foo) () which were deemed ill-formed. gcc/cp/ChangeLog: * call.cc (build_over_call): Set ADDR_EXPR_DENOTES_CALL_P. Don't handle immediate_invocation_p here. * constexpr.cc (cxx_eval_call_expression): Use mce_true for DECL_IMMEDIATE_FUNCTION_P. (cxx_eval_conditional_expression): Call cp_fold_immediate. * cp-gimplify.cc (enum fold_flags): Add ff_fold_immediate. (maybe_replace_decl): Make static. (cp_fold_r): Expand immediate invocations. (cp_fold_immediate_r): New. (cp_fold_immediate): New. * cp-tree.h (ADDR_EXPR_DENOTES_CALL_P): Define. (cp_fold_immediate): Declare. * tree.cc (bot_replace): Don't handle immediate invocations here. libstdc++-v3/ChangeLog: * testsuite/20_util/allocator/105975.cc: Add dg-error. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if2.C: Add xfail. * g++.dg/cpp2a/consteval-memfn1.C: Adjust. * g++.dg/cpp2a/consteval11.C: Remove dg-message. * g++.dg/cpp2a/consteval3.C: Remove dg-message and dg-error. * g++.dg/cpp2a/consteval9.C: Remove dg-message. * g++.dg/cpp2a/consteval32.C: New test. * g++.dg/cpp2a/consteval33.C: New test. * g++.dg/cpp2a/consteval34.C: New test. * g++.dg/cpp2a/consteval35.C: New test.
2023-06-13c++: mutable temps in rodataJason Merrill1-0/+1
If the type of a temporary has mutable members, we can't set TREE_READONLY on the VAR_DECL; this is parallel to the check in cp_apply_type_quals_to_decl. gcc/cp/ChangeLog: * tree.cc (build_target_expr): Check TYPE_HAS_MUTABLE_P. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt6.C: New test.
2023-06-12c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-2/+0
I previously applied this change in r13-4565 but reverted it due to PR108071. That PR was then fixed by r13-4712, but I didn't re-apply this change then because we weren't making the array static; since r14-1500 for PR110070 we now make the initializer array static, so let's bring this back. In situations where the maybe_init_list_as_range optimization isn't viable, we can build an initializer_list<string> with a loop over a constant array of string literals. This is represented using a VEC_INIT_EXPR, which required adjusting a couple of places that expected the initializer array to have the same type as the target array and fixing build_vec_init not to undo our efforts. PR c++/105838 gcc/cp/ChangeLog: * call.cc (convert_like_internal) [ck_list]: Use maybe_init_list_as_array. * constexpr.cc (cxx_eval_vec_init_1): Init might have a different type. * tree.cc (build_vec_init_elt): Likewise. * init.cc (build_vec_init): Handle from_array from a TARGET_EXPR. Retain TARGET_EXPR of a different type. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt5.C: New test.
2023-06-02c++: make initializer_list array static again [PR110070]Jason Merrill1-1/+8
After the maybe_init_list_as_* patches, I noticed that we were putting the array of strings into .rodata, but then memcpying it into an automatic array, which is pointless; we should be able to use it directly. This doesn't happen automatically because TREE_ADDRESSABLE is set (since r12-657 for PR100464), and so gimplify_init_constructor won't promote the variable to static. Theoretically we could do escape analysis to recognize that the address, though taken, never leaves the function; that would allow promotion when we're only using the address for indexing within the function, as in initlist-opt2.C. But this would be a new pass. And in initlist-opt1.C, we're passing the array address to another function, so it definitely escapes; it's only safe in this case because it's calling a standard library function that we know only uses it for indexing. So, a flag seems needed. I first thought to put the flag on the TARGET_EXPR, but the VAR_DECL seems more appropriate. In a previous revision of the patch I called this flag DECL_NOT_OBSERVABLE, but I think DECL_MERGEABLE is a better name, especially if we're going to apply it to the backing array of initializer_list, which is observable. I then also check it in places that check for -fmerge-all-constants, so that multiple equivalent initializer-lists can also be combined. And then it seemed to make sense for [[no_unique_address]] to have this meaning for user-written variables. I think the note in [dcl.init.list]/6 intended to allow this kind of merging for initializer_lists, but it didn't actually work; for an explicit array with the same initializer, if the address escapes the program could tell whether the same variable in two frames have the same address. P2752 is trying to correct this defect, so I'm going to assume that this is the intent. PR c++/110070 PR c++/105838 gcc/ChangeLog: * tree.h (DECL_MERGEABLE): New. * tree-core.h (struct tree_decl_common): Mention it. * gimplify.cc (gimplify_init_constructor): Check it. * cgraph.cc (symtab_node::address_can_be_compared_p): Likewise. * varasm.cc (categorize_decl_for_section): Likewise. gcc/cp/ChangeLog: * call.cc (maybe_init_list_as_array): Set DECL_MERGEABLE. (convert_like_internal) [ck_list]: Set it. (set_up_extended_ref_temp): Copy it. * tree.cc (handle_no_unique_addr_attribute): Set it. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt1.C: Check for static array. * g++.dg/tree-ssa/initlist-opt2.C: Likewise. * g++.dg/tree-ssa/initlist-opt4.C: New test. * g++.dg/opt/icf1.C: New test. * g++.dg/opt/icf2.C: New test. * g++.dg/opt/icf3.C: New test. * g++.dg/tree-ssa/array-temp1.C: Revert r12-657 change.
2023-05-18c++: use _P() defines from tree.hBernhard Reutner-Fischer1-2/+2
gcc/cp/ChangeLog: * call.cc (promoted_arithmetic_type_p): Use _P defines from tree.h. (build_conditional_expr): Ditto. (convert_like_internal): Ditto. (convert_arg_to_ellipsis): Ditto. (build_over_call): Ditto. (compare_ics): Ditto. * class.cc (is_empty_base_ref): Ditto. * coroutines.cc (rewrite_param_uses): Ditto. * cp-tree.h (DECL_DISCRIMINATOR_P): Ditto. (ARITHMETIC_TYPE_P): Ditto. * cvt.cc (ocp_convert): Ditto. * cxx-pretty-print.cc (pp_cxx_template_argument_list): Ditto. * decl.cc (layout_var_decl): Ditto. (get_tuple_size): Ditto. * error.cc (dump_simple_decl): Ditto. * lambda.cc (start_lambda_scope): Ditto. * mangle.cc (write_template_arg): Ditto. * method.cc (spaceship_comp_cat): Ditto. * module.cc (node_template_info): Ditto. (trees_out::start): Ditto. (trees_out::decl_node): Ditto. (trees_in::read_var_def): Ditto. (set_instantiating_module): Ditto. * name-lookup.cc (maybe_record_mergeable_decl): Ditto. (consider_decl): Ditto. (maybe_add_fuzzy_decl): Ditto. * pt.cc (convert_nontype_argument): Ditto. * semantics.cc (handle_omp_array_sections_1): Ditto. (finish_omp_clauses): Ditto. (finish_omp_target_clauses_r): Ditto. (is_this_parameter): Ditto. * tree.cc (build_cplus_array_type): Ditto. (is_this_expression): Ditto. * typeck.cc (do_warn_enum_conversions): Ditto. * typeck2.cc (store_init_value): Ditto. (check_narrowing): Ditto.
2023-04-24c++, tree: declare some basic functions inlinePatrick Palka1-24/+0
The functions strip_array_types, is_typedef_decl, typedef_variant_p and cp_expr_location are used throughout the C++ front end including in some fairly hot parts (e.g. in the tsubst routines and cp_walk_subtree) and they're small enough that the overhead of calling them out-of-line is relatively significant. So this patch moves their definitions into the appropriate headers to enable inlining them. gcc/cp/ChangeLog: * cp-tree.h (cp_expr_location): Define here. * tree.cc (cp_expr_location): Don't define here. gcc/ChangeLog: * tree.cc (strip_array_types): Don't define here. (is_typedef_decl): Don't define here. (typedef_variant_p): Don't define here. * tree.h (strip_array_types): Define here. (is_typedef_decl): Define here. (typedef_variant_p): Define here.
2023-04-21c++, tree: optimize walk_tree_1 and cp_walk_subtreesPatrick Palka1-66/+68
These functions currently repeatedly dereference tp during the subtree walks, dereferences which the compiler can't CSE because it can't guarantee that the subtree walking doesn't modify *tp. But we already implicitly require that TREE_CODE (*tp) remains the same throughout the subtree walks, so it doesn't seem to be a huge leap to strengthen that to requiring *tp remains the same. So this patch manually CSEs the dereferences of *tp. This means that a callback function can no longer replace *tp with another tree (of the same TREE_CODE) when walking one of its subtrees, but that doesn't sound like a useful capability anyway. gcc/cp/ChangeLog: * tree.cc (cp_walk_subtrees): Avoid repeatedly dereferencing tp. <case DECLTYPE_TYPE>: Use cp_unevaluated and WALK_SUBTREE. <case ALIGNOF_EXPR etc>: Likewise. gcc/ChangeLog: * tree.cc (walk_tree_1): Avoid repeatedly dereferencing tp and type_p.
2023-04-20c++: make strip_typedefs generalize strip_typedefs_exprPatrick Palka1-59/+25
Currently if we have a TREE_VEC of types that we want to strip of typedefs, we unintuitively need to call strip_typedefs_expr instead of strip_typedefs since only strip_typedefs_expr handles TREE_VEC, and it also dispatches to strip_typedefs when given a type. But this seems backwards: arguably strip_typedefs_expr should be the more specialized function, which strip_typedefs dispatches to (and thus generalizes). So this patch makes strip_typedefs subsume strip_typedefs_expr rather than vice versa, which allows for some simplifications. gcc/cp/ChangeLog: * tree.cc (strip_typedefs): Move TREE_LIST handling to strip_typedefs_expr. Dispatch to strip_typedefs_expr for non-type 't'. <case TYPENAME_TYPE>: Remove manual dispatching to strip_typedefs_expr. <case TRAIT_TYPE>: Likewise. (strip_typedefs_expr): Replaces calls to strip_typedefs_expr with strip_typedefs throughout. Don't dispatch to strip_typedefs for type 't'. <case TREE_LIST>: Replace this with the better version from strip_typedefs.
2023-04-19c++: Define built-in for std::tuple_element [PR100157]Patrick Palka1-3/+7
This adds a new built-in to replace the recursive class template instantiations done by traits such as std::tuple_element and std::variant_alternative. The purpose is to select the Nth type from a list of types, e.g. __type_pack_element<1, char, int, float> is int. We implement it as a special kind of TRAIT_TYPE. For a pathological example tuple_element_t<1000, tuple<2000 types...>> the compilation time is reduced by more than 90% and the memory used by the compiler is reduced by 97%. In realistic examples the gains will be much smaller, but still relevant. Unlike the other built-in traits, __type_pack_element uses template-id syntax instead of call syntax and is SFINAE-enabled, matching Clang's implementation. And like the other built-in traits, it's not mangleable so we can't use it directly in function signatures. N.B. Clang seems to implement __type_pack_element as a first-class template that can e.g. be used as a template-template argument. For simplicity we implement it in a more ad-hoc way. Co-authored-by: Jonathan Wakely <jwakely@redhat.com> PR c++/100157 gcc/cp/ChangeLog: * cp-trait.def (TYPE_PACK_ELEMENT): Define. * cp-tree.h (finish_trait_type): Add complain parameter. * cxx-pretty-print.cc (pp_cxx_trait): Handle CPTK_TYPE_PACK_ELEMENT. * parser.cc (cp_parser_constant_expression): Document default arguments. (cp_parser_trait): Handle CPTK_TYPE_PACK_ELEMENT. Pass tf_warning_or_error to finish_trait_type. * pt.cc (tsubst) <case TRAIT_TYPE>: Handle non-type first argument. Pass complain to finish_trait_type. * semantics.cc (finish_type_pack_element): Define. (finish_trait_type): Add complain parameter. Handle CPTK_TYPE_PACK_ELEMENT. * tree.cc (strip_typedefs): Handle non-type first argument. Pass tf_warning_or_error to finish_trait_type. * typeck.cc (structural_comptypes) <case TRAIT_TYPE>: Use cp_tree_equal instead of same_type_p for the first argument. libstdc++-v3/ChangeLog: * include/bits/utility.h (_Nth_type): Conditionally define in terms of __type_pack_element if available. * testsuite/20_util/tuple/element_access/get_neg.cc: Prune additional errors from the new built-in. gcc/testsuite/ChangeLog: * g++.dg/ext/type_pack_element1.C: New test. * g++.dg/ext/type_pack_element2.C: New test. * g++.dg/ext/type_pack_element3.C: New test.
2023-03-14c++: Treat unnamed bitfields as padding for ↵Jakub Jelinek1-2/+2
__has_unique_object_representations [PR109096] As reported in the PR, for __has_unique_object_representations we were treating unnamed bitfields as named ones, which is wrong, they are actually padding. THe following patch fixes that. 2023-03-14 Jakub Jelinek <jakub@redhat.com> PR c++/109096 * tree.cc (record_has_unique_obj_representations): Ignore unnamed bitfields. * g++.dg/cpp1z/has-unique-obj-representations3.C: New test.
2023-03-09c++: add __is_deducible trait [PR105841]Jason Merrill1-1/+1
C++20 class template argument deduction for an alias template involves adding a constraint that the template arguments for the alias template can be deduced from the return type of the deduction guide for the underlying class template. In the standard, this is modeled as defining a class template with a partial specialization, but it's much more efficient to implement with a trait that directly tries to perform the deduction. The first argument to the trait is a template rather than a type, so various places needed to be adjusted to accommodate that. PR c++/105841 gcc/ChangeLog: * doc/extend.texi (Type Traits):: Document __is_deducible. gcc/cp/ChangeLog: * cp-trait.def (IS_DEDUCIBLE): New. * cxx-pretty-print.cc (pp_cxx_trait): Handle non-type. * parser.cc (cp_parser_trait): Likewise. * tree.cc (cp_tree_equal): Likewise. * pt.cc (tsubst_copy_and_build): Likewise. (type_targs_deducible_from): New. (alias_ctad_tweaks): Use it. * semantics.cc (trait_expr_value): Handle CPTK_IS_DEDUCIBLE. (finish_trait_expr): Likewise. * constraint.cc (diagnose_trait_expr): Likewise. * cp-tree.h (type_targs_deducible_from): Declare. gcc/testsuite/ChangeLog: * g++.dg/ext/is_deducible1.C: New test.
2023-02-05c++: equivalence of non-dependent calls [PR107461]Patrick Palka1-5/+19
After r13-5684-g59e0376f607805 the (pruned) callee of a non-dependent CALL_EXPR is a bare FUNCTION_DECL rather than ADDR_EXPR of FUNCTION_DECL. This innocent change revealed that cp_tree_equal doesn't first check dependence of a CALL_EXPR before treating a FUNCTION_DECL callee as a dependent name, which leads to us incorrectly accepting the first two testcases below and rejecting the third: * In the first testcase, cp_tree_equal incorrectly returns true for the two non-dependent CALL_EXPRs f(0) and f(0) (whose CALL_EXPR_FN are different FUNCTION_DECLs) which causes us to treat #2 as a redeclaration of #1. * Same issue in the second testcase, for f<int*>() and f<char>(). * In the third testcase, cp_tree_equal incorrectly returns true for f<int>() and f<void(*)(int)>() which causes us to conflate the two dependent specializations A<decltype(f<int>()(U()))> and A<decltype(f<void(*)(int)>()(U()))>. This patch fixes this by making called_fns_equal treat two callees as dependent names only if the overall CALL_EXPRs are dependent, via a new convenience function call_expr_dependent_name that is like dependent_name but also checks dependence of the overall CALL_EXPR. PR c++/107461 gcc/cp/ChangeLog: * cp-tree.h (call_expr_dependent_name): Declare. * pt.cc (iterative_hash_template_arg) <case CALL_EXPR>: Use call_expr_dependent_name instead of dependent_name. * tree.cc (call_expr_dependent_name): Define. (called_fns_equal): Adjust to take two CALL_EXPRs instead of CALL_EXPR_FNs thereof. Use call_expr_dependent_name instead of dependent_name. (cp_tree_equal) <case CALL_EXPR>: Adjust call to called_fns_equal. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/overload5.C: New test. * g++.dg/cpp0x/overload5a.C: New test. * g++.dg/cpp0x/overload6.C: New test.
2023-01-19c++: Fix up handling of non-dependent subscript with static operator[] ↵Jakub Jelinek1-7/+23
[PR108437] As the following testcases shows, when adding static operator[] support I've missed that the 2 build_min_non_dep_op_overload functions need to be adjusted. The first one we only use for the single index case, but as cp_tree_code_length (ARRAY_REF) is 2, we were running into an assertion there which compared nargs and expected_nargs. For ARRAY_REF, the operator[] is either a non-static member or newly static member, never out of class and for the static member case if user uses single index the operator[] needs to have a single argument as well, but the function is called with 2 - the object it is invoked on and the index. We need to evaluate side-effects of the object and use just a single argument in the call - the index. The other build_min_non_dep_op_overload overload has been added solely for ARRAY_REF - CALL_EXPR is the other operator that accepts variable number of operands but that one goes through different routines. There we asserted it is a METHOD_TYPE, so again we shouldn't assert that but handle the case when it is not one by making sure object's side-effects are evaluated if needed and passing all the index arguments to the static operator[]. 2023-01-19 Jakub Jelinek <jakub@redhat.com> PR c++/108437 * cp-tree.h (keep_unused_object_arg): Declare. * call.cc (keep_unused_object_arg): No longer static. * tree.cc (build_min_non_dep_op_overload): Handle ARRAY_REF with overload being static member function. * g++.dg/cpp23/subscript12.C: New test. * g++.dg/cpp23/subscript13.C: New test.
2023-01-16Update copyright years.Jakub Jelinek1-1/+1
2022-12-23c++: get_nsdmi in template context [PR108116]Patrick Palka1-0/+4
Here during ahead of time checking of C{}, we indirectly call get_nsdmi for C::m from finish_compound_literal, which in turn calls break_out_target_exprs for C::m's (non-templated) initializer, during which we build a call to A::~A and check expr_noexcept_p for it (from build_vec_delete_1). But this is all done with processing_template_decl set, so the built A::~A call is templated (whose form was recently changed by r12-6897-gdec8d0e5fa00ceb2) which expr_noexcept_p doesn't expect, and we crash. This patch fixes this by clearing processing_template_decl before the call to break_out_target_exprs from get_nsdmi. And since it more generally seems we shouldn't be seeing (or producing) non-templated trees in break_out_target_exprs, this patch also adds an assert to that effect. PR c++/108116 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_value): Clear processing_template_decl before calling break_out_target_exprs. * init.cc (get_nsdmi): Likewise. * tree.cc (break_out_target_exprs): Assert processing_template_decl is cleared. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template24.C: New test.
2022-12-12Revert "c++: build initializer_list<string> in a loop [PR105838]"Jason Merrill1-0/+2
This patch broke a couple of different patterns; reverting while I work on a fix. PR c++/108701 This reverts commit bd0485f20f4794f9787237706a6308473a8e9415.
2022-12-08c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-2/+0
The previous patch avoided building an initializer_list<string> at all when building a vector<string>, but in situations where that isn't possible, we could still build the initializer_list with a loop over a constant array. This is represented using a VEC_INIT_EXPR, which required adjusting a couple of places that expected the initializer array to have the same type as the target array and fixing build_vec_init not to undo our efforts. PR c++/105838 gcc/cp/ChangeLog: * call.cc (convert_like_internal) [ck_list]: Use maybe_init_list_as_array. * constexpr.cc (cxx_eval_vec_init_1): Init might have a different type. * tree.cc (build_vec_init_elt): Likewise. * init.cc (build_vec_init): Handle from_array from a TARGET_EXPR. Retain TARGET_EXPR of a different type. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt2.C: New test.
2022-12-04c++: pack in requires-expr parm list [PR107417]Patrick Palka1-9/+12
Here find_parameter_packs_r isn't detecting the pack T inside the requires-expr's parameter list ultimately because cp_walk_trees deliberately avoids walking the list so as to avoid false positives in the unexpanded pack checker. But it should still be fine to walk the TREE_TYPE of each parameter, which we already need to do from for_each_template_parm_r, and is sufficient to fix the testcase. PR c++/107417 gcc/cp/ChangeLog: * pt.cc (for_each_template_parm_r) <case REQUIRES_EXPR>: Move walking of the TREE_TYPE of each parameter to ... * tree.cc (cp_walk_subtrees) <case REQUIRES_EXPR>: ... here. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires33.C: New test.
2022-11-18c++: implement P1492 contractsJeff Chapman II1-0/+67
Implement the P1492 versions of contracts, along with extensions that support the emulation of N4820 and other proposals. This implementation assigns a concrete semantic (one of: ignore, assume, enforce, or observe) to each contract attribute depending on its labels and configuration options. Co-authored-by: Andrew Sutton <asutton@lock3software.com> Co-authored-by: Andrew Marmaduke <amarmaduke@lock3software.com> Co-authored-by: Michael Lopez <mlopez@lock3software.com> Co-authored-by: Jason Merrill <jason@redhat.com> gcc/ChangeLog: * doc/invoke.texi: Document contracts flags. gcc/c-family/ChangeLog: * c.opt: Add contracts flags. * c-cppbuiltin.cc (c_cpp_builtins): Add contracts feature-test macros. gcc/cp/ChangeLog: * cp-tree.h (enum cp_tree_index): Add CPTI_PSEUDO_CONTRACT_VIOLATION. (pseudo_contract_violation_type): New macro. (struct saved_scope): Add x_processing_contract_condition. (processing_contract_condition): New macro. (comparing_override_contracts): New variable decl. (find_contract): New inline. (set_decl_contracts): New inline. (get_contract_semantic): New inline. (set_contract_semantic): New inline. * constexpr.cc (cxx_eval_assert): Split out from... (cxx_eval_internal_function): ...here. (cxx_eval_constant_expression): Use it for contracts. (potential_constant_expression_1): Handle contracts. * cp-gimplify.cc (cp_genericize_r): Handle contracts. * cp-objcp-common.cc (cp_tree_size): Handle contracts. (cp_common_init_ts): Handle contracts. (cp_handle_option): Handle contracts. * decl.cc (duplicate_decls): Handle contracts. (check_tag_decl): Check for bogus contracts. (start_decl): Check flag_contracts. (grokfndecl): Call rebuild_postconditions. (grokdeclarator): Handle contract attributes. (start_preparsed_function): Call start_function_contracts. (finish_function): Call finish_function_contracts. * decl2.cc (cp_check_const_attributes): Skip contracts. (comdat_linkage): Handle outlined contracts. * error.cc (dump_type): Handle null TYPE_IDENTIFIER. * g++spec.cc (EXPERIMENTAL): New macro. (lang_specific_driver): Add -lstdc++exp if -fcontracts. * mangle.cc (write_encoding): Handle outlined contracts. * module.cc (trees_out::fn_parms_init): Handle outlined contracts. (trees_in::fn_parms_init): Likewise. (check_mergeable_decl): Likewise. (module_state_config::get_dialect): Record -fcontracts. * parser.h (struct cp_unparsed_functions_entry): Add contracts. * parser.cc (unparsed_contracts): New macro. (push_unparsed_function_queues): Adjust. (contract_attribute_p): New. (cp_parser_statement): Check contracts. (cp_parser_decl_specifier_seq): Handle contracts. (cp_parser_skip_to_closing_square_bracket): Split out... (cp_parser_skip_up_to_closing_square_bracket): ...this fn. (cp_parser_class_specifier): Do contract late parsing. (cp_parser_class_head): Check contracts. (cp_parser_contract_role): New. (cp_parser_contract_mode_opt): New. (find_error, contains_error_p): New. (cp_parser_contract_attribute_spec): New. (cp_parser_late_contract_condition): New. (cp_parser_std_attribute_spec): Handle contracts. (cp_parser_save_default_args): Also save contracts. * pt.cc (register_parameter_specializations): No longer static. (register_local_identity): New. (check_explicit_specialization): Call remove_contract_attributes. (tsubst_contract, tsubst_contract_attribute): New. (tsubst_contract_attributes): New. (tsubst_attribute): Add comment. (tsubst_copy): Also allow parm when processing_contract_condition. (tsubst_expr): Handle contracts. (regenerate_decl_from_template): Handle contracts. * search.cc (check_final_overrider): Compare contracts. * semantics.cc (set_cleanup_locs): Skip POSTCONDITION_STMT. (finish_non_static_data_member): Check contracts. (finish_this_expr): Check contracts. (process_outer_var_ref): Handle contracts. (finish_id_expression_1): Handle contracts. (apply_deduced_return_type): Adjust contracts. * tree.cc (handle_contract_attribute): New. (get_innermost_component, is_this_expression): New. (comparing_this_references): New. (equivalent_member_references): New. (cp_tree_equal): Check it. * typeck.cc (check_return_expr): Apply contracts. * Make-lang.in: Add contracts.o. * config-lang.in: Add contracts.cc. * cp-tree.def (ASSERTION_STMT, PRECONDITION_STMT) (POSTCONDITION_STMT): New. * contracts.h: New file. * contracts.cc: New file. gcc/testsuite/ChangeLog: * g++.dg/modules/modules.exp: Pass dg-options to link command. * lib/g++.exp: Add -L for libstdc++exp.a. * g++.dg/contracts/backtrace_handler/assert_fail.cpp: New test. * g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/contracts-access1.C: New test. * g++.dg/contracts/contracts-assume1.C: New test. * g++.dg/contracts/contracts-assume2.C: New test. * g++.dg/contracts/contracts-assume3.C: New test. * g++.dg/contracts/contracts-assume4.C: New test. * g++.dg/contracts/contracts-assume5.C: New test. * g++.dg/contracts/contracts-assume6.C: New test. * g++.dg/contracts/contracts-comdat1.C: New test. * g++.dg/contracts/contracts-config1.C: New test. * g++.dg/contracts/contracts-constexpr1.C: New test. * g++.dg/contracts/contracts-constexpr2.C: New test. * g++.dg/contracts/contracts-constexpr3.C: New test. * g++.dg/contracts/contracts-conversion1.C: New test. * g++.dg/contracts/contracts-ctor-dtor1.C: New test. * g++.dg/contracts/contracts-ctor-dtor2.C: New test. * g++.dg/contracts/contracts-cv1.C: New test. * g++.dg/contracts/contracts-deduced1.C: New test. * g++.dg/contracts/contracts-deduced2.C: New test. * g++.dg/contracts/contracts-friend1.C: New test. * g++.dg/contracts/contracts-ft1.C: New test. * g++.dg/contracts/contracts-ignore1.C: New test. * g++.dg/contracts/contracts-ignore2.C: New test. * g++.dg/contracts/contracts-large-return.C: New test. * g++.dg/contracts/contracts-multiline1.C: New test. * g++.dg/contracts/contracts-multiple-inheritance1.C: New test. * g++.dg/contracts/contracts-multiple-inheritance2.C: New test. * g++.dg/contracts/contracts-nested-class1.C: New test. * g++.dg/contracts/contracts-nested-class2.C: New test. * g++.dg/contracts/contracts-nocopy1.C: New test. * g++.dg/contracts/contracts-override.C: New test. * g++.dg/contracts/contracts-post1.C: New test. * g++.dg/contracts/contracts-post2.C: New test. * g++.dg/contracts/contracts-post3.C: New test. * g++.dg/contracts/contracts-post4.C: New test. * g++.dg/contracts/contracts-post5.C: New test. * g++.dg/contracts/contracts-post6.C: New test. * g++.dg/contracts/contracts-pre1.C: New test. * g++.dg/contracts/contracts-pre10.C: New test. * g++.dg/contracts/contracts-pre2.C: New test. * g++.dg/contracts/contracts-pre2a1.C: New test. * g++.dg/contracts/contracts-pre2a2.C: New test. * g++.dg/contracts/contracts-pre3.C: New test. * g++.dg/contracts/contracts-pre4.C: New test. * g++.dg/contracts/contracts-pre5.C: New test. * g++.dg/contracts/contracts-pre6.C: New test. * g++.dg/contracts/contracts-pre7.C: New test. * g++.dg/contracts/contracts-pre9.C: New test. * g++.dg/contracts/contracts-redecl1.C: New test. * g++.dg/contracts/contracts-redecl2.C: New test. * g++.dg/contracts/contracts-redecl3.C: New test. * g++.dg/contracts/contracts-redecl4.C: New test. * g++.dg/contracts/contracts-redecl5.C: New test. * g++.dg/contracts/contracts-redecl6.C: New test. * g++.dg/contracts/contracts-redecl7.C: New test. * g++.dg/contracts/contracts-redecl8.C: New test. * g++.dg/contracts/contracts-tmpl-attr1.C: New test. * g++.dg/contracts/contracts-tmpl-spec1.C: New test. * g++.dg/contracts/contracts-tmpl-spec2.C: New test. * g++.dg/contracts/contracts-tmpl-spec3.C: New test. * g++.dg/contracts/contracts1.C: New test. * g++.dg/contracts/contracts10.C: New test. * g++.dg/contracts/contracts11.C: New test. * g++.dg/contracts/contracts12.C: New test. * g++.dg/contracts/contracts13.C: New test. * g++.dg/contracts/contracts14.C: New test. * g++.dg/contracts/contracts15.C: New test. * g++.dg/contracts/contracts16.C: New test. * g++.dg/contracts/contracts17.C: New test. * g++.dg/contracts/contracts18.C: New test. * g++.dg/contracts/contracts19.C: New test. * g++.dg/contracts/contracts2.C: New test. * g++.dg/contracts/contracts20.C: New test. * g++.dg/contracts/contracts22.C: New test. * g++.dg/contracts/contracts24.C: New test. * g++.dg/contracts/contracts25.C: New test. * g++.dg/contracts/contracts3.C: New test. * g++.dg/contracts/contracts35.C: New test. * g++.dg/contracts/contracts4.C: New test. * g++.dg/contracts/contracts5.C: New test. * g++.dg/contracts/contracts6.C: New test. * g++.dg/contracts/contracts7.C: New test. * g++.dg/contracts/contracts8.C: New test. * g++.dg/contracts/contracts9.C: New test. * g++.dg/modules/contracts-1_a.C: New test. * g++.dg/modules/contracts-1_b.C: New test. * g++.dg/modules/contracts-2_a.C: New test. * g++.dg/modules/contracts-2_b.C: New test. * g++.dg/modules/contracts-2_c.C: New test. * g++.dg/modules/contracts-3_a.C: New test. * g++.dg/modules/contracts-3_b.C: New test. * g++.dg/modules/contracts-4_a.C: New test. * g++.dg/modules/contracts-4_b.C: New test. * g++.dg/modules/contracts-4_c.C: New test. * g++.dg/modules/contracts-4_d.C: New test. * g++.dg/modules/contracts-tpl-friend-1_a.C: New test. * g++.dg/modules/contracts-tpl-friend-1_b.C: New test. * g++.dg/contracts/backtrace_handler/Makefile: New test. * g++.dg/contracts/backtrace_handler/README: New test. * g++.dg/contracts/backtrace_handler/example_out.txt: New test. * g++.dg/contracts/backtrace_handler/example_pretty.txt: New test. * g++.dg/contracts/backtrace_handler/prettytrace.sh: New test. * g++.dg/contracts/except_preload_handler/Makefile: New test. * g++.dg/contracts/except_preload_handler/README: New test. * g++.dg/contracts/except_preload_handler/assert_fail.cpp: New test. * g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/noexcept_preload_handler/Makefile: New test. * g++.dg/contracts/noexcept_preload_handler/README: New test. * g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp: New test. * g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/preload_handler/Makefile: New test. * g++.dg/contracts/preload_handler/README: New test. * g++.dg/contracts/preload_handler/assert_fail.cpp: New test. * g++.dg/contracts/preload_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/preload_nocontinue_handler/Makefile: New test. * g++.dg/contracts/preload_nocontinue_handler/README: New test. * g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp: New test. * g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp: New test.
2022-11-14c++: init_priority and SUPPORTS_INIT_PRIORITY [PR107638]Patrick Palka1-4/+6
The commit r13-3706-gd0a492faa6478c for fixing the result of __has_attribute(init_priority) causes a bootstrap failure on hppa64-hpux due to assuming the macro SUPPORTS_INIT_PRIORITY expands to a simple constant, but on this target the macro is defined as #define SUPPORTS_INIT_PRIORITY (TARGET_GNU_LD ? 1 : 0) (where TARGET_GNU_LD expands to something in terms of global_options) which means we can't use the macro to conditionally exclude the entry for init_priority when defining the cxx_attribute_table. So instead of trying to exclude init_priority from the attribute table, this patch just makes __has_attribute handle init_priority specially. PR c++/107638 gcc/c-family/ChangeLog: * c-lex.cc (c_common_has_attribute): Return 1 for init_priority iff SUPPORTS_INIT_PRIORITY. gcc/cp/ChangeLog: * tree.cc (cxx_attribute_table): Don't conditionally exclude the init_priority entry. (handle_init_priority_attribute): Remove ATTRIBUTE_UNUSED. Return error_mark_node if !SUPPORTS_INIT_PRIORITY.
2022-11-09c++: Minimal handling of carries_dependency attributeJakub Jelinek1-0/+28
A comment in D2552R1: "The only questionable (but still conforming) case we found was [[carries_dependency(some_argument)]] on GCC, where the emitted diagnostic said that the carries_dependency attribute is not supported, but did not specifically call out the syntax error in the argument clause." made me try the following patch, where we'll error at least for arguments to the attribute and for some uses of the attribute appertaining to something not mentioned in the standard warn with different diagnostics (or should that be an error?; clang++ does that, but I think we never do for any attribute, standard or not). The diagnostics on toplevel attribute declaration is still an attribute ignored warning and on empty statement different wording. The paper additionally mentions struct X { [[nodiscard]]; }; // no diagnostic on GCC and 2 cases of missing diagnostics on [[fallthrough]] (guess I should file a PR about those; one problem is that do { ... } while (0); there is replaced during genericization just by ... and another that [[fallthrough]] there is followed by a label, but not user/case/default label, but an artificial one created from while loop genericization. 2022-11-09 Jakub Jelinek <jakub@redhat.com> * tree.cc (handle_carries_dependency_attribute): New function. (std_attribute_table): Add carries_dependency attribute. * parser.cc (cp_parser_check_std_attribute): Add carries_dependency attribute. * g++.dg/cpp0x/attr-carries_dependency1.C: New test.
2022-11-06c++: correct __has_attribute(init_priority)Patrick Palka1-13/+7
Currently __has_attribute(init_priority) always returns true, even on targets that don't actually support init priorities, and when using the attribute on such targets we just get a hard error about them being unsupported. This makes it impossible to conditionally use the attribute by querying __has_attribute. This patch fixes this by including init_priority in the attribute table only if the target supports init priorities. Thus on such targets __has_attribute(init_priority) will now return false and we'll treat it as just another unrecognized attribute (e.g. using it gives a -Wattribute warning instead of a hard error). gcc/cp/ChangeLog: * tree.cc (cxx_attribute_table): Include init_priority entry only if SUPPORTS_INIT_PRIORITY. (handle_init_priority_attribute): Add ATTRIBUTE_UNUSED. Assert SUPPORTS_INIT_PRIORITY is true. gcc/testsuite/ChangeLog: * g++.dg/special/initpri3.C: New test.
2022-10-12c++: defer all consteval in default args [DR2631]Jason Merrill1-28/+24
The proposed resolution of CWG2631 extends our current handling of source_location::current to all consteval functions: default arguments are not evaluated until they're used in a call, the same should apply to evaluation of immediate invocations. And similarly for default member initializers. Previously we folded source_location::current in cp_fold_r; now we fold all consteval calls in default arguments/member initializers in bot_replace. DR 2631 gcc/cp/ChangeLog: * cp-tree.h (source_location_current_p): Remove. * name-lookup.h (struct cp_binding_level): Remove immediate_fn_ctx_p. * call.cc (in_immediate_context): All default args and DMI are potentially immediate context. (immediate_invocation_p): Don't treat source_location specially. (struct in_consteval_if_p_temp_override): Move to cp-tree.h. * constexpr.cc (get_nth_callarg): Move to cp-tree.h. * cp-gimplify.cc (cp_fold_r): Don't fold consteval. * name-lookup.cc (begin_scope): Don't set immediate_fn_ctx_p. * parser.cc (cp_parser_lambda_declarator_opt): Likewise. (cp_parser_direct_declarator): Likewise. * pt.cc (tsubst_default_argument): Open sk_function_parms level. * tree.cc (source_location_current_p): Remove. (bot_replace): Fold consteval here. (break_out_target_exprs): Handle errors. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval-defarg3.C: New test.
2022-10-07c++: track whether we expect a TARGET_EXPR to be elidedJason Merrill1-0/+4
A discussion at Cauldron made me think that with the formalization of copy elision in C++17, we should be able to determine before optimization which TARGET_EXPRs will become temporaries and which are initializers. This patch implements that: we set TARGET_EXPR_ELIDING_P if it's used as an initializer, and later check that we were right. There's an exception in the cp_gimplify_expr check to allow extra temporaries of non-addressable type: this is used by gimplify_init_ctor_preeval to materialize subobjects of a CONSTRUCTOR on the rhs of a MODIFY_EXPR rather than materializing the whole object. If the type isn't addressable, there's no way for a program to tell the difference, so this is a valid optimization. I considered changing replace_placeholders_for_class_temp_r to check TARGET_EXPR_ELIDING_P instead of potential_prvalue_result_of, but decided that would be wrong: if we have an eliding TARGET_EXPR inside a non-eliding one, we would miss replacing its placeholders. gcc/cp/ChangeLog: * cp-tree.h (TARGET_EXPR_ELIDING_P): New. (unsafe_copy_elision_p, set_target_expr_eliding) (cp_build_init_expr): Declare. * call.cc (unsafe_copy_elision_p): No longer static. (build_over_call, build_special_member_call) (build_new_method_call): Use cp_build_init_expr. * coroutines.cc (expand_one_await_expression) (build_actor_fn, flatten_await_stmt, handle_nested_conditionals) (await_statement_walker, morph_fn_to_coro): Use cp_build_init_expr. * cp-gimplify.cc (cp_gimplify_init_expr) (cp_gimplify_expr): Check TARGET_EXPR_ELIDING_P. (cp_fold_r): Propagate it. (cp_fold): Use cp_build_init_expr. * decl.cc (check_initializer): Use cp_build_init_expr. * except.cc (build_throw): Use cp_build_init_expr. * init.cc (get_nsdmi): Call set_target_expr_eliding. (perform_member_init, expand_default_init, expand_aggr_init_1) (build_new_1, build_vec_init): Use cp_build_init_expr. * method.cc (do_build_copy_constructor): Use cp_build_init_expr. * semantics.cc (simplify_aggr_init_expr, finalize_nrv_r) (finish_omp_reduction_clause): Use cp_build_init_expr. * tree.cc (build_target_expr): Call set_target_expr_eliding. (bot_manip): Copy TARGET_EXPR_ELIDING_P. * typeck.cc (cp_build_modify_expr): Call set_target_expr_eliding. (check_return_expr): Use cp_build_modify_expr. * typeck2.cc (split_nonconstant_init_1) (split_nonconstant_init): Use cp_build_init_expr. (massage_init_elt): Call set_target_expr_eliding. (process_init_constructor_record): Clear TARGET_EXPR_ELIDING_P on unsafe copy elision. (set_target_expr_eliding, cp_build_init_expr): New.
2022-10-05c++: lvalue_kind tweakJason Merrill1-1/+11
I was wondering how lvalue_kind handles VIEW_CONVERT_EXPR; in cases where the type actually changes, it should have the same prvalue->xvalue effect as ARRAY_REF, since we need to materialize a temporary to get an object we can reinterpret as another type. Currently this only fires on builtin-shufflevector-3.c, where we use VIEW_CONVERT_EXPR to reinterpret a vector as an array. REALPART_EXPR and IMAGPART_EXPR should also be treated like COMPONENT_REF. PREINCREMENT_EXPR and PREDECREMENT_EXPR should only be applied to glvalues, but if for some reason they were applied to a prvalue this would be correct. TRY_CATCH_EXPR around a prvalue is also questionable, but this is the right handling. gcc/cp/ChangeLog: * tree.cc (lvalue_kind) [VIEW_CONVERT_EXPR]: Change prvalue to xvalue.
2022-09-29c++: introduce TRAIT_TYPE alongside TRAIT_EXPRPatrick Palka1-5/+17
We already have generic support for predicate-like traits that yield a boolean value via TRAIT_EXPR, but we lack the same support for traits that yield a type instead of a value. Such support would streamline implementing efficient builtins for the standard library type traits. To that end this patch implements a generic TRAIT_TYPE type alongside TRAIT_EXPR, and reimplements the existing UNDERLYING_TYPE builtin trait using this new TRAIT_TYPE. gcc/cp/ChangeLog: * cp-objcp-common.cc (cp_common_init_ts): Replace UNDERLYING_TYPE with TRAIT_TYPE. * cp-tree.def (TRAIT_TYPE): Define. (UNDERLYING_TYPE): Remove. * cp-tree.h (TRAIT_TYPE_KIND_RAW): Define. (TRAIT_TYPE_KIND): Define. (TRAIT_TYPE_TYPE1): Define. (TRAIT_TYPE_TYPE2): Define. (WILDCARD_TYPE_P): Return true for TRAIT_TYPE. (finish_trait_type): Declare. * cxx-pretty-print.cc (cxx_pretty_printer::primary_expression): Adjust after renaming pp_cxx_trait_expression. (cxx_pretty_printer::simple_type_specifier) <case TRAIT_TYPE>: New. (cxx_pretty_printer::type_id): Replace UNDERLYING_TYPE with TRAIT_TYPE. (pp_cxx_trait_expression): Rename to ... (pp_cxx_trait): ... this. Handle TRAIT_TYPE as well. Correct pretty printing of the trailing arguments. * cxx-pretty-print.h (pp_cxx_trait_expression): Rename to ... (pp_cxx_trait_type): ... this. * error.cc (dump_type) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (dump_type_prefix): Replace UNDERLYING_WITH with TRAIT_TYPE. (dump_type_suffix): Likewise. * mangle.cc (write_type) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. * module.cc (trees_out::type_node) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (trees_in::tree_node): Likewise. * parser.cc (cp_parser_primary_expression): Adjust after renaming cp_parser_trait_expr. (cp_parser_trait_expr): Rename to ... (cp_parser_trait): ... this. Call finish_trait_type for traits that yield a type. (cp_parser_simple_type_specifier): Adjust after renaming cp_parser_trait_expr. * pt.cc (for_each_template_parm_r) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (tsubst): Likewise. (unify): Replace UNDERLYING_TYPE with TRAIT_TYPE. (dependent_type_p_r): Likewise. * semantics.cc (finish_underlying_type): Don't return UNDERLYING_TYPE anymore when processing_template_decl. (finish_trait_type): Define. * tree.cc (strip_typedefs) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (cp_walk_subtrees): Likewise. * typeck.cc (structural_comptypes): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-59.C: Adjust expected error message. * g++.dg/ext/underlying_type7.C: Likewise. * g++.dg/ext/underlying_type13.C: New test. * g++.dg/ext/underlying_type14.C: New test.
2022-09-27c++: Implement C++23 P2266R1, Simpler implicit move [PR101165]Marek Polacek1-1/+1
This patch implements https://wg21.link/p2266, which, once again, changes the implicit move rules. Here's a brief summary of various changes in this area: r125211: Introduced moving from certain lvalues when returning them r171071: CWG 1148, enable move from value parameter on return r212099: CWG 1579, it's OK to call a converting ctor taking an rvalue r251035: CWG 1579, do maybe-rvalue overload resolution twice r11-2411: Avoid calling const copy ctor on implicit move r11-2412: C++20 implicit move changes, remove the fallback overload resolution, allow move on throw of parameters and implicit move of rvalue references P2266 enables the implicit move even for functions that return references. That is, we will now perform a move in X&& foo (X&& x) { return x; } P2266 also removes the fallback overload resolution, but this was resolved by r11-2412: we only do convert_for_initialization with LOOKUP_PREFER_RVALUE in C++17 and older. P2266 also says that a returned move-eligible id-expression is always an xvalue. This required some further short, but nontrivial changes, especially when it comes to deduction, because we have to pay attention to whether we have auto, auto&& (which is like T&&), or decltype(auto) with (un)parenthesized argument. In C++23, decltype(auto) f(int&& x) { return (x); } auto&& f(int x) { return x; } both should deduce to 'int&&' but decltype(auto) f(int x) { return x; } should deduce to 'int'. A cornucopia of tests attached. I've also verified that we behave like clang++. xvalue_p seemed to be broken: since the introduction of clk_implicit_rval, it cannot use '==' when checking for clk_rvalueref. Since this change breaks code, it's only enabled in C++23. In particular, this code will not compile in C++23: int& g(int&& x) { return x; } because x is now treated as an rvalue, and you can't bind a non-const lvalue reference to an rvalue. This patch also fixes PR106882 (the check_return_expr changes). PR c++/101165 PR c++/106882 gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Define __cpp_implicit_move. gcc/cp/ChangeLog: * call.cc (reference_binding): Check clk_implicit_rval in C++20 only. * cp-tree.h (unparenthesized_id_or_class_member_access_p): Declare. * pt.cc (unparenthesized_id_or_class_member_access_p): New function, broken out of... (do_auto_deduction): ...here. Use it. In C++23, maybe call treat_lvalue_as_rvalue_p. * tree.cc (xvalue_p): Check & clk_rvalueref, not == clk_rvalueref. * typeck.cc (check_return_expr): Allow implicit move for functions returning a reference as well, or when the return value type is not a scalar type. gcc/testsuite/ChangeLog: * g++.dg/conversion/pr41426.C: Add dg-error for C++23. * g++.dg/cpp0x/elision_weak.C: Likewise. * g++.dg/cpp0x/move-return3.C: Only link in c++20_down. * g++.dg/cpp1y/decltype-auto2.C: Add dg-error for C++23. * g++.dg/cpp1y/lambda-generic-89419.C: Likewise. * g++.dg/cpp23/feat-cxx2b.C: Test __cpp_implicit_move. * g++.dg/gomp/pr56217.C: Only compile in c++20_down. * g++.dg/warn/Wno-return-local-addr.C: Add dg-error for C++23. * g++.dg/warn/Wreturn-local-addr.C: Adjust dg-error. * g++.old-deja/g++.brendan/crash55.C: Add dg-error for C++23. * g++.old-deja/g++.jason/temporary2.C: Likewise. * g++.old-deja/g++.mike/p2846b.C: Adjust. * g++.dg/cpp1y/decltype-auto6.C: New test. * g++.dg/cpp23/decltype1.C: New test. * g++.dg/cpp23/decltype2.C: New test. * g++.dg/cpp23/elision1.C: New test. * g++.dg/cpp23/elision2.C: New test. * g++.dg/cpp23/elision3.C: New test. * g++.dg/cpp23/elision4.C: New test. * g++.dg/cpp23/elision5.C: New test. * g++.dg/cpp23/elision6.C: New test. * g++.dg/cpp23/elision7.C: New test.
2022-09-12c++: remove '_sfinae' suffix from functionsPatrick Palka1-8/+2
The functions abstract_virtuals_error cxx_constant_value get_target_expr instantiate_non_dependent_expr require_complete_type are each just a non-SFINAE-enabled wrapper for the corresponding SFINAE-enabled version that's suffixed by '_sfinae'. But this suffix is at best redundant since a 'complain' parameter already broadly conveys that a function is SFINAE-enabled, and having two such versions of a function is less concise than just using a default argument for 'complain' (and arguably no less mistake prone). So this patch squashes the two versions of each of the above functions by adding a default 'complain' argument to the SFINAE-enabled version whose '_sfinae' suffix we then remove. gcc/cp/ChangeLog: * call.cc (build_conditional_expr): Adjust calls to '_sfinae'-suffixed functions. (build_temp): Likewise. (convert_like_internal): Likewise. (convert_arg_to_ellipsis): Likewise. (build_over_call): Likewise. (build_cxx_call): Likewise. (build_new_method_call): Likewise. * constexpr.cc (cxx_eval_outermost_constant_expr): Likewise. (cxx_constant_value_sfinae): Rename to ... (cxx_constant_value): ... this. Document its default arguments. (fold_non_dependent_expr): Adjust function comment. * cp-tree.h (instantiate_non_dependent_expr_sfinae): Rename to ... (instantiate_non_dependent_expr): ... this. Give its 'complain' parameter a default argument. (get_target_expr_sfinae, get_target_expr): Likewise. (require_complete_type_sfinae, require_complete_type): Likewise. (abstract_virtuals_error_sfinae, abstract_virtuals_error): Likewise. (cxx_constant_value_sfinae, cxx_constant_value): Likewise. * cvt.cc (build_up_reference): Adjust calls to '_sfinae'-suffixed functions. (ocp_convert): Likewise. * decl.cc (build_explicit_specifier): Likewise. * except.cc (build_noexcept_spec): Likewise. * init.cc (build_new_1): Likewise. * pt.cc (expand_integer_pack): Likewise. (instantiate_non_dependent_expr_internal): Adjust function comment. (instantiate_non_dependent_expr): Rename to ... (instantiate_non_dependent_expr_sfinae): ... this. Document its default argument. (tsubst_init): Adjust calls to '_sfinae'-suffixed functions. (fold_targs_r): Likewise. * semantics.cc (finish_compound_literal): Likewise. (finish_decltype_type): Likewise. (cp_build_bit_cast): Likewise. * tree.cc (build_cplus_new): Likewise. (get_target_expr): Rename to ... (get_target_expr_sfinae): ... this. Document its default argument. * typeck.cc (require_complete_type): Rename to ... (require_complete_type_sfinae): ... this. Document its default argument. (cp_build_array_ref): Adjust calls to '_sfinae'-suffixed functions. (convert_arguments): Likewise. (cp_build_binary_op): Likewise. (build_static_cast_1): Likewise. (cp_build_modify_expr): Likewise. (convert_for_initialization): Likewise. * typeck2.cc (abstract_virtuals_error): Rename to ... (abstract_virtuals_error_sfinae): ... this. Document its default argument. (build_functional_cast_1): Adjust calls to '_sfinae'-suffixed functions.
2022-09-12c++: Refer to internal linkage for -Wsubobject-linkage [PR86491]Jonathan Wakely1-2/+10
Since C++11 relaxed the requirement for template arguments to have external linkage, it's possible to get -Wsubobject-linkage warnings without using any anonymous namespaces. This confuses users when they get diagnostics that refer to an anonymous namespace that doesn't exist in their code. This changes the diagnostic to say "has internal linkage" for C++11 and later, if the type isn't actually a member of the anonymous namespace. Making that distinction involved renaming the current decl_anon_ns_mem_p to something that better expresses its semantics. For C++98 template arguments declared with 'static' are ill-formed anyway, so the only way this warning can arise is via anonymous namespaces. That means the existing wording is accurate for C++98 and so we can keep it. PR c++/86491 gcc/cp/ChangeLog: * decl2.cc (constrain_class_visibility): Adjust wording of -Wsubobject-linkage for cases where anonymous namespaces aren't used. * tree.cc (decl_anon_ns_mem_p): Now only true for actual anonymous namespace members, rename old semantics to... (decl_internal_context_p): ...this. * cp-tree.h, name-lookup.cc, pt.cc: Adjust. gcc/testsuite/ChangeLog: * g++.dg/warn/anonymous-namespace-3.C: Use separate dg-warning directives for C++98 and everything else. * g++.dg/warn/Wsubobject-linkage-5.C: New test.
2022-06-03c++: cv-quals of dummy obj for non-dep memfn call [PR105637]Patrick Palka1-7/+23
In non-dependent23.C below we expect the Base::foo calls to resolve to the second, third and fourth overloads respectively in light of the cv-qualifiers of 'this' in each case. But ever since r12-6075-g2decd2cabe5a4f, the calls incorrectly resolve to the first overload at instantiation time. This happens because the calls to Base::foo are all deemed non-dependent (ever since r7-755-g23cb72663051cd made us ignore 'this' dependence when considering the dependence of a non-static memfn call), hence we end up checking the call ahead of time, using as the object argument a dummy object of type Base. Since this object argument is cv-unqualified, the calls in turn resolve to the unqualified overload of baseDevice. Before r12-6075 this incorrect result would just get silently discarded and we'd end up redoing OR at instantiation time using 'this' as the object argument. But after r12-6075 we now reuse this incorrect result at instantiation time. This patch fixes this by making maybe_dummy_object respect the cv-quals of (the non-lambda) 'this' when returning a dummy object. Thus, ahead of time OR using a dummy object will give us the right answer that's consistent with the instantiation time answer. An earlier version of this patch didn't handle 'this'-capturing lambdas correctly, which broke lambda-this22.C below. PR c++/105637 gcc/cp/ChangeLog: * tree.cc (maybe_dummy_object): When returning a dummy object, respect the cv-quals of 'this' if available. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-this22.C: New test. * g++.dg/template/non-dependent23.C: New test.
2022-05-31c++: squash cp_build_qualified_type/_realPatrick Palka1-7/+4
This combines the two differently named versions of the same function into a single function utilizing a default argument. gcc/cp/ChangeLog: * cp-tree.h (cp_build_qualified_type_real): Rename to ... (cp_build_qualified_type): ... this. Give its last parameter a default argument. Remove macro of the same name. * decl.cc (grokdeclarator): Adjust accordingly. * pt.cc (tsubst_aggr_type): Likewise. (rebuild_function_or_method_type): Likewise. (tsubst): Likewise. (maybe_dependent_member_ref): Likewise. (unify): Likewise. * tree.cc (cp_build_qualified_type_real): Rename to ... (cp_build_qualified_type): ... this. Adjust accordingly.
2022-05-24c++: set TYPE_CANONICAL for more template typesPatrick Palka1-1/+5
When forming a class template specialization, lookup_template_class uses structural equality for the specialized type whenever one of its template arguments uses structural equality. This is the sensible thing to do in a vacuum, but given that we already effectively deduplicate class specializations via the type_specializations table, we ought to be able to safely assume that each class specialization is unique and therefore canonical, regardless of the canonicity of the template arguments. To that end this patch makes us use the canonical type machinery for all type specializations, except for the case where a PARM_DECL appears in the template arguments (this special case was recently added by r12-3766-g72394d38d929c7). Additionally, this patch makes us use the canonical type machinery for TEMPLATE_TEMPLATE_PARMs and BOUND_TEMPLATE_TEMPLATE_PARMs, by extending canonical_type_parameter appropriately. A comment in tsubst says it's unsafe to set TYPE_CANONICAL for a lowered TEMPLATE_TEMPLATE_PARM, but I'm not sure this is true anymore. According to Jason, this comment (from r120341) became obsolete when later that year r129844 started to substitute the template parms of ttps. Note that r10-7817-ga6f400239d792d recently changed process_template_parm to clear TYPE_CANONICAL for TEMPLATE_TEMPLATE_PARM consistent with the tsubst comment; this patch changes both functions to set instead of clear TYPE_CANONICAL for ttps. These changes improve compile time of template-heavy code by around 10% for me (with a release compiler). For instance, compile time for the libstdc++ test std/ranges/adaptors/all.cc drops from 1.45s to 1.25s, and for the range-v3 test test/view/zip.cpp from 5.38s to 4.88s. The total number of calls to structural_comptypes for the latter test drops from 10.5M to 1.8M. Memory use is unaffected (as expected). The new testcase verifies we check the r12-3766 PARM_DECL special case in bind_template_template_parm too. gcc/cp/ChangeLog: * cp-tree.h (any_template_arguments_need_structural_equality_p): Declare. * pt.cc (struct ctp_hasher): Define. (ctp_table): Define. (canonical_type_parameter): Use it. (process_template_parm): Set TYPE_CANONICAL for TEMPLATE_TEMPLATE_PARM too. (lookup_template_class_1): Remove now outdated comment for the any_template_arguments_need_structural_equality_p test. (tsubst) <case TEMPLATE_TEMPLATE_PARM, etc>: Don't specifically clear TYPE_CANONICAL for ttps. Set TYPE_CANONICAL on the substituted type later. (any_template_arguments_need_structural_equality_p): Return true for any_targ_node. Don't return true just because a template argument uses structural equality. Add comment for the PARM_DECL special case. (rewrite_template_parm): Set TYPE_CANONICAL on the rewritten parm's type later. * tree.cc (bind_template_template_parm): Set TYPE_CANONICAL when safe to do so. * typeck.cc (structural_comptypes) [check_alias]: Increment processing_template_decl before checking dependent_alias_template_spec_p. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-52830a.C: New test.
2022-05-11tree: introduce range adaptor for TREE_VECPatrick Palka1-3/+2
This patch implements a simple tree wrapper, named tree_vec_range, which lets us idiomatically loop over all the elements of a TREE_VEC using a C++11 range-based for loop: // v is a TREE_VEC for (tree e : tree_vec_range (v)) ... This is similar to the existing tree-based range adaptors ovl_range and lkp_range added to the C++ FE in r12-340-g3307b9a07a3c51. This patch also converts some existing loops over TREE_VEC within the C++ FE to use tree_vec_range / range-for. gcc/cp/ChangeLog: * constraint.cc (tsubst_parameter_mapping): Convert loop over TREE_VEC into a range-based for loop using tree_vec_range. * pt.cc (iterative_hash_template_arg): Likewise. (template_parms_level_to_args): Likewise. (deducible_template_args): Likewise. (check_undeduced_parms): Likewise. (dependent_type_p_r): Likewise. (value_dependent_expression_p) <case NONTYPE_ARGUMENT_PACK>: Likewise. (dependent_template_arg_p): Likewise. * tree.cc (cp_walk_subtrees) <case NONTYPE_ARGUMENT_PACK>: Likewise. gcc/ChangeLog: * tree.h (TREE_VEC_BEGIN): Define. (TREE_VEC_END): Correct 'length' member access. (class tree_vec_range): Define.
2022-05-09c++: constexpr init of union sub-aggr w/ base [PR105491]Patrick Palka1-2/+2
Here ever since r10-7313-gb599bf9d6d1e18, reduced_constant_expression_p in C++11/14 is rejecting the marked sub-aggregate initializer (of type S) W w = {.D.2445={.s={.D.2387={.m=0}, .b=0}}}; ^ ultimately because said initializer has CONSTRUCTOR_NO_CLEARING set, hence the function must verify that all fields of S are initialized. And before C++17 it doesn't expect to see base class fields (since next_initializable_field skips over them), so the presence thereof causes r_c_e_p to return false. The reason r10-7313-gb599bf9d6d1e18 causes this is because in that commit we began using CONSTRUCTOR_NO_CLEARING to precisely track whether we're in middle of activating a union member. This ends up affecting clear_no_implicit_zero, which recurses into sub-aggregate initializers only if the outer initializer has CONSTRUCTOR_NO_CLEARING set. After that commit, the outer union initializer above no longer has the flag set at this point and so clear_no_implicit_zero no longer recurses into the marked inner initializer. But arguably r_c_e_p should be able to accept the marked initializer regardless of whether CONSTRUCTOR_NO_CLEARING is set. The primary bug therefore seems to be that r_c_e_p relies on next_initializable_field which skips over base class fields in C++11/14. To fix this, this patch introduces a new helper function next_subobject_field which is like next_initializable_field except that it never skips base class fields, and makes r_c_e_p use it. This patch then renames next_initializable_field to next_aggregate_field (and makes it skip over vptr fields again). PR c++/105491 gcc/cp/ChangeLog: * call.cc (field_in_pset): Adjust after next_initializable_field renaming. (build_aggr_conv): Likewise. (convert_like_internal): Likewise. (type_has_extended_temps): Likewise. * class.cc (default_init_uninitialized_part): Likewise. (finish_struct): Likewise. * constexpr.cc (cx_check_missing_mem_inits): Likewise. (reduced_constant_expression_p): Use next_subobject_field instead. * cp-gimplify.cc (get_source_location_impl_type): Adjust after next_initializable_field renaming. (fold_builtin_source_location): Likewise. * cp-tree.h (next_initializable_field): Rename to ... (next_aggregate_field): ... this. (next_subobject_field): Declare. * decl.cc (next_aggregate_field): Renamed from ... (next_initializable_field): ... this. Skip over vptr fields again. (next_subobject_field): Define. (reshape_init_class): Adjust after next_initializable_field renaming. * init.cc (build_value_init_noctor): Likewise. (emit_mem_initializers): Likewise. * lambda.cc (build_capture_proxy): Likewise. * method.cc (build_comparison_op): Likewise. * pt.cc (maybe_aggr_guide): Likewise. * tree.cc (structural_type_p): Likewise. * typeck2.cc (split_nonconstant_init_1): Likewise. (digest_init_r): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-union7.C: New test. * g++.dg/cpp0x/constexpr-union7a.C: New test. * g++.dg/cpp2a/constinit17.C: New test.
2022-05-07c, c++: attribute format on a ctor with a vbase [PR101833, PR47634]Marek Polacek1-0/+19
Attribute format takes three arguments: archetype, string-index, and first-to-check. The last two specify the position in the function parameter list. r63030 clarified that "Since non-static C++ methods have an implicit this argument, the arguments of such methods should be counted from two, not one, when giving values for string-index and first-to-check." Therefore one has to write struct D { D(const char *, ...) __attribute__((format(printf, 2, 3))); }; However -- and this is the problem in this PR -- ctors with virtual bases also get two additional parameters: the in-charge parameter and the VTT parameter (added in maybe_retrofit_in_chrg). In fact we'll end up with two clones of the ctor: an in-charge and a not-in-charge version (see build_cdtor_clones). That means that the argument position the user specified in the attribute argument will refer to different arguments, depending on which constructor we're currently dealing with. This can cause a range of problems: wrong errors, confusing warnings, or crashes. This patch corrects that; for C we don't have to do anything, and in C++ we can use num_artificial_parms_for. It would be wrong to rewrite the attributes the user supplied, so I've changed POS to be passed by reference so that we don't have to change all the call sites of positional_argument and we still get the default_conversion adjustment. Attribute format_arg is not affected, because it requires that the function returns "const char *" which will never be the case for cdtors. PR c++/101833 PR c++/47634 gcc/c-family/ChangeLog: * c-attribs.cc (positional_argument): Pass POS by reference. Deal with FN being either a function declaration or function type. Use maybe_adjust_arg_pos_for_attribute. * c-common.cc (check_function_arguments): Maybe pass FNDECL down to check_function_format. * c-common.h (maybe_adjust_arg_pos_for_attribute): Declare. (positional_argument): Adjust. * c-format.cc (get_constant): Rename to ... (validate_constant): ... this. Take EXPR by reference. Return bool instead of tree. (handle_format_arg_attribute): Don't overwrite FORMAT_NUM_EXPR by the return value of validate_constant. (decode_format_attr): Don't overwrite FORMAT_NUM_EXPR and FIRST_ARG_NUM_EXPR by the return value of validate_constant. (check_function_format): Adjust a parameter name. (handle_format_attribute): Maybe pass FNDECL down to decode_format_attr. gcc/c/ChangeLog: * c-objc-common.cc (maybe_adjust_arg_pos_for_attribute): New. gcc/cp/ChangeLog: * tree.cc (maybe_adjust_arg_pos_for_attribute): New. gcc/ChangeLog: * tree-core.h (struct attribute_spec): Update comment for HANDLER. gcc/testsuite/ChangeLog: * g++.dg/ext/attr-format-arg1.C: New test. * g++.dg/ext/attr-format1.C: New test. * g++.dg/ext/attr-format2.C: New test. * g++.dg/ext/attr-format3.C: New test.
2022-04-27c++: add commentsJason Merrill1-1/+2
gcc/cp/ChangeLog: * tree.cc (strip_typedefs): Add default argument comments.
2022-04-08c++: constexpr non-trivial aggregate init [PR105191]Jason Merrill1-5/+22
My patch for PR92385 made us use VEC_INIT_EXPR for aggregate initialization of an array where some elements are not explicitly initialized. Constexpr handling of that was treating initialization from {} as equivalent to value-initialization, which is problematic for classes with default member initializers that make the default constructor non-trivial; in older standard modes, not initializing all members makes a constructor non-constexpr, but aggregate initialization is fine. PR c++/105191 PR c++/92385 gcc/cp/ChangeLog: * tree.cc (build_vec_init_elt): Do {}-init for aggregates. * constexpr.cc (cxx_eval_vec_init): Only treat {} as value-init for non-aggregate types. (build_vec_init_expr): Also check constancy of explicit initializer elements. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-array28.C: New test.
2022-03-28c++: hash table ICE with variadic alias [PR105003]Jason Merrill1-12/+1
For PR104008 we thought it might be enough to keep strip_typedefs from removing this alias template specialization, but this PR demonstrates that other parts of the compiler also need to know to consider it dependent. So, this patch changes complex_alias_template_p to no longer consider template parameters used when their only use appears in a pack expansion, unless they are the parameter packs being expanded. To do that I also needed to change it to use cp_walk_tree instead of for_each_template_parm. It occurs to me that find_template_parameters should probably also use cp_walk_tree, but I'm not messing with that now. PR c++/105003 PR c++/104008 PR c++/102869 gcc/cp/ChangeLog: * pt.cc (complex_alias_template_r): walk_tree callback, replacing uses_all_template_parms_r, complex_pack_expansion_r. (complex_alias_template_p): Adjust. * tree.cc (strip_typedefs): Revert r12-7710 change. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/variadic-alias6.C: New test. * g++.dg/cpp0x/variadic-alias7.C: New test.
2022-03-28c++: ICE with alias in pack expansion [PR103769]Jason Merrill1-1/+1
This was breaking because when we stripped the 't' typedef in s<t<Args>...> to be s<Args...>, the TYPE_MAIN_VARIANT of "Args..." was still "t<Args>...", because type pack expansions are treated as types. Fixed by using the right function to copy a "type". PR c++/99445 PR c++/103769 gcc/cp/ChangeLog: * tree.cc (strip_typedefs): Use build_distinct_type_copy. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/variadic-alias5.C: New test.
2022-03-18c++: alias template and empty parameter packs [PR104008]Marek Polacek1-1/+12
Zero-length pack expansions are treated as if no list were provided at all, that is, with template<typename...> struct S { }; template<typename T, typename... Ts> void g() { S<std::is_same<T, Ts>...>; } g<int> will result in S<>. In the following test we have something similar: template <typename T, typename... Ts> using IsOneOf = disjunction<is_same<T, Ts>...>; and then we have "IsOneOf<OtherHolders>..." where OtherHolders is an empty pack. Since r11-7931, we strip_typedefs in TYPE_PACK_EXPANSION. In this test that results in "IsOneOf<OtherHolders>" being turned into "disjunction<>". So the whole expansion is now "disjunction<>...". But then we error in make_pack_expansion because find_parameter_packs_r won't find the pack OtherHolders. We strip the alias template because dependent_alias_template_spec_p says it's not dependent. It it not dependent because this alias is not TEMPLATE_DECL_COMPLEX_ALIAS_P. My understanding is that currently we consider an alias complex if it 1) expands a pack from the enclosing class, as in template<template<typename... U> typename... TT> struct S { template<typename... Args> using X = P<TT<Args...>...>; }; where the alias expands TT; or 2) the expansion does *not* name all the template parameters, as in template<typename...> struct R; template<typename T, typename... Ts> using U = R<X<Ts>...>; where T is not named in the expansion. But IsOneOf is neither. And it can't know how it's going to be used. Therefore I think we cannot make it complex (and in turn dependent) to fix this bug. After much gnashing of teeth, I think we simply want to avoid stripping the alias if the new pattern doesn't have any parameter packs to expand. PR c++/104008 gcc/cp/ChangeLog: * tree.cc (strip_typedefs): Don't strip an alias template when doing so would result in losing a parameter pack. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/variadic-alias3.C: New test. * g++.dg/cpp0x/variadic-alias4.C: New test.
2022-02-05c++: assignment, aggregate, array [PR104300]Jason Merrill1-2/+2
The PR92385 fix meant that we see more VEC_INIT_EXPR outside of INIT_EXPR; in such cases, we need to wrap them in TARGET_EXPR. I previously fixed that in build_array_copy; we also need it in process_init_constructor. After fixing that, I needed to adjust a few places to recognize the VEC_INIT_EXPR even inside a TARGET_EXPR. And prevent cp_fully_fold_init from lowering VEC_INIT_EXPR too soon. And handle COMPOUND_EXPR inside TARGET_EXPR better. PR c++/104300 PR c++/92385 gcc/cp/ChangeLog: * cp-tree.h (get_vec_init_expr): New. (target_expr_needs_replace): New. * cp-gimplify.cc (cp_gimplify_init_expr): Use it. (struct cp_fold_data): New. (cp_fold_r): Only genericize inits at end of fn. (cp_fold_function): Here. (cp_fully_fold_init): Not here. * init.cc (build_vec_init): Use get_vec_init_expr. * tree.cc (build_vec_init_expr): Likewise. * typeck2.cc (split_nonconstant_init_1): Likewise. (process_init_constructor): Wrap VEC_INIT_EXPR in TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array14.C: New test.