71193 is a case where we now properly treat as non-dependent some expressions that we previously considered type-dependent, and as a result try to resolve their containing expressions, which can lead to incomplete type errors that weren't seen before even though the code was ill-formed.
This patch adjusts one situation this might occur to catch the problem, give a pedwarn instead of an error, and treat the expression as type-dependent. This doesn't help the testcase for 71773, where the access is more complicated. Tested x86_64-pc-linux-gnu, applying to trunk.
commit debb4f99e55e5c0b8c64fd1957d41417dc951870 Author: Jason Merrill <ja...@redhat.com> Date: Mon Feb 6 14:50:03 2017 -0500 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. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0aa738b..1813adb 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; diff --git a/gcc/testsuite/g++.dg/template/incomplete8.C b/gcc/testsuite/g++.dg/template/incomplete8.C new file mode 100644 index 0000000..d6cde6a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete8.C @@ -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" } +};