From cc5f377864f74f0fbfd013c853d021cb4c909105 Mon Sep 17 00:00:00 2001 From: Ian Piumarta Date: Sat, 1 Feb 2025 15:10:26 +0900 Subject: [PATCH] handle typedefs of anonymous structures --- demofiles/use-after-free.c | 10 +++++----- main.leg | 37 +++++++++++++++++-------------------- test.txt | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/demofiles/use-after-free.c b/demofiles/use-after-free.c index d118d5a..f1d22c0 100644 --- a/demofiles/use-after-free.c +++ b/demofiles/use-after-free.c @@ -8,11 +8,11 @@ int main() { int *ptr = (int *)malloc(sizeof(*ptr)); assert(ptr != 0); *ptr = 42; - printf("%p %d\n", ptr, *ptr); + printf("%d\n", *ptr); free(ptr); - printf("%p %d\n", ptr, *ptr); // use after free - // the following usully causes a SEGV in the interpreter because the store corrupts GC memory - *ptr = 43; // use after free - printf("%p %d\n", ptr, *ptr); // use after free + printf("%d\n", *ptr); // use after free + // the following sometimes causes a SEGV in the interpreter because the store corrupts GC memory + *ptr = 43; // use after free + printf("%d\n", *ptr); // use after free return 0; } diff --git a/main.leg b/main.leg index 1f65bb5..4e7303c 100644 --- a/main.leg +++ b/main.leg @@ -1,6 +1,6 @@ # main.leg -- C parser + interpreter # -# Last edited: 2025-02-01 10:24:25 by piumarta on xubuntu +# Last edited: 2025-02-01 15:04:48 by piumarta on xubuntu %{ ; @@ -755,17 +755,19 @@ oop tags = 0; oop newTstruct(oop tag, oop members) { - List_do(tags, t) { - if (tag == get(t, Tstruct,tag)) { - if (!is(Tstruct, t)) - fatal("tag '%s' redeclared as different type", symbolName(tag)); - oop oldmembers = get(t, Tstruct,members); - if (!isNil(oldmembers) && !isNil(members)) { - fatal("tag '%s' redefined", symbolName(tag)); + if (!isNil(tag)) { + List_do(tags, t) { + if (tag == get(t, Tstruct,tag)) { + if (!is(Tstruct, t)) + fatal("tag '%s' redeclared as different type", symbolName(tag)); + oop oldmembers = get(t, Tstruct,members); + if (!isNil(oldmembers) && !isNil(members)) { + fatal("tag '%s' redefined", symbolName(tag)); + } + if (isNil(oldmembers) && !isNil(members)) + set(t, Tstruct,members, members); + return t; // uniqe types allow comparison by identity } - if (isNil(oldmembers) && !isNil(members)) - set(t, Tstruct,members, members); - return t; // uniqe types allow comparison by identity } } oop obj = new(Tstruct); @@ -1802,6 +1804,7 @@ stmt = WHILE c:cond s:stmt { $$ = newWhile(c, s) } | BREAK SEMI { $$ = newBreak() } | block | e:expr SEMI { $$ = e } + | typedec | vardecl cond = LPAREN e:expr RPAREN { $$ = e } @@ -3198,7 +3201,7 @@ oop assign(oop lhs, oop rhs) } break; } - case Member: { + case Member: { // soru.name = rhs oop name = get(lhs, Member,name); oop soru = eval(get(lhs, Member,lhs)); // struct or union oop type = nil; @@ -3231,7 +3234,7 @@ oop assign(oop lhs, oop rhs) assert(offset + vsize <= size); return setMemory(memory, offset, vtype, eval(rhs)); } - case Dereference: { // *<&var> = rhs + case Dereference: { // *<&var> = rhs, *<&const> = rhs, *<&memory> = rhs lhs = eval(get(lhs, Dereference,rhs)); switch (getType(lhs)) { case Pointer: { // &x @@ -3848,13 +3851,7 @@ oop eval(oop exp) } RETURN(nil); } - case TypeDecls: { - oop types = get(exp, TypeDecls,typenames); - List_do(types, type) { - oop name = get(type, TypeName,name); - oop type = get(type, TypeName,type); - declareType(name, type); - } + case TypeDecls: { // local typenames only used within typeCheck() and can be ignored here RETURN(nil); } case Scope: break; diff --git a/test.txt b/test.txt index 56dc4c6..a5569dd 100755 --- a/test.txt +++ b/test.txt @@ -24,6 +24,10 @@ int gbl[5]; int gg[] = { -2, ~2, !2, 6+7, 6*7 }; +struct G1 { int x, y; }; +typedef struct G2 { int x, y; } G2_t; +typedef struct { int x, y; } G3_t; + int main(int argc, char **argv) { printf("hello, world %d %s\n", foo(), bar()); @@ -106,6 +110,36 @@ int main(int argc, char **argv) for (i = 0; i < sizeof gg / sizeof(int); ++i) printf("g %d ", gg[i]); printf("\n"); for (i = 0; i < sizeof ll / sizeof(int); ++i) printf("l %d ", ll[i]); printf("\n"); + struct S { int a, b; }; + + typedef struct S SS; + + SS s; + + s.a = 42; + s.b = 666; + printf("%d %d\n", s.a, s.b); + + struct L1 { int x, y; }; + typedef struct L2 { int x, y; } L2_t; + typedef struct { int x, y; } L3_t; + + struct G1 g1 = { 10, 11 }; + G2_t g2 = { 12, 13 }; + G3_t g3 = { 14, 15 }; + + struct L1 l1 = { 20, 21 }; + L2_t l2 = { 22, 23 }; + L3_t l3 = { 24, 25 }; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d\n", g1.x, g1.y, g2.x, g2.y, g3.x, g3.y, l1.x, l1.y, l2.x, l2.y, l3.x, l3.y); + + typedef L2_t L2_t_t; + + L2_t_t ll2 = { 42, 666 }; + + printf("%d %d\n", ll2.x, ll2.y); + printf("passed\n"); return 0;