PR c++/10200
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 Feb 2016 00:50:23 +0000 (00:50 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 Feb 2016 00:50:23 +0000 (00:50 +0000)
PR c++/69753
* call.c, cp-tree.h, name-lookup.c, pt.c, search.c, semantics.c,
tree.c, typeck2.c: Revert earlier changes.
* parser.c (cp_parser_lookup_name): Ignore namespace-scope
non-type templates after -> or .

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233481 138bc75d-0d04-0410-961f-82ee72b054a4

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

index d12cb73..b76f85d 100644 (file)
@@ -1,3 +1,12 @@
+2016-02-16  Jason Merrill  <jason@redhat.com>
+
+       PR c++/10200
+       PR c++/69753
+       * call.c, cp-tree.h, name-lookup.c, pt.c, search.c, semantics.c,
+       tree.c, typeck2.c: Revert earlier changes.
+       * parser.c (cp_parser_lookup_name): Ignore namespace-scope
+       non-type templates after -> or .
+
 2016-02-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/69835
index db40654..cb71176 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",
-                    BINFO_TYPE (access_binfo), name))
+                    basetype, 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,9 +8377,6 @@ 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 b7d7bc6..3b91089 100644 (file)
@@ -6252,7 +6252,6 @@ 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.  */
 
@@ -6543,6 +6542,7 @@ 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 b73f3f7..89d84d7 100644 (file)
@@ -3333,6 +3333,8 @@ 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;
@@ -3369,7 +3371,16 @@ do_class_using_decl (tree scope, tree name)
                      || (IDENTIFIER_TYPENAME_P (name)
                          && dependent_type_p (TREE_TYPE (name))));
 
-  bases_dependent_p = any_dependent_bases_p (current_class_type);
+  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;
+       }
 
   decl = NULL_TREE;
 
index b8d8237..18f3902 100644 (file)
@@ -7184,16 +7184,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
   if (token_type == CPP_DEREF)
     postfix_expression = build_x_arrow (location, postfix_expression,
                                        tf_warning_or_error);
-  /* According to the standard, no expression should ever have
-     reference type.  Unfortunately, we do not currently match
-     the standard in this respect in that our internal representation
-     of an expression may have reference type even when the standard
-     says it does not.  Therefore, we have to manually obtain the
-     underlying type here.  */
-  scope = non_reference (TREE_TYPE (postfix_expression));
-  /* Check to see whether or not the expression is type-dependent and
-     not the current instantiation.  */
-  dependent_p = !scope || dependent_scope_p (scope);
+  /* Check to see whether or not the expression is type-dependent.  */
+  dependent_p = type_dependent_expression_p (postfix_expression);
   /* The identifier following the `->' or `.' is not qualified.  */
   parser->scope = NULL_TREE;
   parser->qualifying_scope = NULL_TREE;
@@ -7202,8 +7194,16 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
 
   /* Enter the scope corresponding to the type of the object
      given by the POSTFIX_EXPRESSION.  */
-  if (!dependent_p)
-    {
+  if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
+    {
+      scope = TREE_TYPE (postfix_expression);
+      /* According to the standard, no expression should ever have
+        reference type.  Unfortunately, we do not currently match
+        the standard in this respect in that our internal representation
+        of an expression may have reference type even when the standard
+        says it does not.  Therefore, we have to manually obtain the
+        underlying type here.  */
+      scope = non_reference (scope);
       /* The type of the POSTFIX_EXPRESSION must be complete.  */
       if (scope == unknown_type_node)
        {
@@ -7215,10 +7215,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
         required to be of complete type for purposes of class member
         access (5.2.5) outside the member function body.  */
       else if (postfix_expression != current_class_ref
-              && !(processing_template_decl
-                   && current_class_type
-                   && (same_type_ignoring_top_level_qualifiers_p
-                       (scope, current_class_type))))
+              && !(processing_template_decl && scope == current_class_type))
        scope = complete_type_or_else (scope, NULL_TREE);
       /* Let the name lookup machinery know that we are processing a
         class member access expression.  */
@@ -24727,11 +24724,24 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
        decl = NULL_TREE;
 
       if (!decl)
-       /* Look it up in the enclosing context.  DR 141: When looking for a
-          template-name after -> or ., only consider class templates.  */
-       decl = lookup_name_real (name, tag_type != none_type || is_template,
-                                /*nonclass=*/0,
-                                /*block_p=*/true, is_namespace, 0);
+       {
+         /* Look it up in the enclosing context.  */
+         decl = lookup_name_real (name, tag_type != none_type,
+                                  /*nonclass=*/0,
+                                  /*block_p=*/true, is_namespace, 0);
+         /* DR 141 says when looking for a template-name after -> or ., only
+            consider class templates.  We need to fix our handling of
+            dependent expressions to implement that properly, but for now
+            let's ignore namespace-scope function templates.  */
+         if (decl && is_template && !DECL_TYPE_TEMPLATE_P (decl))
+           {
+             tree d = decl;
+             if (is_overloaded_fn (d))
+               d = get_first_fn (d);
+             if (DECL_P (d) && !DECL_CLASS_SCOPE_P (d))
+               decl = NULL_TREE;
+           }
+       }
       if (object_type == unknown_type_node)
        /* The object is type-dependent, so we can't look anything up; we used
           this to get the DR 141 behavior.  */
index 52e60b9..a55dc10 100644 (file)
@@ -22904,16 +22904,9 @@ 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)
-    {
-      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) == TEMPLATE_DECL
+      && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
+    return false;
 
   if (TREE_CODE (expression) == STMT_EXPR)
     expression = stmt_expr_value_expr (expression);
index 49f3bc5..7924611 100644 (file)
@@ -2842,21 +2842,3 @@ 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 70a7aa5..f0288ea 100644 (file)
@@ -2264,7 +2264,17 @@ 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))
+         || 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)))
        {
          result = build_nt_call_vec (fn, *args);
          SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
@@ -2344,6 +2354,17 @@ 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 041facd..3203aca 100644 (file)
@@ -2071,6 +2071,23 @@ 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
 
index 54a432f..2a76c96 100644 (file)
@@ -1694,10 +1694,7 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
 
   if (processing_template_decl)
     {
-      if (type && TREE_CODE (type) == POINTER_TYPE
-         && !dependent_scope_p (TREE_TYPE (type)))
-       /* Pointer to current instantiation, don't treat as dependent.  */;
-      else if (type_dependent_expression_p (expr))
+      if (type_dependent_expression_p (expr))
        return build_min_nt_loc (loc, ARROW_EXPR, expr);
       expr = build_non_dependent_expr (expr);
     }
diff --git a/gcc/testsuite/g++.dg/template/dependent-expr9.C b/gcc/testsuite/g++.dg/template/dependent-expr9.C
new file mode 100644 (file)
index 0000000..7da060d
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/69753
+
+class A {
+public:
+  template <class> void m_fn1();
+};
+A *fn1(int *);
+template <typename> class B : A {
+  static int *m_fn2() { fn1(m_fn2())->m_fn1<A>(); }
+};