[clang] Add more tests for _Countof (PR #133333)

Alejandro Colomar via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 27 15:53:30 PDT 2025


https://github.com/alejandro-colomar created https://github.com/llvm/llvm-project/pull/133333

Cc: @AaronBallman 

I haven't yet tried to run these tests.  I've pasted and adapted them from the ones I wrote for my own implementation.

>From c9ce60fef4e3af6faaea2a7e7f41b3866856d237 Mon Sep 17 00:00:00 2001
From: Alejandro Colomar <alx at kernel.org>
Date: Thu, 27 Mar 2025 23:51:18 +0100
Subject: [PATCH] Add more tests for _Countof

Signed-off-by: Alejandro Colomar <alx at kernel.org>
---
 clang/test/C/C2y/n3369.c | 45 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/clang/test/C/C2y/n3369.c b/clang/test/C/C2y/n3369.c
index 389828b52b6a2..5f7792962ad21 100644
--- a/clang/test/C/C2y/n3369.c
+++ b/clang/test/C/C2y/n3369.c
@@ -18,6 +18,8 @@
 #endif
 
 int global_array[12];
+int global_multi_array[12][34];
+int global_num;
 
 void test_parsing_failures() {
   (void)_Countof;     // expected-error {{expected expression}}
@@ -36,6 +38,12 @@ void test_semantic_failures() {
                                 expected-note {{forward declaration of 'struct S'}}
   struct T { int x; };
   (void)_Countof(struct T);  // expected-error {{'_Countof' requires an argument of array type; 'struct T' invalid}}
+  struct U { int x[3]; };
+  (void)_Countof(struct U);  // expected-error {{'_Countof' requires an argument of array type; 'struct U' invalid}}
+  int a[3];
+  (void)_Countof(&a);  // expected-error {{'_Countof' requires an argument of array type; 'int (*)[3]' invalid}}
+  int *p;
+  (void)_Countof(p);  // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}
 }
 
 void test_constant_expression_behavior(int n) {
@@ -81,6 +89,22 @@ void test_with_function_param(int array[12], int (*array_ptr)[12], int static_ar
   (void)_Countof(static_array); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}
 }
 
+void test_func_fix_fix(int i, char (*a)[3][5], int (*x)[_Countof(*a)]);
+void test_func_fix_var(int i, char (*a)[3][i], int (*x)[_Countof(*a)]);
+void test_func_fix_uns(int i, char (*a)[3][*], int (*x)[_Countof(*a)]);
+
+void test_funcs() {
+  int i3[3];
+  int i5[5];
+  char c35[3][5];
+  test_func_fix_fix(5, &c35, &i3);
+  test_func_fix_fix(5, &c35, &i5); // expected-error {{incompatible-pointer-types}}
+  test_func_fix_var(5, &c35, &i3);
+  test_func_fix_var(5, &c35, &i5); // expected-error {{incompatible-pointer-types}}
+  test_func_fix_uns(5, &c35, &i3);
+  test_func_fix_uns(5, &c35, &i5); // expected-error {{incompatible-pointer-types}}
+}
+
 void test_multidimensional_arrays() {
   int array[12][7];
   static_assert(_Countof(array) == 12);
@@ -102,6 +126,11 @@ void test_unspecified_array_length() {
   static_assert(_Countof(**x) == 3);
 }
 
+void test_completed_array() {
+  int a[] = {1, 2, errno};
+  static_assert(_Countof(a) == 3);
+}
+
 // Test that the return type of _Countof is what you'd expect (size_t).
 void test_return_type() {
   static_assert(_Generic(typeof(_Countof global_array), typeof(sizeof(0)) : 1, default : 0));
@@ -121,10 +150,14 @@ void test_typedefs() {
   static_assert(_Countof(*x) == 12);
 }
 
-void test_zero_size_arrays() {
+void test_zero_size_arrays(int n) {
   int array[0]; // expected-warning {{zero size arrays are an extension}}
   static_assert(_Countof(array) == 0);
   static_assert(_Countof(int[0]) == 0); // expected-warning {{zero size arrays are an extension}}
+  int multi_array[0][n]; // expected-warning {{zero size arrays are an extension}}
+  static_assert(_Countof(multi_array) == 0);
+  int another_one[0][3]; // expected-warning {{zero size arrays are an extension}}
+  static_assert(_Countof(another_one) == 0);
 }
 
 void test_struct_members() {
@@ -144,3 +177,13 @@ void test_compound_literals() {
   static_assert(_Countof((int[2]){}) == 2);
   static_assert(_Countof((int[]){1, 2, 3, 4}) == 4);	
 }
+
+static int test_f1();
+static int test_f2();  // expected-warning {{never defined}}
+
+void test_symbols() {
+  int a[global_num][global_num];
+
+  static_assert(_Countof(global_multi_array[test_f1()]) == 34);
+  (void)_Countof(a[test_f2()]);
+}



More information about the cfe-commits mailing list