On musl <pthread.h> uses calloc() (via <sched.h>). <memory> includes
it indirectly and exposes use of poisoned calloc() when module code
is built:
/build/build/./prev-gcc/xg++ ... ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc
In file included from /<<NIX>>/musl-1.2.3-dev/include/pthread.h:30,
from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/x86_64-unknown-linux-musl/bits/gthr-default.h:35,
....
from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/memory:77,
from ../../gcc-13-20220626/gcc/../libcody/cody.hh:24,
from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.h:25,
from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.cc:23,
from ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc:32:
/<<NIX>>/musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
84 | void *calloc(size_t, size_t);
| ^
/<<NIX>>/musl-1.2.3-dev/include/sched.h:124:36: error: attempt to use poisoned "calloc"
124 | #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
| ^
gcc/cp/
PR c++/106102
* mapper-client.cc: Include <memory> via "system.h".
* mapper-resolver.cc: Ditto.
* module.cc: Ditto.
libcc1/
PR c++/106102
* libcc1plugin.cc: Include <memory> via "system.h".
* libcp1plugin.cc: Ditto.
In order to properly implement two-stage name lookup for dependent
operator expressions, we need to remember the result of unqualified
lookup of the operator at template definition time, and reuse that
result rather than performing another unqualified lookup at
instantiation time.
Ideally we could just store the lookup in the expression directly, but
as pointed out in r9-6405 this isn't really possible since we use the
standard tree codes to represent most dependent operator expressions.
We could perhaps create a new tree code to represent dependent operator
expressions, with enough operands to store the lookup along with
everything else, but that'd require a lot of careful work to make sure
we handle this new tree code properly across the frontend.
But currently type-dependent operator (and call) expressions are given
an empty TREE_TYPE, which dependent_type_p treats as dependent, so this
field is effectively unused except to signal that the expression is
type-dependent. It'd be convenient if we could store the lookup there
while preserving the dependent-ness of the expression.
To that end, this patch creates a new kind of type, called
DEPENDENT_OPERATOR_TYPE, which we give to dependent operator expressions
and into which we can store the result of operator lookup at template
definition time (DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS). Since this
type is always dependent (by definition), and since the frontend doesn't
seem to care much about the exact type of a type-dependent expression,
using this type in place of a NULL_TREE type seems to "just work"; only
dependent_type_p and WILDCARD_TYPE_P need to be adjusted to return true
for this new type.
The rest of the patch mostly consists of adding the necessary plumbing
to pass DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS to add_operator_candidates,
adjusting all callers of build_x_* appropriately, and removing the now
unnecessary push_operator_bindings mechanism.
In passing, this patch simplifies finish_constraint_binary_op to avoid
using build_x_binary_op for building a binary constraint-expr; we don't
need to consider operator overloads here, as the &&/|| inside a
constraint effectively always has the built-in meaning (since atomic
constraints must have bool type).
This patch also makes FOLD_EXPR_OP yield a tree_code instead of a raw
INTEGER_CST.
Finally, this patch adds the XFAILed test operator-8.C which is about
broken two-stage name lookup for rewritten non-dependent operator
expressions, an existing bug that's otherwise only documented in
build_new_op.
PR c++/51577
PR c++/83035
PR c++/100465
gcc/cp/ChangeLog:
* call.c (add_operator_candidates): Add lookups parameter.
Use it to avoid performing a second unqualified lookup when
instantiating a dependent operator expression.
(build_new_op): Add lookups parameter and pass it appropriately.
* constraint.cc (finish_constraint_binary_op): Use
build_min_nt_loc instead of build_x_binary_op.
* coroutines.cc (build_co_await): Adjust call to build_new_op.
* cp-objcp-common.c (cp_common_init_ts): Mark
DEPENDENT_OPERATOR_TYPE appropriately.
* cp-tree.def (DEPENDENT_OPERATOR_TYPE): Define.
* cp-tree.h (WILDCARD_TYPE_P): Accept DEPENDENT_OPERATOR_TYPE.
(FOLD_EXPR_OP_RAW): New, renamed from ...
(FOLD_EXPR_OP): ... this. Change this to return the tree_code directly.
(DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS): Define.
(templated_operator_saved_lookups): Define.
(build_new_op): Add lookups parameter.
(build_dependent_operator_type): Declare.
(build_x_indirect_ref): Add lookups parameter.
(build_x_binary_op): Likewise.
(build_x_unary_op): Likewise.
(build_x_compound_expr): Likewise.
(build_x_modify_expr): Likewise.
* cxx-pretty-print.c (get_fold_operator): Adjust after
FOLD_EXPR_OP change.
* decl.c (start_preparsed_function): Don't call
push_operator_bindings.
* decl2.c (grok_array_decl): Adjust calls to build_new_op.
* method.c (do_one_comp): Likewise.
(build_comparison_op): Likewise.
* module.cc (trees_out::type_node): Handle DEPENDENT_OPERATOR_TYPE.
(trees_in::tree_node): Likewise.
* name-lookup.c (lookup_name): Revert r11-2876 change.
(op_unqualified_lookup): Remove.
(maybe_save_operator_binding): Remove.
(discard_operator_bindings): Remove.
(push_operator_bindings): Remove.
* name-lookup.h (maybe_save_operator_binding): Remove.
(push_operator_bindings): Remove.
(discard_operator_bindings): Remove.
* parser.c (cp_parser_unary_expression): Adjust calls to build_x_*.
(cp_parser_binary_expression): Likewise.
(cp_parser_assignment_expression): Likewise.
(cp_parser_expression): Likewise.
(do_range_for_auto_deduction): Likewise.
(cp_convert_range_for): Likewise.
(cp_parser_perform_range_for_lookup): Likewise.
(cp_parser_template_argument): Likewise.
(cp_parser_omp_for_cond): Likewise.
(cp_parser_omp_for_incr): Likewise.
(cp_parser_omp_for_loop_init): Likewise.
(cp_convert_omp_range_for): Likewise.
(cp_finish_omp_range_for): Likewise.
* pt.c (fold_expression): Adjust after FOLD_EXPR_OP change. Pass
templated_operator_saved_lookups to build_x_*.
(tsubst_omp_for_iterator): Adjust call to build_x_modify_expr.
(tsubst_expr) <case COMPOUND_EXPR>: Pass
templated_operator_saved_lookups to build_x_*.
(tsubst_copy_and_build) <case INDIRECT_REF>: Likewise.
<case tcc_unary>: Likewise.
<case tcc_binary>: Likewise.
<case MODOP_EXPR>: Likewise.
<case COMPOUND_EXPR>: Likewise.
(dependent_type_p_r): Return true for DEPENDENT_OPERATOR_TYPE.
* ptree.c (cxx_print_type): Handle DEPENDENT_OPERATOR_TYPE.
* semantics.c (finish_increment_expr): Adjust call to
build_x_unary_op.
(finish_unary_op_expr): Likewise.
(handle_omp_for_class_iterator): Adjust calls to build_x_*.
(finish_omp_cancel): Likewise.
(finish_unary_fold_expr): Use build_dependent_operator_type.
(finish_binary_fold_expr): Likewise.
* tree.c (cp_free_lang_data): Don't call discard_operator_bindings.
* typeck.c (rationalize_conditional_expr): Adjust call to
build_x_binary_op.
(op_unqualified_lookup): Define.
(build_dependent_operator_type): Define.
(build_x_indirect_ref): Add lookups parameter and use
build_dependent_operator_type.
(build_x_binary_op): Likewise.
(build_x_array_ref): Likewise.
(build_x_unary_op): Likewise.
(build_x_compound_expr_from_list): Adjust call to
build_x_compound_expr.
(build_x_compound_expr_from_vec): Likewise.
(build_x_compound_expr): Add lookups parameter and use
build_dependent_operator_type.
(cp_build_modify_expr): Adjust call to build_new_op.
(build_x_modify_expr): Add lookups parameter and use
build_dependent_operator_type.
* typeck2.c (build_x_arrow): Adjust call to build_new_op.
libcc1/ChangeLog:
* libcp1plugin.cc (plugin_build_unary_expr): Adjust call to
build_x_unary_op.
(plugin_build_binary_expr): Adjust call to build_x_binary_op.
gcc/testsuite/ChangeLog:
* g++.dg/lookup/operator-3.C: Split out operator overload
declarations into ...
* g++.dg/lookup/operator-3-ops.h: ... here.
* g++.dg/lookup/operator-3a.C: New test.
* g++.dg/lookup/operator-4.C: New test.
* g++.dg/lookup/operator-4a.C: New test.
* g++.dg/lookup/operator-5.C: New test.
* g++.dg/lookup/operator-5a.C: New test.
* g++.dg/lookup/operator-6.C: New test.
* g++.dg/lookup/operator-7.C: New test.
* g++.dg/lookup/operator-8.C: New test.
This patch completes the transition of libcc1 from the use of separate
template functions for different arities to the use of variadic
functions. This is how I had wanted it to work from the very
beginning, and is possible now with C++11.
I had thought that variadic callbacks required C++17, but it turns out
that the approach taken here is basically equivalent to std::apply --
just a bit wordier.
libcc1
* rpc.hh (argument_wrapper) <get>: Replace cast operator.
(argument_wrapper<T *>) <get>: Likewise.
(unmarshall): Add std::tuple overloads.
(callback): Remove.
(class invoker): New.
* libcp1plugin.cc (plugin_init): Update.
* libcp1.cc (libcp1::add_callbacks): Update.
* libcc1plugin.cc (plugin_init): Update.
* libcc1.cc (libcc1::add_callbacks): Update.
* connection.cc (cc1_plugin::connection::do_wait): Update.
Both plugins in libcc1 share a fair amount of boilerplate. They both
share error-emission code, context management code, and tree GC code.
This patch unifies these two bodies of code, avoiding needless
duplication.
libcc1
* libcc1plugin.cc: Move code to context.cc.
* libcp1plugin.cc: Move code to context.cc.
* context.hh: New file.
* context.cc: New file.
* Makefile.in: Rebuild.
* Makefile.am (AM_CPPFLAGS): Add more gcc flags.
(CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update.
(libcc1plugin_la_SOURCES): Add context.hh, context.cc.
(libcp1plugin_la_SOURCES): Likewise.
This changes libcc1 to ues foreach in a couple of spots.
libcc1
* libcp1plugin.cc (plugin_context::mark): Use foreach.
* libcc1plugin.cc (plugin_context::mark): Use foreach.
This changes libcc1 to use std::vector in the code that builds
function types. This avoids some explicit memory management.
libcc1
* libcp1plugin.cc (plugin_build_function_type): Use std::vector.
* libcc1plugin.cc (plugin_build_function_type): Use std::vector.
We're currently neglecting to set the ALIGNOF_EXPR_STD_P flag on an
ALIGNOF_EXPR when its operand is an expression. This leads to us
handling alignof(expr) as if it were written __alignof__(expr), and
returning the preferred alignment instead of the ABI alignment. In the
testcase below, this causes the first and third static_assert to fail on
x86.
gcc/cp/ChangeLog:
PR c++/88115
* cp-tree.h (cxx_sizeof_or_alignof_expr): Add bool parameter.
* decl.c (fold_sizeof_expr): Pass false to
cxx_sizeof_or_alignof_expr.
* parser.c (cp_parser_unary_expression): Pass std_alignof to
cxx_sizeof_or_alignof_expr.
* pt.c (tsubst_copy): Pass false to cxx_sizeof_or_alignof_expr.
(tsubst_copy_and_build): Pass std_alignof to
cxx_sizeof_or_alignof_expr.
* typeck.c (cxx_alignof_expr): Add std_alignof bool parameter
and pass it to cxx_sizeof_or_alignof_type. Set ALIGNOF_EXPR_STD_P
appropriately.
(cxx_sizeof_or_alignof_expr): Add std_alignof bool parameter
and pass it to cxx_alignof_expr. Assert op is either
SIZEOF_EXPR or ALIGNOF_EXPR.
libcc1/ChangeLog:
PR c++/88115
* libcp1plugin.cc (plugin_build_unary_expr): Pass true to
cxx_sizeof_or_alignof_expr.
gcc/testsuite/ChangeLog:
PR c++/88115
* g++.dg/cpp0x/alignof6.C: New test.
Currently, when a static_assert fails, we only say "static assertion failed".
It would be more useful if we could also print the expression that
evaluated to false; this is especially useful when the condition uses
template parameters. Consider the motivating example, in which we have
this line:
static_assert(is_same<X, Y>::value);
if this fails, the user has to play dirty games to get the compiler to
print the template arguments. With this patch, we say:
error: static assertion failed
note: 'is_same<int*, int>::value' evaluates to false
which I think is much better. However, always printing the condition that
evaluated to 'false' wouldn't be very useful: e.g. noexcept(fn) is
always parsed to true/false, so we would say "'false' evaluates to false"
which doesn't help. So I wound up only printing the condition when it was
instantiation-dependent, that is, we called finish_static_assert from
tsubst_expr.
Moreover, this patch also improves the diagnostic when the condition
consists of a logical AND. Say you have something like this:
static_assert(fn1() && fn2() && fn3() && fn4() && fn5());
where fn4() evaluates to false and the other ones to true. Highlighting
the whole thing is not that helpful because it won't say which clause
evaluated to false. With the find_failing_clause tweak in this patch
we emit:
error: static assertion failed
6 | static_assert(fn1() && fn2() && fn3() && fn4() && fn5());
| ~~~^~
so you know right away what's going on. Unfortunately, when you combine
both things, that is, have an instantiation-dependent expr and && in
a static_assert, we can't yet quite point to the clause that failed. It
is because when we tsubstitute something like is_same<X, Y>::value, we
generate a VAR_DECL that doesn't have any location. It would be awesome
if we could wrap it with a location wrapper, but I didn't see anything
obvious.
In passing, I've cleaned up some things:
* use iloc_sentinel when appropriate,
* it's nicer to call contextual_conv_bool instead of the rather verbose
perform_implicit_conversion_flags,
* no need to check for INTEGER_CST before calling integer_zerop.
gcc/cp/ChangeLog:
PR c++/97518
* cp-tree.h (finish_static_assert): Adjust declaration.
* parser.c (cp_parser_static_assert): Pass false to
finish_static_assert.
* pt.c (tsubst_expr): Pass true to finish_static_assert.
* semantics.c (find_failing_clause_r): New function.
(find_failing_clause): New function.
(finish_static_assert): Add a bool parameter. Use
iloc_sentinel. Call contextual_conv_bool instead of
perform_implicit_conversion_flags. Don't check for INTEGER_CST before
calling integer_zerop. Call find_failing_clause and maybe use its
location. Print the original condition or the failing clause if
SHOW_EXPR_P.
gcc/testsuite/ChangeLog:
PR c++/97518
* g++.dg/diagnostic/pr87386.C: Adjust expected output.
* g++.dg/diagnostic/static_assert1.C: New test.
* g++.dg/diagnostic/static_assert2.C: New test.
libcc1/ChangeLog:
PR c++/97518
* libcp1plugin.cc (plugin_add_static_assert): Pass false to
finish_static_assert.
In cleaning up C++'s handling of hidden decls, I renamed its
DECL_BUILTIN_P, which checks for loc == BUILTINS_LOCATION to
DECL_UNDECLARED_BUILTIN_P, because the location gets updated, if user
source declares the builtin, and the predicate no longer holds. The
original name was confusing me. (The builtin may still retain builtin
properties in the redeclaration, and other predicates can still detect
that.)
I discovered that tree.h had its own variant 'DECL_IS_BUILTIN', which
behaves in (almost) the same manner. And therefore has the same
mutating behaviour.
This patch deletes the C++ one, and renames tree.h's to
DECL_IS_UNDECLARED_BUILTIN, to emphasize its non-constantness. I
guess _IS_ wins over _P
gcc/
* tree.h (DECL_IS_BUILTIN): Rename to ...
(DECL_IS_UNDECLARED_BUILTIN): ... here. No need to use SOURCE_LOCUS.
* calls.c (maybe_warn_alloc_args_overflow): Adjust for rename.
* cfgexpand.c (pass_expand::execute): Likewise.
* dwarf2out.c (base_type_die, is_naming_typedef_decl): Likewise.
* godump.c (go_decl, go_type_decl): Likewise.
* print-tree.c (print_decl_identifier): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-ssa-ccp.c (pass_post_ipa_warn::execute): Likewise.
* xcoffout.c (xcoff_assign_fundamental_type_number): Likewise.
gcc/c-family/
* c-ada-spec.c (collect_ada_nodes): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
(collect_ada_node): Likewise.
(dump_forward_type): Likewise.
* c-common.c (set_underlying_type): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
(user_facing_original_type, c_common_finalize_early_debug): Likewise.
gcc/c/
* c-decl.c (diagnose_mismatched_decls): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
(warn_if_shadowing, implicitly_declare, names_builtin_p)
(collect_source_refs): Likewise.
* c-typeck.c (inform_declaration, inform_for_arg)
(convert_for_assignment): Likewise.
gcc/cp/
* cp-tree.h (DECL_UNDECLARED_BUILTIN_P): Delete.
* cp-objcp-common.c (names_bultin_p): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
* decl.c (decls_match): Likewise. Replace
DECL_UNDECLARED_BUILTIN_P with DECL_IS_UNDECLARED_BUILTIN.
(duplicate_decls): Likewise.
* decl2.c (collect_source_refs): Likewise.
* name-lookup.c (anticipated_builtin_p, print_binding_level)
(do_nonmember_using_decl): Likewise.
* pt.c (builtin_pack_fn_p): Likewise.
* typeck.c (error_args_num): Likewise.
gcc/lto/
* lto-symtab.c (lto_symtab_merge_decls_1): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
gcc/go/
* go-gcc.cc (Gcc_backend::call_expression): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
libcc1/
* libcc1plugin.cc (address_rewriter): Rename
DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN.
* libcp1plugin.cc (supplement_binding): Likewise.
DECL_FRIEND_P's meaning has changed over time. It now (almost) means
the the friend function decl has not been met via an explicit decl.
This completes that transition, renaming it to DECL_UNIQUE_FRIEND_P,
so one doesn't think it is the sole indicator of friendliness (plenty
of friends do not have the flag set). This allows reduction in the
complexity of managing the field -- all in duplicate_decls now.
gcc/cp/
* cp-tree.h (struct lang_decl_fn): Adjust context comment.
(DECL_FRIEND_P): Replace with ...
(DECL_UNIQUE_FRIEND_P): ... this. Only for FUNCTION_DECLs.
(DECL_FRIEND_CONTEXT): Adjust.
* class.c (add_implicitly_declared_members): Detect friendly
spaceship from context.
* constraint.cc (remove_constraints): Use a checking assert.
(maybe_substitute_reqs_for): Use DECL_UNIQUE_FRIEND_P.
* decl.c (check_no_redeclaration_friend_default_args):
DECL_UNIQUE_FRIEND_P is signficant, not hiddenness.
(duplicate_decls): Adjust DECL_UNIQUE_FRIEND_P clearing.
(redeclaration_error_message): Use DECL_UNIQUE_FRIEND_P.
(start_preparsed_function): Correct in-class friend processing.
Refactor some initializers.
(grokmethod): Directly check friend decl-spec.
* decl2.c (grokfield): Check DECL_UNIQUE_FRIEND_P.
* friend.c (do_friend): Set DECL_UNIQUE_FRIEND_P first, remove
extraneous conditions. Don't re set it afterwards.
* name-lookup.c (lookup_elaborated_type_1): Simplify revealing
code.
(do_pushtag): Likewise.
* pt.c (optimize_specialization_lookup_p): Check
DECL_UNIQUE_FRIEND_P.
(push_template_decl): Likewise. Drop unneeded friend setting.
(type_dependent_expression_p): Check DECL_UNIQUE_FRIEND_P.
libcc1/
* libcp1plugin.cc (plugin_add_friend): Set DECL_UNIQUE_FRIEND_P.
I realized I'd misnamed DECL_BUILTIN_P, it's only true of compiler
builtins unless and until the user declares them -- at that point
they're real decls, and will have a location in the user's source.
(BUILT_IN_FN and friends still work though). This renames them so
future-me is not confused as to why the predicate becomes false.
gcc/cp/
* cp-tree.h (DECL_BUILTIN_P): Rename to ...
(DECL_UNDECLARED_BUILTIN_P): ... here.
* decl.c (duplicate_decls): Adjust.
* name-lookup.c (anticipated_builtin_p): Adjust.
(do_nonmember_using_decl): Likewise.
libcc1/
* libcp1plugin.cc (supplement_binding): Rename
DECL_BUILTIN_P.
Here's the patch to remove DECL_ANTICIPATED, and with it hiddenness is
managed entirely in the symbol table. Sadly I couldn't get rid of the
actual field without more investigation -- it's repurposed for
OMP_PRIVATIZED_MEMBER. It looks like a the VAR-related flags in
lang_decl_base are not completely orthogonal, so perhaps some can be
turned into an enumeration or something. But that's more than I want
to do right now.
DECL_FRIEND_P Is still slightly suspect as it appears to mean more
than just in-class definition. However, I'm leaving that for now.
gcc/cp/
* cp-tree.h (lang_decl_base): anticipated_p is not used for
anticipatedness.
(DECL_ANTICIPATED): Delete.
* decl.c (duplicate_decls): Delete DECL_ANTICIPATED_management,
use was_hidden.
(cxx_builtin_function): Drop DECL_ANTICIPATED setting.
(xref_tag_1): Drop DECL_ANTICIPATED assert.
* name-lookup.c (name_lookup::adl_class_only): Drop
DECL_ANTICIPATED check.
(name_lookup::search_adl): Always dedup.
(anticipated_builtin_p): Reimplement.
(do_pushdecl): Drop DECL_ANTICIPATED asserts & update.
(lookup_elaborated_type_1): Drop DECL_ANTICIPATED update.
(do_pushtag): Drop DECL_ANTICIPATED setting.
* pt.c (push_template_decl): Likewise.
(tsubst_friend_class): Likewise.
libcc1/
* libcp1plugin.cc (libcp1plugin.cc): Drop DECL_ANTICIPATED test.
We currently detect builtin decls via DECL_ARTIFICIAL &&
!DECL_HIDDEN_FUNCTION_P, which, besides being clunky, is a problem as
hiddenness is a property of the symbol table -- not the decl being
hidden. This adds DECL_BUILTIN_P, which just looks at the
SOURCE_LOCATION -- we have a magic one for builtins.
One of the consequential changes is to make function-scope omp udrs
have function context (needed because otherwise duplicate-decls thinks
the types don't match at the point we check). This is also morally
better, because that's what they are -- nested functions, stop lying.
(That's actually my plan for all DECL_LOCAL_DECL_P decls, as they are
distinct decls to the namespace-scope decl they alias.)
gcc/cp/
* cp-tree.h (DECL_BUILTIN_P): New.
* decl.c (duplicate_decls): Use it. Do not treat omp-udr as a
builtin.
* name-lookup.c (anticipated_builtin): Use it.
(set_decl_context_in_fn): Function-scope OMP UDRs have function context.
(do_nonmember_using_decl): Use DECL_BUILTIN_P.
* parser.c (cp_parser_omp_declare_reduction): Function-scope OMP
UDRs have function context. Assert we never find a valid duplicate.
* pt.c (tsubst_expr): Function-scope OMP UDRs have function context.
libcc1/
* libcp1plugin.cc (supplement_binding): Use DECL_BULTIN_P.
In cleaning up local decl handling, here's an initial patch that takes
advantage of C++'s default args for the is_friend parm of pushdecl,
duplicate_decls and push_template_decl_real and the scope & tpl_header
parms of xref_tag. Then many of the calls simply not mention these.
I also rename push_template_decl_real to push_template_decl, deleting
the original forwarding function. This'll make my later patches
changing their types less intrusive. There are 2 functional changes:
1) push_template_decl requires is_friend to be correct, it doesn't go
checking for a friend function (an assert is added).
2) debug_overload prints out Hidden and Using markers for the overload set.
gcc/cp/
* cp-tree.h (duplicate_decls): Default is_friend to false.
(xref_tag): Default tag_scope & tpl_header_p to ts_current & false.
(push_template_decl_real): Default is_friend to false. Rename to
...
(push_template_decl): ... here. Delete original decl.
* name-lookup.h (pushdecl_namespace_level): Default is_friend to
false.
(pushtag): Default tag_scope to ts_current.
* coroutines.cc (morph_fn_to_coro): Drop default args to xref_tag.
* decl.c (start_decl): Drop default args to duplicate_decls.
(start_enum): Drop default arg to pushtag & xref_tag.
(start_preparsed_function): Pass DECL_FRIEND_P to
push_template_decl.
(grokmethod): Likewise.
* friend.c (do_friend): Rename push_template_decl_real calls.
* lambda.c (begin_lamnbda_type): Drop default args to xref_tag.
(vla_capture_type): Likewise.
* name-lookup.c (maybe_process_template_type_declaration): Rename
push_template_decl_real call.
(pushdecl_top_level_and_finish): Drop default arg to
pushdecl_namespace_level.
* pt.c (push_template_decl_real): Assert no surprising friend
functions. Rename to ...
(push_template_decl): ... here. Delete original function.
(lookup_template_class_1): Drop default args from pushtag.
(instantiate_class_template_1): Likewise.
* ptree.c (debug_overload): Print hidden and using markers.
* rtti.c (init_rtti_processing): Drop refault args from xref_tag.
(build_dynamic_cast_1, tinfo_base_init): Likewise.
* semantics.c (begin_class_definition): Drop default args to
pushtag.
gcc/objcp/
* objcp-decl.c (objcp_start_struct): Drop default args to
xref_tag.
(objcp_xref_tag): Likewise.
libcc1/
* libcp1plugin.cc (supplement_binding): Drop default args to
duplicate_decls.
(safe_pushtag): Drop scope parm. Drop default args to pushtag.
(safe_pushdecl_maybe_friend): Rename to ...
(safe_pushdecl): ... here. Drop is_friend parm. Drop default args
to pushdecl.
(plugin_build_decl): Adjust safe_pushdecl & safe_pushtag calls.
(plugin_build_constant): Adjust safe_pushdecl call.
Our handling of block-scope extern decls is insufficient for modern
C++, in particular modules, (but also constexprs). We mark such local
function decls, and this patch extends that to marking local var decls
too, so mainly a macro rename. Also, we set this flag earlier, rather
than learning about it when pushing the decl. This is a step towards
handling these properly.
gcc/cp/
* cp-tree.h (DECL_LOCAL_FUNCTION_P): Rename to ...
(DECL_LOCAL_DECL_P): ... here. Accept both fns and vars.
* decl.c (start_decl): Set DECL_LOCAL_DECL_P for local externs.
(omp_declare_variant_finalize_one): Use DECL_LOCAL_DECL_P.
(local_variable_p): Simplify.
* name-lookup.c (set_decl_context_in_fn): Assert DECL_LOCAL_DECL_P
is as expected. Simplify.
(do_pushdecl): Don't set decl_context_in_fn for friends.
(is_local_extern): Simplify.
* call.c (equal_functions): Use DECL_LOCAL_DECL_P.
* parser.c (cp_parser_postfix_expression): Likewise.
(cp_parser_omp_declare_reduction): Likewise.
* pt.c (check_default_tmpl_args): Likewise.
(tsubst_expr): Assert nested reduction function is local.
(type_dependent_expression_p): Use DECL_LOCAL_DECL_P.
* semantics.c (finish_call_expr): Likewise.
libcc1/
* libcp1plugin.cc (plugin_build_call_expr): Use DECL_LOCAL_DECL_P.
This patch deals with LOOKUP_HIDDEN, which originally meant 'find
hidden friends', but it's being pressed into service for not ignoring
lambda-relevant internals. However these two functions are different.
(a) hidden friends can occur in block scope (very uncommon) and (b) it
had the semantics of stopping after the innermost enclosing
namepspace. That's really suspect for the lambda case, but not
relevant there because we never get to namespace scope (I think).
Anyway, I've split the flag into two and adjusted the lambda callers
to just search block scope. These two flags are added to the
LOOK_want enum class, which allows dropping another parameter from the
name lookup routines.
The remaining LOOKUP_$FOO flags in cp-tree.h are, I think, now all
related to features of overload resolution, conversion operators and
reference binding. Nothing to do with /name/ lookup.
gcc/cp/
* cp-tree.h (LOOKUP_HIDDEN): Delete.
(LOOKUP_PREFER_RVALUE): Adjust initializer.
* name-lookup.h (enum class LOOK_want): Add HIDDEN_FRIEND and
HIDDEN_LAMBDA flags.
(lookup_name_real): Drop flags parm.
(lookup_qualified_name): Drop find_hidden parm.
* name-lookup.c (class name_lookup): Drop hidden field, adjust
ctors.
(name_lookup::add_overload): Check want for hiddenness.
(name_lookup::process_binding): Likewise.
(name_lookup::search_unqualified): Likewise.
(identifier_type_value_1): Adjust lookup_name_real call.
(set_decl_namespace): Adjust name_lookup ctor.
(qualify_lookup): Drop flags parm, use want for hiddenness.
(lookup_qualified_name): Drop find_hidden parm.
(lookup_name_real_1): Drop flags parm, adjust qualify_lookup
calls.
(lookup_name_real): Drop flags parm.
(lookup_name_nonclass, lookup_name): Adjust lookup_name_real
calls.
(lookup_type_scope_1): Adjust qualify_lookup calls.
* call.c (build_operator_new_call): Adjust lookup_name_real call.
(add_operator_candidates): Likewise.
* coroutines.cc (morph_fn_to_coro): Adjust lookup_qualified_name
call.
* parser.c (cp_parser_lookup_name): Adjust lookup_name_real calls.
* pt.c (check_explicit_specialization): Adjust
lookup_qualified_name call.
(deduction_guides_for): Likewise.
(tsubst_friend_class): Adjust lookup_name_real call.
(lookup_init_capture_pack): Likewise.
(tsubst_expr): Likewise, don't look in namespaces.
* semantics.c (capture_decltype): Adjust lookup_name_real. Don't
look in namespaces.
libcc1/
* libcp1plugin.cc (plugin_build_dependent_exp): Adjust
lookup_name_real call.
Continuing fixing name lookup's API we have two parameters saying what
we'd like to find 'prefer_type', which is a tri-valued boolan with
meaning 'don't care', 'type or namespace', 'type or death'. And we
have a second parameter 'namespaces_only', which means 'namespace or
death'. There are only 4 states, because the latter one has priority.
Firstly 'prefer_type' isn't really the right name -- it's not a preference,
it's a requirement. Name lookup maps those two parameters into 2 LOOKUP_
bits. We can simply have callers express that desire directly.
So this adds another enum class, LOOK_want, which expresses all
those options in 2 bits. Most of this patch is then the expected fallout
from such a change. The parser was mapping its internal state into
a prefer_type value, which was then mapped into the LOOKUP_ bits. So this
saves a conversion there. Also the parser's conversion routine had an
'is_template' flag, which was only ever true in one place, where the parser
also had to deal with other nuances of the flags to pass. So just drop
that parm and deal with it at the call site too.
I've left LOOKUP_HIDDEN alone for the moment. That'll be next.
gcc/cp/
* cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES)
(LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY)
(LOOKUP_QUALIFIERS_ONL): Delete.
(LOOKUP_HIDDEN): Adjust.
* name-lookup.h (enum class LOOK_want): New.
(operator|, operator&): Overloads for it.
(lookup_name_real): Replace prefer_type & namespaces_only with
LOOK_want parm.
(lookup_qualified_name): Replace prefer_type with LOOK_want.
(lookup_name_prefer_type): Replace with ...
(lookup_name): ... this. New overload with LOOK_want parm.
* name-lookup.c (struct name_lookup): Replace flags with want and
hidden fields. Adjust constructors.
(name_lookyp::add_overload): Correct hidden stripping test. Update
for new LOOK_want type.
(name_lookup::process_binding): Likewise.
(name_lookup::search_unqualified): Use hidden flag.
(identifier_type_value_1): Adjust lookup_name_real call.
(set_decl_namespace): Adjust name_lookup ctor.
(lookup_flags): Delete.
(qualify_lookup): Add LOOK_want parm, adjust.
(lookup_qualified_name): Replace prefer_type parm with LOOK_want.
(lookup_name_real_1): Replace prefer_type and namespaces_only with
LOOK_want parm.
(lookup_name_real): Likewise.
(lookup_name_nonclass, lookup_name): Adjust lookup_name_real call.
(lookup_name_prefer_type): Rename to ...
(lookup_name): ... here. New overload with LOOK_want parm.
(lookup_type_scope_1): Adjust qualify_lookup calls.
* call.c (build_operator_new_call)
(add_operator_candidates): Adjust lookup_name_real calls.
* coroutines.cc (find_coro_traits_template_decl)
(find_coro_handle_template_decl, morph_fn_to_coro): Adjust
lookup_qualified_name calls.
* cp-objcp-common.c (identifier_global_tag): Likewise.
* decl.c (get_tuple_size, get_tuple_decomp_init): Likewise.
(lookup_and_check_tag): Use lookup_name overload.
* parser.c (cp_parser_userdef_numeric_literal): Adjust
lookup_qualified_name call.
(prefer_arg_type): Drop template_mem_access parm, return LOOK_want
value.
(cp_parser_lookup_name): Adjust lookup_member, lookup_name_real
calls.
* pt.c (check_explicit_specialization): Adjust lookup_qualified_name
call.
(tsubst_copy_and_build, tsubst_qualified_name): Likewise
(deduction_guides_for): Likewise.
(tsubst_friend_class): Adjust lookup_name_real call.
(lookup_init_capture, tsubst_expr): Likewise.
* rtti.c (emit_support_tinfos): Adjust lookup_qualified_name call.
* semantics.c (omp_reduction_lookup): Likewise.
(capture_decltype): Adjust lookup_name_real call.
libcc1/
* libcp1plugin.cc (plugin_build_dependent_expr): Adjust
lookup_name_real & lookup_qualified_name calls.
The API for lookup_name_real is really confusing. This addresses the part
where we have NONCLASS to say DON'T search class scopes, and BLOCK_P to say
DO search block scopes. I've added a single bitmask to explicitly say which
scopes to search. I used an enum class so one can't accidentally misorder
it. It's also reordered so we don't mix it up with the parameters that say
what kind of thing we're looking for.
gcc/cp/
* name-lookup.h (enum class LOOK_where): New.
(operator|, operator&): Overloads for it.
(lookup_name_real): Replace NONCLASS & BLOCK_P parms with WHERE.
* name-lookup.c (identifier_type_value_w): Adjust
lookup_name_real call.
(lookup_name_real_1): Replace NONCLASS and BLOCK_P parameters
with WHERE bitmask. Don't search namespaces if not asked to.
(lookup_name_real): Adjust lookup_name_real_1 call.
(lookup_name_nonclass, lookup_name)
(lookup_name_prefer_type): Likewise.
* call.c (build_operator_new_call)
(add_operator_candidates): Adjust lookup_name_real calls.
* parser.c (cp_parser_lookup_name): Likewise.
* pt.c (tsubst_friend_class, lookup_init_capture_pack)
(tsubst_expr): Likewise.
* semantics.c (capture_decltype): Likewise.
libcc1/
* libcp1plugin.cc (plugin_build_dependent_expr): Likewise.
On the modules branch I need to expose an intermediate step of the
function cloning, but before that it'd be nice to rationalize the
names somewhat, now that we also use that API for copying the equality
operator. Jason's recent patch caused me some pain by altering the
same code. I can only blame myself for not pushing some bits sooner.
Anyway, this patch makes the newly renamed copy_fndecl_with_name
static, and adds a wrapper copy_operator_fn, that takes an operator
code. The cdtor cloning functions are renamed to explicitly note they
expect cdtors. A followup patch will move some of the logic from
copy_fndecl_with_name to build_cdtor_clones.
gcc/cp/
* cp-tree.h (copy_fndecl_with_name): Rename to ...
(copy_operatorn_fn): ... this. Change arg type.
(clone_function_decl): Rename to ...
(clone_cdtor): ... this.
* class.c (copy_fndecl_with_name): Make static.
(copy_operator_fn): New wrapper.
(build_clones): Rename to ...
(build_cdtor_clones): ... this.
(clone_function_decl): Rename to ...
(clone_cdtor): ... this. Adjust build_clones calls.
(clone_constructors_and_destructors): Adjust clone_function_decl
calls.
* method.c (implicitly_declare_fn): Adjust copy_fndecl_with_name
call.
(lazily_declare_fn): Adjust clone_function_decl call.
* pt.c (tsubst_function_decl): Likewise.
(instantiate_template_1): Likewise.
libcc1/
* libcp1plugin.cc (plugin_build_decl): Adjust clone_function_decl
call.
This patch fixes two issues with return type deduction in the presence of an
abbreviated function template.
The first issue (PR 69448) is that if a placeholder auto return type contains
any modifiers such as & or *, then the abbreviated function template
compensation in splice_late_return_type does not get performed for the
underlying auto node, leading to incorrect return type deduction. This happens
because splice_late_return_type does not consider that a placeholder auto return
type might have modifiers. To fix this it seems we need to look through
modifiers in the return type to obtain the location of the underlying auto node
in order to replace it with the adjusted auto node. To that end this patch
refactors the utility function find_type_usage to return a pointer to the
matched tree, and uses it to find and replace the underlying auto node.
The second issue (PR 80471) is that the AUTO_IS_DECLTYPE flag is not being
preserved in splice_late_return_type when compensating for an abbreviated
function template, leading to us treating a decltype(auto) return type as if it
was an auto return type. Fixed by making make_auto_1 set the AUTO_IS_DECLTYPE
flag whenever we're building a decltype(auto) node and adjusting callers
appropriately. The test for PR 80471 is adjusted to expect the correct
behavior.
gcc/cp/ChangeLog:
PR c++/69448
PR c++/80471
* type-utils.h (find_type_usage): Refactor to take a tree * and to
return a tree *, and update documentation accordingly.
* pt.c (make_auto_1): Set AUTO_IS_DECLTYPE when building a
decltype(auto) node.
(make_constrained_decltype_auto): No need to explicitly set
AUTO_IS_DECLTYPE anymore.
(splice_late_return_type): Use find_type_usage to find and
replace a possibly nested auto node instead of using is_auto.
Check test for is_auto into an assert when deciding whether
to late_return_type.
(type_uses_auto): Adjust the call to find_type_usage.
* parser.c (cp_parser_decltype): No need to explicitly set
AUTO_IS_DECLTYPE anymore.
libcc1/ChangeLog:
PR c++/69448
PR c++/80471
* libcp1plugin.cc (plugin_get_expr_type): No need to explicitly set
AUTO_IS_DECLTYPE anymore.
gcc/testsuite/ChangeLog:
PR c++/69448
PR c++/80471
* g++.dg/concepts/abbrev3.C: New test.
* g++.dg/cpp2a/concepts-pr80471.C: Adjust a static_assert to expect the
correct behavior.
* g++.dg/cpp0x/auto9.C: Adjust a dg-error directive.
gcc/cp/
* cp-tree.h (lang_decl_fn): Remove assignment_operator_p field.
(DECL_COMPLETE_CONSTRUCTOR_P): Directly compare
identifier.
(DECL_BASE_CONSTRUCTOR_P, DECL_COMPLETE_DESTRUCTOR_P)
DECL_BASE_DESTRUCTOR_P, DECL_DELETING_DESTRUCTOR_P): Likewise.
(DECL_ASSIGNMENT_OPERATOR_P): Use IDENTIFIER_ASSIGN_OP_P.
* decl.c (grok_op_properties): Adjust identifier checking.
* init.c (expand_default_init): Adjust identifier descision.
* method.c (implicitly_declare_fn): Don't use
DECL_ASSIGNMENT_OPERATOR_P.
* search.c (lookup_fnfields_1): Use IDENTIFIER_CTOR_P,
IDENTIFIER_DTOR_P.
* call.c (in_charge_arg_for_name): Reimplement.
(build_special_member_call): Use IDENTIFIER_CDTOR_P,
IDENTIFIER_DTOR_P.
libcc1/
* libcp1plugin.cc (plugin_build_decl): Don't set
DECL_ASSIGNMENT_OPERATOR_P.
(--This line, and those below, will be ignored--
M gcc/cp/init.c
M gcc/cp/decl.c
M gcc/cp/method.c
M gcc/cp/cp-tree.h
M gcc/cp/call.c
M gcc/cp/search.c
M gcc/cp/ChangeLog
M libcc1/ChangeLog
M libcc1/libcp1plugin.cc
From-SVN: r249657