From b8836dbec1a36eb3a00c789a4ed1e64ba28ee6fe Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 3 Apr 2019 16:09:17 -0400 Subject: [PATCH] PR c++/89331 - ICE with offsetof in incomplete class. 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 | 5 +++++ 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 +- 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ext/builtin-offsetof4.C 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 + 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. 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 % 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 } +}; -- 2.30.2