History

iitialisation of the empty struct Current tcc don't understand an initialization of the empty struct This problem was found trying to compile a linux kernel 2.4.26 which can be compiled by tcc 0.9.23

A test program: //////////////////// // ./tcc -c test_3.c // test_3.c:31: error: too many field init #undef __GNUC__ #undef __GNUC_MINOR__ #define __GNUC__ 2 #define __GNUC_MINOR__ 95 typedef struct { } rwlock_t; struct fs_struct { int count; rwlock_t lock; int umask; }; #define INIT_FS { \ 1, \ RW_LOCK_UNLOCKED, \ 0022, \ } #if (__GNUC__ > 2 || __GNUC_MINOR__ > 91) typedef struct { } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { } #else typedef struct { int gcc_is_buggy; } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } #endif static struct fs_struct init_fs = INIT_FS; // static struct fs_struct init_fs = { { (1) }, (rwlock_t) { 0 }, 0022, }; // ^ with this all Ok // static struct fs_struct init_fs = { { (1) }, (rwlock_t) { }, 0022, }; // ^ current tcc don't understand, but tcc 0.9.23 can int main() { return 0; } //////////////////// A regression is detected after a patch 69fdb57eddd00c592828605819f0678522d346c6 //////////////////// // A test for patch 69fdb57eddd00c592828605819f0678522d346c6 // Author: grischka <grischka> // Date: Wed Jun 17 02:09:07 2009 +0200 // unions: initzialize only one field // struct { // union { // int a,b; // }; // int c; // } sss = { 1,2 }; // This had previously assigned 1,2 to a,b and 0 to c which is wrong. // // Expected: sss.a=1 sss.b=1 sss.c=2 int main() { struct { union { int a,b; }; int c; } sss = { 1, 2 }; printf ("sss.a=%d sss.b=%d sss.c=%d\n", sss.a, sss.b, sss.c); return 0; } ////////////////////

seyko committed 11 years ago

Commit 1a1e9541 parent bbf82211 file · +20 −0Browse files

Unified · Split

tccgen.c+20−0
@@ -5525,10 +5525,30 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 5524 unmodified lines
5525 5525
5526 /* gr: skip fields from same union - ugly. */5526 /* gr: skip fields from same union - ugly. */
5527 while (f->next) {5527 while (f->next) {
5528 int align = 0;
5529 int f_size = type_size(&f->type, &align);
5530 int f_type = (f->type.t & VT_BTYPE);
5531
5528 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);5532 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5529 /* test for same offset */5533 /* test for same offset */
5530 if (f->next->c != f->c)5534 if (f->next->c != f->c)
5531 break;5535 break;
5536 if ((f_type == VT_STRUCT) && (f_size == 0)) {
5537 /*
5538 Lets assume a structure of size 0 can't be a member of the union.
5539 This allow to compile the following code from a linux kernel v2.4.26
5540 typedef struct { } rwlock_t;
5541 struct fs_struct {
5542 int count;
5543 rwlock_t lock;
5544 int umask;
5545 };
5546 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5547 tcc-0.9.23 can succesfully compile this version of the kernel.
5548 gcc don't have problems with this code too.
5549 */
5550 break;
5551 }
5532 /* if yes, test for bitfield shift */5552 /* if yes, test for bitfield shift */
5533 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {5553 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5534 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;5554 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t