Trying to bootstrap gpc-20030507.tar.gz with GCC 3.3 (actually the gcc-3.3-hammer-branch but that shouldn't make a difference here) on an AMD64 system, the bootstrap fails with:
$ ../.././xgpc -B../.././ -c -g -I. -W -Wall -Wpointer-ar ith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -g -O2 --unit-path=/usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts --automake `cat needed-options` -DRTS_RELEASE_STRING="'`cat /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts/rts-version`'" -DGCC_VERSION="'3.3-hammer'" /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts/rtsc.pas -v -save-temps Reading specs from ../.././specs Configured with: /usr/src/aj/cvs/gcc-hammer-pascal/configure --prefix=/opt/gcc/3.3-pascal --disable-nls --enable-threads=posix --enable-clocale=gnu --enable-__cxa_atexit --enable-shared --enable-languages=c,c++,f77,objc,ada,treelang,java,f77,pascal --with-system-zlib x86_64-suse-linux-gnu Thread model: posix gpc version 20030507, based on gcc-3.3-hammer ../.././gpcpp -D__BITS_LITTLE_ENDIAN__=1 -D__BYTES_LITTLE_ENDIAN__=1 -D__WORDS_LITTLE_ENDIAN__=1 -D__NEED_NO_ALIGNMENT__=1 -quiet -v -I. -iprefix ../.././../lib/gcc-lib/x86_64-suse-linux-gnu/3.3-hammer/ -isystem ../.././include -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=0 -DRTS_RELEASE_STRING='20030507' -DGCC_VERSION='3.3-hammer' /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts/rtsc.pas -funit-path=/usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts -fautomake -famtmpfile=/tmp/cc6ax0Gt.gpa -W -Wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations rtsc.i GNU Pascal Compiler PreProcessor version 20030507, based on gcc-3.3-hammer (x86-64 Linux/ELF) {$include "..."} search starts here: {$include <...>} search starts here: . End of search list. ../.././gpc1 rtsc.i -quiet -dumpbase rtsc.pas -auxbase rtsc -g -g -O2 -W -Wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -version -funit-path=/usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts -fautomake -famtmpfile=/tmp/cc6ax0Gt.gpa -o rtsc.s GNU Pascal version is actually 20030507, based on gcc-3.3-hammer GNU Pascal version 3.3-hammer (x86_64-suse-linux-gnu) compiled by GNU C version 3.3-hammer. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 <implicit code>: In procedure `RunFinalizers': <implicit code>:14: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See URL:http://gcc.gnu.org/bugs.html for instructions.
Running gdb shows the following backtrace:
Starting program: /abuild/aj/builds/gcc/misc/gcc/gpc1 rtsc.i -quiet -dumpbase rtsc.pas -auxbase rtsc -g -g -O2 -W -Wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -version -funit-path=/usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts -o rtsc.s GNU Pascal version is actually 20030507, based on gcc-3.3-hammer GNU Pascal version 3.3-hammer (x86_64-suse-linux-gnu) compiled by GNU C version 3.3-hammer. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Program received signal SIGSEGV, Segmentation fault. 0x0000002a956db314 in free () from /lib64/libc.so.6 (gdb) bt #0 0x0000002a956db314 in free () from /lib64/libc.so.6 #1 0x00000000004025e9 in poplevel (keep=0, reverse=0, routinebody=0) at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/declarations.c:407 #2 0x0000000000427b99 in main_yyparse () at parse.y:2838 #3 0x0000000000494bf2 in compile_file () at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/toplev.c:2185 #4 0x00000000004999fb in do_compile () at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/toplev.c:5558 #5 0x0000000000499a6a in toplev_main (argc=-1789304384, argv=0x0) at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/toplev.c:5588 #6 0x0000002a9568d017 in __libc_start_main () from /lib64/libc.so.6 #7 0x000000000040221a in _start () (gdb) up #1 0x00000000004025e9 in poplevel (keep=0, reverse=0, routinebody=0) at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/declarations.c:407 407 free (level); (gdb) b poplevel Breakpoint 2 at 0x4024a0: file /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/declarations.c, line 316. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Keeping /abuild/aj/builds/gcc/misc/gcc/gpc1... Removing /lib64/libc.so.6... Removing /lib64/ld-linux-x86-64.so.2...
Starting program: /abuild/aj/builds/gcc/misc/gcc/gpc1 rtsc.i -quiet -dumpbase rtsc.pas -auxbase rtsc -g -g -O2 -W -Wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -version -funit-path=/usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/rts -o rtsc.s GNU Pascal version is actually 20030507, based on gcc-3.3-hammer GNU Pascal version 3.3-hammer (x86_64-suse-linux-gnu) compiled by GNU C version 3.3-hammer. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Breakpoint 2, poplevel (keep=-1073747992, reverse=778, routinebody=482) at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/declarations.c:316 316 { (gdb) n 320 check_forward_decls (1); (gdb) 316 { (gdb) 319 struct binding_level *level = current_binding_level; (gdb) 320 check_forward_decls (1); (gdb) p level $2 = (struct binding_level *) 0x2a955961c0 (gdb) n 321 current_binding_level = current_binding_level->level_chain; (gdb) 326 if (reverse) (gdb) 325 decls = level->names; (gdb) 321 current_binding_level = current_binding_level->level_chain; (gdb) 326 if (reverse) (gdb) 327 decls = nreverse (decls); (gdb) 330 for (t = decls; t; t = TREE_CHAIN (t)) (gdb) 367 restore_identifiers (level->shadowed); (gdb) 371 if (level->this_block) (gdb) 376 block = NULL_TREE; (gdb) 377 if (block) (gdb) 389 for (t = level->blocks; t; t = TREE_CHAIN (t)) (gdb) 392 if (routinebody) (gdb) bt #0 poplevel (keep=0, reverse=0, routinebody=0) at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/p/declarations.c:392 #1 0x0000000000427b99 in main_yyparse () at parse.y:2838 #2 0x0000000000494bf2 in compile_file () at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/toplev.c:2185 #3 0x00000000004999fb in do_compile () at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/toplev.c:5558 #4 0x0000000000499a6a in toplev_main (argc=-1789304384, argv=0x0) at /usr/src/aj/cvs/gcc-hammer-pascal/gcc/toplev.c:5588 #5 0x0000002a9568d017 in __libc_start_main () from /lib64/libc.so.6 #6 0x000000000040221a in _start () (gdb) n 394 else if (block) (gdb) 402 else if (level->blocks) (gdb) 404 if (block) (gdb) 407 free (level);
the problem is here that the address of level is wrong, it seems to be in the address space of the dynamic linker.
Any ideas or fixes for this problem?
Andreas
Andreas Jaeger wrote:
Trying to bootstrap gpc-20030507.tar.gz with GCC 3.3 (actually the gcc-3.3-hammer-branch but that shouldn't make a difference here) on an AMD64 system, the bootstrap fails with:
[...]
407 free (level);
the problem is here that the address of level is wrong, it seems to be in the address space of the dynamic linker.
Any ideas or fixes for this problem?
The port to gcc-3.3 is still under development. This `free' statement must be removed with gcc-3.3. However, there may be more problems. (The level should have been ggc_alloc'ed, so its address should be within the memory administered by GGC, and not invalid.)
So, you might want to try removing the statement, but I'm not sure if it will work yet. If gcc-3.2 supports this platform, I recommend to try this for now.
Frank
Frank Heckenbach frank@g-n-u.de writes:
[..]
I'll try your suggestion.
So, you might want to try removing the statement, but I'm not sure if it will work yet. If gcc-3.2 supports this platform, I recommend to try this for now.
GCC 3.2 is available but I need GCC 3.3 for other purposes and will not go back to 3.2,
Andreas
Andreas Jaeger wrote:
Frank Heckenbach frank@g-n-u.de writes:
[..]
I'll try your suggestion.
So, you might want to try removing the statement, but I'm not sure if it will work yet. If gcc-3.2 supports this platform, I recommend to try this for now.
GCC 3.2 is available but I need GCC 3.3 for other purposes and will not go back to 3.2,
You can build GPC with a different GCC version than what you use as the C (or other languages) compiler. Other than that, I can only wish you good luck.
Frank
Frank Heckenbach frank@g-n-u.de writes:
Andreas Jaeger wrote:
Frank Heckenbach frank@g-n-u.de writes:
[..]
I'll try your suggestion.
So, you might want to try removing the statement, but I'm not sure if it will work yet. If gcc-3.2 supports this platform, I recommend to try this for now.
GCC 3.2 is available but I need GCC 3.3 for other purposes and will not go back to 3.2,
You can build GPC with a different GCC version than what you use as
I'd like to have an integrated compiler.
the C (or other languages) compiler. Other than that, I can only wish you good luck.
Doesn't work unfortunatly. Ok, I'll wait some time and retry again.
Andreas
Andreas Jaeger wrote:
I'd like to have an integrated compiler.
the C (or other languages) compiler. Other than that, I can only wish you good luck.
Doesn't work unfortunatly. Ok, I'll wait some time and retry again.
There are three known problem with gcc-3.3+gpc-20030507:
-- spurious `free'. The first patch (hunk) below fixes it -- problem with generating Dwarf-2 debug info. It not clear what the good solution is but the second patch is a workaround. Alternatively you may pass `PFLAGS=-gstubs+' to make build the runtime with stubs debug info (may be a good idea anyway, as gdb has serious troubles with Dwarf-2 debug info, in fact without patches gdb abort on Dwarf-2 info from Pascal). -- problem building `gpidump' utility. The third patch fixes it
If there are another problems let us know
One more thing that does not seems to work are profile driven optimizations. Are you supporting -profile-arcs and -fbranch-probabilities?
Andreas
Andreas Jaeger wrote:
One more thing that does not seems to work are profile driven optimizations. Are you supporting -profile-arcs and -fbranch-probabilities?
We don't do anything special about them. Is this required, i.e., aren't they handled by the backend?
Frank
Frank Heckenbach Frank@G-N-U.De Writes:
Andreas Jaeger Wrote:
One More Thing That Does Not Seems To Work Are Profile Driven Optimizations. Are You Supporting -Profile-Arcs And -Fbranch-Probabilities?
We Don't Do Anything Special About Them. Is This Required, I.E., Aren't They Handled By The Backend?
Honza, can you explain what needs to be done?
AFAIK you do not initialize some fields correctly but Honza knows more...
Andreas
Frank Heckenbach Frank@G-N-U.De Writes:
Andreas Jaeger Wrote:
One More Thing That Does Not Seems To Work Are Profile Driven Optimizations. Are You Supporting -Profile-Arcs And -Fbranch-Probabilities?
We Don't Do Anything Special About Them. Is This Required, I.E., Aren't They Handled By The Backend?
Honza, can you explain what needs to be done?
AFAIK you do not initialize some fields correctly but Honza knows more...
Andreas
I just noticed that hammer backend can not pass Pascal sets as arguments to functions (procedures). The problem should be easy to solve, but first somebody must decide how sets should be treated on hammer. Currently frontend treats sets as a sequence of longs, that should work, but on hammer SSE2 instructions would double efficiency for moderate and large sets. So the question is if we should just teach backend about our current strategy or should we try something more fancy?
Before that is resolved the hammer port can not really work.
Waldek Hebisch wrote:
I just noticed that hammer backend can not pass Pascal sets as arguments to functions (procedures). The problem should be easy to solve, but first somebody must decide how sets should be treated on hammer. Currently frontend treats sets as a sequence of longs, that should work, but on hammer SSE2 instructions would double efficiency for moderate and large sets. So the question is if we should just teach backend about our current strategy or should we try something more fancy?
If someone wants to optimize things using these special instructions, that can always be done (though it might be quite some work, since probably all of the routines in rts/sets.pas and the corresponding compiler support will have to be rewritten).
However, as you say, the current mechanism treats them as arrays of unsigned long (in C terms), so it should also work. (There's not so much special about it.) I don't know how it fails, but it might be a more general problem.
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
I just noticed that hammer backend can not pass Pascal sets as arguments to functions (procedures). The problem should be easy to solve, but first somebody must decide how sets should be treated on hammer. Currently frontend treats sets as a sequence of longs, that should work, but on hammer SSE2 instructions would double efficiency for moderate and large sets. So the question is if we should just teach backend about our current strategy or should we try something more fancy?
If someone wants to optimize things using these special instructions, that can always be done (though it might be quite some work, since probably all of the routines in rts/sets.pas and the corresponding compiler support will have to be rewritten).
However, as you say, the current mechanism treats them as arrays of unsigned long (in C terms), so it should also work. (There's not so much special about it.) I don't know how it fails, but it might be a more general problem.
My point was that we must make an API decision. Easy one is to stick to current scheme. Hard one is to try to use SSE2. SSE2 requires 128 bit alignment and means that when passing set to functions they should go in SSE register.
I infer that Frank prefers easy way but I think that we need broader consensus there, especially since the backend code will affect other frontends (Modula2 and (defunct) Chill at least).
If we choose the easy way the following patch may work (there is a question if 128 bit set should go in a register pair, since Pascal runtime wants such set in memory anyway I choose memory):
--- gcc-3.3.orig/gcc/config/i386/i386.c Thu Apr 3 00:01:58 2003 +++ gcc-3.3/gcc/config/i386/i386.c Thu Jun 12 20:30:48 2003 @@ -1853,6 +1853,18 @@ } } } + else if (TREE_CODE (type) == SET_TYPE) + { + if (mode == DImode) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (mode == BLKmode) + return 0; + else + abort(); + } else abort ();
Waldek Hebisch wrote:
My point was that we must make an API decision. Easy one is to stick to current scheme. Hard one is to try to use SSE2. SSE2 requires 128 bit alignment and means that when passing set to functions they should go in SSE register.
I infer that Frank prefers easy way
Unless someone volunteers to implement the hard one. (I won't stop them, but I won't write it myself.)
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
My point was that we must make an API decision. Easy one is to stick to current scheme. Hard one is to try to use SSE2. SSE2 requires 128 bit alignment and means that when passing set to functions they should go in SSE register.
I infer that Frank prefers easy way
Unless someone volunteers to implement the hard one. (I won't stop them, but I won't write it myself.)
Jan Hubicka pointed out that membership testing is more expensive with SSE2, which means that hard way may in fact be slower. So I am too for easy way.
Waldek Hebisch wrote:
Unless someone volunteers to implement the hard one. (I won't stop them, but I won't write it myself.)
Jan Hubicka pointed out that membership testing is more expensive with SSE2, which means that hard way may in fact be slower. So I am too for easy way.
Though for set constructors, GPC optimizes membership tests and does not use sets internally at all (e.g. `x in [a .. b, c]' is turned to `((x >= a) and (x <= b)) or (x = c)' (taking care of side-effects in x). But this doesn't cover all uses of sets, and if it's not clear that it's a gain, it's probably not worth it.
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
I just noticed that hammer backend can not pass Pascal sets as arguments to functions (procedures). The problem should be easy to solve, but first somebody must decide how sets should be treated on hammer. Currently frontend treats sets as a sequence of longs, that should work, but on hammer SSE2 instructions would double efficiency for moderate and large sets. So the question is if we should just teach backend about our current strategy or should we try something more fancy?
If someone wants to optimize things using these special instructions, that can always be done (though it might be quite some work, since probably all of the routines in rts/sets.pas and the corresponding compiler support will have to be rewritten).
However, as you say, the current mechanism treats them as arrays of unsigned long (in C terms), so it should also work. (There's not so much special about it.) I don't know how it fails, but it might be a more general problem.
My point was that we must make an API decision. Easy one is to stick to current scheme. Hard one is to try to use SSE2. SSE2 requires 128 bit alignment and means that when passing set to functions they should go in SSE register.
I was thinking a bit about it and I am not sure whether using SSE registers is a win here. From my (limited) experience with Pascal programming the sets used are often very small and used for conditionals. SSE is very poor when used to test specific bits, so perhaps integer is better.
--- gcc-3.3.orig/gcc/config/i386/i386.c Thu Apr 3 00:01:58 2003 +++ gcc-3.3/gcc/config/i386/i386.c Thu Jun 12 20:30:48 2003 @@ -1853,6 +1853,18 @@ } } }
else if (TREE_CODE (type) == SET_TYPE)
{
if (mode == DImode)
{
classes[0] = X86_64_INTEGER_CLASS;
return 1;
}
else if (mode == BLKmode)
return 0;
else
abort();
}
What happens for very small sets - will these get QImode or so?
Honza
else abort ();
-- Waldek Hebisch hebisch@math.uni.wroc.pl or hebisch@hera.math.uni.wroc.pl
I was thinking a bit about it and I am not sure whether using SSE registers is a win here. From my (limited) experience with Pascal programming the sets used are often very small and used for conditionals. SSE is very poor when used to test specific bits, so perhaps integer is better.
Agreed
--- gcc-3.3.orig/gcc/config/i386/i386.c Thu Apr 3 00:01:58 2003 +++ gcc-3.3/gcc/config/i386/i386.c Thu Jun 12 20:30:48 2003 @@ -1853,6 +1853,18 @@ } } }
else if (TREE_CODE (type) == SET_TYPE)
{
if (mode == DImode)
{
classes[0] = X86_64_INTEGER_CLASS;
return 1;
}
else if (mode == BLKmode)
return 0;
else
abort();
}
What happens for very small sets - will these get QImode or so?
Pascal forces sets to go in multiples of C longs (even the smallest ones) so the mode is always the same as the mode for long (or BLKmode). Pascal patches the backend (stor-layout.c) to get this. More precisely `stor-layout.c' contains the following (at line 1813):
if (rounded_size > (int) alignment) TYPE_MODE (type) = BLKmode; else TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
Pascal makes alignment equal to size of long. By default alignment is BITS_PER_WORD. I do not know what other front ends are doing, but safe way is to expect any integer mode.
Waldek Hebisch hebisch@math.uni.wroc.pl writes:
I just noticed that hammer backend can not pass Pascal sets as arguments to functions (procedures). The problem should be easy to solve, but first somebody must decide how sets should be treated on hammer. Currently frontend treats sets as a sequence of longs, that should work, but on hammer SSE2 instructions would double efficiency for moderate and large sets. So the question is if we should just teach backend about our current strategy or should we try something more fancy?
Please include jh@suse.cz in this discussion, he might give you details since he designated the backend.
Before that is resolved the hammer port can not really work.
Ok, so there's no chance for now. Thanks for the update,
Andreas
Waldek Hebisch hebisch@math.uni.wroc.pl writes:
Andreas Jaeger wrote:
I'd like to have an integrated compiler.
the C (or other languages) compiler. Other than that, I can only wish you good luck.
Doesn't work unfortunatly. Ok, I'll wait some time and retry again.
There are three known problem with gcc-3.3+gpc-20030507:
-- spurious `free'. The first patch (hunk) below fixes it
-- problem with generating Dwarf-2 debug info. It not clear what the good solution is but the second patch is a workaround. Alternatively you may pass `PFLAGS=-gstubs+' to make build the runtime with stubs debug info (may be a good idea anyway, as gdb has serious troubles with Dwarf-2 debug info, in fact without patches gdb abort on Dwarf-2 info from Pascal).
Thanks, I wasn't aware of this one. Note that I really need dwarf2 since stubs are not 64-bit clean and cannot be used on x86-64 (AMD64).
-- problem building `gpidump' utility. The third patch fixes it
If there are another problems let us know
OK, will retry later with the dwarf2 patch,
Andreas
Some further experiments:
On i686-linux-gnu I get problems running the testsuite:
echo "/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/xgpc -B/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/ -g -O3 -W -Wall -Wundef -Wpointer-arith -Wno-unused " /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/xgpc -B/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/ -g -O3 -W -Wall -Wundef -Wpointer-arith -Wno-unused PC="/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/xgpc -B/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/" PFLAGS="--autobuild -g -O3 -W -Wall -Wundef -Wpointer-arith -Wno-unused -I ../rts --unit-path=/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/p/units " SRCDIR="/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/test" TEST_MAKE_FLAG=test-make-flag "/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/test/test_run" | tee test_log | "/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/test/test_sum" | tee test_summary gawk: cmd. line:44: (FILENAME=- FNR=20) fatal: grow_iop_buffer: iop->buf: can't allocate -2147483646 bytes of memory (Cannot allocate memory)
This could be a bug in gawk or in the gpc gawk script.
On x86_64-linux-gnu I see this problem now:
../.././xgpc -B../.././ -c -I. -W -Wall -Wpointer-arith -Wwrite-strings -Wmissi ng-prototypes -Wmissing-declarations -g -O2 --unit-path=/usr/src/packages/BUIL D/gcc-3.3-hammer-20030605/gcc/p/rts --automake `cat needed-options` -DRTS_RELEAS E_STRING="'`cat /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/rts-ve rsion`'" -DGCC_VERSION="'3.3'" /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/g cc/p/rts/time.pas /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/file.c: In function `_ p_Read_Word': /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/file.c:2293: warning: dereferencing type-punned pointer will break strict-aliasing rules /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/string2.pas:38: warning: duplicate implementation flag in GPI file `error.gpi' /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/string2.pas:38: error: cannot recompile module make[3]: *** [string2.o] Error 1
Andreas
Andreas Jaeger wrote:
On i686-linux-gnu I get problems running the testsuite:
echo "/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/xgpc -B/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/ -g -O3 -W -Wall -Wundef -Wpointer-arith -Wno-unused " /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/xgpc -B/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/ -g -O3 -W -Wall -Wundef -Wpointer-arith -Wno-unused PC="/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/xgpc -B/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/" PFLAGS="--autobuild -g -O3 -W -Wall -Wundef -Wpointer-arith -Wno-unused -I ../rts --unit-path=/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/obj-i586-suse-linux/gcc/p/units " SRCDIR="/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/test" TEST_MAKE_FLAG=test-make-flag "/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/test/test_run" | tee test_log | "/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/test/test_sum" | tee test_summary gawk: cmd. line:44: (FILENAME=- FNR=20) fatal: grow_iop_buffer: iop->buf: can't allocate -2147483646 bytes of memory (Cannot allocate memory)
This could be a bug in gawk or in the gpc gawk script.
I don't know how even a buggy gawk script should cause such an array (after all, awk script don't deal with memory allocation themselves). So I suppose it is a bug in gawk (at least one that causes a possible bug in the script to displayed in a strange way ...).
You can `make pascal.check-long' to avoid using this script (at the cost of more verbose output) ...
/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/file.c: In function `_ p_Read_Word': /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/file.c:2293: warning: dereferencing type-punned pointer will break strict-aliasing rules
--- orig/rts/file.c Sat Apr 12 04:33:08 2003 +++ p/rts/file.c Mon May 19 02:10:56 2003 @@ -2290,7 +2290,7 @@ static char *_p_Read_Word (FDR f) { buf[length++] = ch; if (length >= size) - _p_ReAllocMem ((void **) &buf, size *= 2); + _p_ReAllocMem ((void *) &buf, size *= 2); ch = _p_DirectGetC (f); } while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_');
/usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/string2.pas:38: warning: duplicate implementation flag in GPI file `error.gpi' /usr/src/packages/BUILD/gcc-3.3-hammer-20030605/gcc/p/rts/string2.pas:38: error: cannot recompile module
I don't understand this one. Did you resume building after it failed in rts? In this case, maybe something got messed up. Try removing *.o *.gpi in rts and build again.
Frank
In Metrowerks Pascal, there is a compiler "variable" that has the name of the source file (SrcFile, String) and the current line number (SrcLine, Integer), which can be quite useful for debugging.
Is there an equivalent in GPC?
Thanks, Peter.
On Tue, Jun 24, 2003 at 07:52:44PM +0800, Peter N Lewis wrote:
In Metrowerks Pascal, there is a compiler "variable" that has the name of the source file (SrcFile, String) and the current line number (SrcLine, Integer), which can be quite useful for debugging.
Is there an equivalent in GPC?
GPC preprocessor provides magic "macros" __FILE__ and __LINE__.
Emil
Thanks, Peter.
-- http://www.interarchy.com/ http://documentation.interarchy.com/
At 2:14 PM +0200 24/6/03, Emil Jerabek wrote:
On Tue, Jun 24, 2003 at 07:52:44PM +0800, Peter N Lewis wrote:
In Metrowerks Pascal, there is a compiler "variable" that has the name of the source file (SrcFile, String) and the current line number (SrcLine, Integer), which can be quite useful for debugging.
Is there an equivalent in GPC?
GPC preprocessor provides magic "macros" __FILE__ and __LINE__.
And also __func__ ? (As in C99...) These are the three I use to build my C99 assert() function and some other tracing stuff.
Grant
Grant Jacobs wrote:
At 2:14 PM +0200 24/6/03, Emil Jerabek wrote:
On Tue, Jun 24, 2003 at 07:52:44PM +0800, Peter N Lewis wrote:
In Metrowerks Pascal, there is a compiler "variable" that has the name of the source file (SrcFile, String) and the current line number (SrcLine, Integer), which can be quite useful for debugging.
Is there an equivalent in GPC?
GPC preprocessor provides magic "macros" __FILE__ and __LINE__.
And also __func__ ? (As in C99...)
`CurrentRoutineName' (which is no macro, but a magic "function" yielding a string constant(!); this is because it's handled by the compiler, not the preprocessor, but for most purposes, it should appear mostly the same as a macro).
These are the three I use to build my C99 assert() function and some other tracing stuff.
It's not really necessary. GPC has a built-in `Assert' procedure which in case of failure gives a regular runtime error. Runtime errors contain the code position which can be converted to a source position using `addr2line'. Using the runtime option `--gpc-rts=-E' or `--gpc-rts=-F', you can also get a call trace in case of runtime error. The script `gpc-run' automatizes this.
Frank
These are the three I use to build my C99 assert() function and some other tracing stuff.
It's not really necessary. GPC has a built-in `Assert' procedure which in case of failure gives a regular runtime error.
Yes, but my reading of this was that it could not be compiled out (turned off, but not compiled out), which is insufficient - it does not properly encourage asserting *everything* which (IMO, as well as Steve Maguire's, see Writing Solid Code which is a very good book (despite coming from Microsoft)). As much as possible I assert every precondition on entry and every post condition on exit to procedures, as well as asserting the validity of data structures and such. All this code is far too time consuming to leave in a shipping version.
I understand why the Assert's in GPC are done that way, but it does not work for me in the way I use assertions.
Enjoy, Peter.
At 12:59 PM +0800 25/6/03, Peter N Lewis wrote:
These are the three I use to build my C99 assert() function and some other tracing stuff.
It's not really necessary. GPC has a built-in `Assert' procedure which in case of failure gives a regular runtime error.
Yes, but my reading of this was that it could not be compiled out (turned off, but not compiled out), which is insufficient - it does not properly encourage asserting *everything* which (IMO, as well as Steve Maguire's, see Writing Solid Code which is a very good book (despite coming from Microsoft)). As much as possible I assert every precondition on entry and every post condition on exit to procedures, as well as asserting the validity of data structures and such. All this code is far too time consuming to leave in a shipping version.
Caveat: I haven't used assert in GPC - too busy on the day job... - so maybe I'm barking up the wrong tree...
I agree being able to strip out assert code makes them much more powerful.
In my C code I (try to!) do precisely what you do, using my own onEntry, onExit and assert macros. These macros can strip the code out later, so as you're saying you're encouraged to use them to the nth degree. All of this ties in with traces for automated testing, etc. Nice to see another fan of this sort of thing :-)
I understand why the Assert's in GPC are done that way, but it does not work for me in the way I use assertions.
Enjoy, Peter.
Peter N Lewis wrote:
These are the three I use to build my C99 assert() function and some other tracing stuff.
It's not really necessary. GPC has a built-in `Assert' procedure which in case of failure gives a regular runtime error.
Yes, but my reading of this was that it could not be compiled out (turned off, but not compiled out), which is insufficient - it does not properly encourage asserting *everything* which (IMO, as well as Steve Maguire's, see Writing Solid Code which is a very good book (despite coming from Microsoft)). As much as possible I assert every precondition on entry and every post condition on exit to procedures, as well as asserting the validity of data structures and such. All this code is far too time consuming to leave in a shipping version.
I understand why the Assert's in GPC are done that way, but it does not work for me in the way I use assertions.
I agree that it's useful to assert quite much (though I'm often too lazy to do so myself ...).
But I don't really understand the difference you make between turned off and compiled out. If assertions are turned off, no code is generated for them, unless they have side-effects, i.e. cases such as:
{ Returns True on success, False on failure. } function Foo (a: Integer): Boolean; [...]
Assert (Foo (42));
With assertions turned off, this is equivalent to:
Dummy := Foo (42);
(where Dummy is an otherwise unused Boolean variable).
This behaviour may be debatable. I think it would be more risky to discard side-effects as well (especially if most testing is done with assertions turned on).
But I'm not sure if that's actually what you're referring to.
Frank
But I don't really understand the difference you make between turned off and compiled out. If assertions are turned off, no code is generated for them, unless they have side-effects, i.e. cases such as:
{ Returns True on success, False on failure. } function Foo (a: Integer): Boolean; [...]
Assert (Foo (42));
With assertions turned off, this is equivalent to:
Dummy := Foo (42);
(where Dummy is an otherwise unused Boolean variable).
That's the point. My assertions tend to be things like:
Assert( ValidDataStructure( x ) );
ValidDataStructure might be a very expensive call, it might parse through the entire data structure looking for holes in it.
This behaviour may be debatable. I think it would be more risky to discard side-effects as well (especially if most testing is done with assertions turned on).
But I'm not sure if that's actually what you're referring to.
Absolutely, it is definitely a case of tradeoffs. You have to be disciplined about your use of Asserts to ensure you never use any code in them that is required to be executed. It's all too easy to write things like:
Assert( OpenFile( f, name ) = noErr );
As I said, I fully understand why they are done the way they are done. However for me, the tradeoff with that is that it restricts the cases I would be willing to use Assert for. No one would want to write code like:
procedure AppendToList( var list: ListType; item: ItemType ); begin Assert( ValidList( list ) ); ...
if they new that in the production code their O(1) AppendToList function would actually be O(n) or worse.
It's a trade off of safety (in executing potentially side effect riddled code) with safety (in writing reliable well tested programs).
GPC also makes this more challenging because you can't define a macro in any given unit for asserting the validity of data structures because that macro is not propagated into the using units. For example, in the interface my hypothetical Lists unit above, I would add something like:
{$ifc not do_debug} {$definec AssertValidList( list )} {$elsec} {$definec AssertValidList( list ) AssertValidListCode( list, SrcFile, SrcLine )} {$endc}
{$ifc do_debug} procedure AssertValidListCode( list: ListType; source: String; line: Integer ); {$endc}
but that does not work in GPC. My solution has been to use a prefix file and copy all such macro definitions to the prefix file. This is less than ideal since it breaks the modularity. Perhaps someone has a better solution for me, but it's the best I can come up with so far.
BTW, I really really strongly recommend that all programs go and read Writing Solid Code.
Enjoy, Peter.
Peter N Lewis wrote:
That's the point. My assertions tend to be things like:
Assert( ValidDataStructure( x ) );
ValidDataStructure might be a very expensive call, it might parse through the entire data structure looking for holes in it.
[...]
GPC also makes this more challenging because you can't define a macro in any given unit for asserting the validity of data structures because that macro is not propagated into the using units. For example, in the interface my hypothetical Lists unit above, I would add something like:
{$ifc not do_debug} {$definec AssertValidList( list )} {$elsec} {$definec AssertValidList( list ) AssertValidListCode( list, SrcFile, SrcLine )} {$endc}
{$ifc do_debug} procedure AssertValidListCode( list: ListType; source: String; line: Integer ); {$endc}
but that does not work in GPC. My solution has been to use a prefix file and copy all such macro definitions to the prefix file. This is less than ideal since it breaks the modularity. Perhaps someone has a better solution for me, but it's the best I can come up with so far.
GCC/GPC supports the `const' attribute for functions which means:
: `const' : Many functions do not examine any values except their arguments, : and have no effects except the return value. Basically this is : just slightly more strict class than the `pure' attribute above, : since function is not allowed to read global memory. : : Note that a function that has pointer arguments [or reference parameters in Pascal] : and examines the data pointed to must _not_ be declared : `const'. Likewise, a function that calls a non-`const' : function usually must not be `const'. It does not make sense : for a `const' function to return `void'.
The important thing here is that it tells the compiler that the function has no side effects so `Assert' can safely remove the call.
In case the actual checking function does not fit the `const' description (which will often be the case, I suppose), you can use a conditional as above.
This one does not produce any code for the `Assert':
{$define do_debug False}
unit U;
interface
type ListType = ^TListType; TListType = record Next: ListType; a: Integer; end;
function IsValidList (List: ListType): Boolean; {$ifc not do_debug} attribute (const); {$endc}
implementation
function IsValidList (List: ListType): Boolean; begin {$ifc not do_debug} IsValidList := True {$elsec} { actual checks ... } IsValidList := List <> nil {$endc} end;
end.
{$no-assert}
program Foo;
uses U;
var a: ListType;
begin Assert (IsValidList (a)) end.
Frank
At 10:38 AM +0800 26/6/03, Peter N Lewis wrote:but that does not work in GPC. My solution has been to use a prefix file and copy all such macro definitions to the prefix file. This is less than ideal since it breaks the modularity. Perhaps someone has a better solution for me, but it's the best I can come up with so far.
Forgive me for a rambling a few thoughts on this.
I haven't time to test this, but how does it go if a procedure does no productive activity - does the compiler strip the procedure and its calls out? (i.e. detecting an empty procedure body.) Have a constant, something like:
const doAsserts = false ;
and somewhere in the code calling your own assert defined like:
procedure assert( ... ) begin if doAsserts then begin end end
Would the compiler recognise that the above procedure is useless (when doAsserts = true) and strip out the calls to new assert() procedure ?
(Of course you could also pass the state as a variable and we can all argue about use of globals, etc. In this case the compiler needs to recognise that the variable in fact has a constant value, etc.)
On the same lines you could have your assert() as a function yielding a constant value (false), which the compiler can strip out if it sees:
dummyVar = assert( something ) ;
Like Peter some of my asserts call very expensive functions, so stripping them out in production code is essential.
A possible compromise might be to have GPC continue as-is, but for Peter to put the if's into his testing routines, the ones called by GPCs' assert, e.g.:
Assert( ValidDataStructure( thingy ) );
with assertions off becomes:
DummyVar := ValidDataStructure( thingy ) ;
but ValidDataStructure() contains an 'if' on a constant, which causes the procedure body to be empty, which the compiler then strips... (or doesn't if it can't do this).
This won't cater for everything (for example an assertion on an expression), but it might be OK for the more expensive things since they are likely to be function calls anyway - ?
Just while I'm writing: over-and-above the usual '#if debug' type of thing, my C debugging/assert/etc. routines pass variables that have four-states for this and other forms of testing (always, never, onTrue and onFalse). Usually these are effectively and'ed with another variable, e.g. the result of the assert or a global control variable such as doAsserts. This way the caller has control over individual asserts.
Grant
Grant Jacobs wrote:
Forgive me for a rambling a few thoughts on this.
I haven't time to test this, but how does it go if a procedure does no productive activity - does the compiler strip the procedure and its calls out? (i.e. detecting an empty procedure body.) Have a constant, something like:
const doAsserts = false ;
and somewhere in the code calling your own assert defined like:
procedure assert( ... ) begin if doAsserts then begin end end
Would the compiler recognise that the above procedure is useless (when doAsserts = true) and strip out the calls to new assert() procedure ?
AFAIK, only when inlining (as the special case of inling "nothing").
Inlining doesn't work across units/modules (yet), so I guess it's not too useful for Peter.
Currently, the importer of a unit/module only sees its interface, so it can't know that the body is empty. (The `const' attribute I mentioned in my previous mail is basically a way to specify this fact, or something similar, in the interface.)
Frank
Peter N Lewis wrote:
But I don't really understand the difference you make between turned off and compiled out. If assertions are turned off, no code is generated for them, unless they have side-effects, i.e. cases such as:
{ Returns True on success, False on failure. } function Foo (a: Integer): Boolean; [...]
Assert (Foo (42));
With assertions turned off, this is equivalent to:
Dummy := Foo (42);
(where Dummy is an otherwise unused Boolean variable).
That's the point. My assertions tend to be things like:
Assert( ValidDataStructure( x ) );
ValidDataStructure might be a very expensive call, it might parse through the entire data structure looking for holes in it.
This behaviour may be debatable. I think it would be more risky to discard side-effects as well (especially if most testing is done with assertions turned on).
But I'm not sure if that's actually what you're referring to.
Absolutely, it is definitely a case of tradeoffs. You have to be disciplined about your use of Asserts to ensure you never use any code in them that is required to be executed. It's all too easy to write things like:
Assert( OpenFile( f, name ) = noErr );
As I said, I fully understand why they are done the way they are done. However for me, the tradeoff with that is that it restricts the cases I would be willing to use Assert for. No one would want to write code like:
procedure AppendToList( var list: ListType; item: ItemType ); begin Assert( ValidList( list ) ); ...
if they new that in the production code their O(1) AppendToList function would actually be O(n) or worse.
It's a trade off of safety (in executing potentially side effect riddled code) with safety (in writing reliable well tested programs).
GPC also makes this more challenging because you can't define a macro in any given unit for asserting the validity of data structures because that macro is not propagated into the using units. For example, in the interface my hypothetical Lists unit above, I would add something like:
{$ifc not do_debug} {$definec AssertValidList( list )} {$elsec} {$definec AssertValidList( list ) AssertValidListCode( list, SrcFile, SrcLine )} {$endc}
{$ifc do_debug} procedure AssertValidListCode( list: ListType; source: String; line: Integer ); {$endc}
but that does not work in GPC. My solution has been to use a prefix file and copy all such macro definitions to the prefix file. This is less than ideal since it breaks the modularity. Perhaps someone has a better solution for me, but it's the best I can come up with so far.
Although it wouldn't be backward compatible with CW Pascal, you might want to look into using GPC's support for Extended Pascal's module multiple interface exports and export renaming. For example:
module MyLists;
export MyLists = (AppendToList); MyListsDebug = (AppendToListDebug => AppendToList); {insert const and type declarations needed for interface declarations} procedure AppendToList( var list: ListType; item: ItemType ); procedure AppendToListDebug( var list: ListType; item: ItemType ); end; {module heading}
function ValidList( protected var list: ListType): boolean; {insert list validation implementation code block}
procedure AppendToList( var list: ListType; item: ItemType ); {insert procedure's implementation code block}
procedure AppendToListDebug( var list: ListType; item: ItemType ); begin {pre-condition asserts go here} Assert( ValidList( list ) ); AppendToList( var list: ListType; item: ItemType ); {post-condition asserts go here} end; end. {module block}
Then in code using the MyLists module, use conditional compilation directives to select the debugging interface or the non-debugging interface. For example:
procedure DoSomethingWithLists; {$ifc not do_debug} import MyLists; {$elsec} import MyListsDebug in 'MyLists.pas'; {$endc} {insert other needed declarations} begin {...} {With do_debug = true, this ends up calling AppendToListDebug with the pre- and post-conditions assertion checks. Otherwise, it calls AppendToList which doesn't have the assertion overhead.} AppendToList(theList,anItem); end;
Then as long as you practice a discipline of side-effect free pre-condition and post-condition asserts, the effects of debugging/non-debugging versions will be transparent; will retain modularity; and will avoid the debugging code overhead in non-debug production code. If you're using a smart linker, the debugging code routines should also be dead stripped from the production executeable since the debugging related routines are never called from production code.