From patchwork Fri Jul 21 11:21:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Uecker X-Patchwork-Id: 1810862 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Rxxmwvyl; dkim-atps=neutral Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R6nGD4l1nz1yYc for ; Fri, 21 Jul 2023 21:22:27 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 35335385483D for ; Fri, 21 Jul 2023 11:22:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 35335385483D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1689938545; bh=aQ6ZaMnHPJ1Bi9otazOS6rbDx+vdt/sROqDLA8JT8+Y=; h=Subject:To:Cc:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=RxxmwvylB1QXOOBwrPX0tihiWAZ8YZ6WzJ2PgJhSf+wk2i2N/bAItHxrSzp+5z1ct tElUG134OiM77oN0Xiy7D74guut3lBaU48DGX0U2CfqYIjm8JqUL9aa1VaUgDoJnzp 9MuWDSPcxrFj62Js0wwdLLtWe3bAv42dnboLtPFM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailrelay.tugraz.at (mailrelay.tugraz.at [129.27.2.202]) by sourceware.org (Postfix) with ESMTPS id 959713858D35 for ; Fri, 21 Jul 2023 11:22:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 959713858D35 Received: from vra-173-226.tugraz.at (vra-173-226.tugraz.at [129.27.173.226]) by mailrelay.tugraz.at (Postfix) with ESMTPSA id 4R6nFf1vpRz1LMXv; Fri, 21 Jul 2023 13:21:58 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 mailrelay.tugraz.at 4R6nFf1vpRz1LMXv Message-ID: Subject: [C PATCH]: Add Walloc-type to warn about insufficient size in allocations To: gcc-patches@gcc.gnu.org Cc: Joseph Myers Date: Fri, 21 Jul 2023 13:21:57 +0200 User-Agent: Evolution 3.46.4-2 MIME-Version: 1.0 X-TUG-Backscatter-control: G/VXY7/6zeyuAY/PU2/0qw X-Spam-Scanner: SpamAssassin 3.003001 X-Spam-Score-relay: -1.9 X-Scanned-By: MIMEDefang 2.74 on 129.27.10.117 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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 Uecker via Gcc-patches From: Martin Uecker Reply-To: Martin Uecker Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch adds a warning for allocations with insufficient size based on the "alloc_size" attribute and the type of the pointer  the result is assigned to. While it is theoretically legal to assign to the wrong pointer type and cast it to the right type later, this almost always indicates an error. Since this catches common mistakes and is simple to diagnose, it is suggested to add this warning. Bootstrapped and regression tested on x86. Martin Add option Walloc-type that warns about allocations that have insufficient storage for the target type of the pointer the storage is assigned to. gcc: * doc/invoke.texi: Document -Wstrict-flex-arrays option. gcc/c-family: * c.opt (Walloc-type): New option. gcc/c: * c-typeck.cc (convert_for_assignment): Add Walloc-type warning. gcc/testsuite: * gcc.dg/Walloc-type-1.c: New test. insufficient size" } */ +} + + diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 4abdc8d0e77..8b9d148582b 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -319,6 +319,10 @@ Walloca C ObjC C++ ObjC++ Var(warn_alloca) Warning Warn on any use of alloca. +Walloc-type +C ObjC Var(warn_alloc_type) Warning +Warn when allocating insufficient storage for the target type of the assigned pointer. + Walloc-size-larger-than= C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Joined Host_Wide_Int ByteSize Warning Init(HOST_WIDE_INT_MAX) -Walloc-size-larger-than= Warn for calls to allocation functions that diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 7cf411155c6..2e392f9c952 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -7343,6 +7343,32 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, "request for implicit conversion " "from %qT to %qT not permitted in C++", rhstype, type); + /* Warn of new allocations are not big enough for the target type. */ + tree fndecl; + if (warn_alloc_type + && TREE_CODE (rhs) == CALL_EXPR + && (fndecl = get_callee_fndecl (rhs)) != NULL_TREE + && DECL_IS_MALLOC (fndecl)) + { + tree fntype = TREE_TYPE (fndecl); + tree fntypeattrs = TYPE_ATTRIBUTES (fntype); + tree alloc_size = lookup_attribute ("alloc_size", fntypeattrs); + if (alloc_size) + { + tree args = TREE_VALUE (alloc_size); + int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1; + /* For calloc only use the second argument. */ + if (TREE_CHAIN (args)) + idx = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1; + tree arg = CALL_EXPR_ARG (rhs, idx); + if (TREE_CODE (arg) == INTEGER_CST + && tree_int_cst_lt (arg, TYPE_SIZE_UNIT (ttl))) + warning_at (location, OPT_Walloc_type, "allocation of " + "insufficient size %qE for type %qT with " + "size %qE", arg, ttl, TYPE_SIZE_UNIT (ttl)); + } + } + /* See if the pointers point to incompatible address spaces. */ asl = TYPE_ADDR_SPACE (ttl); asr = TYPE_ADDR_SPACE (ttr); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 88e3c625030..6869bed64c3 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8076,6 +8076,15 @@ always leads to a call to another @code{cold} function such as wrappers of C++ @code{throw} or fatal error reporting functions leading to @code{abort}. @end table +@opindex Wno-alloc-type +@opindex Walloc-type +@item -Walloc-type +Warn about calls to allocation functions decorated with attribute +@code{alloc_size} that specify insufficient size for the target type of +the pointer the result is assigned to, including those to the built-in +forms of the functions @code{aligned_alloc}, @code{alloca}, @code{calloc}, +@code{malloc}, and @code{realloc}. + @opindex Wno-alloc-zero @opindex Walloc-zero @item -Walloc-zero diff --git a/gcc/testsuite/gcc.dg/Walloc-type-1.c b/gcc/testsuite/gcc.dg/Walloc-type-1.c new file mode 100644 index 00000000000..bc62e5e9aa3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Walloc-type-1.c @@ -0,0 +1,37 @@ +/* Tests the warnings for insufficient allocation size. + { dg-do compile } + * { dg-options "-Walloc-type" } + * */ +#include +#include + +struct b { int x[10]; }; + +void fo0(void) +{ + struct b *p = malloc(sizeof *p); +} + +void fo1(void) +{ + struct b *p = malloc(sizeof p); /* { dg- warning "allocation of insufficient size" } */ +} + +void fo2(void) +{ + struct b *p = alloca(sizeof p); /* { dg- warning "allocation of insufficient size" } */ +} + +void fo3(void) +{ + struct b *p = calloc(1, sizeof p); /* { dg-warning "allocation of insufficient size" } */ +} + +void g(struct b* p); + +void fo4(void) +{ + g(malloc(4)); /* { dg-warning "allocation of