From 9bab6be83c98fe62ba9b7aa51f000ade991d3142 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 20 Aug 2020 17:39:21 +0200 Subject: more correct handling of parameter in forward declared procedures --- ecomp-c/ec.c | 47 ++++++++++++++++++++++++++++++++++++++------- ecomp-c/libc-freestanding.c | 2 +- ecomp-c/test1.e | 2 +- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index 7501ec5..0ff71bd 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -2187,7 +2187,7 @@ static void parseProcedureDeclaration( Scope *scope ) size_params = 0; } else if( sym == S_lparen ) { - Symbol *param, *copy; + Symbol *param, *copy, *defparam; int offset; parseParameterDeclarationList( symbol->scope ); @@ -2212,14 +2212,47 @@ static void parseProcedureDeclaration( Scope *scope ) param->name, param->offset, size ); offset -= size; } - - copy = copy_symbol( param ); - copy->scope = NULL; - copy->next = symbol->param; - symbol->param = copy; - param = param->next; } + + /* compare types in case of an already existing forward declaration */ + if( symbol->param != NULL ) { + param = symbol->scope->symbol; + defparam = symbol->param; + while( param != NULL || defparam != NULL ) { + if( param == NULL || defparam == NULL ) { + if( param == NULL ) { + Abort( "Prototype mismatch for procedure '%s', too few parameter in procedure declaration", symbol->name ); + } else { + Abort( "Prototype mismatch for procedure '%s', too few parameter in forward declaration", symbol->name ); + } + } + if( !is_compatible_type( defparam->type, param->type ) ) { + Abort( "Incompatible parameter type between forward declaration for parameter '%s' in procedure '%s', expecting type '%s', got '%s'", + param->name, symbol->name, defparam->type->name, param->type->name ); + } + defparam = defparam->next; + param = param->next; + } + free_symbol( symbol->param ); + symbol->param = NULL; + } + + /* remember types and names of parameters (keeping the variable names + * of the definition of the procedure and not the one of the forward + * declaration */ + if( symbol->param == NULL ) { + param = symbol->scope->symbol; + while( param != NULL ) { + if( param->class == SYMBOL_CLASS_VARIABLE ) { + copy = copy_symbol( param ); + copy->scope = NULL; + copy->next = symbol->param; + symbol->param = copy; + } + param = param->next; + } + } } /* procedure body */ diff --git a/ecomp-c/libc-freestanding.c b/ecomp-c/libc-freestanding.c index f37aa83..9090a27 100644 --- a/ecomp-c/libc-freestanding.c +++ b/ecomp-c/libc-freestanding.c @@ -391,7 +391,7 @@ static int read_string( int fd, char *buf, int size ) } enum { - INTERNAL_STDIO_BUFSIZE = 255 + INTERNAL_STDIO_BUFSIZE = 512 }; typedef struct { diff --git a/ecomp-c/test1.e b/ecomp-c/test1.e index 59ec90a..0dfad07 100644 --- a/ecomp-c/test1.e +++ b/ecomp-c/test1.e @@ -98,5 +98,5 @@ begin a1[3] := 42; s2[a1[2]] := 'Z'; A; - B; + B( 1, 2 ); end -- cgit v1.2.3-54-g00ecf