aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-02-07 23:30:51 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-02-07 23:30:51 +0100
commit8f1f526b9a5b0bd27422b3392f1930f107809675 (patch)
treeec9d7e17e0ff636bc59c4d7ddabaafc047ab0a62 /gcc
parentb35a0ccd139f5df8262ef7ea5fed81d88074ecf8 (diff)
downloadgcc-8f1f526b9a5b0bd27422b3392f1930f107809675.zip
gcc-8f1f526b9a5b0bd27422b3392f1930f107809675.tar.gz
gcc-8f1f526b9a5b0bd27422b3392f1930f107809675.tar.bz2
re PR c++/84082 (ICE with broken template function definition)
PR c++/84082 * parser.c (cp_parser_dot_deref_incomplete): New function. (cp_parser_postfix_dot_deref_expression): Use it. * g++.dg/template/incomplete11.C: New test. * g++.dg/parse/crash67.C: Expect an incomplete type diagnostics too. From-SVN: r257466
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c77
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/parse/crash67.C2
-rw-r--r--gcc/testsuite/g++.dg/template/incomplete11.C10
5 files changed, 80 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 42c3cbf..0b710e9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2018-02-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84082
+ * parser.c (cp_parser_dot_deref_incomplete): New function.
+ (cp_parser_postfix_dot_deref_expression): Use it.
+
2018-02-07 David Malcolm <dmalcolm@redhat.com>
PR c++/81610
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 222db0c..ac5277d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7387,6 +7387,60 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
return postfix_expression;
}
+/* A subroutine of cp_parser_postfix_dot_deref_expression. Handle dot
+ dereference of incomplete type, returns true if error_mark_node should
+ be returned from caller, otherwise adjusts *SCOPE, *POSTFIX_EXPRESSION
+ and *DEPENDENT_P. */
+
+bool
+cp_parser_dot_deref_incomplete (tree *scope, cp_expr *postfix_expression,
+ bool *dependent_p)
+{
+ /* In a template, be permissive by treating an object expression
+ of incomplete type as dependent (after a pedwarn). */
+ diagnostic_t kind = (processing_template_decl
+ && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR);
+
+ switch (TREE_CODE (*postfix_expression))
+ {
+ case CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ case VIEW_CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ kind = DK_ERROR;
+ break;
+ case OVERLOAD:
+ /* Don't emit any diagnostic for OVERLOADs. */
+ kind = DK_IGNORED;
+ break;
+ default:
+ /* Avoid clobbering e.g. DECLs. */
+ if (!EXPR_P (*postfix_expression))
+ kind = DK_ERROR;
+ break;
+ }
+
+ if (kind == DK_IGNORED)
+ return false;
+
+ location_t exploc = location_of (*postfix_expression);
+ cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind);
+ if (!MAYBE_CLASS_TYPE_P (*scope))
+ return true;
+ if (kind == DK_ERROR)
+ *scope = *postfix_expression = error_mark_node;
+ else if (processing_template_decl)
+ {
+ *dependent_p = true;
+ *scope = TREE_TYPE (*postfix_expression) = NULL_TREE;
+ }
+ return false;
+}
+
/* A subroutine of cp_parser_postfix_expression that also gets hijacked
by cp_parser_builtin_offsetof. We're looking for
@@ -7451,26 +7505,9 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
{
scope = complete_type (scope);
if (!COMPLETE_TYPE_P (scope)
- /* Avoid clobbering e.g. OVERLOADs or DECLs. */
- && EXPR_P (postfix_expression))
- {
- /* In a template, be permissive by treating an object expression
- of incomplete type as dependent (after a pedwarn). */
- diagnostic_t kind = (processing_template_decl
- && MAYBE_CLASS_TYPE_P (scope)
- ? DK_PEDWARN
- : DK_ERROR);
- cxx_incomplete_type_diagnostic
- (location_of (postfix_expression),
- postfix_expression, scope, kind);
- if (!MAYBE_CLASS_TYPE_P (scope))
- return error_mark_node;
- if (processing_template_decl)
- {
- dependent_p = true;
- scope = TREE_TYPE (postfix_expression) = NULL_TREE;
- }
- }
+ && cp_parser_dot_deref_incomplete (&scope, &postfix_expression,
+ &dependent_p))
+ return error_mark_node;
}
if (!dependent_p)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6d82e4e..6e26641 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-02-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84082
+ * g++.dg/template/incomplete11.C: New test.
+ * g++.dg/parse/crash67.C: Expect an incomplete type diagnostics too.
+
2018-02-07 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/82994
diff --git a/gcc/testsuite/g++.dg/parse/crash67.C b/gcc/testsuite/g++.dg/parse/crash67.C
index 0befc9e..dee0fc7 100644
--- a/gcc/testsuite/g++.dg/parse/crash67.C
+++ b/gcc/testsuite/g++.dg/parse/crash67.C
@@ -3,4 +3,4 @@
class x0;
template <x1> x2() { // { dg-error "declared|type" }
-x0 x3 = x3. // { dg-error "expected" }
+x0 x3 = x3. // { dg-error "expected|incomplete type" }
diff --git a/gcc/testsuite/g++.dg/template/incomplete11.C b/gcc/testsuite/g++.dg/template/incomplete11.C
new file mode 100644
index 0000000..38c92e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/incomplete11.C
@@ -0,0 +1,10 @@
+// PR c++/84082
+// { dg-do compile }
+// { dg-options "" }
+
+struct A;
+
+template<typename> void foo()
+{
+ static int a[A().operator=(A())]; // { dg-error "invalid use of incomplete type 'struct A'" }
+}