Hello, all
During the recent exercise in comp.lang.c in writing a C program to strip comments from a C source, I have encountered what seems to be a bug in TCC. It is manifest when compiling looser drug's entry with TCC and feeding it the following test input (between --- markers): --- a/\ \ \ \ /b --- which causes the program to hang infinitely. When complied with other compilers (e.g. GCC), however, it processes the file correctly and terminates. The source follows: #define DEBUG(...) #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef union uobject *object; typedef object list; typedef enum tag { INVALID, INTEGER, LIST } tag; union uobject { tag t; struct { tag t; int i, continues; } Int; struct { tag t; object a, b; } List; }; typedef struct record { int mark; struct record *prev; union uobject o; } record; list cons( object a, object b ); list skip_quote( object q, list o ); list nested_comment( list o ); void print( list o ); record *allocation_list; object global_roots; object add_global_root( object o ){ global_roots = cons( o, global_roots ); return o; } record *alloc(){ return calloc( 1, sizeof(record) ); } void mark( object ob ){ if( !ob ) return; record *r = ((void*)( (char*)ob - offsetof( record, o ) ) ); if( r->mark ) return; r->mark = 1; switch( ob ? ob->t : 0 ){ case LIST: mark( ob->List.a ); mark( ob->List.b ); break; } } int sweep( record **ptr ){ int count = 0; while( *ptr ){ if( (*ptr)->mark ){ (*ptr)->mark = 0; ptr = &(*ptr)->prev; } else { record *z = *ptr; *ptr = (*ptr)->prev; free( z ); ++count; } } return count; } int collect( object local_roots ){ mark( local_roots ); mark( global_roots ); return sweep( &allocation_list ); } #define OBJECT(...) new_( (union uobject[]){{ __VA_ARGS__ }} ) object new_( object a ){ record *r = alloc(); object p = NULL; if( r ){ r->prev = allocation_list; allocation_list = r; p = (void*)( ((char*)r) + offsetof( record, o ) ); *p = *a; } return p; } object Int( int i ){ return OBJECT( .Int = { INTEGER, i } ); } list cons( object a, object b ){ return OBJECT( .List = { LIST, a, b } ); } list one( object a ){ return cons( a, NULL ); } object car( list o ){ return o && o->t == LIST ? o->List.a : NULL; } object cdr( list o ){ return o && o->t == LIST ? o->List.b : NULL; } int eq( object a, object b ){ return !a && !b ? 1 : !a || !b ? 0 : a->t != b->t ? 0 : a->t == INTEGER ? a->Int.i == b->Int.i : !memcmp( a, b, sizeof *a ); } int eqint( object a, int i ){ union uobject b = { .Int = { INTEGER, i } }; return eq( a, &b ); } int match( object pat, object it, object *matched, object *tail ){ if( !pat ){ return *tail = it, 1; } if( pat->t != (it ? it->t : 0) ) return 0; switch( pat->t ){ case LIST: { object sink; if( match( car( pat ), car( it ), & sink, tail ) ){ return *matched = it, match( cdr( pat ), cdr( it ), & sink, tail ); } } break; case INTEGER: if( eq( pat, it ) ){ return *matched = it, 1; } } return 0; } list chars_from_file( FILE *f ){ int c = fgetc( f ); return c != EOF ? cons( Int( c ), chars_from_file( f ) ) : one( Int( c ) ); } list logical_lines( list o ){ static list pat; if( !pat ) pat = add_global_root( cons( Int( '\\' ), one( Int( '\n' ) ) ) ); object matched, tail; DEBUG( if( car(o)->Int.i!=EOF ) fprintf( stderr, "[%c%c]", car(o)->Int.i, car(cdr(o))->Int.i ); ) if( match( pat, o, &matched, &tail ) ){ DEBUG( fprintf( stderr, "@" ); ) car( tail )->Int.continues = car( o )->Int.continues + 1; return logical_lines( tail ); } else { object a = car( o ); return eqint( a, EOF ) ? o : cons( a, logical_lines( cdr( o ) ) ); } } list restore_continues( list o ){ if( !o ) return NULL; object a = car( o ); if( eqint( a, EOF ) ) return o; object z = cdr( o ); object r = cons( a, restore_continues( z ) ); while( a->Int.continues ){ r = cons( Int( '\\' ), cons( Int( '\n' ), r ) ); --a->Int.continues; } return r; } list strip_comments( list o ){ static list single, multi; if( !single ) single = add_global_root( cons( Int('/'), one(Int('/')) ) ); if( !multi ) multi = add_global_root( cons( Int('/'), one(Int('*')) ) ); object matched, tail; DEBUG( if(car(o)->Int.i!=EOF) fprintf(stderr,"<%c%c>", car(o)->Int.i, car(cdr(o))->Int.i); ) if( match( single, o, &matched, &tail ) ){ DEBUG( fprintf( stderr, "@" ); ) do { tail = cdr( tail ); matched = car( tail ); } while( !eqint( matched, '\n' ) ); return strip_comments( tail ); } else if( match( multi, o, &matched, &tail ) ){ DEBUG( fprintf( stderr, "@" ); ) return cons( Int( ' ' ), strip_comments( nested_comment( cdr( tail ) ) ) ); } object a = car( o ); if( eqint( a, '\'' ) || eqint( a, '"' ) ) return cons( a, skip_quote( a, cdr( o ) ) ); return eqint( a, EOF ) ? o : cons( a, strip_comments( cdr( o ) ) ); } list nested_comment( list o ){ DEBUG(fprintf( stderr, "(%c%c)", car( o )->Int.i, car( cdr( o ) )->Int.i );) static list end; if( !end ) end = add_global_root( cons( Int( '*' ), one( Int( '/' ) ) ) ); object matched, tail; if( match( end, o, &matched, &tail ) ) return tail; if( eqint( car( o ), EOF ) ) fprintf( stderr, "Unterminated comment\n"), exit( 1 ); return nested_comment( cdr( o ) ); } list skip_quote( object q, list o ){ object a = car( o ); if( eqint( a, '\\' ) ){ return cons( a, cons( car( cdr( o ) ), skip_quote( q, cdr( cdr( o ) ) ) ) ); } else if( eq( a, q ) ){ return cons( a, strip_comments( cdr( o ) ) ); } if( eqint( a, EOF ) ) fprintf( stderr, "Unterminated literal\n"), exit( 1 ); return cons( a, skip_quote( q, cdr( o ) ) ); } void print( list o ){ switch( o ? o->t : 0 ){ case INTEGER: if( o->Int.i != EOF ) fputc( o->Int.i, stdout ); break; case LIST: print( car( o ) ); print( cdr( o ) ); break; } } int main( int argc, char **argv ){ list input = chars_from_file( argc > 1 ? fopen( argv[1], "r" ) : stdin ); DEBUG( printf( "input:\n"); print( input ); ) list logical = logical_lines( input ); DEBUG( printf( "logical:\n"); print( logical ); ) list stripped = strip_comments( logical ); DEBUG( printf( "stripped:\n"); print( stripped ); ) list restored = restore_continues( stripped ); DEBUG( printf( "restored:\n"); ) print( restored ); DEBUG( printf( "@%d\n", collect( restored ) ); ) } _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
On 2020-12-13 14:40:17 +0300, Anton Shepelev wrote:
> Hello, all > > During the recent exercise in comp.lang.c in writing a C > program to strip comments from a C source, I have > encountered what seems to be a bug in TCC. It is manifest > when compiling looser drug's entry with TCC and feeding it > the following test input (between --- markers): > > --- > a/\ > \ > \ > \ > /b > --- > > which causes the program to hang infinitely. When complied > with other compilers (e.g. GCC), however, it processes the > file correctly and terminates. The source follows: No issue with tcc 0.9.27+git20200814.62c30a4a-1 provided by Debian. -- Vincent Lefèvre <[hidden email]> - Web: <https://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon) _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
Vincent Lefevre:
> No issue with tcc 0.9.27+git20200814.62c30a4a-1 provided > by Debian. The bug on my side is reproduced with this version just five days old: https://repo.or.cz/tinycc.git/snapshot/8ff705554de47f16726ec5f1a6c49a162b926732.zip I had to compile it myself on Windows, using win32\build-tcc.bat . Is there a pre-compiled win32 build available? I have also tried the same on a Linux. Since I had not enough permissions to install TCC, I only built it and tried the following from the root of the source directory: ./tcc -Iinclude -L. ld.c tcc failed with error: file '/usr/local/lib/tcc/libtcc1.a' not found The file libtcc1.a is right there in the working directory. Why did it ignore -L. ? _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
Since I had not enough permissions to install TCC Le 13/12/2020 à 21:35, Anton Shepelev a
écrit :
Since I had not enough permissions to install TCC _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
In reply to this post by Vincent Lefevre-10
I just recompiled you test program with mob. On Windows, cl, clang, gcc and ... tcc all produce the same output result.
Sorry, I can't reproduce. C. -----Original Message----- From: Tinycc-devel [mailto:tinycc-devel-bounces+eligis=[hidden email]] On Behalf Of Vincent Lefevre Sent: Sunday, December 13, 2020 14:17 To: [hidden email] Subject: Re: [Tinycc-devel] A possible bug in TCC On 2020-12-13 14:40:17 +0300, Anton Shepelev wrote: > Hello, all > > During the recent exercise in comp.lang.c in writing a C > program to strip comments from a C source, I have > encountered what seems to be a bug in TCC. It is manifest > when compiling looser drug's entry with TCC and feeding it > the following test input (between --- markers): > > --- > a/\ > \ > \ > \ > /b > --- > > which causes the program to hang infinitely. When complied > with other compilers (e.g. GCC), however, it processes the > file correctly and terminates. The source follows: No issue with tcc 0.9.27+git20200814.62c30a4a-1 provided by Debian. -- Vincent Lefèvre <[hidden email]> - Web: <https://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon) _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
In reply to this post by Ant_222
Hello,
On Sun, 13 Dec 2020, Anton Shepelev wrote: > Vincent Lefevre: > >> No issue with tcc 0.9.27+git20200814.62c30a4a-1 provided >> by Debian. > > The bug on my side is reproduced with this version just five > days old: > > https://repo.or.cz/tinycc.git/snapshot/8ff705554de47f16726ec5f1a6c49a162b926732.zip > > I had to compile it myself on Windows, using > win32\build-tcc.bat . Is there a pre-compiled win32 build > available? > > I have also tried the same on a Linux. Since I had not > enough permissions to install TCC, I only built it and tried > the following from the root of the source directory: > > ./tcc -Iinclude -L. ld.c For uninstalled tcc you need to use './tcc -B. ...' to set the compiler path to something else than the install directory. > tcc failed with error: > > file '/usr/local/lib/tcc/libtcc1.a' not found > > The file libtcc1.a is right there in the working directory. > Why did it ignore -L. ? A deficiency. libtcc1.a is searched in a different way than normal -lfoo libraries. FWIW, I also can't reproduce the problem you're seeing on linux x86-64, with various revisions of the mob branch. Ciao, Michael. _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
In reply to this post by Christian Jullien-3
Christian Jullien:
> I just recompiled you test program with mob. On Windows, > cl, clang, gcc and ... tcc all produce the same output > result. Sorry, I can't reproduce. I thank everybody for their help and answers and give up on this one. I will write it off as a hallucicatio of my PC. _______________________________________________ Tinycc-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/tinycc-devel |
Free forum by Nabble | Edit this page |