]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[C++ PATCH] Simplify overloads
authorNathan Sidwell <nathan@acm.org>
Wed, 31 Oct 2018 12:42:35 +0000 (12:42 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 31 Oct 2018 12:42:35 +0000 (12:42 +0000)
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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/name-lookup.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/using60.C [new file with mode: 0644]

index d76d3177a1c5ffa6a9a3fed04069ac0602fe1dbf..8e586a1f51450e51e1542494681968a39b14973b 100644 (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).
index c9427a0b624d921ed3c30cb71c991c87aa5dbf78..03e88838cbe28c282297e87ba8767e796b425a49 100644 (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.  */
index 5b026da59e0bf9f34eb146a3d3ffa15e974849cb..f2d9d2225050dded584257786e21942e532aba08 100644 (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,
index 251c344f18157735d8a09b3d3917a95f5d947816..74018e97bb76c90806c524209bb3b2476308f3b2 100644 (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;
              }
index 84923163780405ec01a1548f59c07a40d336a1da..18c3ac644788606bc899c31bac1533b6831391df 100644 (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
diff --git a/gcc/testsuite/g++.dg/lookup/using60.C b/gcc/testsuite/g++.dg/lookup/using60.C
new file mode 100644 (file)
index 0000000..9a275e9
--- /dev/null
@@ -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);
+}