1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-02 19:42:23 +00:00

Fixed compound initialization with omitted enclosing curly braces when an array/struct/union to initialize is nested.

This commit is contained in:
acqn 2023-09-22 10:29:52 +08:00
parent dd833125a8
commit 13e1ed3e7b
2 changed files with 65 additions and 8 deletions

View File

@ -343,8 +343,8 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* Char array initialized by string constant */ /* Char array initialized by string constant */
int NeedParen; int NeedParen;
/* If we initializer is enclosed in brackets, remember this fact and /* If the initializer is enclosed in curly braces, remember this fact
** skip the opening bracket. ** and skip the opening one.
*/ */
NeedParen = (CurTok.Tok == TOK_LCURLY); NeedParen = (CurTok.Tok == TOK_LCURLY);
if (NeedParen) { if (NeedParen) {
@ -377,7 +377,9 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
} else { } else {
/* Arrays can be initialized without a pair of curly braces */ /* An array can be initialized without a pair of enclosing curly braces
** if it is itself a member of a struct/union or an element of an array.
*/
if (*Braces == 0 || CurTok.Tok == TOK_LCURLY) { if (*Braces == 0 || CurTok.Tok == TOK_LCURLY) {
/* Consume the opening curly brace */ /* Consume the opening curly brace */
HasCurly = ConsumeLCurly (); HasCurly = ConsumeLCurly ();
@ -387,14 +389,22 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* Initialize the array members */ /* Initialize the array members */
Count = 0; Count = 0;
while (CurTok.Tok != TOK_RCURLY) { while (CurTok.Tok != TOK_RCURLY) {
/* Flexible array members may not be initialized within /* Flexible array members cannot be initialized within an array.
** an array (because the size of each element may differ ** (Otherwise the size of each element may differ.)
** otherwise).
*/ */
ParseInitInternal (ElementType, Braces, 0); ParseInitInternal (ElementType, Braces, 0);
++Count; ++Count;
if (CurTok.Tok != TOK_COMMA) if (CurTok.Tok != TOK_COMMA) {
break; break;
}
if (!HasCurly && ElementCount > 0 && Count >= ElementCount) {
/* If the array is initialized without enclosing curly braces,
** it only accepts how many elements initializers up to its
** count of elements, leaving any following initializers out.
*/
break;
}
NextToken (); NextToken ();
} }
@ -491,7 +501,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers)
Error ("Excess elements in %s initializer", GetBasicTypeName (T)); Error ("Excess elements in %s initializer", GetBasicTypeName (T));
SkipInitializer (HasCurly); SkipInitializer (HasCurly);
} }
return SI.Offs; break;
} }
/* Check for special members that don't consume the initializer */ /* Check for special members that don't consume the initializer */

47
test/val/bug2135.c Normal file
View File

@ -0,0 +1,47 @@
/* Bug #2135 - Compound initialization consumes wrong amount of initializers with omitted
** enclosing curly braces when an array/struct/union to initialize is itself
** a member/element of a struct/union/array.
*/
#include <stdint.h>
#include <stdio.h>
struct s {
union {
int8_t a[2][2];
char c[sizeof (int8_t) * 2 * 2 + sizeof (int16_t) * 4];
};
int16_t b[4];
};
struct s x = { 1, 2, 3, 4, 5, 6 };
struct s y = { {{{1, 2}, {3, 4}}}, {5, 6} };
unsigned failures;
int main(void)
{
unsigned i, j;
for (i = 0; i < 2; ++i)
{
for (j = 0; j < 2; ++j)
{
if (x.a[i][j] != y.a[i][j])
{
++failures;
printf("x.a[%u][%u] = %d\n, expected %d\n", i, j, x.a[i][j], y.a[i][j]);
}
}
}
for (i = 0; i < 4; ++i)
{
if (x.b[i] != y.b[i])
{
++failures;
printf("x.b[%u] = %d\n, expected %d\n", i, x.b[i], y.b[i]);
}
}
return failures;
}