]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/69753 (bogus: expected primary-expression before ‘>’ token)
authorJason Merrill <jason@redhat.com>
Mon, 15 Feb 2016 21:14:05 +0000 (16:14 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 15 Feb 2016 21:14:05 +0000 (16:14 -0500)
PR c++/69753

* search.c (any_dependent_bases_p): Split out...
* name-lookup.c (do_class_using_decl): ...from here.
* call.c (build_new_method_call_1): Don't complain about missing object
if there are dependent bases.  Tweak error.
* tree.c (non_static_member_function_p): Remove.
* pt.c (type_dependent_expression_p): A member template of a
dependent type is dependent.
* cp-tree.h: Adjust.

From-SVN: r233431

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

index 85473df23d5a961e9bae082d1a6846315a582eb4..04d55bc60b919d8bbc7a23c820e3f6a364e29419 100644 (file)
@@ -1,5 +1,17 @@
 2016-02-15  Jason Merrill  <jason@redhat.com>
 
+       PR c++/69753
+       * semantics.c (finish_call_expr): Implicit 'this' does not make
+       the call dependent.
+       * search.c (any_dependent_bases_p): Split out...
+       * name-lookup.c (do_class_using_decl): ...from here.
+       * call.c (build_new_method_call_1): Don't complain about missing object
+       if there are dependent bases.  Tweak error.
+       * tree.c (non_static_member_function_p): Remove.
+       * pt.c (type_dependent_expression_p): A member template of a
+       dependent type is dependent.
+       * cp-tree.h: Adjust.
+
        PR c++/68890
        * constexpr.c (verify_ctor_sanity): Remove CONSTRUCTOR_NELTS check.
 
index cb71176c6ca148ecaf49b24f2e16238d3653685a..db406543522f502113bff53eee3d61f398e5fbb0 100644 (file)
@@ -8160,7 +8160,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
 
       if (permerror (input_location,
                     "cannot call constructor %<%T::%D%> directly",
-                    basetype, name))
+                    BINFO_TYPE (access_binfo), name))
        inform (input_location, "for a function-style cast, remove the "
                "redundant %<::%D%>", name);
       call = build_functional_cast (basetype, build_tree_list_vec (user_args),
@@ -8377,6 +8377,9 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
                     we know we really need it.  */
                  cand->first_arg = instance;
                }
+             else if (any_dependent_bases_p ())
+               /* We can't tell until instantiation time whether we can use
+                  *this as the implicit object argument.  */;
              else
                {
                  if (complain & tf_error)
index 3b91089f50d08645519305b797c6616b767bec79..b7d7bc685028df4976e38f9b24d13b0a584522b2 100644 (file)
@@ -6252,6 +6252,7 @@ extern tree adjust_result_of_qualified_name_lookup
 extern tree copied_binfo                       (tree, tree);
 extern tree original_binfo                     (tree, tree);
 extern int shared_member_p                     (tree);
+extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ());
 
 /* The representation of a deferred access check.  */
 
@@ -6542,7 +6543,6 @@ extern tree get_first_fn                  (tree);
 extern tree ovl_cons                           (tree, tree);
 extern tree build_overload                     (tree, tree);
 extern tree ovl_scope                          (tree);
-extern bool non_static_member_function_p        (tree);
 extern const char *cxx_printable_name          (tree, int);
 extern const char *cxx_printable_name_translate        (tree, int);
 extern tree build_exception_variant            (tree, tree);
index 8d6e75a134745f1f03f12f6bc5438d9f9366a79b..b5961e573f3ebb31671d826ab2c3cf17804ac068 100644 (file)
@@ -3333,8 +3333,6 @@ do_class_using_decl (tree scope, tree name)
   /* True if any of the bases of CURRENT_CLASS_TYPE are dependent.  */
   bool bases_dependent_p;
   tree binfo;
-  tree base_binfo;
-  int i;
 
   if (name == error_mark_node)
     return NULL_TREE;
@@ -3371,16 +3369,7 @@ do_class_using_decl (tree scope, tree name)
                      || (IDENTIFIER_TYPENAME_P (name)
                          && dependent_type_p (TREE_TYPE (name))));
 
-  bases_dependent_p = false;
-  if (processing_template_decl)
-    for (binfo = TYPE_BINFO (current_class_type), i = 0;
-        BINFO_BASE_ITERATE (binfo, i, base_binfo);
-        i++)
-      if (dependent_type_p (TREE_TYPE (base_binfo)))
-       {
-         bases_dependent_p = true;
-         break;
-       }
+  bases_dependent_p = any_dependent_bases_p (current_class_type);
 
   decl = NULL_TREE;
 
index a55dc10fdfc1e8d1a847c4d4e89efcc6f574cccf..52e60b948b4fac08fd9c43bd2d0e42b207d6fe27 100644 (file)
@@ -22904,9 +22904,16 @@ type_dependent_expression_p (tree expression)
       && DECL_TEMPLATE_INFO (expression))
     return any_dependent_template_arguments_p (DECL_TI_ARGS (expression));
 
-  if (TREE_CODE (expression) == TEMPLATE_DECL
-      && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
-    return false;
+  if (TREE_CODE (expression) == TEMPLATE_DECL)
+    {
+      if (DECL_CLASS_SCOPE_P (expression)
+         && dependent_type_p (DECL_CONTEXT (expression)))
+       /* A template's own parameters don't make it dependent, since those can
+          be deduced, but the enclosing class does.  */
+       return true;
+      if (!DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
+       return false;
+    }
 
   if (TREE_CODE (expression) == STMT_EXPR)
     expression = stmt_expr_value_expr (expression);
index 792461189152ad68c40023ae4756d5c3403c7e3a..49f3bc5ed8085837441ad2741f959f09dfa4f0ae 100644 (file)
@@ -2842,3 +2842,21 @@ original_binfo (tree binfo, tree here)
   return result;
 }
 
+/* True iff TYPE has any dependent bases (and therefore we can't say
+   definitively that another class is not a base of an instantiation of
+   TYPE).  */
+
+bool
+any_dependent_bases_p (tree type)
+{
+  if (!type || !CLASS_TYPE_P (type) || !processing_template_decl)
+    return false;
+
+  unsigned i;
+  tree base_binfo;
+  FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo)
+    if (BINFO_DEPENDENT_BASE_P (base_binfo))
+      return true;
+
+  return false;
+}
index 0cf5f930b1e987d60e4bcd92d1881c12715e74f2..0f6a6b5c539f752fff38a1a3c3b457877d08f889 100644 (file)
@@ -2264,17 +2264,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
         with no type; type_dependent_expression_p recognizes
         expressions with no type as being dependent.  */
       if (type_dependent_expression_p (fn)
-         || any_type_dependent_arguments_p (*args)
-         /* For a non-static member function that doesn't have an
-            explicit object argument, we need to specifically
-            test the type dependency of the "this" pointer because it
-            is not included in *ARGS even though it is considered to
-            be part of the list of arguments.  Note that this is
-            related to CWG issues 515 and 1005.  */
-         || (TREE_CODE (fn) != COMPONENT_REF
-             && non_static_member_function_p (fn)
-             && current_class_ref
-             && type_dependent_expression_p (current_class_ref)))
+         || any_type_dependent_arguments_p (*args))
        {
          result = build_nt_call_vec (fn, *args);
          SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
@@ -2354,17 +2344,6 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
       object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
                                   NULL);
 
-      if (processing_template_decl)
-       {
-         if (type_dependent_expression_p (object))
-           {
-             tree ret = build_nt_call_vec (orig_fn, orig_args);
-             release_tree_vector (orig_args);
-             return ret;
-           }
-         object = build_non_dependent_expr (object);
-       }
-
       result = build_new_method_call (object, fn, args, NULL_TREE,
                                      (disallow_virtual
                                       ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
index 3203acaff9e94f6d6c23a4f8390b82764ef5158e..041facda96a38580a414558299b9a6e97e91b339 100644 (file)
@@ -2071,23 +2071,6 @@ ovl_scope (tree ovl)
     ovl = OVL_CHAIN (ovl);
   return CP_DECL_CONTEXT (OVL_CURRENT (ovl));
 }
-
-/* Return TRUE if FN is a non-static member function, FALSE otherwise.
-   This function looks into BASELINK and OVERLOAD nodes.  */
-
-bool
-non_static_member_function_p (tree fn)
-{
-  if (fn == NULL_TREE)
-    return false;
-
-  if (is_overloaded_fn (fn))
-    fn = get_first_fn (fn);
-
-  return (DECL_P (fn)
-         && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn));
-}
-
 \f
 #define PRINT_RING_SIZE 4
 
diff --git a/gcc/testsuite/g++.dg/lookup/member3.C b/gcc/testsuite/g++.dg/lookup/member3.C
new file mode 100644 (file)
index 0000000..f4e097e
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/69753
+// { dg-do compile { target c++11 } }
+
+class A {
+public:
+  template <typename> void As();
+  static A *FromWebContents();
+  A *FromWebContents2();
+};
+template <typename T> class B : A {
+  void FromWebContents() {
+    auto guest = A::FromWebContents();
+    guest ? guest->As<T>() : nullptr;
+    auto guest2 = A::FromWebContents2();
+    guest2 ? guest2->As<T>() : nullptr;
+  }
+};