From patchwork Sun Nov 7 00:17:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: will wray X-Patchwork-Id: 47177 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0DE483858406 for ; Sun, 7 Nov 2021 00:18:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0DE483858406 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636244338; bh=PdBAw3SlHjwdGeYxbPQ488mMYv68QxrS1Ru2MlfWM/w=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=VeDbSlLJRXxJ2geamGTeYpNOcXhM5Nn7EOYIaOGjzES+qpEzUaF3AIkKnlimLoXrm bJKF2lhpc5H8/L2aRcQM59vTh7O1T5zsMXeweNgi7kUdkZb7u4AIWpnK5lGkRo+/Of 2zguIgMxQf4qMSdxZTy/jU+W8pPonTyupIAsXLF8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x733.google.com (mail-qk1-x733.google.com [IPv6:2607:f8b0:4864:20::733]) by sourceware.org (Postfix) with ESMTPS id C88193858401 for ; Sun, 7 Nov 2021 00:18:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C88193858401 Received: by mail-qk1-x733.google.com with SMTP id r8so12271341qkp.4 for ; Sat, 06 Nov 2021 17:18:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=PdBAw3SlHjwdGeYxbPQ488mMYv68QxrS1Ru2MlfWM/w=; b=ggcq2Chi4NB7racDK9s5Piz54CDQ9fqNyqRNZULMt8/LJIM/B/LPojUZVMJ1XXUEOa 1tzhsdUyNVGJHujQ2TBoOU6zWOtqnMWOZmWLbgsqtyiacmbOfBE9uNEDDtr4sR1NveO5 av7Q+aOq+oYBQhGpg+bUi7q55btCJmV/PX5NrswHP+LklZ6d4+HdhjTtlZKu9TywVjgy PO3HrV8AXSf/02ctnUFirpJEW4OfU+e0mCihTYztdjdGi4Qn2p3lZShbK+XFj3fidz33 zdvvjgGzuybEhZ4ob392eo3Iralekd1rTxoc+2ccK2ZOUpNMfuhDypt2zBc2kpp8HSGW zcWQ== X-Gm-Message-State: AOAM531ag9SFgte0R/nOVJuouLNjxUnXTdqMFUU4s7RfWcJfZQuaH6B/ mjqC+0diKpQGQa8smSeGTIZsCebtrbk= X-Google-Smtp-Source: ABdhPJzXnx7PJkSyiqQ7MTNXzaFKFaNMpBWDa3Sh+5ZwfGmx50njMTuh723HS6rPocdU+g+YtqL1qg== X-Received: by 2002:a05:620a:2548:: with SMTP id s8mr54634989qko.173.1636244301974; Sat, 06 Nov 2021 17:18:21 -0700 (PDT) Received: from localhost.localdomain (bras-base-sttnpq8102w-grc-12-174-93-227-155.dsl.bell.ca. [174.93.227.155]) by smtp.googlemail.com with ESMTPSA id v19sm9168556qtk.6.2021.11.06.17.18.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Nov 2021 17:18:21 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: designated init of char array by string constant [PR55227] Date: Sat, 6 Nov 2021 20:17:23 -0400 Message-Id: <20211107001723.2528944-1-wjwray@gmail.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Will Wray via Gcc-patches From: will wray Reply-To: Will Wray Cc: Will Wray Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch aims to fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55227. There are two underlying bugs in the designated initialization of char array fields by string literals that cause: (1) Rejection of valid cases with: (a) brace-enclosed string literal initializer (of any valid size), or (b) unbraced string literal shorter than the target char array field. (2) Acceptance of invalid cases with designators appearing within the braces of a braced string literal, in which case the bogus 'designator' was being entirely ignored and the string literal treated as a positional initializer. Please review these changes carefully; there are likely errors of omission, logic or an anon anomaly. The fixes above allow to address a FIXME in cp_complete_array_type: /* FIXME: this code is duplicated from reshape_init. Probably we should just call reshape_init here? */ I believe that this was obstructed by the designator bugs (see comment here https://patchwork.ozlabs.org/project/gcc/list/?series=199783) Boostraps/regtests on x86_64-pc-linux-gnu. PR c++/55227 gcc/cp/ChangeLog: * decl.c (reshape_init_r): restrict has_designator_check, (cp_complete_array_type): do reshape_init on braced-init-list. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/desig20.C: New test. --- gcc/cp/decl.c | 28 ++++++---------- gcc/testsuite/g++.dg/cpp2a/desig20.C | 48 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/desig20.C diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 947bbfc6637..f01655c5c14 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6820,6 +6820,7 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, { tree str_init = init; tree stripped_str_init = stripped_init; + reshape_iter stripd = {}; /* Strip one level of braces if and only if they enclose a single element (as allowed by [dcl.init.string]). */ @@ -6827,7 +6828,8 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, && TREE_CODE (stripped_str_init) == CONSTRUCTOR && CONSTRUCTOR_NELTS (stripped_str_init) == 1) { - str_init = (*CONSTRUCTOR_ELTS (stripped_str_init))[0].value; + stripd.cur = CONSTRUCTOR_ELT (stripped_str_init, 0); + str_init = stripd.cur->value; stripped_str_init = tree_strip_any_location_wrapper (str_init); } @@ -6836,7 +6838,8 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, array types (one value per array element). */ if (TREE_CODE (stripped_str_init) == STRING_CST) { - if (has_designator_problem (d, complain)) + if ((first_initializer_p && has_designator_problem (d, complain)) + || (stripd.cur && has_designator_problem (&stripd, complain))) return error_mark_node; d->cur++; return str_init; @@ -9538,23 +9541,10 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) if (initial_value) { - /* An array of character type can be initialized from a - brace-enclosed string constant. - - FIXME: this code is duplicated from reshape_init. Probably - we should just call reshape_init here? */ - if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype))) - && TREE_CODE (initial_value) == CONSTRUCTOR - && !vec_safe_is_empty (CONSTRUCTOR_ELTS (initial_value))) - { - vec *v = CONSTRUCTOR_ELTS (initial_value); - tree value = (*v)[0].value; - STRIP_ANY_LOCATION_WRAPPER (value); - - if (TREE_CODE (value) == STRING_CST - && v->length () == 1) - initial_value = value; - } + if (TREE_CODE (initial_value) == CONSTRUCTOR + && BRACE_ENCLOSED_INITIALIZER_P (initial_value)) + initial_value = reshape_init (*ptype, initial_value, + tf_warning_or_error); /* If any of the elements are parameter packs, we can't actually complete this type now because the array size is dependent. */ diff --git a/gcc/testsuite/g++.dg/cpp2a/desig20.C b/gcc/testsuite/g++.dg/cpp2a/desig20.C new file mode 100644 index 00000000000..03eab764325 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/desig20.C @@ -0,0 +1,48 @@ +// PR c++/55227 +// Test designated initializer for char array by string constant + +// { dg-do compile } +// { dg-options "-pedantic" } + +struct C {char a[2];}; + +/* Case a; designated, unbraced, string-literal of the same size as the target + char array to be initialized; valid and accepted before and after. */ + +C a = {.a="a"}; // { dg-warning "designated initializers only available with" "" { target c++17_down } .-0 } + +/* Cases b,c,d; designated mismatched-size string literal, or designated braced + string literal (of any size less than or equal to the target char array), + previously rejected ("C99 designator 'a' outside aggregate initializer"). */ + +C b = {.a=""}; // { dg-warning "designated initializers only available with" "" { target c++17_down } .-0 } +C c = {.a={""}}; // { dg-warning "designated initializers only available with" "" { target c++17_down } .-0 } +C d = {.a={"a"}}; // { dg-warning "designated initializers only available with" "" { target c++17_down } .-0 } + +/* Case e; designated char array field and braced, designated array element(s) + (with GNU [N]= extension) valid extension, accepted before and after. */ + +C e = {.a={[0]='a'}}; // { dg-warning "ISO C.. does not allow C99 designated initializers" } +// { dg-warning "designated initializers only available with" "" { target c++17_down } .-1 } + +/* Cases f,g,h; braced string literal, 'designated' within inner braces; + invalid, previously accepted as positional with 'designator' ignored. */ + +C f = {{[0]="a"}}; // { dg-error "C99 designator .0. outside aggregate initializer" } +// { dg-warning "ISO C.. does not allow C99 designated initializers" "C99 desig" { target *-*-* } .-1 } +C g = {{.a="a"}}; // { dg-error "C99 designator .a. outside aggregate initializer" } +// { dg-warning "designated initializers only available with" "" { target c++17_down } .-1 } +C h = {{.b="a"}}; // { dg-error "C99 designator .b. outside aggregate initializer" } +// { dg-warning "designated initializers only available with" "" { target c++17_down } .-1 } + +template +void t() +{ + C ca[] = { {.a=""}, {.a={""}}, }; +// { dg-warning "designated initializers only available with" "" { target c++17_down } .-1 } +} + +void u() +{ + return t(); +}