PR c++/89331 - ICE with offsetof in incomplete class.
authorJason Merrill <jason@redhat.com>
Wed, 3 Apr 2019 20:09:17 +0000 (16:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 3 Apr 2019 20:09:17 +0000 (16:09 -0400)
We were aborting when build_base_path returned an error because of the
derived class not being complete yet, which wasn't considered by the assert.
Fixed by checking for complete type first.  The semantics.c change avoids
a duplicate error message.

* semantics.c (finish_offsetof): Handle error_mark_node.
* typeck.c (build_class_member_access_expr): Call
complete_type_or_maybe_complain before converting to base.

From-SVN: r270135

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/ext/builtin-offsetof4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/offsetof8.C

index bb719133a9726bb1b57345c316422ecddcc4126e..a224517b566052cbf0ec98e0d92d42fa3b766cee 100644 (file)
@@ -1,5 +1,10 @@
 2019-04-03  Jason Merrill  <jason@redhat.com>
 
+       PR c++/89331 - ICE with offsetof in incomplete class.
+       * semantics.c (finish_offsetof): Handle error_mark_node.
+       * typeck.c (build_class_member_access_expr): Call
+       complete_type_or_maybe_complain before converting to base.
+
        PR c++/89917 - ICE with lambda in variadic mem-init.
        * pt.c (make_pack_expansion): Change type_pack_expansion_p to false.
 
index a08a2a57f5ffcb6ce9ddd2dddfde361043266d49..408675b80992bde555ec790592bc4d1b3411554b 100644 (file)
@@ -4144,6 +4144,9 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc)
       return expr;
     }
 
+  if (expr == error_mark_node)
+    return error_mark_node;
+
   if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
     {
       error ("cannot apply %<offsetof%> to destructor %<~%T%>",
index a00b0f48b69c670577486525e1c05332fe0d87dd..56def144a3e14ac57ca5aaefe01c2d60dc622424 100644 (file)
@@ -2474,6 +2474,14 @@ build_class_member_access_expr (cp_expr object, tree member,
          tree binfo;
          base_kind kind;
 
+         /* We didn't complain above about a currently open class, but now we
+            must: we don't know how to refer to a base member before layout is
+            complete.  But still don't complain in a template.  */
+         if (!dependent_type_p (object_type)
+             && !complete_type_or_maybe_complain (object_type, object,
+                                                  complain))
+           return error_mark_node;
+
          binfo = lookup_base (access_path ? access_path : object_type,
                               member_scope, ba_unique, &kind, complain);
          if (binfo == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/ext/builtin-offsetof4.C b/gcc/testsuite/g++.dg/ext/builtin-offsetof4.C
new file mode 100644 (file)
index 0000000..b30c31d
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/89331
+
+class A {
+public:
+    char a;
+};
+
+class B : public A {
+public:
+    static const unsigned b = __builtin_offsetof(B, a); // { dg-error "incomplete" }
+};
index 211c5127026c63e42c53995c3527201de92e5df9..daca70a6fe4c24ee3e075c90cf1fbde69669c605 100644 (file)
@@ -9,4 +9,4 @@ struct B: virtual A { };
 int a[]  = {
   !&((B*)0)->i,    // { dg-error "invalid access to non-static data member" }
   __builtin_offsetof (B, i)   // { dg-error "invalid access to non-static" }
-};                           // { dg-message "offsetof within non-standard-layout type" "" { target *-*-* } .-1 }
+};