Clearly the DR 141 change is requiring much larger adjustments in the
rest of the compiler than I'm comfortable making at this point in the
GCC 6 schedule, so I'm backing out my earlier changes for 10200 and
69753 and replacing them with a more modest fix for 10200: Now we will
still find member function templates by unqualified lookup, we just
won't find namespace-scope function templates. The earlier approach
will return in GCC 7 stage 1.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 862c6a750fc12cb41d29aa8f91c013f7705836c1
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Feb 16 19:11:35 2016 -0500
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 .
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index db40654..cb71176 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b7d7bc6..3b91089 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index b73f3f7..89d84d7 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b8d8237..18f3902 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 52e60b9..a55dc10 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 49f3bc5..7924611 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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;
-}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 70a7aa5..f0288ea 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 041facd..3203aca 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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));
+}
+
#define PRINT_RING_SIZE 4
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 54a432f..2a76c96 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 0000000..7da060d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/dependent-expr9.C
@@ -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>(); }
+};