An Internal compiler error has been reported on the macpascal mailing list, as reproduced by the following program:
[G5:gcc/p/test] adriaan% cat avo10.pas program avo10; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( [bold, italic]); {internal compiler error} end.
[G5:gcc/p/test] adriaan% gpc avo10.pas ../../gcc-3.4.3/gcc/p/typecheck.c:123:incomplete_type_error: failed assertion `0' avo10.pas: In main program: avo10.pas:8: error: Internal compiler error. Please submit a full bug report to the GPC mailing list gpc@gnu.de. See URL:http://www.gnu-pascal.de/todo.html for details.
G5:gcc/p/test] adriaan% gpc -v Reading specs from /Developer/Pascal/gpc343d7/lib/gcc/powerpc-apple-darwin7/3.4.3/specs Configured with: ../gcc-3.4.3/configure --enable-languages=pascal,c --enable-threads=posix --prefix=/Developer/Pascal/gpc343d7 --target=powerpc-apple-darwin7 --host=powerpc-apple-darwin7 Thread model: posix gpc version 20050217, based on gcc-3.4.3
Adding a typecast triggers another error:
G5:gcc/p/test] adriaan% cat avo11.pas program avo11; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( StyleParameter( [bold, italic])); {internal compiler error} end.
[G5:gcc/p/test] adriaan% gpc avo11.pas avo11.pas: In main program: avo11.pas:8: warning: cast to type of different size avo11.pas:8: internal compiler error: Bus error Please submit a full bug report, with preprocessed source if appropriate. See URL:http://www.gnu-pascal.de/todo.html for instructions.
with backtrace:
Command: gpc1 Path: /Developer/Pascal/gpc343d7/libexec/gcc/powerpc-apple-darwin7/3.4.3/gpc1 Version: ??? (???) PID: 1333 Thread: 0
Exception: EXC_BAD_ACCESS (0x0001) Codes: KERN_PROTECTION_FAILURE (0x0002) at 0x00000038
Thread 0 Crashed: 0 gpc1 0x000c66d4 get_set_constructor_bits + 0x34 (tree.c:4654) 1 gpc1 0x000c693c get_set_constructor_bytes + 0x4c (tree.c:4730) 2 gpc1 0x000e4204 const_hash_1 + 0x3b4 (varasm.c:2130) 3 gpc1 0x002f773c htab_find_slot + 0x2c (hashtab.c:560) 4 gpc1 0x000e34c8 output_constant_def + 0x38 (varasm.c:2496) 5 gpc1 0x0007d6b0 expand_expr_real + 0x3c88 (expr.c:6910) 6 gpc1 0x0007d54c expand_expr_real + 0x3b24 (expr.c:8863) 7 gpc1 0x0007e9a0 expand_expr_real + 0x4f78 (expr.c:7658) 8 gpc1 0x0007a620 expand_expr_real + 0xbf8 (expr.c:6952) 9 gpc1 0x0007e9a0 expand_expr_real + 0x4f78 (expr.c:7658) 10 gpc1 0x00196ac8 expand_call + 0x2760 (calls.c:793) 11 gpc1 0x0007b6a0 expand_expr_real + 0x1c78 (expr.c:7595) 12 gpc1 0x000c9ff4 expand_expr_stmt_value + 0xe0 (stmt.c:2171) 13 gpc1 0x00007e5c yyuserAction + 0x4cd8 (parse.c:4691) 14 gpc1 0x000114cc main_yyparse + 0x738 (parse.c:8136) 15 gpc1 0x000be2ec toplev_main + 0x7b8 (toplev.c:1826) 16 gpc1 0x00001ed8 _start + 0x188 (crt.c:267) 17 dyld 0x8fe1a558 _dyld_start + 0x64
Regards,
Adriaan van Os
On 28 Feb 2005 at 12:11, Adriaan van Os wrote:
An Internal compiler error has been reported on the macpascal mailing list, as reproduced by the following program:
[G5:gcc/p/test] adriaan% cat avo10.pas program avo10; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( [bold, italic]); {internal compiler error} end.
[G5:gcc/p/test] adriaan% gpc avo10.pas ../../gcc-3.4.3/gcc/p/typecheck.c:123:incomplete_type_error: failed assertion `0' avo10.pas: In main program: avo10.pas:8: error: Internal compiler error.
I can reproduce this under Mingw. The program of course is buggy (wrong parameter passed to TextFace) but the compiler shouldn't crash.
By way of comparison, the Delphi error message here is: "D:\tmp\avo10.pas(6) Error: Declaration expected but ';' found D:\tmp\avo10.pas(9) Error: Incompatible types: 'Cardinal' and 'Set' D:\tmp\avo10.pas(10) Error: ';' expected but '.' found D:\tmp\avo10.pas(11) D:\tmp\avo10.pas(12) Error: Declaration expected but end of file found"
[...]
Adding a typecast triggers another error:
[...] Again, reproducible under Mingw. The Delphi error message here is: "D:\tmp\avo10.pas(6) Error: Declaration expected but ';' found D:\tmp\avo10.pas(9) Error: Invalid typecast D:\tmp\avo10.pas(10) Error: ';' expected but '.' found D:\tmp\avo10.pas(11) D:\tmp\avo10.pas(12) Error: Declaration expected but end of file found"
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Adriaan van Os wrote:
An Internal compiler error has been reported on the macpascal mailing list, as reproduced by the following program:
[G5:gcc/p/test] adriaan% cat avo10.pas program avo10; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( [bold, italic]); {internal compiler error} end.
[G5:gcc/p/test] adriaan% gpc avo10.pas ../../gcc-3.4.3/gcc/p/typecheck.c:123:incomplete_type_error: failed assertion `0' avo10.pas: In main program: avo10.pas:8: error: Internal compiler error. Please submit a full bug report to the GPC mailing list gpc@gnu.de. See URL:http://www.gnu-pascal.de/todo.html for details.
That one looks easy to correct: we just need proper error message (patch below).
G5:gcc/p/test] adriaan% gpc -v Reading specs from /Developer/Pascal/gpc343d7/lib/gcc/powerpc-apple-darwin7/3.4.3/specs Configured with: ../gcc-3.4.3/configure --enable-languages=pascal,c --enable-threads=posix --prefix=/Developer/Pascal/gpc343d7 --target=powerpc-apple-darwin7 --host=powerpc-apple-darwin7 Thread model: posix gpc version 20050217, based on gcc-3.4.3
Adding a typecast triggers another error:
G5:gcc/p/test] adriaan% cat avo11.pas program avo11; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( StyleParameter( [bold, italic])); {internal compiler error} end.
I am not sure if we should accept this program -- set constants in Pascal are really typeless, and their type is determined by the context. This cast gives no such context. The patch below tries to do something sensible...
--- p/typecheck.c.bb 2005-02-28 13:40:33.768665488 +0100 +++ p/typecheck.c 2005-02-28 13:40:55.883303552 +0100 @@ -119,6 +119,8 @@ error ("invalid use of array with unspecified bounds"); else if (TREE_CODE (type) == LANG_TYPE) error ("invalid use of forward declared type"); + else if (TREE_CODE (type) == SET_TYPE) + error ("invalid use of set type"); else assert (0); } --- p/expressions.c.bb 2005-02-22 19:03:40.000000000 +0100 +++ p/expressions.c 2005-02-28 14:37:28.252585032 +0100 @@ -3155,6 +3155,18 @@ else { /* Variable type cast. Convert a pointer internally. */ + /* Convert a set */ + if (TREE_CODE (otype) == SET_TYPE && TYPE_SIZE (otype) == NULL_TREE) + { + tree elements; + assert (TREE_CODE (value) == CONSTRUCTOR); + elements = CONSTRUCTOR_ELTS (value); + if (elements) + value = construct_set (value, NULL_TREE, 1); + else + return build_type_cast (type, integer_zero_node); + otype = TREE_TYPE (value); + } if (TREE_CODE (otype) != VOID_TYPE && TREE_CODE (type) != VOID_TYPE && !tree_int_cst_equal (TYPE_SIZE (otype), TYPE_SIZE (type)))
Waldek Hebisch wrote:
That one looks easy to correct: we just need proper error message (patch below).
I am not sure if we should accept this program -- set constants in Pascal are really typeless, and their type is determined by the context. This cast gives no such context. The patch below tries to do something sensible...
Thanks for the patches, that solve both reported problems.
Regards,
Adriaan van Os
Waldek Hebisch wrote:
[G5:gcc/p/test] adriaan% gpc avo10.pas
That one looks easy to correct: we just need proper error message (patch below).
OK, thanks.
G5:gcc/p/test] adriaan% gpc -v Reading specs from /Developer/Pascal/gpc343d7/lib/gcc/powerpc-apple-darwin7/3.4.3/specs Configured with: ../gcc-3.4.3/configure --enable-languages=pascal,c --enable-threads=posix --prefix=/Developer/Pascal/gpc343d7 --target=powerpc-apple-darwin7 --host=powerpc-apple-darwin7 Thread model: posix gpc version 20050217, based on gcc-3.4.3
Adding a typecast triggers another error:
G5:gcc/p/test] adriaan% cat avo11.pas program avo11; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( StyleParameter( [bold, italic])); {internal compiler error} end.
I am not sure if we should accept this program --
We should not. According to BP (the only documented reference I have about type-casts at all), there are two kinds of type-casts: Variable type-casts (which require variables, or rather "lvalues" and cast to types of the same size -- as for lvalues the size is well-defined), and value type-casts which apply to ordinal types (and pointers in MP) and which conserve ordinal values (or addresses).
Neither of them applies here. This patch gives a proper error message instead of crashing:
--- p/expressions.c.orig Sun Feb 27 06:56:51 2005 +++ p/expressions.c Mon Feb 28 16:59:30 2005 @@ -3138,6 +3138,11 @@ if (!tree_int_cst_equal (TYPE_SIZE (otype), TYPE_SIZE (type))) value = non_lvalue (value); } + else if (!lvalue_p (value)) + { + error ("invalid type cast"); + return error_mark_node; + } else { /* Variable type cast. Convert a pointer internally. */
Waldek Hebisch wrote:
Some thoughts, if you search for good way to express the intent. [...]
I don't think any of these ways is reliable. If your external routine wants a 16-bit integer, use this on the Pascal side. Then you can either work with bit masks and/or convert to/from sets in a subroutine explicitly.
Anything else would rely on the internal representation of sets in GPC which may change in the future, and which already now is not what you want AFAICS. Currently sets are composed of `MedCard' values (which are usually, if not always, larger than 16 bits). Little-endian systems might hide the problem; fortunately yours is big-endian, so you won't even get the impression that it worked. ;-)
Frank
Frank Heckenbach wrote:
We should not. According to BP (the only documented reference I have about type-casts at all), there are two kinds of type-casts: Variable type-casts (which require variables, or rather "lvalues" and cast to types of the same size -- as for lvalues the size is well-defined), and value type-casts which apply to ordinal types (and pointers in MP) and which conserve ordinal values (or addresses).
I thing that BP really mixed different things together. I would say that there are two kinds of casts: raw cast, which just interpret storage (bit pattern) as a different type and conversions, which may do some non-trivial computation.
Additionaly, cast may silently "do the work", or they may serve as assertions that the value "really" is of different type.
Raw casts typically do not signal errors, still one could signal them for invalid or out of range values.
I see a few different uses of casts:
1) for low-level programming, here we want raw cast and it should not matter if the value converted is variable or constant. Actually, the only bad case seem to be set constants, since we can extend/truncate integers to desired size and other constansts have well defined size. So forbiding all constansts (even typed!) seem to harsh for me.
2) Our current signed/unsigned problems clearly show need for explicit conversions in arithmetic expressions. It make some sense to allow such conversions also for sets (but I do not insists).
3) Cast as type assertions are frequently used in OOP, where one wants to treat an object as object of different class (handled by `as')
Waldek Hebisch wrote:
Frank Heckenbach wrote:
We should not. According to BP (the only documented reference I have about type-casts at all), there are two kinds of type-casts: Variable type-casts (which require variables, or rather "lvalues" and cast to types of the same size -- as for lvalues the size is well-defined), and value type-casts which apply to ordinal types (and pointers in MP) and which conserve ordinal values (or addresses).
I thing that BP really mixed different things together.
Yes, it might have been preferable to use different syntax for the two kinds of type-casts it supports, but now we have no choice. But at least there's no real conflict, as in the case where both casts are applicable -- casting an ordinal lvalue to an ordinal type of the same size, and using it as an rvalue -- both yield the same result.
I would say that there are two kinds of casts: raw cast, which just interpret storage (bit pattern) as a different type and
That's "variable type-casts" for BP. In BP, they're only allowed for lvalues, and I think that's good, since other expressions may not have a well-defined bit pattern, in particular size.
conversions, which may do some non-trivial computation.
That's not what BP type-casts do. Of course, some implicit conversions (Integer -> Real, Char -> String) which BP also does, could fall in this category.
But BP's "value type-casts" would then be a third category: They do not necessarily preserve storage (as they can cast between different sizes), but they do not do any non-trivial computations (only possibly extending/shrinking the size, and perhaps range-checking).
Additionaly, cast may silently "do the work", or they may serve as assertions that the value "really" is of different type.
Raw casts typically do not signal errors, still one could signal them for invalid or out of range values.
I see a few different uses of casts:
- for low-level programming, here we want raw cast and it should not matter if the value converted is variable or constant.
It's not really about being variable or constant. `protected' and `const' parameters can be casted, even variables declared with `attribute (const)'. It's more about "lvalues".
Actually, the only bad case seem to be set constants, since we can extend/truncate integers to desired size and other constansts have well defined size. So forbiding all constansts (even typed!) seem to harsh for me.
"Typed constants" in the BP sense are really lvalues, so do you mean EP structured values?
I'm not convinced. E.g., when truncating a (signed) integer, do you use a signed or unsigned shorte type? Both will clip some values, but different ones.
And you forgot reals. "Casting" a real to another type may on some platforms preserve the bit pattern, on others do a conversion to another size (which usually changes the bit pattern quite a bit) and preserve that, and on others fail completely as no such sized real type is available.
You also forgot string constants. Should they be represented as fix-strings or string schemata, possibly short strings in the future?
I think the general principle is just that constants do not (necessarily) carry enough memory-layout information. They represent values, and values can be stored in different forms.
As you say, it's usually used for low-level programming, and low-level programming should be the exception in Pascal, I don't feel the need to simplify it (given the problems). After all, the additional "difficulty" with the current (BP) system is only having to assign the value to a temporary variable before the type-cast.
- Our current signed/unsigned problems clearly show need for explicit conversions in arithmetic expressions.
But these are value type casts, in that they don't change the numeric value, and they're range-safe. Thus they're equivalent to the standard construct of assigning to a temporary variable of the target type (without needing any type-cast).
It make some sense to allow such conversions also for sets (but I do not insists).
By "such conversion" I suppose then you mean converting a set value to a compatible set type, preserving the value (elements)? What could this ever be useful for? (For integers we have different sizes and overflow problems, but set operations always choose fitting result types anyway.)
- Cast as type assertions are frequently used in OOP, where one wants to treat an object as object of different class (handled by `as')
Yes. That's a safe operator as it checks before conversion and allows only valid "casts".
Frank
Adriaan van Os wrote:
Adding a typecast triggers another error:
G5:gcc/p/test] adriaan% cat avo11.pas program avo11; type UInt16 = cardinal attribute( size = 16); StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleParameter = UInt16; procedure TextFace(face: StyleParameter); external name 'TextFace'; begin TextFace( StyleParameter( [bold, italic])); {internal compiler error} end.
Some thoughts, if you search for good way to express the intent. AFAICS on Mac OSX you can define:
StyleParameter = set of StyleItemGPC;
and that should do the right thing here.
Alternatively, cast of set constructor should work:
....
StyleParameterGPC = set of StyleItemGPC;
...
TextFace( StyleParameter(StyleParameterGPC[bold, italic]));
Double cast
TextFace( StyleParameter(StyleParameterGPC([bold, italic])));
should work too, but I just noticed that it did not work (without the patch I posted).
Waldek Hebisch wrote:
Some thoughts, if you search for good way to express the intent. AFAICS on Mac OSX you can define:
StyleParameter = set of StyleItemGPC;
and that should do the right thing here.
Yes, I tried that and It does. There is some history (with ABI problems) behind the call. Here are the original comments.
Quickdraw Types Style Quickdraw font rendering styles StyleParameter Style when used as a parameter (historical 68K convention) StyleField Style when used as a field (historical 68K convention) Note: The original Macintosh toolbox in 68K Pascal defined Style as a SET. Both Style and CHAR occupy 8-bits in packed records or 16-bits when used as fields in non-packed records or as parameters.
and the (messy) declarations:
StyleItemGPC = (bold,italic,underline,outline,shadow,condense,extend); StyleItem = packed bold..extend; StyleGPC = set of StyleItem; Style = UInt8;
StyleParameter = UInt16; StyleField = Style;
procedure TextFace(face: StyleParameter); external name 'TextFace';
In GPC a set is at least 32-bits, but still this works - fortunately: StyleParameter = set of StyleItemGPC
as you mentioned.
Alternatively, cast of set constructor should work:
....
StyleParameterGPC = set of StyleItemGPC;
...
TextFace( StyleParameter(StyleParameterGPC[bold, italic]));
Double cast
TextFace( StyleParameter(StyleParameterGPC([bold, italic])));
should work too, but I just noticed that it did not work (without the patch I posted).
The compiler accepts it, but it doesn't have the desired effect (on high-endian systems). Type-casting to a signed 32-bit integer however does (with the patch):
TextFace( SInt32( [italic]));
Regards,
Adriaan van Os