From patchwork Fri Aug 17 12:01:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 958786 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-483842-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=hotmail.de Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ataXVwiO"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41sMHp1Yytz9s3Z for ; Fri, 17 Aug 2018 22:01:40 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:content-type:mime-version; q=dns; s= default; b=yep0NcqGW/kCpIYYYT/TL/DmQxqnLSeLYf3y+G118fRWN2h1SjDrp Q0bvNI3Foeo+lFLFpW2wpnHuwR8kuXiGgHfMHF3Wr5KrI1GG4OKOO8ud3GyVJNQl M6K0OrizYP9S9keM2Y1Q++UK03hca0DqKcYPfNwiB5LrG9TsO795HI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:content-type:mime-version; s= default; bh=oh657Rhwu4hdFTvaiiZJQLFisxE=; b=ataXVwiOnz+tN8abDZ3A EBxntExYbpO/lsarzN5IqHwb9nDtZrOYp2jTXNujtCZr4ewYyMgfWN9WVzt4/Al2 PUdf2KjwDLsQhopsdp8ySuu+8tCV+JVj5jHZn6h/e//ROcoVq3TxWYAL7I16i4FH enPWrG79MvjE5ZNSfoB5OV0= Received: (qmail 53074 invoked by alias); 17 Aug 2018 12:01:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 53056 invoked by uid 89); 17 Aug 2018 12:01:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_MANYTO, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=defense, UD:typeck2.c, rich_location, typeck2c X-HELO: EUR02-VE1-obe.outbound.protection.outlook.com Received: from mail-oln040092069103.outbound.protection.outlook.com (HELO EUR02-VE1-obe.outbound.protection.outlook.com) (40.92.69.103) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Aug 2018 12:01:29 +0000 Received: from HE1EUR02FT018.eop-EUR02.prod.protection.outlook.com (10.152.10.58) by HE1EUR02HT037.eop-EUR02.prod.protection.outlook.com (10.152.11.189) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.20.1059.14; Fri, 17 Aug 2018 12:01:25 +0000 Received: from AM5PR0701MB2657.eurprd07.prod.outlook.com (10.152.10.51) by HE1EUR02FT018.mail.protection.outlook.com (10.152.10.248) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.1059.14 via Frontend Transport; Fri, 17 Aug 2018 12:01:25 +0000 Received: from AM5PR0701MB2657.eurprd07.prod.outlook.com ([fe80::24cf:823c:758c:41b7]) by AM5PR0701MB2657.eurprd07.prod.outlook.com ([fe80::24cf:823c:758c:41b7%5]) with mapi id 15.20.1059.007; Fri, 17 Aug 2018 12:01:25 +0000 From: Bernd Edlinger To: "gcc-patches@gcc.gnu.org" , Jeff Law , Richard Biener , Jason Merrill , Joseph Myers , Martin Sebor Subject: [PATCH] Call braced_list_to_string after array size is fixed Date: Fri, 17 Aug 2018 12:01:25 +0000 Message-ID: received-spf: None (protection.outlook.com: hotmail.de does not designate permitted sender hosts) authentication-results: spf=none (sender IP is ) smtp.mailfrom=bernd.edlinger@hotmail.de; MIME-Version: 1.0 Hi, Yes I know Martin will see this as a capital offense, but to my excuse I must say it only happened in self defense :-) As my other patch series depends on STRNG_CSTs with certain properties, it got broken by the way the string constants are created now, due to the 71625 patch. In order to be able to bootstrap my patch with current trunk, I had to move the point where the char array constructor is converted to a STRING_CST to the point directly after the array bounds are fixed, so that it is possible to create the string constant (with implicit NUL termination) like all other C strings, without making the array larger. I added a test case for a crash with an invalid string intializer (in C++). and removed an xfail in the new test case string2.C. This way the C++ diagnostics matches the state before 71625 was applied. This does not fix the other problems with 71625, but I don't think they are related to the way the string constants are created, so there should be no conflict. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd. c-family: 2018-08-17 Bernd Edlinger * c-common.c (braced_list_to_string): Remove eval parameter. Add some more checks. Always create zero-terminated STRING_CST. * c-common.h (braced_list_to_string): Adjust prototype. c: 2018-08-17 Bernd Edlinger * c-decl.c (finish_decl): Call braced_list_to_string here ... * c-parser.c (c_parser_declaration_or_fndef): ... instead of here. cp: 2018-08-17 Bernd Edlinger * decl.c (eval_check_narrowing): Remove. (check_initializer): Move call to braced_list_to_string from here ... * typeck2.c (store_init_value): ... to here. (digest_init_r): Remove handing of signed/unsigned char strings. testsuite: 2018-08-17 Bernd Edlinger * c-c++-common/array-init.c: New test. * g++.dg/init/string2.C: Remove xfail. Index: gcc/c/c-decl.c =================================================================== --- gcc/c/c-decl.c (revision 263554) +++ gcc/c/c-decl.c (working copy) @@ -5011,6 +5011,17 @@ finish_decl (tree decl, location_t init_ relayout_decl (decl); } + if (TREE_CODE (type) == ARRAY_TYPE + && DECL_INITIAL (decl) + && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR) + { + tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); + if (typ1 == char_type_node + || typ1 == signed_char_type_node + || typ1 == unsigned_char_type_node) + DECL_INITIAL (decl) = braced_list_to_string (type, DECL_INITIAL (decl)); + } + if (VAR_P (decl)) { if (init && TREE_CODE (init) == CONSTRUCTOR) Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 263554) +++ gcc/c/c-parser.c (working copy) @@ -2126,15 +2126,6 @@ c_parser_declaration_or_fndef (c_parser if (d != error_mark_node) { maybe_warn_string_init (init_loc, TREE_TYPE (d), init); - - /* Try to convert a string CONSTRUCTOR into a STRING_CST. */ - tree valtype = TREE_TYPE (init.value); - if (TREE_CODE (init.value) == CONSTRUCTOR - && TREE_CODE (valtype) == ARRAY_TYPE - && TYPE_STRING_FLAG (TREE_TYPE (valtype))) - if (tree str = braced_list_to_string (valtype, init.value)) - init.value = str; - finish_decl (d, init_loc, init.value, init.original_type, asm_name); } Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 263554) +++ gcc/c-family/c-common.c (working copy) @@ -8510,39 +8510,24 @@ maybe_add_include_fixit (rich_location * } /* Attempt to convert a braced array initializer list CTOR for array - TYPE into a STRING_CST for convenience and efficiency. When non-null, - use EVAL to attempt to evalue constants (used by C++). Return - the converted string on success or null on failure. */ + TYPE into a STRING_CST for convenience and efficiency. Return + the converted string on success or the original ctor on failure. */ tree -braced_list_to_string (tree type, tree ctor, tree (*eval)(tree, tree)) +braced_list_to_string (tree type, tree ctor) { unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); - /* If the array has an explicit bound, use it to constrain the size - of the string. If it doesn't, be sure to create a string that's - as long as implied by the index of the last zero specified via - a designator, as in: - const char a[] = { [7] = 0 }; */ + /* When this function is called, the array has already an explicit bound, + but in the case of VLAs it can be a variable length. + See testsuite/g++.dg/ext/vla19.C for an example. + Allow this conversion to succeed in this case. */ unsigned HOST_WIDE_INT maxelts = HOST_WIDE_INT_M1U; - if (tree size = TYPE_SIZE_UNIT (type)) + if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))) { - if (tree_fits_uhwi_p (size)) - { - maxelts = tree_to_uhwi (size); - maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); - - /* Avoid converting initializers for zero-length arrays. */ - if (!maxelts) - return NULL_TREE; - } + maxelts = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); } - else if (!nelts) - /* Avoid handling the undefined/erroneous case of an empty - initializer for an arrays with unspecified bound. */ - return NULL_TREE; - - tree eltype = TREE_TYPE (type); auto_vec str; str.reserve (nelts + 1); @@ -8552,19 +8537,21 @@ braced_list_to_string (tree type, tree c FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value) { - unsigned HOST_WIDE_INT idx = index ? tree_to_uhwi (index) : i; + unsigned HOST_WIDE_INT idx = i; + if (index) + { + if (!tree_fits_uhwi_p (index)) + return ctor; + idx = tree_to_uhwi (index); + } /* auto_vec is limited to UINT_MAX elements. */ if (idx > UINT_MAX) - return NULL_TREE; + return ctor; - /* Attempt to evaluate constants. */ - if (eval) - value = eval (eltype, value); - - /* Avoid non-constant initializers. */ + /* Avoid non-constant initializers. */ if (!tree_fits_shwi_p (value)) - return NULL_TREE; + return ctor; /* Skip over embedded nuls except the last one (initializer elements are in ascending order of indices). */ @@ -8572,11 +8559,14 @@ braced_list_to_string (tree type, tree c if (!val && i + 1 < nelts) continue; + if (idx < str.length()) + return ctor; + /* Bail if the CTOR has a block of more than 256 embedded nuls due to implicitly initialized elements. */ unsigned nchars = (idx - str.length ()) + 1; if (nchars > 256) - return NULL_TREE; + return ctor; if (nchars > 1) { @@ -8585,17 +8575,15 @@ braced_list_to_string (tree type, tree c } if (idx > maxelts) - return NULL_TREE; + return ctor; str.safe_insert (idx, val); } - if (!nelts) - /* Append a nul for the empty initializer { }. */ - str.safe_push (0); + /* Append a nul string termination. */ + str.safe_push (0); - /* Build a STRING_CST with the same type as the array, which - may be an array of unknown bound. */ + /* Build a STRING_CST with the same type as the array */ tree res = build_string (str.length (), str.begin ()); TREE_TYPE (res) = type; return res; Index: gcc/c-family/c-common.h =================================================================== --- gcc/c-family/c-common.h (revision 263554) +++ gcc/c-family/c-common.h (working copy) @@ -1331,7 +1331,7 @@ extern void maybe_add_include_fixit (ric extern void maybe_suggest_missing_token_insertion (rich_location *richloc, enum cpp_ttype token_type, location_t prev_token_loc); -extern tree braced_list_to_string (tree, tree, tree (*)(tree, tree) = NULL); +extern tree braced_list_to_string (tree, tree); #if CHECKING_P namespace selftest { Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 263554) +++ gcc/cp/decl.c (working copy) @@ -6282,30 +6282,6 @@ build_aggr_init_full_exprs (tree decl, t return build_aggr_init (decl, init, flags, tf_warning_or_error); } -/* Attempt to determine the constant VALUE of integral type and convert - it to TYPE, issuing narrowing warnings/errors as necessary. Return - the constant result or null on failure. Callback for - braced_list_to_string. */ - -static tree -eval_check_narrowing (tree type, tree value) -{ - if (tree valtype = TREE_TYPE (value)) - { - if (TREE_CODE (valtype) != INTEGER_TYPE) - return NULL_TREE; - } - else - return NULL_TREE; - - value = scalar_constant_value (value); - if (!value) - return NULL_TREE; - - check_narrowing (type, value, tf_warning_or_error); - return value; -} - /* Verify INIT (the initializer for DECL), and record the initialization in DECL_INITIAL, if appropriate. CLEANUP is as for grok_reference_init. @@ -6421,17 +6397,7 @@ check_initializer (tree decl, tree init, } else { - /* Try to convert a string CONSTRUCTOR into a STRING_CST. */ - tree valtype = TREE_TYPE (decl); - if (TREE_CODE (valtype) == ARRAY_TYPE - && TYPE_STRING_FLAG (TREE_TYPE (valtype)) - && BRACE_ENCLOSED_INITIALIZER_P (init)) - if (tree str = braced_list_to_string (valtype, init, - eval_check_narrowing)) - init = str; - - if (TREE_CODE (init) != STRING_CST) - init = reshape_init (type, init, tf_warning_or_error); + init = reshape_init (type, init, tf_warning_or_error); flags |= LOOKUP_NO_NARROWING; } } Index: gcc/cp/typeck2.c =================================================================== --- gcc/cp/typeck2.c (revision 263554) +++ gcc/cp/typeck2.c (working copy) @@ -813,6 +813,16 @@ store_init_value (tree decl, tree init, vec int tmplen () { static const T - a[] = { 1, 2, 333, 0 }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } } + a[] = { 1, 2, 333, 0 }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" } return __builtin_strlen (a); }