[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:
parent
0db78d0a5e
commit
8e82c473f5
6 changed files with 61 additions and 31 deletions
|
@ -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).
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
18
gcc/testsuite/g++.dg/lookup/using60.C
Normal file
18
gcc/testsuite/g++.dg/lookup/using60.C
Normal 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);
|
||||
}
|
Loading…
Add table
Reference in a new issue