PR c++/71193 - incomplete types in templates

* parser.c (cp_parser_postfix_dot_deref_expression): In a template
	handle incomplete type by pedwarning and then treating as dependent.

From-SVN: r245223
This commit is contained in:
Jason Merrill 2017-02-06 16:12:13 -05:00 committed by Jason Merrill
parent 391675acd2
commit 44a6da7bac
3 changed files with 57 additions and 16 deletions

View file

@ -1,3 +1,9 @@
2017-02-06 Jason Merrill <jason@redhat.com>
PR c++/71193 - incomplete types in templates
* parser.c (cp_parser_postfix_dot_deref_expression): In a template
handle incomplete type by pedwarning and then treating as dependent.
2017-02-06 Jakub Jelinek <jakub@redhat.com>
PR c++/79379

View file

@ -7309,7 +7309,7 @@ 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
@ -7324,26 +7324,50 @@ 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. */
if (postfix_expression != current_class_ref
&& scope != error_mark_node
&& !(processing_template_decl
&& current_class_type
&& (same_type_ignoring_top_level_qualifiers_p
(scope, current_class_type))))
scope = complete_type_or_else (scope, postfix_expression);
/* Let the name lookup machinery know that we are processing a
class member access expression. */
parser->context->object_type = scope;
/* If something went wrong, we want to be able to discern that case,
as opposed to the case where there was no SCOPE due to the type
of expression being dependent. */
if (!scope)
scope = error_mark_node;
/* If the SCOPE was erroneous, make the various semantic analysis
functions exit quickly -- and without issuing additional error
messages. */
if (scope == error_mark_node)
postfix_expression = error_mark_node;
{
scope = complete_type (scope);
if (!COMPLETE_TYPE_P (scope))
{
/* In a template, be permissive by treating an object expression
of incomplete type as dependent (after a pedwarn). */
diagnostic_t kind = (processing_template_decl
? DK_PEDWARN
: DK_ERROR);
cxx_incomplete_type_diagnostic
(location_of (postfix_expression),
postfix_expression, scope, kind);
if (processing_template_decl)
{
dependent_p = true;
scope = TREE_TYPE (postfix_expression) = NULL_TREE;
}
}
}
if (!dependent_p)
{
/* Let the name lookup machinery know that we are processing a
class member access expression. */
parser->context->object_type = scope;
/* If something went wrong, we want to be able to discern that case,
as opposed to the case where there was no SCOPE due to the type
of expression being dependent. */
if (!scope)
scope = error_mark_node;
/* If the SCOPE was erroneous, make the various semantic analysis
functions exit quickly -- and without issuing additional error
messages. */
if (scope == error_mark_node)
postfix_expression = error_mark_node;
}
}
else
if (dependent_p)
/* Tell cp_parser_lookup_name that there was an object, even though it's
type-dependent. */
parser->context->object_type = unknown_type_node;

View file

@ -0,0 +1,11 @@
// PR c++/71193
// { dg-options "" }
class Heap;
class A {
public:
Heap *m_fn1();
};
template <typename> class B : A {
void m_fn2() { m_fn1()->HashSeed; } // { dg-warning "incomplete" }
};