[clang] [clang][Sema] Don't report pointer subtraction on a VLA as zero size (PR #217465)

via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 22 04:43:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Aditya Medhane (flash1729)

<details>
<summary>Changes</summary>

CheckSubtractionOperands warns when the pointee type has zero size, because the subtraction divides by that size. A variably modified type such as int[n] has no statically known size, and getTypeInfoImpl models it as zero, so the check reported it as an empty type even though its size is only determined at run time.

Exclude variably modified pointee types. Genuinely empty types keep warning: int[0] and zero-sized structs are constant arrays and records, not variably modified.

Fixes #<!-- -->28328

---
Full diff: https://github.com/llvm/llvm-project/pull/217465.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+5) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+4-1) 
- (modified) clang/test/Analysis/pointer-sub.c (+2-4) 
- (modified) clang/test/Sema/empty1.c (+7) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3c6694f510952..8a5ed09e173ba 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -416,6 +416,11 @@ features cannot lower the translation-unit ABI level;
 - `-Wc++98-compat` now diagnoses explicit conversion functions in C++20 and
   later, matching the behavior in C++11 through C++17. (#GH161689)
 
+- `-Wpointer-arith` no longer reports subtraction of pointers to a variably
+  modified type, such as `int[n]`, as a subtraction of pointers to a type of
+  zero size. The size of such a type is not known statically and is modelled as
+  zero, which is not the same as the type being empty. (#GH28328)
+
 ### Improvements to Clang's time-trace
 
 ### Improvements to Coverage Mapping
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index da76bbf3c35f0..3977dc4932743 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11916,7 +11916,10 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
       // The pointee type may have zero size.  As an extension, a structure or
       // union may have zero size or an array may have zero length.  In this
       // case subtraction does not make sense.
-      if (!rpointee->isVoidType() && !rpointee->isFunctionType()) {
+      // A variably modified type has no statically known size; it is modelled
+      // as zero here, so exclude it rather than report it as empty.
+      if (!rpointee->isVoidType() && !rpointee->isFunctionType() &&
+          !rpointee->isVariablyModifiedType()) {
         CharUnits ElementSize = Context.getTypeSizeInChars(rpointee);
         if (ElementSize.isZero()) {
           Diag(Loc,diag::warn_sub_ptr_zero_size_types)
diff --git a/clang/test/Analysis/pointer-sub.c b/clang/test/Analysis/pointer-sub.c
index 25fb7f043d468..d2155e110ba54 100644
--- a/clang/test/Analysis/pointer-sub.c
+++ b/clang/test/Analysis/pointer-sub.c
@@ -65,11 +65,9 @@ void f4(void) {
   int (*p)[m] = a; // p == &a[0]
   p += 1; // p == &a[1]
 
-  // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328)
-  int d = p - a; // d == 1 // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}}
+  int d = p - a; // d == 1
 
-  // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328)
-  d = &(a[2]) - &(a[1]); // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}}
+  d = &(a[2]) - &(a[1]);
 
   d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}}
 }
diff --git a/clang/test/Sema/empty1.c b/clang/test/Sema/empty1.c
index 6c5fe76833f3f..0e18023b7d313 100644
--- a/clang/test/Sema/empty1.c
+++ b/clang/test/Sema/empty1.c
@@ -85,3 +85,10 @@ int func_9(struct emp_1 (*x)[], struct emp_1 (*y)[]) {
 int func_10(int (*x)[0], int (*y)[0]) {
   return x - y; // expected-warning {{subtraction of pointers to type 'int[0]' of zero size has undefined behavior}}
 }
+
+// A variably modified type is modelled as having zero size because its size is
+// not known statically. It is not an empty type, so it must not be diagnosed.
+int func_11(int n) {
+  int v[n];
+  return &v + 1 - &v;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/217465


More information about the cfe-commits mailing list