aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-02-06 16:12:13 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-02-06 16:12:13 -0500
commit44a6da7bac79f288af814cd401a666c81fb8735c (patch)
tree4cbfd8e8e59100224d7526f61ef5a0a997da535c
parent391675acd2d18d0b6e5130a4105cf66eb1664683 (diff)
downloadgcc-44a6da7bac79f288af814cd401a666c81fb8735c.zip
gcc-44a6da7bac79f288af814cd401a666c81fb8735c.tar.gz
gcc-44a6da7bac79f288af814cd401a666c81fb8735c.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c56
-rw-r--r--gcc/testsuite/g++.dg/template/incomplete8.C11
3 files changed, 57 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0e3e38c..80f1113 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 592f903..d2df777 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" }
+};