mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 22:47:59 +02:00
* explicit typecasting of any ordinal type to a boolean of the same
size must happen without any mangling of the value (mantis #11027) * moved checking for signed-to-unsigned (or vice versa) type conversions in assignments from htypechk to ncnv (where there was already code for similar checks) and added support for bool_to_bool there as well git-svn-id: trunk@10521 -
This commit is contained in:
parent
e0593d7e6a
commit
62e66d2a56
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -8105,6 +8105,7 @@ tests/webtbs/tw10966.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1097.pp svneol=native#text/plain
|
||||
tests/webtbs/tw10979.pp svneol=native#text/plain
|
||||
tests/webtbs/tw11006.pp svneol=native#text/plain
|
||||
tests/webtbs/tw11027.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1103.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1104.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1111.pp svneol=native#text/plain
|
||||
|
@ -190,14 +190,11 @@ implementation
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
||||
{ be accepted for var parameters, and must not change the }
|
||||
{ the ordinal value }
|
||||
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||
{ must not change the ordinal value }
|
||||
if (nf_explicit in flags) and
|
||||
(left.resultdef.size=resultdef.size) and
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
||||
is_cbool(resultdef) and
|
||||
not is_pasbool(left.resultdef) then
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||
begin
|
||||
location_copy(location,left.location);
|
||||
location.size:=def_cgsize(resultdef);
|
||||
|
@ -1068,16 +1068,6 @@ implementation
|
||||
CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
|
||||
end;
|
||||
|
||||
{ when typecasting to the same size but changing the signdness of
|
||||
an ordinal, the value cannot be in a register if it's < sizeof(aint).
|
||||
The reason is that a tc_int_2_int type conversion changing the sign
|
||||
of a such value in a register also has to modify this register (JM) }
|
||||
if is_ordinal(fromdef) and is_ordinal(todef) and
|
||||
(fromdef.size=todef.size) and
|
||||
(fromdef.size<sizeof(aint)) and
|
||||
(is_signed(fromdef) xor is_signed(todef)) then
|
||||
make_not_regable(hp,[ra_addr_regable]);
|
||||
|
||||
{ don't allow assignments to typeconvs that need special code }
|
||||
if not(gotsubscript or gotvec or gotderef) and
|
||||
not(ttypeconvnode(hp).assign_allowed) then
|
||||
|
@ -164,14 +164,11 @@ implementation
|
||||
|
||||
{$warning needs LOC_JUMP support, because called for bool_to_bool from ncgcnv }
|
||||
|
||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
||||
{ be accepted for var parameters, and must not change the }
|
||||
{ the ordinal value }
|
||||
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||
{ must not change the ordinal value }
|
||||
if (nf_explicit in flags) and
|
||||
(left.resultdef.size=resultdef.size) and
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
||||
is_cbool(resultdef) and
|
||||
not is_pasbool(left.resultdef) then
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||
begin
|
||||
location_copy(location,left.location);
|
||||
location.size:=def_cgsize(resultdef);
|
||||
|
@ -2923,13 +2923,18 @@ implementation
|
||||
)
|
||||
) or
|
||||
{ int 2 bool/bool 2 int, explicit typecast, see also nx86cnv }
|
||||
((convtype in [tc_int_2_bool,tc_bool_2_int]) and
|
||||
((convtype in [tc_int_2_bool,tc_bool_2_int,tc_bool_2_bool]) and
|
||||
(nf_explicit in flags) and
|
||||
(resultdef.size=left.resultdef.size));
|
||||
|
||||
{ When using only a part of the value it can't be in a register since
|
||||
that will load the value in a new register first }
|
||||
if (resultdef.size<left.resultdef.size) then
|
||||
{ the same goes for changing the sign of equal-sized values which
|
||||
are smaller than an entire register }
|
||||
if (resultdef.size<left.resultdef.size) or
|
||||
((resultdef.size=left.resultdef.size) and
|
||||
(left.resultdef.size<sizeof(aint)) and
|
||||
(is_signed(resultdef) xor is_signed(left.resultdef))) then
|
||||
make_not_regable(left,[ra_addr_regable]);
|
||||
end;
|
||||
|
||||
|
@ -85,14 +85,11 @@ implementation
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
||||
{ be accepted for var parameters, and must not change the }
|
||||
{ the ordinal value }
|
||||
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||
{ must not change the ordinal value }
|
||||
if (nf_explicit in flags) and
|
||||
(left.resultdef.size=resultdef.size) and
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
||||
is_cbool(resultdef) and
|
||||
not is_pasbool(left.resultdef) then
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||
begin
|
||||
location_copy(location,left.location);
|
||||
location.size:=def_cgsize(resultdef);
|
||||
|
@ -233,14 +233,11 @@ implementation
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
||||
{ be accepted for var parameters, and must not change the }
|
||||
{ the ordinal value }
|
||||
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||
{ must not change the ordinal value }
|
||||
if (nf_explicit in flags) and
|
||||
(left.resultdef.size=resultdef.size) and
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
||||
is_cbool(resultdef) and
|
||||
not is_pasbool(left.resultdef) then
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||
begin
|
||||
location_copy(location,left.location);
|
||||
location.size:=def_cgsize(resultdef);
|
||||
|
@ -102,14 +102,11 @@ implementation
|
||||
secondpass(left);
|
||||
if codegenerror then
|
||||
exit;
|
||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
||||
{ be accepted for var parameters, and must not change the }
|
||||
{ the ordinal value }
|
||||
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||
{ must not change the ordinal value }
|
||||
if (nf_explicit in flags) and
|
||||
(left.resultdef.size=resultdef.size) and
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
||||
is_cbool(resultdef) and
|
||||
not is_pasbool(left.resultdef) then
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||
begin
|
||||
location_copy(location,left.location);
|
||||
location.size:=def_cgsize(resultdef);
|
||||
|
10
tests/webtbs/tw11027.pp
Normal file
10
tests/webtbs/tw11027.pp
Normal file
@ -0,0 +1,10 @@
|
||||
var i : char;
|
||||
bb: bytebool;
|
||||
begin
|
||||
boolean(i) := (1=1);
|
||||
if not boolean(i) then
|
||||
halt(1);
|
||||
boolean(bb):=boolean(i);
|
||||
if not(bb) then
|
||||
halt(2);
|
||||
end.
|
Loading…
Reference in New Issue
Block a user