[PR c++/87531] Fix second bug
authorNathan Sidwell <nathan@acm.org>
Thu, 13 Dec 2018 15:57:24 +0000 (15:57 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 13 Dec 2018 15:57:24 +0000 (15:57 +0000)
https://gcc.gnu.org/ml/gcc-patches/2018-12/msg00929.html

PR c++/87531
* class.c (finish_struct): Set DECL_CONTEXT of template assign op.
* name-lookup.c (get_class_binding_direct): Don't strip using-decl
of overload here.
* parser.c (cp_parser_postfix_expression): Cope with using decl in
overload set.
* semantics.c (finish_id_expr): Likewise.

* g++.dg/lookup/pr87531-2.C: New.

From-SVN: r267096

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/pr87531-2.C [new file with mode: 0644]

index a32e1d05491a82205de3dbcdcf8df8d7a39d5c2a..503bbbb7598a2066bb204e2b55d1ac639e41dd71 100644 (file)
@@ -1,3 +1,13 @@
+2018-12-13  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/87531
+       * class.c (finish_struct): Set DECL_CONTEXT of template assign op.
+       * name-lookup.c (get_class_binding_direct): Don't strip using-decl
+       of overload here.
+       * parser.c (cp_parser_postfix_expression): Cope with using decl in
+       overload set.
+       * semantics.c (finish_id_expr): Likewise.
+
 2018-12-12  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * decl.c (grokdeclarator): Fix location of error message about
index fec1c5dd7d050e3cf6fa1271d342d9414588cede..36e17572a3322657694b97a3ea423d99a463681e 100644 (file)
@@ -7158,6 +7158,7 @@ finish_struct (tree t, tree attributes)
         time.  */
       tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
                                     NULL_TREE);
+      DECL_CONTEXT (ass_op) = t;
       USING_DECL_SCOPE (ass_op) = t;
       DECL_DEPENDENT_P (ass_op) = true;
       DECL_ARTIFICIAL (ass_op) = true;
index cadf3808237ba1531b28a81defb3e5a5ac6263ac..39710fcb50598513a5110b4951fa78b2da595198 100644 (file)
@@ -1242,17 +1242,6 @@ get_class_binding_direct (tree klass, tree name, int type_or_fns)
        }
       else if (STAT_HACK_P (val))
        val = STAT_DECL (val);
-
-      if (val && TREE_CODE (val) == OVERLOAD
-         && TREE_CODE (OVL_FUNCTION (val)) == USING_DECL)
-       {
-         /* An overload with a dependent USING_DECL.  Does the caller
-            want the USING_DECL or the functions?  */
-         if (type_or_fns < 0)
-           val = OVL_CHAIN (val);
-         else
-           val = OVL_FUNCTION (val);  
-       }
     }
   else
     {
index 8b669a82b14719ee662176b7f3452d32952aa117..7ff113f3c0fa4ae44d63009ecc4023a37aecb055 100644 (file)
@@ -7240,14 +7240,19 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                else if (!args->is_empty ()
                         && is_overloaded_fn (postfix_expression))
                  {
+                   /* We only need to look at the first function,
+                      because all the fns share the attribute we're
+                      concerned with (all member fns or all local
+                      fns).  */
                    tree fn = get_first_fn (postfix_expression);
                    fn = STRIP_TEMPLATE (fn);
 
                    /* Do not do argument dependent lookup if regular
                       lookup finds a member function or a block-scope
                       function declaration.  [basic.lookup.argdep]/3  */
-                   if (!DECL_FUNCTION_MEMBER_P (fn)
-                       && !DECL_LOCAL_FUNCTION_P (fn))
+                   if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn))
+                         || DECL_FUNCTION_MEMBER_P (fn)
+                         || DECL_LOCAL_FUNCTION_P (fn)))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
index c1240cce1e16a2239381a61e84709327e27d316c..09ed97de2c7b3d9e79d7d4de92b89c3d20e10b7d 100644 (file)
@@ -3805,9 +3805,10 @@ finish_id_expression (tree id_expression,
            return error_mark_node;
 
          if (!template_arg_p
-             && TREE_CODE (first_fn) == FUNCTION_DECL
-             && DECL_FUNCTION_MEMBER_P (first_fn)
-             && !shared_member_p (decl))
+             && (TREE_CODE (first_fn) == USING_DECL
+                 || (TREE_CODE (first_fn) == FUNCTION_DECL
+                     && DECL_FUNCTION_MEMBER_P (first_fn)
+                     && !shared_member_p (decl))))
            {
              /* A set of member functions.  */
              decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
index 8957b2121fe986423638c24a8bb0c6ff16147149..50ccb916eb22b1d2f353550983896894d7355401 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-13  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/87531
+       * g++.dg/lookup/pr87531-2.C: New.
+
 2018-12-13  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        PR testsuite/88041
diff --git a/gcc/testsuite/g++.dg/lookup/pr87531-2.C b/gcc/testsuite/g++.dg/lookup/pr87531-2.C
new file mode 100644 (file)
index 0000000..93231ce
--- /dev/null
@@ -0,0 +1,63 @@
+// PR 87531 part 2.  dependent using decls + template decls.
+
+template<typename T>
+struct One
+{
+  One& operator=(T* p_)
+  {
+    return operator=<T>(p_); // Parse failed here
+  }
+
+  template<typename U>
+  One& operator=(U* p_);
+  
+};
+
+
+template<typename T>
+struct Two : T
+{
+  using T::f;
+  template<typename U> void f ();
+
+  using T::operator T*;
+  operator T * () const;
+  
+  int frob ()
+  {
+    return f<int> (1);
+  }
+
+  T *quux ()
+  {
+    return operator T * ();
+  }
+
+  T *quux () const
+  {
+    return operator T * ();
+  }
+};
+
+struct Base 
+{
+  template <typename T> int f (T i) 
+  {
+    return i;
+  }
+
+  operator Base *() const;
+};
+
+void foo ()
+{
+  One<int> one;
+  Two<Base> two;
+
+  one = One<int> ();
+
+  two.frob ();
+  two.quux ();
+  const_cast <const Two<Base> &> (two).quux ();
+}
+