From 5201312cb242ea943848fcf864adacc44d3d190f Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 15 Feb 2021 23:58:18 +0100 Subject: [PATCH] Fix segfault with nested flex array structs when used with string initialization the size of nested struct flex array member was tested too late for < 0. GCC accepts but discards such initializers (the flex array member will become zero sized). TCC supports flex arrays members only in top-level structs and gives an error in this case. --- tccgen.c | 3 +-- tests/tests2/60_errors_and_warnings.c | 6 ++++++ tests/tests2/60_errors_and_warnings.expect | 15 +++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tccgen.c b/tccgen.c index 931d6d68..241d706d 100644 --- a/tccgen.c +++ b/tccgen.c @@ -8237,6 +8237,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f goto do_init_array; } + decl_design_flex(p, s, len); if (!(flags & DIF_SIZE_ONLY)) { int nb = n; if (len < nb) @@ -8270,8 +8271,6 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f init_putv(p, t1, c + i * size1); } } - } else { - decl_design_flex(p, s, len); } } else { diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c index 5c576061..29c302ba 100644 --- a/tests/tests2/60_errors_and_warnings.c +++ b/tests/tests2/60_errors_and_warnings.c @@ -354,6 +354,12 @@ struct c1 c1 = { 1, { 2, 3, 4 } }; struct c2 { int c; struct c1 c1; }; struct c2 c2 = { 1, { 2, { 3, 4, 5 }}}; +#elif defined test_var_array3 +/* similar to test_var_array2 but with string initializers */ +struct A { int a; char b[]; }; +struct A a = { 1, "1" }; +struct B { struct A a; }; +struct B b = { { 1, "1" } }; /******************************************************************/ #elif defined test_default_int_type n; // warn diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect index ad3c3808..fb39cc21 100644 --- a/tests/tests2/60_errors_and_warnings.expect +++ b/tests/tests2/60_errors_and_warnings.expect @@ -166,20 +166,23 @@ bar : 3 ; 3 [test_var_array2] 60_errors_and_warnings.c:355: error: flexible array has zero size in this context +[test_var_array3] +60_errors_and_warnings.c:362: error: flexible array has zero size in this context + [test_default_int_type] -60_errors_and_warnings.c:359: warning: type defaults to int +60_errors_and_warnings.c:365: warning: type defaults to int [test_invalid_global_stmtexpr] -60_errors_and_warnings.c:363: error: statement expression outside of function +60_errors_and_warnings.c:369: error: statement expression outside of function [test_invalid_tokckill] -60_errors_and_warnings.c:366: error: ';' expected (got "3") +60_errors_and_warnings.c:372: error: ';' expected (got "3") [test_duplicate_member] -60_errors_and_warnings.c:372: error: duplicate member 'a' +60_errors_and_warnings.c:378: error: duplicate member 'a' [test_duplicate_member_anon] -60_errors_and_warnings.c:385: error: duplicate member 'd' +60_errors_and_warnings.c:391: error: duplicate member 'd' [test_conflicting_array_definition] -60_errors_and_warnings.c:390: error: incompatible types for redefinition of 'array' +60_errors_and_warnings.c:396: error: incompatible types for redefinition of 'array'