re PR c++/84082 (ICE with broken template function definition)
authorJakub Jelinek <jakub@redhat.com>
Wed, 7 Feb 2018 22:30:51 +0000 (23:30 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 7 Feb 2018 22:30:51 +0000 (23:30 +0100)
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

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/crash67.C
gcc/testsuite/g++.dg/template/incomplete11.C [new file with mode: 0644]

index 42c3cbf4b3cbb35cc66b2ccf9c4703ea89c77cbc..0b710e9140fc9383b12ecd85062cd8a60feceeba 100644 (file)
@@ -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
index 222db0cad3fa33e75764675e908be43be9d2f841..ac5277db9ad250ca76c010ddfd66cc16d0ed12ae 100644 (file)
@@ -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)
index 6d82e4e2d746a6805a9eba3d37be68412a2e6c3c..6e266415765b767a87ffe3a8e0ed19fc56630295 100644 (file)
@@ -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
index 0befc9e2457570f024ac5f71fcac46f312a52caa..dee0fc72212a01cea0b43770b96941170e1c31ae 100644 (file)
@@ -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 (file)
index 0000000..38c92e3
--- /dev/null
@@ -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'" }
+}