diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 02e66bfc..f9620849 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -558,10 +558,10 @@ (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type) 4)) (info ((expr->accu* info) o))) - (append-text info (wrap-as (append (case size - ((1) (i386:byte-mem->accu)) - ((4) (i386:mem->accu)) - (else '()))))))) + (append-text info (wrap-as (case size + ((1) (i386:byte-mem->accu)) + ((4) (i386:mem->accu)) + (else '())))))) ;; foo.bar[baz]) ((array-ref ,index (d-sel (ident ,field0) (p-expr (ident ,struct0)))) @@ -569,9 +569,11 @@ (type0 (ident->type info struct0)) (type1 (field-type info type0 field0)) (ptr (field-pointer info type0 field0)) - (size (ast-type->size info type1))) - (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu) - (i386:mem->accu)))))) + (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1) + 4))) + (append-text info (wrap-as (case size + ((1) (i386:byte-mem->accu)) + (else (i386:mem->accu))))))) ;; foo->bar[baz]) ((array-ref ,index (i-sel (ident ,field0) (p-expr (ident ,struct0)))) @@ -579,9 +581,11 @@ (type0 (ident->type info struct0)) (type1 (field-type info type0 field0)) (ptr (field-pointer info type0 field0)) - (size (ast-type->size info type1))) - (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu) - (i386:mem->accu)))))) + (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1) + 4))) + (append-text info (wrap-as (case size + ((1) (i386:byte-mem->accu)) + (else (i386:mem->accu))))))) ;; [baz] ((array-ref ,index ,array) @@ -962,11 +966,28 @@ (pmatch a ((p-expr (ident ,name)) (append-text info ((accu->ident info) name))) - ((d-sel (ident ,field) ,p-expr) - (let* ((type (p-expr->type info p-expr)) - (offset (field-offset info type field)) - (info ((expr->base* info) a))) - (append-text info (wrap-as (i386:accu->base-mem))))) ; FIXME: size + ((d-sel (ident ,field) ,expr) + (let* ((info ((expr->base* info) a)) + (type (p-expr->type info expr)) + (ptr (field-pointer info type field)) + (type1 (field-type info type field)) + (size (if (= ptr 0) (ast-type->size info type1) + 4))) + (append-text info (case size + ((1) (wrap-as (i386:byte-accu->base-mem))) + ((2) (wrap-as (i386:word-accu->base-mem))) + (else (wrap-as (i386:accu->base-mem))))))) + ((i-sel (ident ,field) ,expr) + (let* ((info ((expr->base* info) a)) + (type (p-expr->type info expr)) + (ptr (field-pointer info type field)) + (type1 (field-type info type field)) + (size (if (= ptr 0) (ast-type->size info type1) + 4))) + (append-text info (case size + ((1) (wrap-as (i386:byte-accu->base-mem))) + ((2) (wrap-as (i386:word-accu->base-mem))) + (else (wrap-as (i386:accu->base-mem))))))) ((de-ref (p-expr (ident ,name))) (let* ((type (ident->type info name)) (ptr (ident->pointer info name)) @@ -980,15 +1001,33 @@ (size (expr->size info expr))) (append-text info (wrap-as (i386:accu->base-mem))))) ((array-ref ,index (d-sel (ident ,field) (p-expr (ident ,struct)))) - (let ((info ((expr->base* info) a))) - (append-text info (wrap-as (i386:accu->base-mem))))) + (let* ((info ((expr->base* info) a)) + (type (ident->type info struct)) + (offset (field-offset info type field)) + (ptr (field-pointer info type field)) + (type1 (field-type info type field)) + (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1) + 4))) + (append-text info (case size + ((1) (wrap-as (i386:byte-accu->base-mem))) + ((2) (wrap-as (i386:word-accu->base-mem))) + (else (wrap-as (i386:accu->base-mem))))))) ((array-ref ,index (i-sel (ident ,field) (p-expr (ident ,struct)))) - (let ((info ((expr->base* info) a))) - (append-text info (wrap-as (i386:accu->base-mem))))) + (let* ((info ((expr->base* info) a)) + (type (ident->type info struct)) + (offset (field-offset info type field)) + (ptr (field-pointer info type field)) + (type1 (field-type info type field)) + (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type1) + 4))) + (append-text info (case size + ((1) (wrap-as (i386:byte-accu->base-mem))) + ((2) (wrap-as (i386:word-accu->base-mem))) + (else (wrap-as (i386:accu->base-mem))))))) ((array-ref ,index (p-expr (ident ,array))) (let* ((type (ident->type info array)) (ptr (ident->pointer info array)) - (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type) + (size (if (or (= ptr -1) (= ptr 1)) (ast-type->size info type) 4)) (info ((expr->base* info) a))) (append-text info @@ -1003,11 +1042,6 @@ (wrap-as (append (i386:accu+value 4) (i386:base+value 4) (i386:accu-mem->base-mem))))))))))) - - ((i-sel (ident ,field) ,array) - (let ((info ((expr->base* info) a))) - (append-text info (wrap-as (i386:accu->base-mem))))) - (_ (error "expr->accu: unsupported assign: " a))))) (_ (error "expr->accu: unsupported: " o)))))) @@ -1151,7 +1185,8 @@ (info ((expr->accu info) index)) (struct? (or #t (memq (type:type (ast-type->type info type0)) '(struct union)))) (ptr (field-pointer info type0 field0)) - (size (if (= ptr -1) (ast-type->size info type1) + (size (if (or (= ptr -1) + (= ptr 1)) (ast-type->size info type1) 4))) (append-text info (append (wrap-as (append (i386:accu->base) (if (eq? size 1) '() @@ -1165,8 +1200,9 @@ ((ident->accu info) struct0) (wrap-as (append (i386:accu+value offset) (i386:pop-base) - (if (and struct? (or (= ptr -2) - (= ptr 2))) (i386:mem->accu) '()) + (if (and struct? (or (= ptr -2) (= ptr 2) + (= ptr 1))) + (i386:mem->accu) '()) (i386:accu+base))))))) ;; foo->bar[baz] @@ -1177,7 +1213,8 @@ (info ((expr->accu info) index)) (struct? (or #t (memq (type:type (ast-type->type info type0)) '(struct union)))) (ptr (field-pointer info type0 field0)) - (size (if (= ptr -1) (ast-type->size info type1) + (size (if (or (= ptr -1) + (= ptr 1)) (ast-type->size info type1) 4))) (append-text info (append (wrap-as (append (i386:accu->base) (if (eq? size 1) '() @@ -1191,8 +1228,9 @@ ((ident->accu info) struct0) (wrap-as (append (i386:accu+value offset) (i386:pop-base) - (if (and struct? (or (= ptr -2) - (= ptr 2))) (i386:mem->accu) '()) + (if (and struct? (or (= ptr -2) (= ptr 2) + (= ptr 1))) + (i386:mem->accu) '()) (i386:accu+base))))))) ((array-ref ,index ,array) @@ -1710,6 +1748,14 @@ (define (expr->size info o) (pmatch o ((p-expr (ident ,name)) (ident->size info name)) + ((d-sel (ident ,field) (p-expr (ident ,struct))) + (let* ((type (ident->type info struct)) + (type1 (field-type info type field))) + (ast-type->size info type1))) + ((i-sel (ident ,field) (p-expr (ident ,struct))) + (let* ((type (ident->type info struct)) + (type1 (field-type info type field))) + (ast-type->size info type1))) ((de-ref ,expr) (expr->size info expr)) ((add ,a ,b) (expr->size info a)) ((sub ,a ,b) (expr->size info a)) diff --git a/scaffold/tests/7a-struct-char-array.c b/scaffold/tests/7a-struct-char-array.c index ea33087a..9c0d0084 100644 --- a/scaffold/tests/7a-struct-char-array.c +++ b/scaffold/tests/7a-struct-char-array.c @@ -19,49 +19,104 @@ */ #include "30-test.i" +#include +#include struct file { - unsigned char buffer[1]; + char buffer[1]; }; -int fill0; -int fill1; -int fill2; -int fill3; -int fill4; +struct xfile { + char *buffer; +}; struct file file; +struct xfile xfile; -int fill5; -int fill6; -int fill7; -int fill8; -int fill9; +char *buffer = "aaaaaaaaaaaa"; +char *bufzor = "bbbbbbbbbbbb"; int test () { + char *p; + struct file *pfile = &file; strcpy (file.buffer, "0123456789\n"); eputs (file.buffer); - char *p = pfile->buffer; - if (p[4] != '4') return 1; - if (file.buffer[4] != '4') return 2; - if (pfile->buffer[4] != '4') return 3; - - memcpy (pfile->buffer + 4, " ", 1); - eputs (file.buffer); - if (p[4] != ' ') return 4; - if (file.buffer[4] != ' ') return 5; - if (pfile->buffer[4] != ' ') return 6; + p = pfile->buffer; + if (p[1] != '1') return 1; + if (file.buffer[1] != '1') return 2; + if (pfile->buffer[1] != '1') return 3; strcpy (file.buffer, "0123456789\n"); eputs (file.buffer); - p[4] = 'A'; + memcpy (pfile->buffer + 1, " ", 1); eputs (file.buffer); - if (p[4] != 'A') return 7; - if (file.buffer[4] != 'A') return 8; - if (pfile->buffer[4] != 'A') return 9; + if (p[1] != ' ') return 4; + if (file.buffer[1] != ' ') return 5; + if (pfile->buffer[1] != ' ') return 6; + strcpy (file.buffer, "0123456789\n"); + eputs (file.buffer); + p[2] = ' '; + eputs (file.buffer); + if (p[2] != ' ') return 7; + if (file.buffer[2] != ' ') return 8; + if (pfile->buffer[2] != ' ') return 9; + + strcpy (file.buffer, "0123456789\n"); + eputs (file.buffer); + file.buffer[3] = ' '; + eputs (file.buffer); + if (p[3] != ' ') return 10; + if (p[4] != '4') return 11; + + strcpy (file.buffer, "0123456789\n"); + eputs (file.buffer); + pfile->buffer[4] = ' '; + eputs (file.buffer); + if (p[4] != ' ') return 12; + if (p[5] != '5') return 13; + + xfile.buffer = &buffer; + struct xfile *pxfile = &xfile; + strcpy (xfile.buffer, "0123456789\n"); + eputs (xfile.buffer); + p = pxfile->buffer; + if (p[5] != '5') return 20; + if (xfile.buffer[5] != '5') return 22; + if (pxfile->buffer[5] != '5') return 23; + + strcpy (xfile.buffer, "0123456789\n"); + eputs (xfile.buffer); + memcpy (pxfile->buffer + 5, " ", 1); + eputs (xfile.buffer); + if (p[5] != ' ') return 24; + if (xfile.buffer[5] != ' ') return 25; + if (pxfile->buffer[5] != ' ') return 26; + + strcpy (xfile.buffer, "0123456789\n"); + eputs (xfile.buffer); + p[6] = ' '; + eputs (xfile.buffer); + if (p[6] != ' ') return 27; + if (xfile.buffer[6] != ' ') return 28; + if (pxfile->buffer[6] != ' ') return 29; + + strcpy (xfile.buffer, "0123456789\n"); + eputs (xfile.buffer); + xfile.buffer[7] = ' '; + eputs (xfile.buffer); + if (p[7] != ' ') return 30; + if (p[8] != '8') return 31; + + strcpy (xfile.buffer, "0123456789\n"); + eputs (xfile.buffer); + pxfile->buffer[8] = ' '; + eputs (xfile.buffer); + if (p[8] != ' ') return 32; + if (p[9] != '9') return 33; + return 0; }