Go to file
Patrick Palka bb2a7f80a9 c++: two-stage name lookup for overloaded operators [PR51577]
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.
2021-12-16 13:40:42 -05:00
c++tools
config Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
contrib Verbose support in analyze_brprob_spec 2021-12-15 19:58:10 -06:00
fixincludes
gcc c++: two-stage name lookup for overloaded operators [PR51577] 2021-12-16 13:40:42 -05:00
gnattools
gotools
include Daily bump. 2021-12-13 00:16:28 +00:00
INSTALL
intl
libada
libatomic
libbacktrace
libcc1 c++: two-stage name lookup for overloaded operators [PR51577] 2021-12-16 13:40:42 -05:00
libcody
libcpp
libdecnumber
libffi
libgcc Daily bump. 2021-12-14 00:16:25 +00:00
libgfortran Fix FLUSH IOSTAT value 2021-12-16 17:46:28 +01:00
libgo
libgomp Daily bump. 2021-12-14 00:16:25 +00:00
libiberty Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
libitm
libobjc
liboffloadmic
libphobos Daily bump. 2021-12-16 00:16:28 +00:00
libquadmath
libsanitizer
libssp
libstdc++-v3 Daily bump. 2021-12-16 00:16:28 +00:00
libvtv
lto-plugin
maintainer-scripts
zlib Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
.dir-locals.el
.gitattributes
.gitignore
ABOUT-NLS
ar-lib
ChangeLog Daily bump. 2021-12-16 00:16:28 +00:00
ChangeLog.jit
ChangeLog.tree-ssa
compile
config-ml.in
config.guess
config.rpath
config.sub Fixed typo 2021-12-16 17:54:45 +01:00
configure Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
configure.ac Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
COPYING
COPYING3
COPYING3.LIB
COPYING.LIB
COPYING.RUNTIME
depcomp
install-sh
libtool-ldflags
libtool.m4 Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
lt~obsolete.m4
ltgcc.m4
ltmain.sh
ltoptions.m4
ltsugar.m4
ltversion.m4
MAINTAINERS MAINTAINERS: Add myself to write after approval 2021-12-14 15:59:29 +01:00
Makefile.def
Makefile.in Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
Makefile.tpl Revert "Sync with binutils: GCC: Pass --plugin to AR and RANLIB" 2021-12-15 20:45:58 -08:00
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
symlink-tree
test-driver
ylwrap

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.