From patchwork Wed Jan 23 01:18:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1029610 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-494572-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="hBN6iBUb"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Sz6UtPdE"; 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 43knVX2qCpz9s3q for ; Wed, 23 Jan 2019 12:18:42 +1100 (AEDT) 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=dmuogg8YcPObTLaj0ZhPjmdmbIqUDPmolrUkGdAy7ZJJ7k/yl9 2i2iX61bnpasv7fR5Yktg4vB9Jshhwly3dBA4F7TKzvveBdhp5Fxi/6+NP+Ftz5g cySEnfzjQkkDdRdswtADjMROQW2LmCV7fwFKv+ZqaO9YGx9Pfpfi657wg= 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=bjQnFPGaFsBiuAuqKR4UL+0h3p8=; b=hBN6iBUbGt5odUKdhQVj EEJikLju+/+ZWqCHHX4D1Te+TOoTfeH2onR7nbwo06jRKbnvU6xbWqgTv++DE9f9 XXpHhjnwHPrZfByhYil3w+tvEWZrgYlQvmBBN0nsaRX/1SLhHfYyXS9KciyPpnNP 00mBXT+6X/1HaPBMUeDMs0w= Received: (qmail 9608 invoked by alias); 23 Jan 2019 01:18:34 -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 8841 invoked by uid 89); 23 Jan 2019 01:18:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-16.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1115 X-HELO: mail-qt1-f196.google.com Received: from mail-qt1-f196.google.com (HELO mail-qt1-f196.google.com) (209.85.160.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Jan 2019 01:18:32 +0000 Received: by mail-qt1-f196.google.com with SMTP id n32so577374qte.11 for ; Tue, 22 Jan 2019 17:18:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=4gHYAxAN7awKS1jjh3a+jSWIVZVXW00EELhx4jnqdBA=; b=Sz6UtPdEygGg2HkZw+bi1eRXHEMKBPAJsKBK5aEZMZ6tNmo35/bZDf2VRuJvXRAqc8 F5S9vA9KeVw8FrxyWkLtrH+7SE0ZoMaFuYRRIv2M1zIV0xGBUmyroKOR0z0zC3rJ36xc cMZW4GVZIYbHBDi4THsUYec58Vvhi9yqLT+85tnKOPkTcA4Tz3OXoxBjjvW5VcflMjZJ 5vltZvrYIkq8JdRp0oaGQiWmN6Yms4ku5cgzv4pmUX/0hhc7Rd2CqbApXw1uCZ5r2s7j gsOUYSm8H05JJTRe8lrvHsZjavJme71yPz/hoijkwms4a76DY8DtwDZ4pBCEAoskpep5 Istg== Received: from [192.168.0.106] (75-166-110-80.hlrn.qwest.net. [75.166.110.80]) by smtp.gmail.com with ESMTPSA id 64sm265060qkd.92.2019.01.22.17.18.29 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Jan 2019 17:18:29 -0800 (PST) To: "gcc-patches@gcc.gnu.org" From: Martin Sebor Subject: [PATCH] avoid assuming arrays have nonzero size (PR 88956) Message-ID: <8d56ad7d-88d9-b5b9-35da-4d7fadf2ec00@gmail.com> Date: Tue, 22 Jan 2019 18:18:28 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 X-IsSubscribed: yes The enhancement to treat char initializer-lists as STRING_CSTs committed earlier last year introduced an assumption that array elements have a non-zero size. As it turns out, the zero-length array extension that makes it possible to define even multi- dimensional zero-length array objects breaks that assumption when it's passed as an argument to a function like memcpy. The attached patch removes that assumption. Tested on x86_64-linux. Martin PS In GCC 10, unless there is an important use case that escapes me, I think GCC should warn for zero-length non-member array objects, or perhaps even for internal struct members (those followed by another member). Not to avoid these sorts of bugs but because they seem too dangerous to use safely. PR middle-end/88956 - ICE: Floating point exception on a memcpy from an zero-length constant array gcc/ChangeLog: PR c/88956 * gimple-fold.c (fold_array_ctor_reference): Avoid zero-length arrays. gcc/testsuite/ChangeLog: PR c/88956 * gcc.dg/Warray-bounds-39.c: New test. Index: gcc/gimple-fold.c =================================================================== --- gcc/gimple-fold.c (revision 268086) +++ gcc/gimple-fold.c (working copy) @@ -6715,12 +6715,14 @@ fold_array_ctor_reference (tree type, tree ctor, elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)))); /* When TYPE is non-null, verify that it specifies a constant-sized - accessed not larger than size of array element. */ - if (type - && (!TYPE_SIZE_UNIT (type) - || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST - || elt_size < wi::to_offset (TYPE_SIZE_UNIT (type)) - || elt_size == 0)) + accessed not larger than size of array element. Avoid using zero + ELT_SIZE, the result of an empty initializer for a zero-length + array. */ + if (elt_size == 0 + || (type + && (!TYPE_SIZE_UNIT (type) + || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST + || elt_size < wi::to_offset (TYPE_SIZE_UNIT (type))))) return NULL_TREE; /* Compute the array index we look for. */ Index: gcc/testsuite/gcc.dg/Warray-bounds-39.c =================================================================== --- gcc/testsuite/gcc.dg/Warray-bounds-39.c (nonexistent) +++ gcc/testsuite/gcc.dg/Warray-bounds-39.c (working copy) @@ -0,0 +1,115 @@ +/* PR middle-end/88956 - ICE: Floating point exception on a memcpy from + an zero-length constant array + Verify both that memory and string calls with a zero-length array + don't cause an ICE, and also that they emit warnings. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void* memcpy (void*, const void*, size_t); +extern void* memmove (void*, const void*, size_t); +extern char* strcpy (char*, const char*); +extern char* strncpy (char*, const char*, size_t); + +const char s0[0] = { }; +const char s0_0[0][0] = { }; +const char s0_1[0][1] = { }; +const char s1_0[1][0] = { }; + +char d[4]; + +void* test_memcpy_s0_1 (void *d) +{ + return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memcpy_s0_2 (void *d) +{ + return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memcpy_s0_0_1 (void *d) +{ + return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memcpy_s0_0_2 (void *d) +{ + return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ +} + + +void* test_memcpy_s0_1_1 (void *d) +{ + return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memcpy_s0_1_2 (void *d) +{ + return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds" } */ +} + + +void* test_memcpy_s1_0_1 (void *d) +{ + return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memcpy_s1_0_2 (void *d) +{ + return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ +} + + +void* test_memmove_s0_1 (void *d) +{ + return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memmove_s0_2 (void *d) +{ + return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memmove_s0_0_1 (void *d) +{ + return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ +} + +void* test_memmove_s0_0_2 (void *d) +{ + return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ +} + + +char* test_strcpy_s0 (char *d) +{ + return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ +} + +char* test_strcpy_s0_0 (char *d) +{ + return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ +} + + +char* test_strncpy_s0_1 (char *d) +{ + return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ +} + +char* test_strncpy_s0_2 (char *d) +{ + return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ +} + +char* test_strncpy_s0_0_1 (char *d) +{ + return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ +} + +char* test_strncpy_s0_0_2 (char *d) +{ + return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ +}