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

PR c++/10200

	* parser.c (cp_parser_lookup_name): When looking for a template
	after . or ->, only consider class templates.
	(cp_parser_postfix_dot_deref_expression): Handle the current
	instantiation.  Remember a dependent object expression.
	* typeck2.c (build_x_arrow): Handle the current instantiation.

From-SVN: r233277
This commit is contained in:
Jason Merrill 2016-02-10 10:34:52 -05:00 committed by Jason Merrill
parent 3a4219caad
commit ff2faafcf6
4 changed files with 42 additions and 15 deletions

View File

@ -1,5 +1,12 @@
2016-02-10 Jason Merrill <jason@redhat.com>
PR c++/10200
* parser.c (cp_parser_lookup_name): When looking for a template
after . or ->, only consider class templates.
(cp_parser_postfix_dot_deref_expression): Handle the current
instantiation. Remember a dependent object expression.
* typeck2.c (build_x_arrow): Handle the current instantiation.
* ptree.c (debug_tree): Implement for cp_expr.
2016-02-08 Patrick Palka <ppalka@gcc.gnu.org>

View File

@ -7184,8 +7184,16 @@ 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);
/* Check to see whether or not the expression is type-dependent. */
dependent_p = type_dependent_expression_p (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 (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);
/* The identifier following the `->' or `.' is not qualified. */
parser->scope = NULL_TREE;
parser->qualifying_scope = NULL_TREE;
@ -7194,16 +7202,8 @@ 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 && TREE_TYPE (postfix_expression) != NULL_TREE)
if (!dependent_p)
{
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,7 +7215,10 @@ 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 && scope == current_class_type))
&& !(processing_template_decl
&& current_class_type
&& (same_type_ignoring_top_level_qualifiers_p
(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. */
@ -7231,6 +7234,10 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
if (scope == error_mark_node)
postfix_expression = error_mark_node;
}
else
/* Tell cp_parser_lookup_name that there was an object, even though it's
type-dependent. */
parser->context->object_type = unknown_type_node;
/* Assume this expression is not a pseudo-destructor access. */
pseudo_destructor_p = false;
@ -24720,10 +24727,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
decl = NULL_TREE;
if (!decl)
/* Look it up in the enclosing context. */
decl = lookup_name_real (name, tag_type != none_type,
/* 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);
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. */
object_type = NULL_TREE;
parser->object_scope = object_type;
parser->qualifying_scope = NULL_TREE;
}

View File

@ -1694,7 +1694,10 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
if (processing_template_decl)
{
if (type_dependent_expression_p (expr))
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))
return build_min_nt_loc (loc, ARROW_EXPR, expr);
expr = build_non_dependent_expr (expr);
}

View File

@ -0,0 +1,5 @@
// PR c++/10200
template<class Tp> inline void end(Tp) { }
template <typename T> bool tnegative(const T& t) { return t.end < 0; }