diff mbox series

[C++] PR c++/89331 - ICE with offsetof in incomplete class.

Message ID 20190403200905.26861-1-jason@redhat.com
State New
Headers show
Series [C++] PR c++/89331 - ICE with offsetof in incomplete class. | expand

Commit Message

Jason Merrill April 3, 2019, 8:09 p.m. UTC
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.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* 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.
---
 gcc/cp/semantics.c                           |  3 +++
 gcc/cp/typeck.c                              |  8 ++++++++
 gcc/testsuite/g++.dg/ext/builtin-offsetof4.C | 11 +++++++++++
 gcc/testsuite/g++.dg/other/offsetof8.C       |  2 +-
 gcc/cp/ChangeLog                             |  5 +++++
 5 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/builtin-offsetof4.C


base-commit: 9939b2f79bd9b75b99080a17f3d6f1214d543477
diff mbox series

Patch

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index a08a2a57f5f..408675b8099 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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%>",
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a00b0f48b69..56def144a3e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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
index 00000000000..b30c31dbfa9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin-offsetof4.C
@@ -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" }
+};
diff --git a/gcc/testsuite/g++.dg/other/offsetof8.C b/gcc/testsuite/g++.dg/other/offsetof8.C
index 211c5127026..daca70a6fe4 100644
--- a/gcc/testsuite/g++.dg/other/offsetof8.C
+++ b/gcc/testsuite/g++.dg/other/offsetof8.C
@@ -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 }
+};
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bb719133a97..a224517b566 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.