re PR c++/10200 (Weird clash with same names in different scopes)

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 .

From-SVN: r233481
This commit is contained in:
Jason Merrill 2016-02-16 19:50:23 -05:00 committed by Jason Merrill
parent a529923e35
commit 6bab4c63c4
11 changed files with 106 additions and 59 deletions

View 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

View 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)

View 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);

View 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;

View 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. */

View 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);

View 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;
}

View 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

View 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));
}
#define PRINT_RING_SIZE 4

View 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);
}

View file

@ -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>(); }
};