From patchwork Wed Jan 27 22:50:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1432399 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=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=klNMPxoJ; 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 4DQzNP0CqJz9sT6 for ; Thu, 28 Jan 2021 09:50:59 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5AA23382E807; Wed, 27 Jan 2021 22:50:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5AA23382E807 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1611787856; bh=Bl7+KQ/NWOnHAwM8+P18YjPgazQVdl04QmTPkcaSxR4=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=klNMPxoJWKuiE7PM13nhwAfbMsFUeMGOXS7kr9R9OW4PMxrJ5EyxVeTb7G6dFZxcH YvxtOO+5Qk8rZl5h7aNsyZTHNV5sll8B6nh5hXt8gb11lP52ZwyhipJjd1K39cBbU2 rq5GAbL7FEoKeOaSufx/R7aTZA/7R5EpZVmjQ2mM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x834.google.com (mail-qt1-x834.google.com [IPv6:2607:f8b0:4864:20::834]) by sourceware.org (Postfix) with ESMTPS id A9345386103B for ; Wed, 27 Jan 2021 22:50:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A9345386103B Received: by mail-qt1-x834.google.com with SMTP id e15so2745384qte.9 for ; Wed, 27 Jan 2021 14:50:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=Bl7+KQ/NWOnHAwM8+P18YjPgazQVdl04QmTPkcaSxR4=; b=Cov64zzhwwIAWCDRKtVrka6+Yi/eFOkKxxV1iRJSAMmITlZNpp8/RKrO7Whg1ecojH HD3mSz7b1Ak9Ujrn7QjdUPz0r0qlODg+pd8dzsHPC88slCXrTr4okKrJUR12uHYrqC2X 6WwYWwTZy+zPaxM5gPTqsOj+J7OqnVzpShCwFMp2rgc0UJWUNxmg0Sv3Yi6kM7NAI7Nz 4h9b14CNyOAFCmTO9lA0UxgywuJVDJQJg7kLDPhjL1gi4+Gh6FuwfWQ5rvH14p9wL01g zfMbFLSLTMKzcGCBLv6Kgf0RZE7WaIZc2tttcoX0xuzN2/QHWwajBcgQlz1wEfuYUnNi x/1Q== X-Gm-Message-State: AOAM532Wcmc8JA/19Nrvj2nh500E29y/h89kzoJ5sRhxQ88MYjjaGAVH xcupGEdCgiLMZaXv2DqXO0zjKguSU9Y= X-Google-Smtp-Source: ABdhPJy9KYJWEYI1rKzBAqO6fZrDZkADSZhu+ZC79ItOX5zOEDhOarIuDL8NBoV4Q4/BXV4Im5ERAg== X-Received: by 2002:ac8:6d16:: with SMTP id o22mr12041682qtt.383.1611787853100; Wed, 27 Jan 2021 14:50:53 -0800 (PST) Received: from [192.168.0.41] (184-96-239-30.hlrn.qwest.net. [184.96.239.30]) by smtp.gmail.com with ESMTPSA id j21sm2174953qtr.74.2021.01.27.14.50.51 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 27 Jan 2021 14:50:52 -0800 (PST) Subject: [PATCH v3] clear VLA bounds in attribute access (PR 97172) To: gcc-patches Message-ID: Date: Wed, 27 Jan 2021 15:50:41 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, 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: , X-Patchwork-Original-From: Martin Sebor via Gcc-patches From: Martin Sebor Reply-To: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Attached is another attempt to fix the problem caused by allowing front-end trees representing nontrivial VLA bound expressions to stay in attribute access attached to functions. Since removing these trees seems to be everyone's preference this patch does that by extending the free_lang_data pass to look for and zero out these trees. Because free_lang_data only frees anything when LTO is enabled and we want these trees cleared regardless to keep them from getting clobbered during gimplification, this change also modifies the pass to do the clearing even when the pass is otherwise inactive. Tested on x86_64-linux. Martin PR middle-end/97172 - ICE: tree code 'ssa_name' is not supported in LTO streams gcc/ChangeLog: PR middle-end/97172 * attribs.c (attr_access::free_lang_data): Define new function. * attribs.h (attr_access::free_lang_data): Declare new function. * tree.c (free_lang_data_in_type): Call attr_access::free_lang_data. (array_bound_from_maxval): Define new function. * tree.h (array_bound_from_maxval): Declare new function. gcc/c-family/ChangeLog: PR middle-end/97172 * c-pretty-print.c (c_pretty_printer::direct_abstract_declarator): Call array_bound_from_maxval. gcc/c/ChangeLog: PR middle-end/97172 * c-decl.c (get_parm_array_spec): Call array_bound_from_maxval. gcc/testsuite/ChangeLog: PR middle-end/97172 * gcc.dg/pr97172.c: New test. diff --git a/gcc/attribs.c b/gcc/attribs.c index 94991fbbeab..81322d40f1d 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -2238,6 +2238,38 @@ attr_access::vla_bounds (unsigned *nunspec) const return list_length (size); } +/* Reset front end-specific attribute access data from ATTRS. + Called from the free_lang_data pass. */ + +/* static */ void +attr_access::free_lang_data (tree attrs) +{ + for (tree acs = attrs; (acs = lookup_attribute ("access", acs)); + acs = TREE_CHAIN (acs)) + { + tree vblist = TREE_VALUE (acs); + vblist = TREE_CHAIN (vblist); + if (!vblist) + continue; + + vblist = TREE_VALUE (vblist); + if (!vblist) + continue; + + for (vblist = TREE_VALUE (vblist); vblist; vblist = TREE_CHAIN (vblist)) + { + tree *pvbnd = &TREE_VALUE (vblist); + if (!*pvbnd || DECL_P (*pvbnd)) + continue; + + /* VLA bounds that are expressions as opposed to DECLs are + only used in the front end. Reset them to keep front end + trees leaking into the middle end (see pr97172) and to + free up memory. */ + *pvbnd = NULL_TREE; + } + } +} /* Defined in attr_access. */ constexpr char attr_access::mode_chars[]; diff --git a/gcc/attribs.h b/gcc/attribs.h index 21d28a47f39..898e73db3e4 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -274,6 +274,9 @@ struct attr_access /* Return the access mode corresponding to the character code. */ static access_mode from_mode_char (char); + /* Reset front end-specific attribute access data from attributes. */ + static void free_lang_data (tree); + /* The character codes corresponding to all the access modes. */ static constexpr char mode_chars[5] = { '-', 'r', 'w', 'x', '^' }; diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index 2095d4badf7..c6e8a45afd5 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -635,22 +635,7 @@ c_pretty_printer::direct_abstract_declarator (tree t) /* Strip the expressions from around a VLA bound added internally to make it fit the domain mold, including any casts. */ - if (TREE_CODE (maxval) == NOP_EXPR) - maxval = TREE_OPERAND (maxval, 0); - if (TREE_CODE (maxval) == PLUS_EXPR - && integer_all_onesp (TREE_OPERAND (maxval, 1))) - { - maxval = TREE_OPERAND (maxval, 0); - if (TREE_CODE (maxval) == NOP_EXPR) - maxval = TREE_OPERAND (maxval, 0); - } - if (TREE_CODE (maxval) == SAVE_EXPR) - { - maxval = TREE_OPERAND (maxval, 0); - if (TREE_CODE (maxval) == NOP_EXPR) - maxval = TREE_OPERAND (maxval, 0); - } - + maxval = array_bound_from_maxval (maxval); expression (maxval); } } diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 4ba9477f5d1..9dcad5e362d 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5781,7 +5781,8 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs) { /* Each variable VLA bound is represented by the dollar sign. */ - spec += "$"; + spec += '$'; + nelts = array_bound_from_maxval (nelts); tpbnds = tree_cons (NULL_TREE, nelts, tpbnds); } } @@ -5835,7 +5836,8 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs) } /* Each variable VLA bound is represented by a dollar sign. */ - spec += "$"; + spec += '$'; + nelts = array_bound_from_maxval (nelts); vbchain = tree_cons (NULL_TREE, nelts, vbchain); } diff --git a/gcc/testsuite/gcc.dg/pr97172.c b/gcc/testsuite/gcc.dg/pr97172.c new file mode 100644 index 00000000000..ab5b2e9e7e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97172.c @@ -0,0 +1,50 @@ +/* PR middle-end/97172 - ICE: tree code ‘ssa_name’ is not supported in LTO + streams + { dg-do compile } + { dg-options "-Wall -flto" } + { dg-require-effective-target lto } */ + +int n; + +void fn (int a[n]); +void fnp1 (int a[n + 1]); + +void fx_n (int a[][n]); +void fx_np1 (int a[][n + 1]); + +void f2_n (int a[2][n]); +void f2_np1 (int a[2][n + 1]); + +void fn_3 (int a[n][3]); +void fnp1_3 (int a[n + 1][3]); + +void fn_n (int a[n][n]); +void fn_np1 (int a[n][n + 1]); +void fnp1_np1 (int a[n + 1][n + 1]); + +void fn_n_n (int a[n][n][n]); +void fn_n_np1 (int a[n][n][n + 1]); +void fn_np1_np1 (int a[n][n + 1][n + 1]); +void fnp1_np1_np1 (int a[n + 1][n + 1][n + 1]); + + +void gn (int a[n]) { fn (a); } +void gnp1 (int a[n + 1]) { fnp1 (a); } + +void gx_n (int a[][n]) { fx_n (a); } +void gx_np1 (int a[][n + 1]) { fx_np1 (a); } + +void g2_n (int a[2][n]) { f2_n (a); } +void g2_np1 (int a[2][n + 1]) { f2_np1 (a); } + +void gn_3 (int a[n][3]) { fn_3 (a); } +void gnp1_3 (int a[n + 1][3]) { fnp1_3 (a); } + +void gn_n (int a[n][n]) { fn_n (a); } +void gn_np1 (int a[n][n + 1]) { fn_np1 (a); } +void gnp1_np1 (int a[n + 1][n + 1]) { fnp1_np1 (a); } + +void gn_n_n (int a[n][n][n]) { fn_n_n (a); } +void gn_n_np1 (int a[n][n][n + 1]) { fn_n_np1 (a); } +void gn_np1_np1 (int a[n][n + 1][n + 1]) { fn_np1_np1 (a); } +void gnp1_np1_np1 (int a[n + 1][n + 1][n + 1]) { fnp1_np1_np1 (a); } diff --git a/gcc/tree.c b/gcc/tree.c index f9d57e6d409..2d9003bfcae 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5622,6 +5622,10 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld) if (TREE_CODE (type) == FUNCTION_TYPE) { TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld); + + /* Free front end-specific attribute access data. */ + attr_access::free_lang_data (TYPE_ATTRIBUTES (type)); + /* Remove the const and volatile qualifiers from arguments. The C++ front end removes them, but the C front end does not, leading to false ODR violation errors when merging two @@ -6374,6 +6378,26 @@ free_lang_data_in_cgraph (class free_lang_data_d *fld) free_lang_data_in_type (t, fld); } +/* Free attribute access data that are not needed by the middle end. */ + +static void +free_attr_access_data () +{ + struct cgraph_node *n; + + /* Iterate over all functions declared in the translation unit. */ + FOR_EACH_FUNCTION (n) + { + tree fntype = TREE_TYPE (n->decl); + if (!fntype) + continue; + tree attrs = TYPE_ATTRIBUTES (fntype); + if (!attrs) + continue; + + attr_access::free_lang_data (attrs); + } +} /* Free resources that are used by FE but are not needed once they are done. */ @@ -6387,6 +6411,9 @@ free_lang_data (void) if (in_lto_p || (!flag_generate_lto && !flag_generate_offload)) { + if (!in_lto_p) + free_attr_access_data (); + /* Rebuild type inheritance graph even when not doing LTO to get consistent profile data. */ rebuild_type_inheritance_graph (); @@ -9356,6 +9383,48 @@ variably_modified_type_p (tree type, tree fn) #undef RETURN_TRUE_IF_VAR } +/* Strip any expressions from around the array bound MAXVAL, including + any casts, added internally to VLAs to make them fit the array domain + mold. Return the result. */ + +tree +array_bound_from_maxval (tree maxval) +{ + tree bound = maxval; + + if (TREE_CODE (bound) == NOP_EXPR) + bound = TREE_OPERAND (bound, 0); + + if (TREE_CODE (bound) == CONVERT_EXPR) + { + tree op0 = TREE_OPERAND (bound, 0); + tree bndtyp = TREE_TYPE (bound); + tree op0typ = TREE_TYPE (op0); + if (TYPE_PRECISION (bndtyp) == TYPE_PRECISION (op0typ)) + bound = op0; + } + + if (TREE_CODE (bound) == NON_LVALUE_EXPR) + bound = TREE_OPERAND (bound, 0); + + if (TREE_CODE (bound) == PLUS_EXPR + && integer_all_onesp (TREE_OPERAND (bound, 1))) + { + bound = TREE_OPERAND (bound, 0); + if (TREE_CODE (bound) == NOP_EXPR) + bound = TREE_OPERAND (bound, 0); + } + + if (TREE_CODE (bound) == SAVE_EXPR) + { + bound = TREE_OPERAND (bound, 0); + if (TREE_CODE (bound) == NOP_EXPR) + bound = TREE_OPERAND (bound, 0); + } + + return bound; +} + /* Given a DECL or TYPE, return the scope in which it was declared, or NULL_TREE if there is no containing scope. */ diff --git a/gcc/tree.h b/gcc/tree.h index 17a811c02e8..0c4ec76ad21 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5234,6 +5234,7 @@ extern bool int_fits_type_p (const_tree, const_tree) extern void get_type_static_bounds (const_tree, mpz_t, mpz_t); #endif extern bool variably_modified_type_p (tree, tree); +extern tree array_bound_from_maxval (tree) ATTRIBUTE_NONNULL (1); extern int tree_log2 (const_tree); extern int tree_floor_log2 (const_tree); extern unsigned int tree_ctz (const_tree);