From b8911cb870585c08881d3c424cb1e508e99b9ace Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 15 Jun 2016 15:23:40 +0000 Subject: [PATCH] re PR c++/70202 (ICE on invalid code on x86_64-linux-gnu in build_simple_base_path, at cp/class.c:579) /cp 2016-06-15 Paolo Carlini PR c++/70202 * decl.c (xref_basetypes): Revert r117839 changes; add fix-up code at the end of the for loop; also revert r159637 changes, add back the gcc_assert. * cp-tree.h (xref_basetypes): Adjust declaration. * parser.c (cp_parser_class_head): Adjust xref_basetypes call. /testsuite 2016-06-15 Paolo Carlini PR c++/70202 * g++.dg/inherit/crash6.C: New. * g++.dg/inherit/union2.C: Likewise. * g++.dg/inherit/virtual12.C: Likewise. * g++.dg/inherit/virtual13.C: Likewise. * g++.dg/inherit/virtual1.C: Tweak dg-* tests. From-SVN: r237482 --- gcc/cp/ChangeLog | 9 ++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 53 ++++++++++++------------ gcc/cp/parser.c | 5 +-- gcc/testsuite/ChangeLog | 9 ++++ gcc/testsuite/g++.dg/inherit/crash6.C | 10 +++++ gcc/testsuite/g++.dg/inherit/union2.C | 3 ++ gcc/testsuite/g++.dg/inherit/virtual1.C | 8 ++-- gcc/testsuite/g++.dg/inherit/virtual12.C | 14 +++++++ gcc/testsuite/g++.dg/inherit/virtual13.C | 16 +++++++ 10 files changed, 94 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/crash6.C create mode 100644 gcc/testsuite/g++.dg/inherit/union2.C create mode 100644 gcc/testsuite/g++.dg/inherit/virtual12.C create mode 100644 gcc/testsuite/g++.dg/inherit/virtual13.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 775b61482d4..7e68d054197 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2016-06-15 Paolo Carlini + + PR c++/70202 + * decl.c (xref_basetypes): Revert r117839 changes; add fix-up + code at the end of the for loop; also revert r159637 changes, + add back the gcc_assert. + * cp-tree.h (xref_basetypes): Adjust declaration. + * parser.c (cp_parser_class_head): Adjust xref_basetypes call. + 2016-06-14 David Malcolm * search.c: Include spellcheck-tree.h rather than spellcheck.h. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6c6ad10804e..5b87bb391d9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5788,7 +5788,7 @@ extern int grok_ctor_properties (const_tree, const_tree); extern bool grok_op_properties (tree, bool); extern tree xref_tag (enum tag_types, tree, tag_scope, bool); extern tree xref_tag_from_type (tree, tree, tag_scope); -extern bool xref_basetypes (tree, tree); +extern void xref_basetypes (tree, tree); extern tree start_enum (tree, tree, tree, tree, bool, bool *); extern void finish_enum_value_list (tree); extern void finish_enum (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a03e48ff618..1aa5e523cb3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12879,12 +12879,9 @@ xref_tag_from_type (tree old, tree id, tag_scope scope) /* Create the binfo hierarchy for REF with (possibly NULL) base list BASE_LIST. For each element on BASE_LIST the TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of the base-class. - Non-NULL TREE_TYPE indicates virtual inheritance. - - Returns true if the binfo hierarchy was successfully created, - false if an error was detected. */ + Non-NULL TREE_TYPE indicates virtual inheritance. */ -bool +void xref_basetypes (tree ref, tree base_list) { tree *basep; @@ -12897,7 +12894,7 @@ xref_basetypes (tree ref, tree base_list) tree igo_prev; /* Track Inheritance Graph Order. */ if (ref == error_mark_node) - return false; + return; /* The base of a derived class is private by default, all others are public. */ @@ -12941,11 +12938,7 @@ xref_basetypes (tree ref, tree base_list) /* The binfo slot should be empty, unless this is an (ill-formed) redefinition. */ - if (TYPE_BINFO (ref) && !TYPE_SIZE (ref)) - { - error ("redefinition of %q#T", ref); - return false; - } + gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref)); gcc_assert (TYPE_MAIN_VARIANT (ref) == ref); @@ -12965,19 +12958,13 @@ xref_basetypes (tree ref, tree base_list) CLASSTYPE_NON_AGGREGATE (ref) = 1; if (TREE_CODE (ref) == UNION_TYPE) - { - error ("derived union %qT invalid", ref); - return false; - } + error ("derived union %qT invalid", ref); } if (max_bases > 1) { if (TYPE_FOR_JAVA (ref)) - { - error ("Java class %qT cannot have multiple bases", ref); - return false; - } + error ("Java class %qT cannot have multiple bases", ref); else warning (OPT_Wmultiple_inheritance, "%qT defined with multiple direct bases", ref); @@ -12988,10 +12975,7 @@ xref_basetypes (tree ref, tree base_list) vec_alloc (CLASSTYPE_VBASECLASSES (ref), max_vbases); if (TYPE_FOR_JAVA (ref)) - { - error ("Java class %qT cannot have virtual bases", ref); - return false; - } + error ("Java class %qT cannot have virtual bases", ref); else if (max_dvbases) warning (OPT_Wvirtual_inheritance, "%qT defined with direct virtual base", ref); @@ -13014,7 +12998,7 @@ xref_basetypes (tree ref, tree base_list) { error ("base type %qT fails to be a struct or class type", basetype); - return false; + goto dropped_base; } if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0)) @@ -13048,7 +13032,7 @@ xref_basetypes (tree ref, tree base_list) error ("recursive type %qT undefined", basetype); else error ("duplicate base type %qT invalid", basetype); - return false; + goto dropped_base; } if (PACK_EXPANSION_P (TREE_VALUE (base_list))) @@ -13064,8 +13048,25 @@ xref_basetypes (tree ref, tree base_list) BINFO_BASE_APPEND (binfo, base_binfo); BINFO_BASE_ACCESS_APPEND (binfo, access); + continue; + + dropped_base: + /* Update max_vbases to reflect the reality that we are dropping + this base: if it reaches zero we want to undo the vec_alloc + above to avoid inconsistencies during error-recovery: eg, in + build_special_member_call, CLASSTYPE_VBASECLASSES non null + and vtt null (c++/27952). */ + if (via_virtual) + max_vbases--; + if (CLASS_TYPE_P (basetype)) + max_vbases + -= vec_safe_length (CLASSTYPE_VBASECLASSES (basetype)); } + if (CLASSTYPE_VBASECLASSES (ref) + && max_vbases == 0) + vec_free (CLASSTYPE_VBASECLASSES (ref)); + if (vec_safe_length (CLASSTYPE_VBASECLASSES (ref)) < max_vbases) /* If we didn't get max_vbases vbases, we must have shared at least one of them, and are therefore diamond shaped. */ @@ -13096,8 +13097,6 @@ xref_basetypes (tree ref, tree base_list) else break; } - - return true; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 632b25fac95..a9c636b7f41 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22050,9 +22050,8 @@ cp_parser_class_head (cp_parser* parser, /* If we're really defining a class, process the base classes. If they're invalid, fail. */ - if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) - && !xref_basetypes (type, bases)) - type = NULL_TREE; + if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + xref_basetypes (type, bases); done: /* Leave the scope given by the nested-name-specifier. We will diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b10f973671..d9dd04db118 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2016-06-15 Paolo Carlini + + PR c++/70202 + * g++.dg/inherit/crash6.C: New. + * g++.dg/inherit/union2.C: Likewise. + * g++.dg/inherit/virtual12.C: Likewise. + * g++.dg/inherit/virtual13.C: Likewise. + * g++.dg/inherit/virtual1.C: Tweak dg-* tests. + 2016-06-15 Uros Bizjak * gcc.dg/torture/float128-nan.c: Include stdint.h to define uint64_t. diff --git a/gcc/testsuite/g++.dg/inherit/crash6.C b/gcc/testsuite/g++.dg/inherit/crash6.C new file mode 100644 index 00000000000..bce999ccbe5 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/crash6.C @@ -0,0 +1,10 @@ +// PR c++/70202 + +class A +{ + virtual void foo () { } +}; +class B : public A, A { }; // { dg-error "duplicate base type" } + +B b1, &b2 = b1; +A a = b2; diff --git a/gcc/testsuite/g++.dg/inherit/union2.C b/gcc/testsuite/g++.dg/inherit/union2.C new file mode 100644 index 00000000000..e3a9130480a --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/union2.C @@ -0,0 +1,3 @@ +struct A { }; +union U : A { }; // { dg-error "derived union 'U' invalid" } +U u; diff --git a/gcc/testsuite/g++.dg/inherit/virtual1.C b/gcc/testsuite/g++.dg/inherit/virtual1.C index 08bcbb143cf..ed597e2a3d7 100644 --- a/gcc/testsuite/g++.dg/inherit/virtual1.C +++ b/gcc/testsuite/g++.dg/inherit/virtual1.C @@ -1,12 +1,12 @@ -//PR c++/27952 +// PR c++/27952 struct A { virtual ~A() {} }; -struct B : A, virtual A {}; // { dg-error "duplicate base|forward declaration" } +struct B : A, virtual A {}; // { dg-error "duplicate base" } -struct C : A, B {}; // { dg-error "duplicate base|invalid use" } +struct C : A, B {}; // { dg-message "direct base 'A' inaccessible" } -C c; // { dg-error "aggregate" } +C c; diff --git a/gcc/testsuite/g++.dg/inherit/virtual12.C b/gcc/testsuite/g++.dg/inherit/virtual12.C new file mode 100644 index 00000000000..3e96d2e1e74 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/virtual12.C @@ -0,0 +1,14 @@ +// PR c++/70202 + +union U { }; + +struct A +{ + virtual ~A() {} +}; + +struct B : A, virtual U { }; // { dg-error "base type 'U' fails" } + +struct C : A, B {}; // { dg-message "direct base 'A' inaccessible" } + +C c; diff --git a/gcc/testsuite/g++.dg/inherit/virtual13.C b/gcc/testsuite/g++.dg/inherit/virtual13.C new file mode 100644 index 00000000000..ca504eb60c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/virtual13.C @@ -0,0 +1,16 @@ +// PR c++/70202 + +struct D { }; + +union U : virtual D { }; // { dg-error "derived union" } + +struct A +{ + virtual ~A() {} +}; + +struct B : A, virtual U { }; // { dg-error "base type 'U' fails" } + +struct C : A, B {}; // { dg-message "direct base 'A' inaccessible" } + +C c; -- 2.30.2