================
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c2y -pedantic -Wall -Wno-comment -verify 
%s
+// RUN: %clang_cc1 -fsyntax-only -std=c2y -pedantic -Wall -Wno-comment 
-fexperimental-new-constant-interpreter -verify %s
+
+/* WG14 N3369: Clang 21
+ * _Lengthof operator
+ *
+ * Adds an operator to get the length of an array. Note that WG14 N3469 renamed
+ * this operator to _Countof.
+ */
+
+#if !__has_feature(c_countof)
+#error "Expected to have _Countof support"
+#endif
+
+#if !__has_extension(c_countof)
+// __has_extension returns true if __has_feature returns true.
+#error "Expected to have _Countof support"
+#endif
+
+int global_array[12];
+
+void test_parsing_failures() {
+  (void)_Countof;     // expected-error {{expected expression}}
+  (void)_Countof(;    // expected-error {{expected expression}}
+  (void)_Countof();   // expected-error {{expected expression}}
+  (void)_Countof int; // expected-error {{expected expression}}
+}
+
+void test_semantic_failures() {
+  (void)_Countof(1);         // expected-error {{'_Countof' requires an 
argument of array type; 'int' invalid}}
+  int non_array;
+  (void)_Countof non_array;  // expected-error {{'_Countof' requires an 
argument of array type; 'int' invalid}}  
+  (void)_Countof(int);       // expected-error {{'_Countof' requires an 
argument of array type; 'int' invalid}}  
+}
+
+void test_constant_expression_behavior(int n) {
+  static_assert(_Countof(global_array) == 12);
+  static_assert(_Countof global_array == 12);  
+  static_assert(_Countof(int[12]) == 12);
+
+  // Use of a VLA makes it not a constant expression, same as with sizeof.
+  int array[n];
+  static_assert(_Countof(array)); // expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(sizeof(array));   // expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(_Countof(int[n]));// expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(sizeof(int[n]));  // expected-error {{static assertion 
expression is not an integral constant expression}}
+  
+  // Constant folding works the same way as sizeof, too.
+  const int m = 12;
+  int other_array[m];
+  static_assert(sizeof(other_array));   // expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(_Countof(other_array)); // expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(sizeof(int[m]));        // expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(_Countof(int[m]));      // expected-error {{static assertion 
expression is not an integral constant expression}}
+  
+  // Note that this applies to each array dimension.
+  int another_array[n][7];
+  static_assert(_Countof(another_array)); // expected-error {{static assertion 
expression is not an integral constant expression}}
+  static_assert(_Countof(*another_array) == 7);
+
+  // Only the first dimension is needed for constant evaluation; other
+  // dimensions can be ignored.
+  int yet_another_array[7][n];
+  static_assert(_Countof(yet_another_array) == 7);
+  static_assert(_Countof(*yet_another_array)); // expected-error {{static 
assertion expression is not an integral constant expression}}
+  
+  int one_more_time[n][n][7];
+  static_assert(_Countof(one_more_time));  // expected-error {{static 
assertion expression is not an integral constant expression}}
+  static_assert(_Countof(*one_more_time)); // expected-error {{static 
assertion expression is not an integral constant expression}}
+  static_assert(_Countof(**one_more_time) == 7);
+}
+
+void test_with_function_param(int array[12], int (*array_ptr)[12], int 
static_array[static 12]) {
+  (void)_Countof(array); // expected-error {{'_Countof' requires an argument 
of array type; 'int *' invalid}}
+  static_assert(_Countof(*array_ptr) == 12);
+  (void)_Countof(static_array); // expected-error {{'_Countof' requires an 
argument of array type; 'int *' invalid}}
+}
+
+void test_multidimensional_arrays() {
+  int array[12][7];
+  static_assert(_Countof(array) == 12);
+  static_assert(_Countof(*array) == 7);
+
+  int mdarray[12][7][100][3];
+  static_assert(_Countof(mdarray) == 12);
+  static_assert(_Countof(*mdarray) == 7);
+  static_assert(_Countof(**mdarray) == 100);
+  static_assert(_Countof(***mdarray) == 3);
+}
+
+void test_unspecified_array_length() {
+  static_assert(_Countof(int[])); // expected-error {{invalid application of 
'_Countof' to an incomplete type 'int[]'}}
+
+  extern int x[][6][3];
+  static_assert(_Countof(x)); // expected-error {{invalid application of 
'_Countof' to an incomplete type 'int[][6][3]'}}
+  static_assert(_Countof(*x) == 6);
+  static_assert(_Countof(**x) == 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));
+}
+
+// Test that _Countof is able to look through typedefs.
+void test_typedefs() {
+  typedef int foo[12];
+  foo f;
+  static_assert(_Countof(foo) == 12);
+  static_assert(_Countof(f) == 12);
+
+  // Ensure multidimensional arrays also work.
+  foo x[100];
+  static_assert(_Generic(typeof(x), int[100][12] : 1, default : 0));
+  static_assert(_Countof(x) == 100);
+  static_assert(_Countof(*x) == 12);
+}
----------------
shafik wrote:
What about arrays that are members of a struct? e.g.:

```c
struct A {
  int arr[5];
};
```

Assuming that this won't work on a FAM?

Zero sized arrays?

https://github.com/llvm/llvm-project/pull/133125
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to