mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-24 11:09:16 +08:00
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:
parent
3a4219caad
commit
ff2faafcf6
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
5
gcc/testsuite/g++.dg/lookup/member2.C
Normal file
5
gcc/testsuite/g++.dg/lookup/member2.C
Normal 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; }
|
Loading…
Reference in New Issue
Block a user