From patchwork Fri Jan 29 17:09:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1433398 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=OrK/VI8d; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DS3k23qfxz9sSs for ; Sat, 30 Jan 2021 04:10:00 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3D5D03938C39; Fri, 29 Jan 2021 17:09:58 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf2a.google.com (mail-qv1-xf2a.google.com [IPv6:2607:f8b0:4864:20::f2a]) by sourceware.org (Postfix) with ESMTPS id 354CD38708CB for ; Fri, 29 Jan 2021 17:09:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 354CD38708CB Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qv1-xf2a.google.com with SMTP id u20so738796qvx.7 for ; Fri, 29 Jan 2021 09:09:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=dFMhKQMU5AyB5mcfzCLSKZxzd+7usRHE2yFSQxVtgmo=; b=OrK/VI8dMJ9UWN8iuUOEPdS9wJn0gGQGAMUyoLwV0ahl4sDTjiZU0eirjMYEd+QJpw Ww1CiaCi4pCJvOv3rqzzhvw7qGyBO4azTkP6BOzX39aW43SBF9/F+Nusfh4AoNksQuUX 19l5nD4TGmuRgAI3SMEY8aXkyhcJoYgb2vN9gO5C6+nJNTNRtV7jzUKgVB4JLd9VUG3k XL3PflZEjj9wEQGTxz1Edapcur+bBZoM0nGuhICAWa8o8vMf4nb2fC8jHZLjVq1uZvzo Fukq7OAnRFaPCnPFMyKtwVN1E+TDXvpXc9VQumxJcV3iPQuWU8BpuWaY2wzN/Um3IVK0 TuDA== 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=dFMhKQMU5AyB5mcfzCLSKZxzd+7usRHE2yFSQxVtgmo=; b=qCHef2W0wpcg/KWTMXNDmv1OCAKQcXLdUaG1W077I7SKhX8fVAZWgNEsmPcdqcm9Oe HlxRBlhMk9TqlnBCiIRU79sg41CIcQmYx6ylFTutJ64Ytd7o2p9YfIZ1BghoJAHf2A/5 UlXKV36sHiDRUQH0NC8oS9Nem5LMXl8SaV+o1TLHW1kk0KXkW/S+UMAVXOOogd0lhGjl Zv2BBuvYJuubajrK9rV6iyhXYfk7NOROMZ2hZcXvvN2IE+TL4qLFUhxKFa8Espo9XeSp OL4XDEDhxu4pMBoKQONNiHSGMc5HyX1CWXlyBvNtHWD2aaVXkrIPGRrDD1jZNJo8cbl5 5Ogw== X-Gm-Message-State: AOAM5329eoGDSCjXCZBU4h8mI6/eyV6XuRq2uEW4KGW//bPzyrYr+gYC GAWrGq8nWQnRUGLOUJi/++g= X-Google-Smtp-Source: ABdhPJyMGxH9vCW78lJUpHwq7xYiQYSE9cJ0Ilp2A1B1D8mDF0yhvDSwoY7meID92+YETEYO4G20Pw== X-Received: by 2002:a05:6214:20af:: with SMTP id 15mr5076611qvd.42.1611940186854; Fri, 29 Jan 2021 09:09:46 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:d052:343d:cacb:131d? ([2620:10d:c091:480::1:c6bb]) by smtp.googlemail.com with ESMTPSA id 196sm6278399qkn.64.2021.01.29.09.09.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 29 Jan 2021 09:09:45 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: Fix unordered entity array [PR 98843] Message-ID: Date: Fri, 29 Jan 2021 12:09:44 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" A couple of module invariants are that the modules are always allocated in ascending order and appended to the module array. The entity array is likewise ordered, with each module having spans in that array in ascending order. Prior to header-units, this was provided by the way import declarations were encountered. With header-units we need to load the preprocessor state of header units before we parse the C++, and this can lead to incorrect ordering of the entity array. I had made the initialization of a module's language state a little too lazy. This moves the allocation of entity array spans into the initial read of a module, thus ensuring the ordering of those spans. We won't be looking in them until we've loaded the language portions of that particular module, and even if we did, we'd find NULLs there and issue a diagnostic. PR c++/98843 gcc/cp/ * module.cc (module_state_config): Add num_entities field. (module_state::read_entities): The entity_ary span is already allocated. (module_state::write_config): Write num_entities. (module_state::read_config): Read num_entities. (module_state::write): Set config's num_entities. (module_state::read_initial): Allocate the entity ary span here. (module_state::read_language): Do not set entity_lwm here. gcc/testsuite/ * g++.dg/modules/pr98843_a.C: New. diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc index daf75b16007..2d761452505 100644 --- c/gcc/cp/module.cc +++ w/gcc/cp/module.cc @@ -4064,6 +4064,7 @@ import_entity_module (unsigned index) /* This is an index for an exported entity. */ return (*modules)[0]; + /* Do not include the current TU (not an off-by-one error). */ unsigned pos = 1; unsigned len = modules->length () - pos; while (len) @@ -14480,6 +14481,7 @@ struct module_state_config { const char *dialect_str; unsigned num_imports; unsigned num_partitions; + unsigned num_entities; unsigned ordinary_locs; unsigned macro_locs; unsigned ordinary_loc_align; @@ -14487,7 +14489,7 @@ struct module_state_config { public: module_state_config () :dialect_str (get_dialect ()), - num_imports (0), num_partitions (0), + num_imports (0), num_partitions (0), num_entities (0), ordinary_locs (0), macro_locs (0), ordinary_loc_align (0) { } @@ -15286,9 +15288,7 @@ module_state::read_entities (unsigned count, unsigned lwm, unsigned hwm) dump () && dump ("Reading entities"); dump.indent (); - vec_safe_reserve (entity_ary, count); - unsigned ix; - for (ix = 0; ix != count; ix++) + for (binding_slot *slot = entity_ary->begin () + entity_lwm; count--; slot++) { unsigned snum = sec.u (); if (snum && (snum - lwm) >= (hwm - lwm)) @@ -15296,13 +15296,9 @@ module_state::read_entities (unsigned count, unsigned lwm, unsigned hwm) if (sec.get_overrun ()) break; - binding_slot slot; - slot.u.binding = NULL_TREE; if (snum) - slot.set_lazy (snum << 2); - entity_ary->quick_push (slot); + slot->set_lazy (snum << 2); } - entity_num = ix; dump.outdent (); if (!sec.end (from ())) @@ -17301,6 +17297,7 @@ module_state::write_config (elf_out *to, module_state_config &config, cfg.u (config.num_imports); cfg.u (config.num_partitions); + cfg.u (config.num_entities); cfg.u (config.ordinary_locs); cfg.u (config.macro_locs); @@ -17484,6 +17481,7 @@ module_state::read_config (module_state_config &config) config.num_imports = cfg.u (); config.num_partitions = cfg.u (); + config.num_entities = cfg.u (); config.ordinary_locs = cfg.u (); config.macro_locs = cfg.u (); @@ -17717,6 +17715,7 @@ module_state::write (elf_out *to, cpp_reader *reader) /* Write the entitites. None happens if we contain namespaces or nothing. */ + config.num_entities = counts[MSC_entities]; if (counts[MSC_entities]) write_entities (to, sccs, counts[MSC_entities], &crc); @@ -17818,6 +17817,21 @@ module_state::read_initial (cpp_reader *reader) gcc_checking_assert (mod == MODULE_UNKNOWN); gcc_checking_assert (this != (*modules)[0]); + { + /* Allocate space in the entities array now -- that array must be + monotionically in step with the modules array. */ + entity_lwm = vec_safe_length (entity_ary); + entity_num = config.num_entities; + gcc_checking_assert (modules->length () == 1 + || modules->last ()->entity_lwm <= entity_lwm); + vec_safe_reserve (entity_ary, config.num_entities); + + binding_slot slot; + slot.u.binding = NULL_TREE; + for (unsigned count = config.num_entities; count--;) + entity_ary->quick_push (slot); + } + /* We'll run out of other resources before we run out of module indices. */ mod = modules->length (); @@ -17939,8 +17953,8 @@ module_state::read_language (bool outermost) function_depth++; /* Prevent unexpected GCs. */ - /* Read the entity table. */ - entity_lwm = vec_safe_length (entity_ary); + if (counts[MSC_entities] != entity_num) + ok = false; if (ok && counts[MSC_entities] && !read_entities (counts[MSC_entities], counts[MSC_sec_lwm], counts[MSC_sec_hwm])) diff --git c/gcc/testsuite/g++.dg/modules/pr98843_a.C w/gcc/testsuite/g++.dg/modules/pr98843_a.C new file mode 100644 index 00000000000..97820cff3cc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr98843_a.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodules-ts } +// PR 98843 ICE due to inconsistent entity_ary order + +export module foo; +export void *frob (); diff --git c/gcc/testsuite/g++.dg/modules/pr98843_b.H w/gcc/testsuite/g++.dg/modules/pr98843_b.H new file mode 100644 index 00000000000..d6734bd382d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr98843_b.H @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodule-header } +// PR 98843 ICE due to inconsistent entity_ary order + +template int Fn () +{ + return I; +} + +template<> int Fn<1> () +{ + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/pr98843_c.C w/gcc/testsuite/g++.dg/modules/pr98843_c.C new file mode 100644 index 00000000000..a176e09410e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr98843_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } +// PR 98843 ICE due to inconsistent entity_ary order + +import foo; +import "pr98843_b.H"; + +int main () +{ + return Fn<1> (); +}