[clang] [Sema] Allow zero-size allocations for -Walloc-size (PR #155793)
Vladimir Vuksanovic via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 28 01:59:14 PDT 2025
https://github.com/vvuksanovic created https://github.com/llvm/llvm-project/pull/155793
Allocations of size zero are usually done intentionally and then reallocated before use.
>From cbfe5c017190ea3f7cbcc458845656ba4eef8d54 Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic <vladimir.vuksanovic at htecgroup.com>
Date: Thu, 28 Aug 2025 10:36:21 +0200
Subject: [PATCH] [Sema] Allow zero-size allocations for -Walloc-size
Allocations of size zero are usually done intentionally and then
reallocated before use.
---
clang/lib/Sema/SemaExpr.cpp | 4 +++-
.../Malloc+MismatchedDeallocator+NewDelete.cpp | 4 ++--
.../Malloc+MismatchedDeallocator_intersections.cpp | 2 +-
.../Analysis/MismatchedDeallocator-checker-test.mm | 4 ++--
clang/test/Analysis/NewDelete-checker-test.cpp | 6 ------
clang/test/Analysis/NewDelete-intersections.mm | 3 ---
clang/test/Analysis/unix-fns.c | 4 ++--
clang/test/Sema/warn-alloc-size.c | 11 ++++-------
8 files changed, 14 insertions(+), 24 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d383544e54329..c65ca09ee12bb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7841,7 +7841,9 @@ static void CheckSufficientAllocSize(Sema &S, QualType DestType,
return;
std::optional<llvm::APInt> AllocSize =
CE->evaluateBytesReturnedByAllocSizeCall(S.Context);
- if (!AllocSize)
+ // Allocations of size zero are permitted as a special case. They are usually
+ // done intentionally.
+ if (!AllocSize || AllocSize->isZero())
return;
auto Size = CharUnits::fromQuantity(AllocSize->getZExtValue());
diff --git a/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
index fc324c311f82d..b9eb85d6b69fa 100644
--- a/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
+++ b/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1 -Wno-alloc-size -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
-// RUN: %clang_analyze_cc1 -Wno-alloc-size -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
#include "Inputs/system-header-simulator-for-malloc.h"
diff --git a/clang/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp b/clang/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
index 98873409a4fa2..b0cef2591486d 100644
--- a/clang/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
+++ b/clang/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -Wno-alloc-size -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -std=c++11 -verify %s
// expected-no-diagnostics
typedef __typeof(sizeof(int)) size_t;
diff --git a/clang/test/Analysis/MismatchedDeallocator-checker-test.mm b/clang/test/Analysis/MismatchedDeallocator-checker-test.mm
index 21cbe86c9726f..ef8b24ba8de32 100644
--- a/clang/test/Analysis/MismatchedDeallocator-checker-test.mm
+++ b/clang/test/Analysis/MismatchedDeallocator-checker-test.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1 -Wno-alloc-size -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
-// RUN: %clang_analyze_cc1 -Wno-alloc-size -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
#include "Inputs/system-header-simulator-objc.h"
#include "Inputs/system-header-simulator-cxx.h"
diff --git a/clang/test/Analysis/NewDelete-checker-test.cpp b/clang/test/Analysis/NewDelete-checker-test.cpp
index 5ab6e16edf0df..c417b9c2ac97e 100644
--- a/clang/test/Analysis/NewDelete-checker-test.cpp
+++ b/clang/test/Analysis/NewDelete-checker-test.cpp
@@ -1,37 +1,31 @@
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=expected,newdelete \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete
//
// RUN: %clang_analyze_cc1 -DLEAKS -std=c++11 -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=expected,newdelete,leak \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
//
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -verify %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=expected,leak \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
//
// RUN: %clang_analyze_cc1 -std=c++17 -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=expected,newdelete \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete
//
// RUN: %clang_analyze_cc1 -DLEAKS -std=c++17 -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=expected,newdelete,leak \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
//
// RUN: %clang_analyze_cc1 -std=c++17 -fblocks -verify %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=expected,leak,inspection \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \
diff --git a/clang/test/Analysis/NewDelete-intersections.mm b/clang/test/Analysis/NewDelete-intersections.mm
index dec9c2922cfea..eddfb3294073e 100644
--- a/clang/test/Analysis/NewDelete-intersections.mm
+++ b/clang/test/Analysis/NewDelete-intersections.mm
@@ -1,5 +1,4 @@
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=newdelete \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete
@@ -7,13 +6,11 @@
// leak-no-diagnostics
// RUN: %clang_analyze_cc1 -std=c++11 -DLEAKS -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=leak \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
// RUN: %clang_analyze_cc1 -std=c++11 -DLEAKS -fblocks %s \
-// RUN: -Wno-alloc-size \
// RUN: -verify=mismatch \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=unix.MismatchedDeallocator
diff --git a/clang/test/Analysis/unix-fns.c b/clang/test/Analysis/unix-fns.c
index 2a971be2e6023..77894285bcb69 100644
--- a/clang/test/Analysis/unix-fns.c
+++ b/clang/test/Analysis/unix-fns.c
@@ -1,6 +1,6 @@
-// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -Wno-alloc-size -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-output=plist -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-output=plist -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
// RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/unix-fns.c.plist -
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -Wno-alloc-size -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-output=plist -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-output=plist -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
// RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/unix-fns.c.plist -
// RUN: mkdir -p %t.dir
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API,optin.portability -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
diff --git a/clang/test/Sema/warn-alloc-size.c b/clang/test/Sema/warn-alloc-size.c
index 445b0ba677337..3d403610c46f9 100644
--- a/clang/test/Sema/warn-alloc-size.c
+++ b/clang/test/Sema/warn-alloc-size.c
@@ -1,10 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -Walloc-size %s
struct Foo { int x[10]; };
-struct ZeroSize {
- int flexible_array[];
-};
-
typedef __typeof__(sizeof(int)) size_t;
void *my_malloc(size_t) __attribute__((alloc_size(1)));
void *my_calloc(size_t, size_t) __attribute__((alloc_size(2, 1)));
@@ -42,8 +38,9 @@ void alloc_foo(void) {
// expected-warning at -1 {{allocation of insufficient size '1' for type 'int' with size '4'}}
(void)(int *)my_malloc(1); // expected-warning {{allocation of insufficient size '1' for type 'int' with size '4'}}
- struct ZeroSize *ptr18 = my_malloc(0); // okay because sizeof(struct ZeroSize) = 0
+ void *funcptr_1 = (void (*)(int))my_malloc(1);
- void *funcptr_1 = (void (*)(int))my_malloc(0); // expected-warning {{allocation of insufficient size '0' for type 'void (int)' with size '1'}}
- void *funcptr_2 = (void (*)(int))my_malloc(1);
+ // Zero size allocations are assumed to be intentional.
+ int *zero_alloc1 = my_malloc(0);
+ int *zero_alloc2 = (int *)my_malloc(0);
}
More information about the cfe-commits
mailing list