From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 42422 invoked by alias); 27 Feb 2018 20:51:03 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 41934 invoked by uid 89); 27 Feb 2018 20:51:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=sk:IDENTIF X-HELO: mail-yw0-f179.google.com Received: from mail-yw0-f179.google.com (HELO mail-yw0-f179.google.com) (209.85.161.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Feb 2018 20:51:01 +0000 Received: by mail-yw0-f179.google.com with SMTP id f2so77541ywa.1 for ; Tue, 27 Feb 2018 12:51:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=4aDxYzEP/VsXgVdX9OVtU2gmcUcvRjA7HSljQMu/R58=; b=Jp7AWmJFbKZfKFerpxNQNh1y1CgwDRGn/fqvnXj+hReXju3lwYhAOMIjiaZjwZGQlC jzq2h/BHsiu+tI7EJthEXuPziWr1hEYqa2CRwbF8t30Qqj9gsq1cFMu5pTbWpM9PvQvE O5VkiNwnq+Nj8AyLK2+EnLWaI/D6U4m/CxSpyWsgPGtS2K6OYT5ZoQMM28TTSfOJzXTP TN9kUhtdecwxXxCPUl/bMdhe6tRXYDAzU3ftNpwEOHY6I3huq2+mDOB9LIdV0ubMDUXS N2xClTL0kyH4VxAxH2UGQGhLBoVyoj/x+MhyVG8LpYT+RjechDSSmDehN18b+tMjfHLE gFew== X-Gm-Message-State: APf1xPAug/weZnUglvJmHVQlUDUo124NF+C0bZa5lvZtbac5WfJ+O9gf FzL8HYcr0AUDtODi9QrMRaI= X-Google-Smtp-Source: AG47ELvzSrwlrpY2Tji3G0glM0e3vDbY3QFvXXDS4YcL14n343Bv7MpR9vf6eBO7L0EtPz3dbOc68Q== X-Received: by 10.129.1.212 with SMTP id 203mr4295088ywb.396.1519764659487; Tue, 27 Feb 2018 12:50:59 -0800 (PST) Received: from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254? ([2620:10d:c091:200::3:acb8]) by smtp.googlemail.com with ESMTPSA id s63sm23389ywc.46.2018.02.27.12.50.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Feb 2018 12:50:58 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: [PR c++/84426] ICE after conflicting member decl Message-ID: <312184d2-5a10-85eb-5911-f01c7ad630a1@acm.org> Date: Tue, 27 Feb 2018 20:51:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------C3F3AE5BD44AEF364DA84262" X-SW-Source: 2018-02/txt/msg01529.txt.bz2 This is a multi-part message in MIME format. --------------C3F3AE5BD44AEF364DA84262 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 607 The crash was happening because add_method wasn't telling it's caller something went wrong. We then ended up with a vfunc and a regular field on the TYPE_MEMBERS list, but only the field in the CLASSTYPE_MEMBER_VEC. So we knew there was a virtual func, but couldn't find it. Fixed by having add_method return false. But that leads to the possibility of having NULL slots during class definition time as get_member_slot would always create the slot. I should have know that might bite somewhere else. So fixed by breaking get_member_slot into a finder and an adder. nathan -- Nathan Sidwell --------------C3F3AE5BD44AEF364DA84262 Content-Type: text/x-patch; name="84426.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="84426.diff" Content-length: 6035 2018-02-27 Nathan Sidwell PR c++/84426 * name-lookup.h (get_member_slot): Rename ... (find_member_slot): ... here. (add_member_slot): New. * name-lookup.c (member_vec_linear_search): No need to check for NULL slot. (get_member_slot): Rename ... (find_member_slot): ... here. Don't add slot for incomplete class. (add_member_slot): New. * class.c (add_method): Adjust get_member_slot rename. Bail out if push_class_level_binding fails. Create slot and grok properties once we're committed to insertion. PR c++/84426 * g++.dg/lookup/pr84426.C: New. Index: cp/class.c =================================================================== --- cp/class.c (revision 258041) +++ cp/class.c (working copy) @@ -993,14 +993,11 @@ add_method (tree type, tree method, bool if (method == error_mark_node) return false; - /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */ - grok_special_member_properties (method); - - tree *slot = get_member_slot (type, DECL_NAME (method)); - tree current_fns = *slot; - gcc_assert (!DECL_EXTERN_C_P (method)); + tree *slot = find_member_slot (type, DECL_NAME (method)); + tree current_fns = slot ? *slot : NULL_TREE; + /* Check to see if we've already got this method. */ for (ovl_iterator iter (current_fns); iter; ++iter) { @@ -1146,8 +1143,15 @@ add_method (tree type, tree method, bool current_fns = ovl_insert (method, current_fns, via_using); - if (!DECL_CONV_FN_P (method) && !COMPLETE_TYPE_P (type)) - push_class_level_binding (DECL_NAME (method), current_fns); + if (!COMPLETE_TYPE_P (type) && !DECL_CONV_FN_P (method) + && !push_class_level_binding (DECL_NAME (method), current_fns)) + return false; + + if (!slot) + slot = add_member_slot (type, DECL_NAME (method)); + + /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */ + grok_special_member_properties (method); *slot = current_fns; Index: cp/name-lookup.c =================================================================== --- cp/name-lookup.c (revision 258041) +++ cp/name-lookup.c (working copy) @@ -1146,17 +1146,9 @@ static tree member_vec_linear_search (vec *member_vec, tree name) { for (int ix = member_vec->length (); ix--;) - /* We can get a NULL binding during insertion of a new method - name, because the identifier_binding machinery performs a - lookup. If we find such a NULL slot, that's the thing we were - looking for, so we might as well bail out immediately. */ if (tree binding = (*member_vec)[ix]) - { - if (OVL_NAME (binding) == name) - return binding; - } - else - break; + if (OVL_NAME (binding) == name) + return binding; return NULL_TREE; } @@ -1334,15 +1326,15 @@ get_class_binding (tree klass, tree name } /* Find the slot containing overloads called 'NAME'. If there is no - such slot, create an empty one. KLASS might be complete at this - point, in which case we need to preserve ordering. Deals with - conv_op marker handling. */ + such slot and the class is complete, create an empty one, at the + correct point in the sorted member vector. Otherwise return NULL. + Deals with conv_op marker handling. */ tree * -get_member_slot (tree klass, tree name) +find_member_slot (tree klass, tree name) { bool complete_p = COMPLETE_TYPE_P (klass); - + vec *member_vec = CLASSTYPE_MEMBER_VEC (klass); if (!member_vec) { @@ -1389,24 +1381,34 @@ get_member_slot (tree klass, tree name) break; } - /* No slot found. Create one at IX. We know in this case that our - caller will succeed in adding the function. */ + /* No slot found, add one if the class is complete. */ if (complete_p) { - /* Do exact allocation when complete, as we don't expect to add - many. */ + /* Do exact allocation, as we don't expect to add many. */ + gcc_assert (name != conv_op_identifier); vec_safe_reserve_exact (member_vec, 1); + CLASSTYPE_MEMBER_VEC (klass) = member_vec; member_vec->quick_insert (ix, NULL_TREE); + return &(*member_vec)[ix]; } - else - { - gcc_checking_assert (ix == length); - vec_safe_push (member_vec, NULL_TREE); - } + + return NULL; +} + +/* KLASS is an incomplete class to which we're adding a method NAME. + Add a slot and deal with conv_op marker handling. */ + +tree * +add_member_slot (tree klass, tree name) +{ + gcc_assert (!COMPLETE_TYPE_P (klass)); + + vec *member_vec = CLASSTYPE_MEMBER_VEC (klass); + vec_safe_push (member_vec, NULL_TREE); CLASSTYPE_MEMBER_VEC (klass) = member_vec; - tree *slot = &(*member_vec)[ix]; - if (name == conv_op_identifier) + tree *slot = &member_vec->last (); + if (IDENTIFIER_CONV_OP_P (name)) { /* Install the marker prefix. */ *slot = ovl_make (conv_op_marker, NULL_TREE); Index: cp/name-lookup.h =================================================================== --- cp/name-lookup.h (revision 258041) +++ cp/name-lookup.h (working copy) @@ -310,7 +310,8 @@ extern tree lookup_arg_dependent (tree, extern tree search_anon_aggr (tree, tree); extern tree get_class_binding_direct (tree, tree, int type_or_fns = -1); extern tree get_class_binding (tree, tree, int type_or_fns = -1); -extern tree *get_member_slot (tree klass, tree name); +extern tree *find_member_slot (tree klass, tree name); +extern tree *add_member_slot (tree klass, tree name); extern void resort_type_member_vec (void *, void *, gt_pointer_operator, void *); extern void set_class_bindings (tree, unsigned extra = 0); Index: testsuite/g++.dg/lookup/pr84426.C =================================================================== --- testsuite/g++.dg/lookup/pr84426.C (revision 0) +++ testsuite/g++.dg/lookup/pr84426.C (working copy) @@ -0,0 +1,9 @@ +// PR c++/84426 ICE after error + +struct A +{ + int foo; // { dg-message "previous" } + virtual void foo(); // { dg-error "conflict" } +}; + +struct B : A {}; // ICED here --------------C3F3AE5BD44AEF364DA84262--