From patchwork Tue Aug 6 23:11:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Colomar X-Patchwork-Id: 1969722 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=G5Lyb5m9; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WdpxD07CGz1yfC for ; Wed, 7 Aug 2024 09:12:31 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3A3673858402 for ; Tue, 6 Aug 2024 23:12:30 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by sourceware.org (Postfix) with ESMTPS id 349233858C56 for ; Tue, 6 Aug 2024 23:12:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 349233858C56 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 349233858C56 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2604:1380:40e1:4800::1 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722985927; cv=none; b=sav7R1d7R7reDwRARdaqoW9evd/uP+sP+2aQ5XbNV6VDxfYrikE//UyVsvNxBVN2JYJPG7ChzXc6Up7ALo0s7mf7aHM7+dNhsxKuIWqB22LCXLwbFQPGi7IEUCXHl5qhHyW38Ucw8bUtirXZreu1+lGR48xGyIfDIWWvCCyERNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722985927; c=relaxed/simple; bh=DI0QGSoPn8BG3UXTZ2fyH7RrXFS+0OGKLulaPrw43DQ=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=s64kdoEbYj1c+wnWgcL/mHZwhypNCoEIh3zc4nSRF2ogpUlwWSuw5lRI4hj7G0a0Cr50LCBSq7jMDB5klKp2j2XGtFf0mbDc5nWnD5n+LneSrlYgqe2X11piFoPsTkXxRMocQdchxNOicpYKctXmkV3kRqPtswTdMR1c1D1l64o= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id D4EAFCE0FA0; Tue, 6 Aug 2024 23:12:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B7F78C32786; Tue, 6 Aug 2024 23:11:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722985920; bh=DI0QGSoPn8BG3UXTZ2fyH7RrXFS+0OGKLulaPrw43DQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=G5Lyb5m9ZO5J5qDmchOeIJmfmlKLOQRXcqjYa4I3O71Wpl/gVGf4+aZ7C/xrvyl94 XVd1dwR0B+1CIAI1mMNacB8rCXBPmUqojCDqrZ8fHcXsSk6+lFeey8tiPa2aFNi/2r ru58j54YTqBf8e3YeMkdRMZShCbZdHtxalJgyqNZSDgQR3nPZkVFUQ0fflR2tqgPGI qvbSNSS+L7NT4jxAU16OXX7DxJ9o6Q0W4kf6DJ2N+BHmyfbN4DR2U/1QBrQANTUvDy 3b+bJunEvD42wEdPNHqr+UzMSILGAB9tuiN77AVJOJB6CfNw3XRuugG0PVR3mo9Trg K/weZW5Tp2/OA== Date: Wed, 7 Aug 2024 01:11:56 +0200 From: Alejandro Colomar To: gcc-patches@gcc.gnu.org Cc: Alejandro Colomar , Martin Uecker , Xavier Del Campo Romero , Joseph Myers , Gabriel Ravier , Jakub Jelinek , Kees Cook , Qing Zhao , Jens Gustedt , David Brown , Florian Weimer , Andreas Schwab Subject: [PATCH v5 0/3] c: Add __lengthof__ operator Message-ID: <20240806231151.1046913-1-alx@kernel.org> X-Mailer: git-send-email 2.45.2 References: <20240728141547.302478-1-alx@kernel.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240728141547.302478-1-alx@kernel.org> X-Spam-Status: No, score=-3.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Hi! This is ready for review. v5: - Add changelog entries. - Wording fixes in commit messages. - s/sizeof/lengthof/ in comment. - CC += David, Florian, Andreas [Qing] - Docs: Remove some details about future directions. [Qing] - Docs: Add examples. [Qing] - Docs: Clarify when __lengthof__ evaluates as a constant expression and when it evaluates as a run-time value. [Joseph, Qing] - Tests: Use several -Wno-* flags to turn off unwanted warnings. [Martin, Joseph] - Tests: Merge into the same commit that adds the feature. - Tests: Fix style (whitespace). I won't paste the example program I used for development, since it's the same as in v4. Check that cover letter if necessary. When reviewing, mind that some parts of the code have been blindly pasted from sizeof, and might not make much sense; I didn't fully understand some parts. However, it seems to behave well, and more or less it makes sense. Just be careful about it. At the bottom of this message is the range-diff against v4. Have a lovely night! Alex BTW, I've tested that there are no regressions: alx@debian:~/src/gnu/gcc$ find len0 -type f len0/host-x86_64-pc-linux-gnu/gcc/testsuite/gcc/gcc.sum len0/host-x86_64-pc-linux-gnu/gcc/testsuite/gfortran/gfortran.sum len0/host-x86_64-pc-linux-gnu/gcc/testsuite/objc/objc.sum len0/host-x86_64-pc-linux-gnu/gcc/testsuite/g++/g++.sum len0/x86_64-pc-linux-gnu/libitm/testsuite/libitm.sum len0/x86_64-pc-linux-gnu/libgomp/testsuite/libgomp.sum len0/x86_64-pc-linux-gnu/libatomic/testsuite/libatomic.sum len0/x86_64-pc-linux-gnu/libstdc++-v3/testsuite/libstdc++.sum alx@debian:~/src/gnu/gcc$ find len1 -type f len1/host-x86_64-pc-linux-gnu/gcc/testsuite/gcc/gcc.sum len1/host-x86_64-pc-linux-gnu/gcc/testsuite/gfortran/gfortran.sum len1/host-x86_64-pc-linux-gnu/gcc/testsuite/objc/objc.sum len1/host-x86_64-pc-linux-gnu/gcc/testsuite/g++/g++.sum len1/x86_64-pc-linux-gnu/libitm/testsuite/libitm.sum len1/x86_64-pc-linux-gnu/libgomp/testsuite/libgomp.sum len1/x86_64-pc-linux-gnu/libatomic/testsuite/libatomic.sum len1/x86_64-pc-linux-gnu/libstdc++-v3/testsuite/libstdc++.sum alx@debian:~/src/gnu/gcc$ cat <(cd len0; find -type f) \ | while read f; do diff -u "len0/$f" "len1/$f"; done; --- len0/./host-x86_64-pc-linux-gnu/gcc/testsuite/gcc/gcc.sum 2024-08-06 +22:22:44.514175252 +0200 +++ len1/./host-x86_64-pc-linux-gnu/gcc/testsuite/gcc/gcc.sum 2024-08-06 +23:29:53.693730123 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === gcc tests === @@ -86504,6 +86504,15 @@ PASS: gcc.dg/large-size-array.c (test for errors, line 19) PASS: gcc.dg/large-size-array.c (test for excess errors) UNSUPPORTED: gcc.dg/lazy-ptr-test.c +PASS: gcc.dg/lengthof-compile.c (test for errors, line 11) +PASS: gcc.dg/lengthof-compile.c (test for errors, line 15) +PASS: gcc.dg/lengthof-compile.c (test for errors, line 27) +PASS: gcc.dg/lengthof-compile.c (test for errors, line 42) +PASS: gcc.dg/lengthof-compile.c (test for errors, line 45) +PASS: gcc.dg/lengthof-compile.c (test for errors, line 48) +PASS: gcc.dg/lengthof-compile.c (test for excess errors) +PASS: gcc.dg/lengthof.c (test for excess errors) +PASS: gcc.dg/lengthof.c execution test PASS: gcc.dg/limits-width-1.c (test for excess errors) PASS: gcc.dg/limits-width-2.c (test for excess errors) PASS: gcc.dg/live-patching-1.c (test for excess errors) @@ -204639,7 +204648,7 @@ === gcc Summary === -# of expected passes 199780 +# of expected passes 199789 # of unexpected failures 31 # of unexpected successes 2 # of expected failures 1463 --- len0/./host-x86_64-pc-linux-gnu/gcc/testsuite/gfortran/gfortran.sum 2024-08-06 +22:22:44.546175561 +0200 +++ len1/./host-x86_64-pc-linux-gnu/gcc/testsuite/gfortran/gfortran.sum 2024-08-06 +23:29:53.877731933 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === gfortran tests === --- len0/./host-x86_64-pc-linux-gnu/gcc/testsuite/objc/objc.sum 2024-08-06 +22:22:44.462174752 +0200 +++ len1/./host-x86_64-pc-linux-gnu/gcc/testsuite/objc/objc.sum 2024-08-06 +23:29:53.845731618 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === objc tests === --- len0/./host-x86_64-pc-linux-gnu/gcc/testsuite/g++/g++.sum 2024-08-06 +22:22:44.622176292 +0200 +++ len1/./host-x86_64-pc-linux-gnu/gcc/testsuite/g++/g++.sum 2024-08-06 +23:29:53.781730989 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === g++ tests === --- len0/./x86_64-pc-linux-gnu/libitm/testsuite/libitm.sum 2024-08-06 +22:22:46.206191541 +0200 +++ len1/./x86_64-pc-linux-gnu/libitm/testsuite/libitm.sum 2024-08-06 +23:29:55.573748613 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === libitm tests === --- len0/./x86_64-pc-linux-gnu/libgomp/testsuite/libgomp.sum 2024-08-06 +22:22:45.694186612 +0200 +++ len1/./x86_64-pc-linux-gnu/libgomp/testsuite/libgomp.sum 2024-08-06 +23:29:54.717740194 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === libgomp tests === --- len0/./x86_64-pc-linux-gnu/libatomic/testsuite/libatomic.sum 2024-08-06 +22:22:46.110190617 +0200 +++ len1/./x86_64-pc-linux-gnu/libatomic/testsuite/libatomic.sum 2024-08-06 +23:29:55.393746843 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:53 2024 +Test run by alx on Tue Aug 6 22:49:12 2024 Native configuration is x86_64-pc-linux-gnu === libatomic tests === --- len0/./x86_64-pc-linux-gnu/libstdc++-v3/testsuite/libstdc++.sum 2024-08-06 +22:22:45.998189539 +0200 +++ len1/./x86_64-pc-linux-gnu/libstdc++-v3/testsuite/libstdc++.sum 2024-08-06 +23:29:55.137744325 +0200 @@ -1,4 +1,4 @@ -Test run by alx on Tue Aug 6 19:28:54 2024 +Test run by alx on Tue Aug 6 22:49:13 2024 Native configuration is x86_64-pc-linux-gnu === libstdc++ tests === Alejandro Colomar (3): gcc/: Rename array_type_nelts() => array_type_nelts_minus_one() Merge definitions of array_type_nelts_top() c: Add __lengthof__ operator gcc/c-family/c-common.cc | 26 +++++ gcc/c-family/c-common.def | 3 + gcc/c-family/c-common.h | 2 + gcc/c/c-decl.cc | 30 ++++-- gcc/c/c-fold.cc | 7 +- gcc/c/c-parser.cc | 61 +++++++++--- gcc/c/c-tree.h | 4 + gcc/c/c-typeck.cc | 114 ++++++++++++++++++++- gcc/config/aarch64/aarch64.cc | 2 +- gcc/config/i386/i386.cc | 2 +- gcc/cp/cp-tree.h | 1 - gcc/cp/decl.cc | 2 +- gcc/cp/init.cc | 8 +- gcc/cp/lambda.cc | 3 +- gcc/cp/operators.def | 1 + gcc/cp/tree.cc | 13 --- gcc/doc/extend.texi | 23 +++++ gcc/expr.cc | 8 +- gcc/fortran/trans-array.cc | 2 +- gcc/fortran/trans-openmp.cc | 4 +- gcc/rust/backend/rust-tree.cc | 13 --- gcc/rust/backend/rust-tree.h | 2 - gcc/target.h | 3 + gcc/testsuite/gcc.dg/lengthof-compile.c | 49 +++++++++ gcc/testsuite/gcc.dg/lengthof.c | 127 ++++++++++++++++++++++++ gcc/tree.cc | 17 +++- gcc/tree.h | 3 +- 27 files changed, 451 insertions(+), 79 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c create mode 100644 gcc/testsuite/gcc.dg/lengthof.c Range-diff against v4: 1: 73010cb4af6 = 1: 73010cb4af6 gcc/: Rename array_type_nelts() => array_type_nelts_minus_one() 2: 2bb966a0a89 ! 2: 9b835478721 Merge definitions of array_type_nelts_top() @@ Commit message Merge definitions of array_type_nelts_top() There were two identical definitions, and none of them are available - where they are needed for implementing __lengthof__(). Merge them, and + where they are needed for implementing __lengthof__. Merge them, and provide the single definition in gcc/tree.{h,cc}, where it's available - for __lengthof__(). + for __lengthof__, which will be added in the following commit. + + gcc/ChangeLog: + + * tree.h (array_type_nelts_top): + * tree.cc (array_type_nelts_top): Define function (moved from + gcc/cp/). + + gcc/cp/ChangeLog: + + * cp-tree.h (array_type_nelts_top): + * tree.cc (array_type_nelts_top): Remove function (move + to gcc/). + + gcc/rust/ChangeLog: + + * backend/rust-tree.h (array_type_nelts_top): + * backend/rust-tree.cc (array_type_nelts_top): Remove function. Signed-off-by: Alejandro Colomar 3: e2dbfc43b14 ! 3: af05d01e68d c: Add __lengthof__() operator (n2529) @@ Metadata Author: Alejandro Colomar ## Commit message ## - c: Add __lengthof__() operator (n2529) + c: Add __lengthof__ operator - This operator is similar to sizeof() but can only be applied to an - array, and returns its length (number of elements). + This operator is similar to sizeof but can only be applied to an array, + and returns its length (number of elements). FUTURE DIRECTIONS: - We could make it work with array parameters to functions, and - somehow magically return the length designator of the array, - regardless of it being really a pointer. + We could make it work with array parameters to functions, and + somehow magically return the length designator of the array, + regardless of it being really a pointer. - Link: - Link: - Suggested-by: Xavier Del Campo Romero - Co-developed-by: Martin Uecker - Cc: Gabriel Ravier Cc: Joseph Myers + Cc: Gabriel Ravier Cc: Jakub Jelinek Cc: Kees Cook Cc: Qing Zhao Cc: Jens Gustedt + Cc: David Brown + Cc: Florian Weimer + Cc: Andreas Schwab + + gcc/ChangeLog: + + * doc/extend.texi: Document __lengthof__ operator. + * target.h (enum type_context_kind): Add __lengthof__ operator. + + gcc/c-family/ChangeLog: + + * c-common.h: + * c-common.def: + * c-common.cc (c_lengthof_type): Add __lengthof__ operator. + + gcc/c/ChangeLog: + + * c-tree.h + (c_expr_lengthof_expr, c_expr_lengthof_type): + * c-decl.cc + (start_struct, finish_struct): + (start_enum, finish_enum): + * c-parser.cc + (c_parser_sizeof_expression): + (c_parser_lengthof_expression): + (c_parser_sizeof_or_lengthof_expression): + (c_parser_unary_expression): + * c-typeck.cc + (build_external_ref): + (record_maybe_used_decl, pop_maybe_used): + (is_top_array_vla): + (c_expr_lengthof_expr, c_expr_lengthof_type): + Add __lengthof__operator. + + gcc/cp/ChangeLog: + + * operators.def: Add __lengthof__ operator. + + gcc/testsuite/ChangeLog: + + * gcc.dg/lengthof-compile.c: + * gcc.dg/lengthof.c: Add tests for __lengthof__ operator. + + Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf + Link: https://inbox.sourceware.org/gcc/M8S4oQy--3-2@tutanota.com/T/ + Suggested-by: Xavier Del Campo Romero + Co-developed-by: Martin Uecker Signed-off-by: Alejandro Colomar ## gcc/c-family/c-common.cc ## @@ gcc/c/c-typeck.cc: int in_alignof; /* The level of nesting inside "sizeof". */ int in_sizeof; -+/* The level of nesting inside "sizeof". */ ++/* The level of nesting inside "lengthof". */ +int in_lengthof; + /* The level of nesting inside "typeof". */ @@ gcc/doc/extend.texi: If the operand of the @code{__alignof__} expression is a fu +Its syntax is just like @code{sizeof}. +The operand must be a complete array type. +The operand is not evaluated -+if the top-level length designator is an integer constant expression; ++if the top-level length designator is an integer constant expression ++(in this case, the operator results in a constant expression); +and it is evaluated -+if the top-level length designator is not an integer constant expression. ++if the top-level length designator is not an integer constant expression ++(in this case, the operator results in a run-time value). ++For example: + -+XXX: Do we want to document the following? I think so. -+XXX: It would prevent users from relying on __lengthof__ -+XXX: for distinguishing arrays from pointers. -+XXX: I don't want users to complain in the future -+XXX: if this doesn't report errors on function parameters anymore -+XXX: and that breaks their assumptions. -+In the future, -+it might also accept a function parameter with array notation, -+an incomplete array whose length is specified by other means, -+such as attributes, -+or other similar cases. ++@smallexample ++__lengthof__ (int [7][n++]); // constexpr ++__lengthof__ (int [n++][7]); // run-time value ++@end smallexample + @node Inline @section An Inline Function is As Fast As a Macro @@ gcc/target.h: enum type_context_kind { /* Creating objects of type T with static storage duration. */ TCTX_STATIC_STORAGE, + + ## gcc/testsuite/gcc.dg/lengthof-compile.c (new) ## +@@ ++/* { dg-do compile } */ ++/* { dg-options "-Wno-declaration-after-statement -Wno-pedantic -Wno-vla" } */ ++ ++extern int x[]; ++ ++void ++incomplete (int p[]) ++{ ++ unsigned n; ++ ++ n = __lengthof__ (x); /* { dg-error "incomplete" } */ ++ ++ /* We want to support the following one in the future, ++ but for now it should fail. */ ++ n = __lengthof__ (p); /* { dg-error "invalid" } */ ++} ++ ++void ++fam (void) ++{ ++ struct { ++ int x; ++ int fam[]; ++ } s; ++ unsigned n; ++ ++ n = __lengthof__ (s.fam); /* { dg-error "incomplete" } */ ++} ++ ++void fix_fix (int i, char (*a)[3][5], int (*x)[__lengthof__ (*a)]); ++void fix_var (int i, char (*a)[3][i], int (*x)[__lengthof__ (*a)]); ++void fix_uns (int i, char (*a)[3][*], int (*x)[__lengthof__ (*a)]); ++ ++void ++func (void) ++{ ++ int i3[3]; ++ int i5[5]; ++ char c35[3][5]; ++ ++ fix_fix (5, &c35, &i3); ++ fix_fix (5, &c35, &i5); /* { dg-error "incompatible-pointer-types" } */ ++ ++ fix_var (5, &c35, &i3); ++ fix_var (5, &c35, &i5); /* { dg-error "incompatible-pointer-types" } */ ++ ++ fix_uns (5, &c35, &i3); ++ fix_uns (5, &c35, &i5); /* { dg-error "incompatible-pointer-types" } */ ++} + + ## gcc/testsuite/gcc.dg/lengthof.c (new) ## +@@ ++/* { dg-do run } */ ++/* { dg-options "-Wno-declaration-after-statement -Wno-pedantic -Wno-vla" } */ ++ ++#undef NDEBUG ++#include ++ ++void ++array (void) ++{ ++ short a[7]; ++ ++ assert (__lengthof__ (a) == 7); ++ assert (__lengthof__ (long [0]) == 0); ++ assert (__lengthof__ (unsigned [99]) == 99); ++} ++ ++void ++vla (void) ++{ ++ unsigned n; ++ ++ n = 99; ++ assert (__lengthof__ (short [n - 10]) == 99 - 10); ++ ++ int v[n / 2]; ++ assert (__lengthof__ (v) == 99 / 2); ++ ++ n = 0; ++ int z[n]; ++ assert (__lengthof__ (z) == 0); ++} ++ ++void ++member (void) ++{ ++ struct { ++ int a[8]; ++ } s; ++ ++ assert (__lengthof__ (s.a) == 8); ++} ++ ++void ++vla_eval (void) ++{ ++ int i; ++ ++ i = 7; ++ assert (__lengthof__ (struct {int x;}[i++]) == 7); ++ assert (i == 7 + 1); ++ ++ int v[i]; ++ int (*p)[i]; ++ p = &v; ++ assert (__lengthof__ (*p++) == i); ++ assert (p - 1 == &v); ++} ++ ++void ++inner_vla_noeval (void) ++{ ++ int i; ++ ++ i = 3; ++ assert (__lengthof__ (struct {int x[i++];}[3]) == 3); ++ assert (i == 3); ++} ++ ++void ++array_noeval (void) ++{ ++ long a[5]; ++ long (*p)[__lengthof__ (a)]; ++ ++ p = &a; ++ assert (__lengthof__ (*p++) == 5); ++ assert (p == &a); ++} ++ ++void ++matrix_zero (void) ++{ ++ int i; ++ ++ assert (__lengthof__ (int [0][4]) == 0); ++ i = 3; ++ assert (__lengthof__ (int [0][i]) == 0); ++} ++ ++void ++matrix_fixed (void) ++{ ++ int i; ++ ++ assert (__lengthof__ (int [7][4]) == 7); ++ i = 3; ++ assert (__lengthof__ (int [7][i]) == 7); ++} ++ ++void ++matrix_vla (void) ++{ ++ int i, j; ++ ++ i = 7; ++ assert (__lengthof__ (int [i++][4]) == 7); ++ assert (i == 7 + 1); ++ ++ i = 9; ++ j = 3; ++ assert (__lengthof__ (int [i++][j]) == 9); ++ assert (i == 9 + 1); ++} ++ ++int ++main (void) ++{ ++ array (); ++ vla (); ++ member (); ++ vla_eval (); ++ inner_vla_noeval (); ++ array_noeval (); ++ matrix_zero (); ++ matrix_fixed (); ++ matrix_vla (); ++} 4: 9a691f7f208 < -: ----------- testsuite: Add tests for __lengthof__