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:
parent
a529923e35
commit
6bab4c63c4
11 changed files with 106 additions and 59 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
13
gcc/cp/pt.c
13
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
10
gcc/testsuite/g++.dg/template/dependent-expr9.C
Normal file
10
gcc/testsuite/g++.dg/template/dependent-expr9.C
Normal 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>(); }
|
||||
};
|
Loading…
Add table
Reference in a new issue