[C++ PATCH] Simplify overloads

https://gcc.gnu.org/ml/gcc-patches/2018-10/msg02026.html
	gcc/cp/
	* cp-tree.h (OVL_DEDUP_P): New.
	* name-lookup.c (name_lookup::add_overload): Check OVL_DEDUP_P.
	(get_class_binding_direct): Likwise.
	* tree.c (ovl_make): Propagate OVL_DEDUP_P.
	(ovl_copy): Copy it.
	(ovl_insert): Do not keep using-decls ordered.
	(lookup_maybe_add): Adjust comment.

	gcc/testsuite/
	* g++.dg/lookup/using60.C: New.

From-SVN: r265679
This commit is contained in:
Nathan Sidwell 2018-10-31 12:42:35 +00:00 committed by Nathan Sidwell
parent 0db78d0a5e
commit 8e82c473f5
6 changed files with 61 additions and 31 deletions

View file

@ -1,3 +1,13 @@
2018-10-31 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (OVL_DEDUP_P): New.
* name-lookup.c (name_lookup::add_overload): Check OVL_DEDUP_P.
(get_class_binding_direct): Likwise.
* tree.c (ovl_make): Propagate OVL_DEDUP_P.
(ovl_copy): Copy it.
(ovl_insert): Do not keep using-decls ordered.
(lookup_maybe_add): Adjust comment.
2018-10-30 Marek Polacek <polacek@redhat.com>
Implement P0892R2, explicit(bool).

View file

@ -409,6 +409,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
SWITCH_STMT_ALL_CASES_P (in SWITCH_STMT)
REINTERPRET_CAST_P (in NOP_EXPR)
ALIGNOF_EXPR_STD_P (in ALIGNOF_EXPR)
OVL_DEDUP_P (in OVERLOAD)
1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@ -695,6 +696,8 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
#define OVL_CHAIN(NODE) \
(((struct tree_overload*)OVERLOAD_CHECK (NODE))->common.chain)
/* If set, this or a subsequent overload contains decls that need deduping. */
#define OVL_DEDUP_P(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE))
/* If set, this was imported in a using declaration. */
#define OVL_USING_P(NODE) TREE_LANG_FLAG_1 (OVERLOAD_CHECK (NODE))
/* If set, this overload is a hidden decl. */

View file

@ -422,7 +422,8 @@ name_lookup::add_overload (tree fns)
tree probe = fns;
if (flags & LOOKUP_HIDDEN)
probe = ovl_skip_hidden (probe);
if (probe && TREE_CODE (probe) == OVERLOAD && OVL_USING_P (probe))
if (probe && TREE_CODE (probe) == OVERLOAD
&& OVL_DEDUP_P (probe))
{
/* We're about to add something found by a using
declaration, so need to engage deduping mode. */
@ -1260,7 +1261,8 @@ get_class_binding_direct (tree klass, tree name, int type_or_fns)
if (type_or_fns < 0)
/* Don't bother looking for field. We don't want it. */;
else if (!val || (TREE_CODE (val) == OVERLOAD && OVL_USING_P (val)))
else if (!val || (TREE_CODE (val) == OVERLOAD
&& OVL_DEDUP_P (val)))
/* Dependent using declarations are a 'field', make sure we
return that even if we saw an overload already. */
if (tree field_val = fields_linear_search (klass, lookup,

View file

@ -2153,6 +2153,8 @@ ovl_make (tree fn, tree next)
TREE_TYPE (result) = (next || TREE_CODE (fn) == TEMPLATE_DECL
? unknown_type_node : TREE_TYPE (fn));
if (next && TREE_CODE (next) == OVERLOAD && OVL_DEDUP_P (next))
OVL_DEDUP_P (result) = true;
OVL_FUNCTION (result) = fn;
OVL_CHAIN (result) = next;
return result;
@ -2167,64 +2169,54 @@ ovl_copy (tree ovl)
TREE_TYPE (result) = TREE_TYPE (ovl);
OVL_FUNCTION (result) = OVL_FUNCTION (ovl);
OVL_CHAIN (result) = OVL_CHAIN (ovl);
OVL_DEDUP_P (result) = OVL_DEDUP_P (ovl);
OVL_LOOKUP_P (result) = OVL_LOOKUP_P (ovl);
OVL_HIDDEN_P (result) = OVL_HIDDEN_P (ovl);
OVL_USING_P (result) = OVL_USING_P (ovl);
OVL_LOOKUP_P (result) = OVL_LOOKUP_P (ovl);
return result;
}
/* Add FN to the (potentially NULL) overload set OVL. USING_P is
true, if FN is via a using declaration. We also pay attention to
DECL_HIDDEN. Overloads are ordered as hidden, using, regular. */
DECL_HIDDEN. We keep the hidden decls first, but remaining ones
are unordered. */
tree
ovl_insert (tree fn, tree maybe_ovl, bool using_p)
{
bool copying = false; /* Checking use only. */
bool hidden_p = DECL_HIDDEN_P (fn);
int weight = (hidden_p << 1) | (using_p << 0);
tree result = NULL_TREE;
tree result = maybe_ovl;
tree insert_after = NULL_TREE;
/* Find insertion point. */
while (maybe_ovl && TREE_CODE (maybe_ovl) == OVERLOAD
&& (weight < ((OVL_HIDDEN_P (maybe_ovl) << 1)
| (OVL_USING_P (maybe_ovl) << 0))))
/* Skip hidden. */
for (; maybe_ovl && TREE_CODE (maybe_ovl) == OVERLOAD
&& OVL_HIDDEN_P (maybe_ovl);
maybe_ovl = OVL_CHAIN (maybe_ovl))
{
gcc_checking_assert (!OVL_LOOKUP_P (maybe_ovl)
&& (!copying || OVL_USED_P (maybe_ovl)));
if (OVL_USED_P (maybe_ovl))
{
copying = true;
maybe_ovl = ovl_copy (maybe_ovl);
if (insert_after)
OVL_CHAIN (insert_after) = maybe_ovl;
}
if (!result)
result = maybe_ovl;
&& !OVL_USED_P (maybe_ovl));
insert_after = maybe_ovl;
maybe_ovl = OVL_CHAIN (maybe_ovl);
}
tree trail = fn;
bool hidden_p = DECL_HIDDEN_P (fn);
if (maybe_ovl || using_p || hidden_p || TREE_CODE (fn) == TEMPLATE_DECL)
{
trail = ovl_make (fn, maybe_ovl);
maybe_ovl = ovl_make (fn, maybe_ovl);
if (hidden_p)
OVL_HIDDEN_P (trail) = true;
OVL_HIDDEN_P (maybe_ovl) = true;
if (using_p)
OVL_USING_P (trail) = true;
OVL_DEDUP_P (maybe_ovl) = OVL_USING_P (maybe_ovl) = true;
}
else
maybe_ovl = fn;
if (insert_after)
{
OVL_CHAIN (insert_after) = trail;
OVL_CHAIN (insert_after) = maybe_ovl;
TREE_TYPE (insert_after) = unknown_type_node;
}
else
result = trail;
result = maybe_ovl;
return result;
}
@ -2367,7 +2359,8 @@ lookup_maybe_add (tree fns, tree lookup, bool deduping)
for (; fns != probe; fns = OVL_CHAIN (fns))
{
lookup = lookup_add (OVL_FUNCTION (fns), lookup);
/* Propagate OVL_USING, but OVL_HIDDEN doesn't matter. */
/* Propagate OVL_USING, but OVL_HIDDEN &
OVL_DEDUP_P don't matter. */
if (OVL_USING_P (fns))
OVL_USING_P (lookup) = true;
}

View file

@ -1,3 +1,7 @@
2018-10-31 Nathan Sidwell <nathan@acm.org>
* g++.dg/lookup/using60.C: New.
2018-10-31 Richard Biener <rguenther@suse.de>
PR middle-end/70359

View file

@ -0,0 +1,18 @@
// ICE with overloads not ordering using decls. Failed to invoke
// deduping logic
void remove (const char *);
namespace std
{
using ::remove;
void remove ();
}
using namespace std;
void test01 ()
{
remove (0);
}