From patchwork Mon Nov 22 23:54:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 48017 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 4DEB73858409 for ; Mon, 22 Nov 2021 23:55:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4DEB73858409 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637625301; bh=zFj4vloD30TBJYOJCXfJMdsu4ddX2S8Sjpb2IzzcSuo=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=qaMHFfSbvR9FwPwAHvu3EPm4YI4AzieVkTf5bamPjs8IuQ5sRHhEDAdmFZ0k1jUcV LEk7IYl/E6/S2L6pZwzbCCuHZ4S4uerMu2QSUCsH1tSDNSxzWDZBRLjnMTnhudq4Ja taXlt9aLkguHENT4szwaLmX8TK5L52T8TAiqv15I= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 354D83858409 for ; Mon, 22 Nov 2021 23:54:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 354D83858409 Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-71-ObXUoDpdMoqAaqSfRJ9oQw-1; Mon, 22 Nov 2021 18:54:22 -0500 X-MC-Unique: ObXUoDpdMoqAaqSfRJ9oQw-1 Received: by mail-qv1-f72.google.com with SMTP id 1-20020ad45ba1000000b003bdfcecfe10so17720267qvq.23 for ; Mon, 22 Nov 2021 15:54:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=zFj4vloD30TBJYOJCXfJMdsu4ddX2S8Sjpb2IzzcSuo=; b=ES29Wx/U2ltygE9FPceMOgjqoa+Ack1QlknHHsdLiBHbbTA22bae02o5AXxyORnoTM u3Jk0boZ53B4YDkZp+domNkTL0AbZxVdJWgik+yhVNvukpaNAB5yrXjIuF2vec4Ie+mF UK+v0LkPUXIeTyQqWX1ogjETMFYuIvCHdT3Dj0R06tKlaKqeTavhNlDs2Yx6ewSXjTyc ku1ExPhlzSRA1TcWdClssGZAfnUkVdD+GzzprKRaTZGpJWKvnHvj4RmcKCrn3SxsG2zP Y+V2EMIR47BFPLdBuGHwMIdwUZlgO0yeB13hHKpm8zj7xbh9AQCApJrHAvzkA/OnZ22h Btzg== X-Gm-Message-State: AOAM533l+//Z1AVGuTSin/1nr1PQKiqlde5tlbJDuL6y7CuM19o0axFw wQEBZfgHMZ2ForHeX3eXAbLUInrOdlc9XRFaTzNO5CQQcL6WlilJVHHiWjF89k7BldRiBc9Yv7j qIsn/Bo87R63XfXEt6d55JRdJVOENIOCdviZqKHLQsVF24Vcm/EyT6gjhhh2mQuVR7A4= X-Received: by 2002:a37:6d3:: with SMTP id 202mr799627qkg.16.1637625261407; Mon, 22 Nov 2021 15:54:21 -0800 (PST) X-Google-Smtp-Source: ABdhPJx/PEkxbT7HJ2LBcVfsHBbB9EWmVuOOcRDeRmylqrKQUfZG5r7cxOoFQ5PBj1snuQpoTqcZlA== X-Received: by 2002:a37:6d3:: with SMTP id 202mr799595qkg.16.1637625261109; Mon, 22 Nov 2021 15:54:21 -0800 (PST) Received: from [192.168.0.41] (184-96-250-76.hlrn.qwest.net. [184.96.250.76]) by smtp.gmail.com with ESMTPSA id d19sm5285112qtb.47.2021.11.22.15.54.20 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 22 Nov 2021 15:54:20 -0800 (PST) Subject: [PATCH] correct handling of offsets in PHI expressions [PR103215] To: gcc-patches Message-ID: <0a747b7c-4cff-b643-3b34-5c9e113c7523@redhat.com> Date: Mon, 22 Nov 2021 16:54:19 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SCC_10_SHORT_WORD_LINES, SCC_20_SHORT_WORD_LINES, SCC_35_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_NONE, 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: Martin Sebor via Gcc-patches From: Martin Sebor Reply-To: Martin Sebor Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" In an effort to avoid false positives while still detecting certain out-of-bounds accesses the warning code that handles PHI nodes chooses the operand with the most space remaining as the one representative of the PHI. That's not right when the offsets into the operands are unequal, because it overly constrains the range of offsets that can be substracted from the pointer. The attached change corrects the logic here to not only use the size of the largest operand but also to extend the range of offsets into it to reflect all operand. Unfortunately, as a result of the more conservative offset computation, the fix leads to a fair number of false negatives. I tried to avoid those but couldn't come up with a clean solution that didn't require design changes, so I defer those to GCC 13. The diff is relative to the "cleanup" patch submitted below: https://gcc.gnu.org/pipermail/gcc-patches/2021-November/583735.html Tested on x86_64-linux and by building Glibc and confirming no new warnings. Martin Extend the offset and size of merged object references [PR103215]. Resolves: PR tree-optimization/103215 - bogus -Warray-bounds with two pointers with different offsets each gcc/ChangeLog: PR tree-optimization/103215 * pointer-query.cc (access_ref::merge_ref): Extend the offset and size of the merged object instead of using the larger. gcc/testsuite/ChangeLog: PR tree-optimization/103215 * gcc.dg/Wstringop-overflow-58.c: Adjust and xfail expected warnings. * gcc.dg/Wstringop-overflow-59.c: Same. * gcc.dg/warn-strnlen-no-nul.c: Same. * gcc.dg/Warray-bounds-91.c: New test. * gcc.dg/Warray-bounds-92.c: New test. * gcc.dg/Wstringop-overflow-83.c: New test. * gcc.dg/Wstringop-overflow-85.c: New test. diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 2f305514ddc..7dc6e0141f8 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -686,27 +686,32 @@ access_ref::merge_ref (vec *all_refs, tree arg, gimple *stmt, if (known_size && aref.sizrng[0] < minsize) minsize = aref.sizrng[0]; - /* Determine the amount of remaining space in the argument. */ - offset_int argrem[2]; - argrem[1] = aref.size_remaining (argrem); + /* Extend the size and offset of *THIS to account for AREF. The result + can be cached but results in false negatives. */ - /* Determine the amount of remaining space computed so far and - if the remaining space in the argument is more use it instead. */ - offset_int merged_rem[2]; - merged_rem[1] = size_remaining (merged_rem); + offset_int orng[2]; + if (sizrng[1] < aref.sizrng[1]) + { + orng[0] = offrng[0]; + orng[1] = offrng[1]; + *this = aref; + } + else + { + orng[0] = aref.offrng[0]; + orng[1] = aref.offrng[1]; + } + + if (orng[0] < offrng[0]) + offrng[0] = orng[0]; + if (offrng[1] < orng[1]) + offrng[1] = orng[1]; /* Reset the PHI's BASE0 flag if any of the nonnull arguments refers to an object at an unknown offset. */ if (!aref.base0) base0 = false; - if (merged_rem[1] < argrem[1] - || (merged_rem[1] == argrem[1] - && sizrng[1] < aref.sizrng[1])) - /* Use the argument with the most space remaining as the result, - or the larger one if the space is equal. */ - *this = aref; - sizrng[0] = minsize; parmarray = merged_parmarray; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-91.c b/gcc/testsuite/gcc.dg/Warray-bounds-91.c new file mode 100644 index 00000000000..1c81091b2a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-91.c @@ -0,0 +1,145 @@ +/* PR middle-end/103215 - bogus -Warray-bounds with two pointers with + different offsets each + Test for accesses into the same array through pointers with different + offsets each. + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +#define NOIPA __attribute__ ((noipa)) + +#define A(p, off) ((p)[off] = __COUNTER__) + +extern int a4[4]; + + +NOIPA void p0_p1 (int i) +{ + int *p0 = a4 + 0; + int *p1 = a4 + 1; + int *q = i ? p0 : p1; + A (q, -2); // { dg-warning "-Warray-bounds" } + A (q, -1); A (q, 0); A (q, 1); A (q, 2); + /* Since q points to a4 and -1 is a valid subscript, +3 must be invalid. + But the warning for each subscript is independent of prior subscripts + into the same object. That should be improved. */ + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" } +} + +NOIPA void p1_p0 (int i) +{ + int *p1 = a4 + 1; + int *p0 = a4 + 0; + int *q = i ? p0 : p1; + A (q, -2); // { dg-warning "-Warray-bounds" } + A (q, -1); A (q, 0); A (q, 1); A (q, 2); + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void p1_p2 (int i) +{ + int *p1 = a4 + 1; + int *p2 = a4 + 2; + int *q = i ? p1 : p2; + A (q, -3); // { dg-warning "-Warray-bounds" } + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" } +} + +NOIPA void p2_p1 (int i) +{ + int *p2 = a4 + 2; + int *p1 = a4 + 1; + int *q = i ? p1 : p2; + A (q, -3); // { dg-warning "-Warray-bounds" } + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void p1_p3 (int i) +{ + int *p1 = a4 + 1; + int *p3 = a4 + 3; + int *q = i ? p1 : p3; + A (q, -4); // { dg-warning "-Warray-bounds" } + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" } +} + +NOIPA void p3_p1 (int i) +{ + int *p3 = a4 + 3; + int *p1 = a4 + 1; + int *q = i ? p1 : p3; + A (q, -4); // { dg-warning "-Warray-bounds" } + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void p1_p4 (int i) +{ + int *p1 = a4 + 1; + int *p4 = a4 + 4; + int *q = i ? p1 : p4; + A (q, -5); // { dg-warning "-Warray-bounds" } + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" } +} + +NOIPA void p4_p1 (int i) +{ + int *p4 = a4 + 4; + int *p1 = a4 + 1; + int *q = i ? p1 : p4; + A (q, -5); // { dg-warning "-Warray-bounds" } + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void p0_p1_p2 (int i) +{ + int *p0 = a4 + 0; + int *p1 = a4 + 1; + int *p2 = a4 + 2; + int *q = i < 0 ? p1 : 0 < i ? p2 : p0; + A (q, -3); // { dg-warning "-Warray-bounds" } + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void p0_p1_p2_p3_p4 (int i) +{ + int *p0 = a4 + 0; + int *p1 = a4 + 1; + int *p2 = a4 + 2; + int *p3 = a4 + 3; + int *p4 = a4 + 4; + int *q = i < -1 ? p1 : i < 0 ? p2 : 1 < i ? p4 : 0 < i ? p3 : p0; + A (q, -5); // { dg-warning "-Warray-bounds" } + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" } +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-92.c b/gcc/testsuite/gcc.dg/Warray-bounds-92.c new file mode 100644 index 00000000000..8c8f5f7f459 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-92.c @@ -0,0 +1,149 @@ +/* PR middle-end/103215 - bogus -Warray-bounds with two pointers with + different offsets each + Test for accesses into distinct arrays through pointers with different + offsets each. + + If/when -Warray-bounds is enhanced to issue "maybe" kinds of warnings + some of the accesses here will trigger those and will need updating. + + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +#define NOIPA __attribute__ ((noipa)) + +#define A(p, off) ((p)[off] = __COUNTER__) + +extern int a4[4], a8[8]; + + +NOIPA void a4_p1_a8_p3 (int i) +{ + int *a4_p1 = a4 + 1; + int *a8_p3 = a8 + 3; + int *q = i ? a4_p1 : a8_p3; + A (q, -4); // { dg-warning "-Warray-bounds" } + /* Because -3 is a valid offset into a8 but not a4, q must point + to the former and so subscripts between -3 and +4 refer to its + elements. */ + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + A (q, 1); A (q, 2); A (q, 3); A (q, 4); + A (q, 5); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + /* Both of the following are definitely out of bounds but the first isn't + diagnosed because the code conservatively merges the offsets into A4 + and A8. */ + A (q, 7); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void a4_p1_a8_p5 (int i) +{ + int *a4_p1 = a4 + 1; + int *a8_p5 = a8 + 5; + int *q = i ? a4_p1 : a8_p5; + A (q, -6); // { dg-warning "-Warray-bounds" } + /* Similarly to the above, because -5 is a valid offset into a8 but + not a4, q must point to the former and so subscripts between -5 + and +2 refer to its elements. */ + A (q, -5); A (q, -4); A (q, -3); A (q, -2); + A (q, -1); A (q, 0); A (q, 1); A (q, 2); + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void a4_p1_a8_p7 (int i) +{ + int *a4_p1 = a4 + 1; + int *a8_p7 = a8 + 7; + int *q = i ? a4_p1 : a8_p7; + A (q, -8); // { dg-warning "-Warray-bounds" } + A (q, -7); A (q, -6); A (q, -5); A (q, -4); + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + /* Since -7 is valid, q must point to a8 and the last valid subscript + must be 0. */ + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void mp_1_a4_p1_a8_p7 (int i, int j) +{ + int *a4_p1 = a4 + 1; + int *a8_p7 = a8 + 7; + int *p = i ? a4_p1 : a8_p7; + int *q = j ? p + 1 : p - 1; + + A (q, -9); // { dg-warning "-Warray-bounds" } + + /* q points either to a8 + [6, 8] or a4 + [0, 2]. */ + A (q, -8); A (q, -7); A (q, -6); A (q, -5); + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + + /* Since all the above are valid, q must point to a8 + 8. But as + mentioned above, the warning for each subscript is independent + of prior subscripts into the same object so the access below + aren't diagnosed. */ + A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 8); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void mp1_a4_p1_a8_p5 (int i, int j) +{ + int *a4_p1 = a4 + 1; + int *a8_p5 = a8 + 5; + int *p = i ? a4_p1 : a8_p5; + + int *q = j ? p + 1 : p - 1; + + // q is assumed to point to a8 + 6 + A (q, -7); // { dg-warning "-Warray-bounds" } + A (q, -6); A (q, -5); A (q, -4); A (q, -3); + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + /* Even though the above accesses rule it out, q is now assumed + to point to either a4 + [0, 2] or a8 + [4, 5]. */ + A (q, 2); + /* q is now assumed to point tp a4. Given that, only the first store + is valid. */ + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 5); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 6); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 8); // { dg-warning "-Warray-bounds" } +} + + +NOIPA void mp1_a4_p1_a8_p4 (int i, int j) +{ + int *a4_p1 = a4 + 1; + int *a8_p4 = a8 + 4; + int *p = i ? a4_p1 : a8_p4; + + int *q = j ? p + 1 : p - 1; + + // q is assumed to point to a8 + 5 + A (q, -6); // { dg-warning "-Warray-bounds" } + A (q, -5); + A (q, -4); + A (q, -3); + A (q, -2); + A (q, -1); + A (q, 0); + A (q, 1); + A (q, 2); + /* Even though the above accesses rule it out, q is now assumed + to point tp a4. Given that, only the first store is valid. */ + A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 5); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 6); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } } + A (q, 8); // { dg-warning "-Warray-bounds" } +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c index b81186cfb94..e0a40788f0d 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c @@ -182,8 +182,8 @@ void memset_decl_2_off (void) int i2 = SR (2, INT_MAX); { - char a5[5]; // { dg-warning "at offset [1, 5] into destination object 'a5' - char a7[7]; // { dg-warning "at offset [2, 7] into destination object 'a7' + char a5[5]; // { dg-message "at offset \\\[1, 5] into destination object 'a5'" "note" } + char a7[7]; // { dg-message "at offset \\\[2, 7] into destination object 'a7'" "note" } char *p5_p1 = a5 + i1; char *p7_p2 = a7 + i2; char *p5_7 = cond1 ? p5_p1 : p7_p2; @@ -193,7 +193,11 @@ void memset_decl_2_off (void) memset (p5_7, 0, 3); memset (p5_7, 0, 4); memset (p5_7, 0, 5); - memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " } + /* The warning code conservatively "merges" both the sizes and the offsets + into A5 and A7 and so only the second store below is diagnosed but not + the first. See PR 103215. The logic needs to be tightened up. */ + memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " "pr??????" { xfail *-*-* } } + memset (p5_7, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6 " } } int i3 = SR (3, INT_MAX); @@ -208,7 +212,8 @@ void memset_decl_2_off (void) // { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 } // { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 } // { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 } - // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 } + // { dg-message "at offset \\\[1, 9] into destination object 'a9'" "note" { target *-*-* } .-4 } + // { dg-message ": destination object 'a9'" "pr??????" { xfail *-*-* } .-5 } char *p5_p2 = a5 + i2; // 3 bytes left char *p9_p3 = a9 + i3; // 6 bytes left char *p = @@ -220,7 +225,8 @@ void memset_decl_2_off (void) memset (q, 0, 3); memset (q, 0, 4); memset (q, 0, 5); - memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" } + memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" "pr??????" { xfail *-*-* } } + memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" } --q; // [3 - 6] bytes left memset (q, 0, 1); @@ -229,7 +235,8 @@ void memset_decl_2_off (void) memset (q, 0, 4); memset (q, 0, 5); memset (q, 0, 6); - memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" } + memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" "pr??????" { xfail *-*-* } } + memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" } --q; // [4 - 7] bytes left memset (q, 0, 1); @@ -239,7 +246,8 @@ void memset_decl_2_off (void) memset (q, 0, 5); memset (q, 0, 6); memset (q, 0, 7); - memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" } + memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" "pr??????" { xfail *-*-* } } + memset (q, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 8" } int m1_x = SR (-1, INT_MAX); int m2_x = SR (-2, INT_MAX); diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c index c45a92d21e1..b6265e37c86 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c @@ -200,7 +200,11 @@ void memset_malloc_2_off (void) memset (p5_7, 0, 3); memset (p5_7, 0, 4); memset (p5_7, 0, 5); - memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " } + /* The warning code conservatively "merges" both the sizes and the offsets + into A5 and A7 and so only the second store below is diagnosed but not + the first. See PR 103215. The logic needs to be tightened up. */ + memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " "pr??????" { xfail *-*-* } } + memset (p5_7, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6 " } } int i3 = SR (3, INT_MAX); @@ -215,7 +219,8 @@ void memset_malloc_2_off (void) // { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 } // { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 } // { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 } - // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 } + // { dg-message "at offset \\\[1, 9] into destination object 'a9'" "note" { target *-*-* } .-4 } + // { dg-message ": destination object 'a9'" "pr??????" { xfail *-*-* } .-5 } char *p5_p2 = a5 + i2; // 3 bytes left char *p9_p3 = a9 + i3; // 6 bytes left char *p = @@ -227,7 +232,8 @@ void memset_malloc_2_off (void) memset (q, 0, 3); memset (q, 0, 4); memset (q, 0, 5); - memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" } + memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" "pr??????" { xfail *-*-* } } + memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" } --q; // [3 - 6] bytes left memset (q, 0, 1); @@ -236,7 +242,8 @@ void memset_malloc_2_off (void) memset (q, 0, 4); memset (q, 0, 5); memset (q, 0, 6); - memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" } + memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" "pr??????" { xfail *-*-* } } + memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" } --q; // [4 - 7] bytes left memset (q, 0, 1); @@ -246,7 +253,8 @@ void memset_malloc_2_off (void) memset (q, 0, 5); memset (q, 0, 6); memset (q, 0, 7); - memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" } + memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" "pr??????" { xfail *-*-* } } + memset (q, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 8" } int m1_x = SR (-1, INT_MAX); int m2_x = SR (-2, INT_MAX); diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-83.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-83.c new file mode 100644 index 00000000000..bc121928f1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-83.c @@ -0,0 +1,147 @@ +/* PR middle-end/103215 - bogus -Warray-bounds with two pointers with + different offsets each + Test for accesses by a user-defined function into the same array + through pointers with different offsets each. See Warray-bounds-91.c + for the corresponding test exercising -Warray-bounds for direct accesses. + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +#define NOIPA __attribute__ ((noipa)) + +void sink (int[1]); +#define A(p, off) sink (p + off) + +extern int a4[4]; + + +NOIPA void p0_p1 (int i) +{ + int *p0 = a4 + 0; + int *p1 = a4 + 1; + int *q = i ? p0 : p1; + A (q, -2); // { dg-warning "-Wstringop-overflow" } + A (q, -1); A (q, 0); A (q, 1); A (q, 2); + /* Since q points to a4 and -1 is a valid subscript, +3 must be invalid. + But the warning for each subscript is independent of prior subscripts + into the same object. That should be improved. */ + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" } +} + +NOIPA void p1_p0 (int i) +{ + int *p1 = a4 + 1; + int *p0 = a4 + 0; + int *q = i ? p0 : p1; + A (q, -2); // { dg-warning "-Wstringop-overflow" } + A (q, -1); A (q, 0); A (q, 1); A (q, 2); + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void p1_p2 (int i) +{ + int *p1 = a4 + 1; + int *p2 = a4 + 2; + int *q = i ? p1 : p2; + A (q, -3); // { dg-warning "-Wstringop-overflow" } + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" } +} + +NOIPA void p2_p1 (int i) +{ + int *p2 = a4 + 2; + int *p1 = a4 + 1; + int *q = i ? p1 : p2; + A (q, -3); // { dg-warning "-Wstringop-overflow" } + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void p1_p3 (int i) +{ + int *p1 = a4 + 1; + int *p3 = a4 + 3; + int *q = i ? p1 : p3; + A (q, -4); // { dg-warning "-Wstringop-overflow" } + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" } +} + +NOIPA void p3_p1 (int i) +{ + int *p3 = a4 + 3; + int *p1 = a4 + 1; + int *q = i ? p1 : p3; + A (q, -4); // { dg-warning "-Wstringop-overflow" } + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void p1_p4 (int i) +{ + int *p1 = a4 + 1; + int *p4 = a4 + 4; + int *q = i ? p1 : p4; + A (q, -5); // { dg-warning "-Wstringop-overflow" } + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" } +} + +NOIPA void p4_p1 (int i) +{ + int *p4 = a4 + 4; + int *p1 = a4 + 1; + int *q = i ? p1 : p4; + A (q, -5); // { dg-warning "-Wstringop-overflow" } + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void p0_p1_p2 (int i) +{ + int *p0 = a4 + 0; + int *p1 = a4 + 1; + int *p2 = a4 + 2; + int *q = i < 0 ? p1 : 0 < i ? p2 : p0; + A (q, -3); // { dg-warning "-Wstringop-overflow" } + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void p0_p1_p2_p3_p4 (int i) +{ + int *p0 = a4 + 0; + int *p1 = a4 + 1; + int *p2 = a4 + 2; + int *p3 = a4 + 3; + int *p4 = a4 + 4; + int *q = i < -1 ? p1 : i < 0 ? p2 : 1 < i ? p4 : 0 < i ? p3 : p0; + A (q, -5); // { dg-warning "-Wstringop-overflow" } + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" } +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-85.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-85.c new file mode 100644 index 00000000000..ac61e0a0a64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-85.c @@ -0,0 +1,153 @@ +/* PR middle-end/103215 - bogus -Wstringop-overflow with two pointers with + different offsets each + Test for accesses into distinct arrays through pointers with different + offsets each. + + If/when -Wstringop-overflow is enhanced to issue "maybe" kinds of + warnings some of the accesses here will trigger those and will need + updating. + + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +#define NOIPA __attribute__ ((noipa)) + +void sink (int[1]); +#define A(p, off) sink (p + off) + +extern int a4[4], a8[8]; + + + + +NOIPA void a4_p1_a8_p3 (int i) +{ + int *a4_p1 = a4 + 1; + int *a8_p3 = a8 + 3; + int *q = i ? a4_p1 : a8_p3; + A (q, -4); // { dg-warning "-Wstringop-overflow" } + /* Because -3 is a valid offset into a8 but not a4, q must point + to the former and so subscripts between -3 and +4 refer to its + elements. */ + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + A (q, 1); A (q, 2); A (q, 3); A (q, 4); + A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + /* Both of the following are definitely out of bounds but the first isn't + diagnosed because the code conservatively merges the offsets into A4 + and A8. */ + A (q, 7); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void a4_p1_a8_p5 (int i) +{ + int *a4_p1 = a4 + 1; + int *a8_p5 = a8 + 5; + int *q = i ? a4_p1 : a8_p5; + A (q, -6); // { dg-warning "-Wstringop-overflow" } + /* Similarly to the above, because -5 is a valid offset into a8 but + not a4, q must point to the former and so subscripts between -5 + and +2 refer to its elements. */ + A (q, -5); A (q, -4); A (q, -3); A (q, -2); + A (q, -1); A (q, 0); A (q, 1); A (q, 2); + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void a4_p1_a8_p7 (int i) +{ + int *a4_p1 = a4 + 1; + int *a8_p7 = a8 + 7; + int *q = i ? a4_p1 : a8_p7; + A (q, -8); // { dg-warning "-Wstringop-overflow" } + A (q, -7); A (q, -6); A (q, -5); A (q, -4); + A (q, -3); A (q, -2); A (q, -1); A (q, 0); + /* Since -7 is valid, q must point to a8 and the last valid subscript + must be 0. */ + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void mp_1_a4_p1_a8_p7 (int i, int j) +{ + int *a4_p1 = a4 + 1; + int *a8_p7 = a8 + 7; + int *p = i ? a4_p1 : a8_p7; + int *q = j ? p + 1 : p - 1; + + A (q, -9); // { dg-warning "-Wstringop-overflow" } + + /* q points either to a8 + [6, 8] or a4 + [0, 2]. */ + A (q, -8); A (q, -7); A (q, -6); A (q, -5); + A (q, -4); A (q, -3); A (q, -2); A (q, -1); + + /* Since all the above are valid, q must point to a8 + 8. But as + mentioned above, the warning for each subscript is independent + of prior subscripts into the same object so the access below + aren't diagnosed. */ + A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 8); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void mp1_a4_p1_a8_p5 (int i, int j) +{ + int *a4_p1 = a4 + 1; + int *a8_p5 = a8 + 5; + int *p = i ? a4_p1 : a8_p5; + + int *q = j ? p + 1 : p - 1; + + // q is assumed to point to a8 + 6 + A (q, -7); // { dg-warning "-Wstringop-overflow" } + A (q, -6); A (q, -5); A (q, -4); A (q, -3); + A (q, -2); A (q, -1); A (q, 0); A (q, 1); + /* Even though the above accesses rule it out, q is now assumed + to point to either a4 + [0, 2] or a8 + [4, 5]. */ + A (q, 2); + /* q is now assumed to point tp a4. Given that, only the first store + is valid. */ + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 6); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 8); // { dg-warning "-Wstringop-overflow" } +} + + +NOIPA void mp1_a4_p1_a8_p4 (int i, int j) +{ + int *a4_p1 = a4 + 1; + int *a8_p4 = a8 + 4; + int *p = i ? a4_p1 : a8_p4; + + int *q = j ? p + 1 : p - 1; + + // q is assumed to point to a8 + 5 + A (q, -6); // { dg-warning "-Wstringop-overflow" } + A (q, -5); + A (q, -4); + A (q, -3); + A (q, -2); + A (q, -1); + A (q, 0); + A (q, 1); + A (q, 2); + /* Even though the above accesses rule it out, q is now assumed + to point tp a4. Given that, only the first store is valid. */ + A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 6); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 7); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } } + A (q, 8); // { dg-warning "-Wstringop-overflow" } +} diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c index 846e9300750..4ce70d036b7 100644 --- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c +++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c @@ -143,17 +143,18 @@ T (v0 ? b[1] : "", bsz); T (v0 ? b[2] : "", bsz); T (v0 ? b[3] : "", bsz); -/* The warnings below are strictly correct but the strnlen calls are safe - because the reads are bounded by the length of the constant arguments. - It might make sense to relax the warning to avoid triggering for them. */ +/* Warning for the calls below would be strictly correct even though + the strnlen calls are safe because the reads are bounded by + the length of the constant arguments. Most of the calls are + not diagnosed anymore as a result of the fix for PR 103215. */ T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? "" : b[1], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? "" : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? "" : b[1], bsz + 1); +T (v0 ? "" : b[2], bsz + 1); +T (v0 ? "" : b[3], bsz + 1); T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[1] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[2] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[1] : "", bsz + 1); +T (v0 ? b[2] : "", bsz + 1); +T (v0 ? b[3] : "", bsz + 1); T (v0 ? "" : b[i0], bsz); T (v0 ? "" : b[i1], bsz); @@ -167,11 +168,11 @@ T (v0 ? b[i3] : "", bsz); T (v0 ? "" : b[i0], bsz + 1); T (v0 ? "" : b[i1], bsz + 1); T (v0 ? "" : b[i2], bsz + 1); -T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */ +T (v0 ? "" : b[i3], bsz + 1); T (v0 ? b[i0] : "", bsz + 1); T (v0 ? b[i1] : "", bsz + 1); T (v0 ? b[i2] : "", bsz + 1); -T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */ +T (v0 ? b[i3] : "", bsz + 1); T (v0 ? "1234" : b[3], bsz); T (v0 ? "1234" : b[i3], bsz); @@ -183,14 +184,16 @@ T (v0 ? b[0] : b[2], bsz); T (v0 ? b[2] : b[3], bsz); T (v0 ? b[3] : b[2], bsz); -T (v0 ? "1234" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? "1234" : b[3], bsz + 1); +T (v0 ? "1234" : b[i3], bsz + 1); +T (v0 ? b[3] : "1234", bsz + 1); +T (v0 ? b[i3] : "1234", bsz + 1); -T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +/* That the following are not diagnosed is a bug/limitation resulting from + the fix for PR 103215. */ +T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr??????" { xfail *-*-* } } */ +T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr??????" { xfail *-*-* } } */ +T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr??????" { xfail *-*-* } } */ T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ struct A { char a[5], b[5]; };