[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