From ff8f491bc432ff42b52ec7de70945900ceeab1f7 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Wed, 11 Feb 2026 14:59:10 +0100 Subject: [PATCH] preparser_serializer: json: fix anonymous struct in for-loop initializer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The json_array_foreach_ref macro declares an anonymous struct type inside a for-loop initializer: for (struct { size_t i; const struct json_array *a; } idx = ... C11 6.8.5p3 constrains the for-loop initializer to only declare objects with auto or register storage class — in other words, it is only meant to create loop variables, not to define new types. However, writing `struct { ... } x = ...;` does two things at once: it defines a new type (the anonymous struct) and declares a variable. In C11 standard 6.2.1, struct tags declared inside a for-loop initializer get block scope of the enclosing block, so the type definition escapes the for-loop, violating the "only objects" constraint. Extract the anonymous struct into a named struct json_array_iter defined before the macro, so the for-loop initializer only declares a plain object of an already-existing type. Clang on armv7 iOS (via xcode-cross) enforces this constraint strictly and rejects the original code with "declaration of non-local variable in 'for' loop". --- modules/misc/preparser_serializer/json/fromjson.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/misc/preparser_serializer/json/fromjson.c b/modules/misc/preparser_serializer/json/fromjson.c index 6b140802b0..bc9c2bbcb1 100644 --- a/modules/misc/preparser_serializer/json/fromjson.c +++ b/modules/misc/preparser_serializer/json/fromjson.c @@ -360,11 +360,16 @@ static inline bool json_object_to_boolean(const struct json_object *obj, * Macro definition */ +struct json_array_iter { + size_t i; + const struct json_array *a; +}; + /* Get the array with `name` as a key, if there is not array with this key set * `error` to true and don't start the loop, else iterate over the array and * set `item` to the current value each round. */ #define json_array_foreach_ref(obj, name, item, error) \ - for (struct { size_t i; const struct json_array *a; } \ + for (struct json_array_iter \ idx_##item = { 0, json_get_array(obj, name) }; \ ((idx_##item.a != NULL || (*(error) = true, false)) && \ idx_##item.i < idx_##item.a->size && \