From patchwork Fri Oct 21 23:47:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 78759 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1548628qge; Fri, 21 Oct 2016 16:48:50 -0700 (PDT) X-Received: by 10.98.194.68 with SMTP id l65mr6160128pfg.159.1477093730467; Fri, 21 Oct 2016 16:48:50 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id m81si4545685pfi.25.2016.10.21.16.48.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Oct 2016 16:48:50 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439299-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-439299-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439299-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=I3Xgjy8AqGTowOxZuY3XcQpdFHR8E5Kt7pK/nIQ3C8DcCxrfp0 Qy/8ujELk4YV4CzndZmV2bsdPP3FVdHtU/BFEVmWHbTMgiU98mjLi1qZr9ltrKCa P0JpfS7ikPK3vi0A+iU4N6J2VVNaERYYGix9hj084HCH0+9HJGTL7QPfY= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=5q60PixDa+Nw5mIsveQL6h2EUUo=; b=cR+Y8P/UygSIrD2VbPne dPSN+vrPDV5aoZ0CWWf46iKItE4Swyyx1G7/0uveBuAbS8W+YGQ1lYJPl4SfsWmk qNLeffWKvsna/HKnOaPARaLmC/Csyp0BzOojfKUIh2kK8TAbTDpuhOcnrRxET+OT J9mw1xUtcYHBUY0JrPdp3zU= Received: (qmail 92348 invoked by alias); 21 Oct 2016 23:48:28 -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 92088 invoked by uid 89); 21 Oct 2016 23:48:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=relationships, unnamed, s24, S24 X-HELO: mail-qt0-f173.google.com Received: from mail-qt0-f173.google.com (HELO mail-qt0-f173.google.com) (209.85.216.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 21 Oct 2016 23:47:54 +0000 Received: by mail-qt0-f173.google.com with SMTP id m5so97973131qtb.3 for ; Fri, 21 Oct 2016 16:47:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version; bh=G8qoslI4UVk65DUQtxeSnC8dcZhYmXpGPCUykwRAYJc=; b=Vkj/Xevi38YXNkWcNKxGmJN1D44y84mz/EmsU9EjGYBJMi3nr5n9OsIU+07akZuPT1 im0QcroIvcmJ6q5nm3ROd/SmvDgGkbKJHu46wFYJg3Mv//y81B6mUB9qVOrA3en826Uj B6dnd7g8R0LNT6VBLfpo3n+5FLdpN2pUDj3uP1QWG8e7a3ftBZTb/SyA6ZachpuRDREC th7TnlTh6YQULojCcjP7d5NWkuIXe12/jGQDH7GupsWQyjjDQJFXb+D6eocT0BuF0C/x JIEj4ROAd4QKFCOeNNFg7JWa4hv6FXiUbONU9rKM73N4PZhYzn0bu3WdIve1d0xxfKfN MiFA== X-Gm-Message-State: ABUngvcqfw4fwKlGVfuqidT9nOr592ZJfV1kZsU1O9Z9uNiqVMpO6yUdAlYNqZCLq9zA9A== X-Received: by 10.200.48.49 with SMTP id f46mr4094191qte.64.1477093672264; Fri, 21 Oct 2016 16:47:52 -0700 (PDT) Received: from [192.168.0.26] (71-212-250-41.hlrn.qwest.net. [71.212.250.41]) by smtp.gmail.com with ESMTPSA id 58sm2583186qtz.33.2016.10.21.16.47.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Oct 2016 16:47:51 -0700 (PDT) To: Gcc Patch List , Jason Merrill From: Martin Sebor Subject: relax rule for flexible array members in 6.x (78039 - fails to compile glibc tests) Message-ID: <780797da-9742-2f9b-dbc0-4209a9176391@gmail.com> Date: Fri, 21 Oct 2016 17:47:48 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 X-IsSubscribed: yes Bug 78039 complains that the fix for c++/71912 recently backported to the GCC 6 branch causes GCC 6 to reject Glibc tests that expect to be able to define structs with multiple flexible array members, despite it violating the C standard(*). The rejected code is unsafe and was intended to be rejected in 6.1 to begin with (i.e., it was a bug I had missed that the code wasn't rejected in 6.1), and an alternate solution exists, so the backport seemed appropriate to me. However, it was pointed out to me that apparently there is a policy or convention of not backporting to release branches bug fixes that cause GCC to reject code that was previously accepted, even if the code is invalid. To comply with this policy the attached patch adjusts the backported code to accept the invalid flexible array member with just a pedantic warning (same as in C mode). The patch also adds the tests that were part of the fix for bug 71912 but that were accidentally left out of the original backport. Martin [*] Bug 77650 discusses the background on this. PS I checked the GCC Development Plan but couldn't find a mention of this policy. Since this seems like an important guarantee for users to know about and for contributors to maintain I suggest to update the document to reflect it. If there is are no objections I'll propose a separate change to mention it. https://gcc.gnu.org/develop.html PR c++/78039 - fails to compile glibc tests gcc/cp/ChangeLog: 2016-10-21 Martin Sebor PR c++/78039 * class.c (diagnose_flexarrays): Avoid rejecting an invalid flexible array member with a hard error when it is followed by anbother member in a different struct, and instead issue just a pedantic warning. gcc/testsuite/ChangeLog: 2016-10-21 Martin Sebor PR c++/78039 * g++.dg/ext/flexary18.C: New test. * g++.dg/ext/flexary19.C: New test. Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 241433) +++ gcc/cp/class.c (working copy) @@ -6960,7 +6960,20 @@ diagnose_flexarrays (tree t, const flexmems_t *fme location_t loc = DECL_SOURCE_LOCATION (fmem->array); diagd = true; - error_at (loc, msg, fmem->array, t); + /* For compatibility with GCC 6.2 and 6.1 reject with an error + a flexible array member of a plain struct that's followed + by another member only if they are both members of the same + struct. Otherwise, issue just a pedantic warning. See bug + 71375 for details. */ + if (fmem->after[0] + && (!TYPE_BINFO (t) + || 0 == BINFO_N_BASE_BINFOS (TYPE_BINFO (t))) + && DECL_CONTEXT (fmem->array) != DECL_CONTEXT (fmem->after[0]) + && !ANON_AGGR_TYPE_P (DECL_CONTEXT (fmem->array)) + && !ANON_AGGR_TYPE_P (DECL_CONTEXT (fmem->after[0]))) + pedwarn (loc, OPT_Wpedantic, msg, fmem->array, t); + else + error_at (loc, msg, fmem->array, t); /* In the unlikely event that the member following the flexible array member is declared in a different class, or the member Index: gcc/testsuite/g++.dg/ext/flexary18.C =================================================================== --- gcc/testsuite/g++.dg/ext/flexary18.C (revision 0) +++ gcc/testsuite/g++.dg/ext/flexary18.C (working copy) @@ -0,0 +1,213 @@ +// PR c++/71912 - [6/7 regression] flexible array in struct in union rejected +// { dg-do compile } +// { dg-additional-options "-Wpedantic -Wno-error=pedantic" } + +#if __cplusplus + +namespace pr71912 { + +#endif + +struct foo { + int a; + char s[]; // { dg-message "array member .char pr71912::foo::s \\\[\\\]. declared here" } +}; + +struct bar { + double d; + char t[]; +}; + +struct baz { + union { + struct foo f; + struct bar b; + } + // The definition of struct foo is fine but the use of struct foo + // in the definition of u below is what's invalid and must be clearly + // diagnosed. + u; // { dg-warning "invalid use of .struct pr71912::foo. with a flexible array member in .struct pr71912::baz." } +}; + +struct xyyzy { + union { + struct { + int a; + char s[]; // { dg-message "declared here" } + } f; + struct { + double d; + char t[]; + } b; + } u; // { dg-warning "invalid use" } +}; + +struct baz b; +struct xyyzy x; + +#if __cplusplus + +} + +#endif + +// The following definitions aren't strictly valid but, like those above, +// are accepted for compatibility with GCC (in C mode). They are benign +// in that the flexible array member is at the highest offset within +// the outermost type and doesn't overlap with other members except for +// those of the union. +union UnionStruct1 { + struct { int n1, a[]; } s; + int n2; +}; + +union UnionStruct2 { + struct { int n1, a1[]; } s1; + struct { int n2, a2[]; } s2; + int n3; +}; + +union UnionStruct3 { + struct { int n1, a1[]; } s1; + struct { double n2, a2[]; } s2; + char n3; +}; + +union UnionStruct4 { + struct { int n1, a1[]; } s1; + struct { struct { int n2, a2[]; } s2; } s3; + char n3; +}; + +union UnionStruct5 { + struct { struct { int n1, a1[]; } s1; } s2; // { dg-warning "invalid use" } + struct { double n2, a2[]; } s3; + char n3; +}; + +union UnionStruct6 { + struct { struct { int n1, a1[]; } s1; } s2; // { dg-warning "invalid use" } + struct { struct { int n2, a2[]; } s3; } s4; + char n3; +}; + +union UnionStruct7 { + struct { int n1, a1[]; } s1; + struct { double n2, a2[]; } s2; + struct { struct { int n3, a3[]; } s3; } s4; +}; + +union UnionStruct8 { + struct { int n1, a1[]; } s1; + struct { struct { int n2, a2[]; } s2; } s3; + struct { struct { int n3, a3[]; } s4; } s5; +}; + +union UnionStruct9 { + struct { struct { int n1, a1[]; } s1; } s2; // { dg-warning "invalid use" } + struct { struct { int n2, a2[]; } s3; } s4; + struct { struct { int n3, a3[]; } s5; } s6; +}; + +struct StructUnion1 { + union { + struct { int n1, a1[]; } s1; // { dg-message "declared here" } + struct { double n2, a2[]; } s2; + char n3; + } u; // { dg-warning "invalid use" } +}; + +// The following are invalid and rejected. +struct StructUnion2 { + union { + struct { int n1, a1[]; } s1; // { dg-warning "not at end" } + } u; + char n3; // { dg-message "next member" } +}; + +struct StructUnion3 { + union { + struct { int n1, a1[]; } s1; // { dg-warning "not at end" } + struct { double n2, a2[]; } s2; + } u; + char n3; // { dg-message "next member" } +}; + +struct StructUnion4 { + union { + struct { int n1, a1[]; } s1; // { dg-warning "not at end" } + } u1; + union { + struct { double n2, a2[]; } s2; + } u2; // { dg-message "next member" } +}; + +struct StructUnion5 { + union { + union { + struct { int n1, a1[]; } s1; // { dg-message "declared here" } + } u1; + union { struct { int n2, a2[]; } s2; } u2; + } u; // { dg-warning "invalid use" } +}; + +struct StructUnion6 { + union { + struct { int n1, a1[]; } s1; // { dg-message "declared here" } + union { struct { int n2, a2[]; } s2; } u2; + } u; // { dg-warning "invalid use" } +}; + +struct StructUnion7 { + union { + union { + struct { double n2, a2[]; } s2; // { dg-message "declared here" } + } u2; + struct { int n1, a1[]; } s1; + } u; // { dg-warning "invalid use" } +}; + +struct StructUnion8 { + struct { + union { + union { + struct { int n1, a1[]; } s1; // { dg-warning "not at end" } + } u1; + union { + struct { double n2, a2[]; } s2; + } u2; + } u; + } s1; + + struct { + union { + union { + struct { int n1, a1[]; } s1; + } u1; + union { + struct { double n2, a2[]; } s2; + } u2; + } u; } s2; // { dg-message "next member" } +}; + +struct StructUnion9 { // { dg-message "in the definition" } + struct A1 { + union B1 { + union C1 { + struct Sx1 { int n1, a1[]; } sx1; // { dg-warning "not at end" } + } c1; + union D1 { + struct Sx2 { double n2, a2[]; } sx2; + } d1; + } b1; // { dg-warning "invalid use" } + } a1; + + struct A2 { + union B2 { + union C2 { + struct Sx3 { int n3, a3[]; } sx3; // { dg-message "declared here" } + } c2; + union D2 { struct Sx4 { double n4, a4[]; } sx4; } d2; + } b2; // { dg-warning "invalid use" } + } a2; // { dg-message "next member" } +}; Index: gcc/testsuite/g++.dg/ext/flexary19.C =================================================================== --- gcc/testsuite/g++.dg/ext/flexary19.C (revision 0) +++ gcc/testsuite/g++.dg/ext/flexary19.C (working copy) @@ -0,0 +1,343 @@ +// { dg-do compile } +// { dg-additional-options "-Wpedantic -Wno-error=pedantic" } + +// Verify that flexible array members are recognized as either valid +// or invalid in anonymous structs (a G++ extension) and C++ anonymous +// unions as well as in structs and unions that look anonymous but +// aren't. +struct S1 +{ + int i; + + // The following declares a named data member of an unnamed struct + // (i.e., it is not an anonymous struct). + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s; +}; + +struct S2 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s[1]; +}; + +struct S3 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s[]; +}; + +struct S4 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s[2]; +}; + +struct S5 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s[1][2]; +}; + +struct S6 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s[][2]; +}; + +struct S7 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } *s; +}; + +struct S8 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } **s; +}; + +struct S9 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } *s[1]; +}; + +struct S10 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } *s[]; +}; + +struct S11 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } **s[1]; +}; + +struct S12 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } **s[]; +}; + +struct S13 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } **s[2]; +}; + +struct S14 +{ + int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } &s; +}; + +struct S15 +{ + int i; + + typedef struct { + int a[]; // { dg-error "in an otherwise empty" } + } T15; +}; + +struct S16 +{ + int i; + + struct { // { dg-warning "invalid use" } + // A flexible array as a sole member of an anonymous struct is + // rejected with an error in C mode but emits just a pedantic + // warning in C++. Other than excessive pedantry there is no + // reason to reject it. + int a[]; + }; // { dg-warning "anonymous struct" } +}; + +struct S17 +{ + int i; + + union { // anonymous union + int a[]; // { dg-error "flexible array member in union" } + }; +}; + +struct S18 +{ + int i; + + struct { + int j, a[]; // { dg-message "declared here" } + } s; // { dg-warning "invalid use" } +}; + +struct S19 +{ + int i; + + struct { // { dg-warning "invalid use" } + int j, a[]; // { dg-message "declared here" } + }; // { dg-warning "anonymous struct" } +}; + +struct S20 +{ + static int i; + typedef int A[]; + + struct { + int j; + A a; // { dg-message "declared here" } + } s; // { dg-warning "invalid use" } +}; + +struct S21 +{ + static int i; + typedef int A[]; + + struct { // { dg-warning "invalid use" } + int j; + A a; // { dg-message "declared here" } + }; // { dg-warning "anonymous struct" } +}; + +struct S22 +{ + struct S22S { + static int i; + + int a[]; // { dg-error "in an otherwise empty" } + } s; +}; + +struct S23 +{ + struct { + static int i; // { dg-error "static data member" } + + int a[]; // { dg-error "in an otherwise empty" } + }; // { dg-warning "anonymous struct" } +}; + +struct S24 +{ + static int i; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s; +}; + +struct S25 +{ + int i; + + struct { + int j, a[]; // { dg-message "declared here" } + } s; // { dg-warning "invalid use" } + + // Verify that a static data member of the enclosing class doesn't + // cause infinite recursion or some such badness. + static S25 s2; +}; + +struct S26 +{ + template + struct S26S { + static int a; + }; + + struct { + int a[]; // { dg-error "in an otherwise empty" } + } s; +}; + +struct S27 +{ + S27 *p; + int a[]; +}; + +struct S28 +{ + struct A { + struct B { + S28 *ps28; + A *pa; + B *pb; + } b, *pb; + A *pa; + } a, *pa; + + S28::A *pa2; + S28::A::B *pb; + + int flexarray[]; +}; + +// Verify that the notes printed along with the warnings point to the types +// or members they should point to and mention the correct relationships +// with the flexible array members. +namespace Notes +{ +union A +{ + struct { + struct { + int i, a[]; // { dg-message "declared here" } + } c; // { dg-warning "invalid use" } + } d; + int j; +}; + +union B +{ + struct { + struct { // { dg-warning "invalid use" } + int i, a[]; // { dg-message "declared here" } + }; // { dg-warning "anonymous struct" } + }; // { dg-warning "anonymous struct" } + int j; +}; + +} + +typedef struct Opaque* P29; +struct S30 { P29 p; }; +struct S31 { S30 s; }; + +typedef struct { } S32; +typedef struct { S32 *ps32; } S33; +typedef struct +{ + S33 *ps33; +} S34; + +struct S35 +{ + struct A { + int i1, a1[]; + }; + + struct B { + int i2, a2[]; + }; + + typedef struct { + int i3, a3[]; + } C; + + typedef struct { + int i4, a4[]; + } D; + + typedef A A2; + typedef B B2; + typedef C C2; + typedef D D2; +}; +