mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-25 19:02:35 +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/tw1097.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw10979.pp svneol=native#text/plain
|
tests/webtbs/tw10979.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw11006.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/tw1103.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1104.pp svneol=native#text/plain
|
tests/webtbs/tw1104.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1111.pp svneol=native#text/plain
|
tests/webtbs/tw1111.pp svneol=native#text/plain
|
||||||
|
@ -190,14 +190,11 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||||
{ be accepted for var parameters, and must not change the }
|
{ must not change the ordinal value }
|
||||||
{ the ordinal value }
|
|
||||||
if (nf_explicit in flags) and
|
if (nf_explicit in flags) and
|
||||||
(left.resultdef.size=resultdef.size) and
|
(left.resultdef.size=resultdef.size) and
|
||||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||||
is_cbool(resultdef) and
|
|
||||||
not is_pasbool(left.resultdef) then
|
|
||||||
begin
|
begin
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
location.size:=def_cgsize(resultdef);
|
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));
|
CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
|
||||||
end;
|
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 }
|
{ don't allow assignments to typeconvs that need special code }
|
||||||
if not(gotsubscript or gotvec or gotderef) and
|
if not(gotsubscript or gotvec or gotderef) and
|
||||||
not(ttypeconvnode(hp).assign_allowed) then
|
not(ttypeconvnode(hp).assign_allowed) then
|
||||||
|
@ -164,14 +164,11 @@ implementation
|
|||||||
|
|
||||||
{$warning needs LOC_JUMP support, because called for bool_to_bool from ncgcnv }
|
{$warning needs LOC_JUMP support, because called for bool_to_bool from ncgcnv }
|
||||||
|
|
||||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||||
{ be accepted for var parameters, and must not change the }
|
{ must not change the ordinal value }
|
||||||
{ the ordinal value }
|
|
||||||
if (nf_explicit in flags) and
|
if (nf_explicit in flags) and
|
||||||
(left.resultdef.size=resultdef.size) and
|
(left.resultdef.size=resultdef.size) and
|
||||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||||
is_cbool(resultdef) and
|
|
||||||
not is_pasbool(left.resultdef) then
|
|
||||||
begin
|
begin
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
location.size:=def_cgsize(resultdef);
|
location.size:=def_cgsize(resultdef);
|
||||||
|
@ -2923,13 +2923,18 @@ implementation
|
|||||||
)
|
)
|
||||||
) or
|
) or
|
||||||
{ int 2 bool/bool 2 int, explicit typecast, see also nx86cnv }
|
{ 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
|
(nf_explicit in flags) and
|
||||||
(resultdef.size=left.resultdef.size));
|
(resultdef.size=left.resultdef.size));
|
||||||
|
|
||||||
{ When using only a part of the value it can't be in a register since
|
{ 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 }
|
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]);
|
make_not_regable(left,[ra_addr_regable]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -85,14 +85,11 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||||
{ be accepted for var parameters, and must not change the }
|
{ must not change the ordinal value }
|
||||||
{ the ordinal value }
|
|
||||||
if (nf_explicit in flags) and
|
if (nf_explicit in flags) and
|
||||||
(left.resultdef.size=resultdef.size) and
|
(left.resultdef.size=resultdef.size) and
|
||||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||||
is_cbool(resultdef) and
|
|
||||||
not is_pasbool(left.resultdef) then
|
|
||||||
begin
|
begin
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
location.size:=def_cgsize(resultdef);
|
location.size:=def_cgsize(resultdef);
|
||||||
|
@ -233,14 +233,11 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||||
{ be accepted for var parameters, and must not change the }
|
{ must not change the ordinal value }
|
||||||
{ the ordinal value }
|
|
||||||
if (nf_explicit in flags) and
|
if (nf_explicit in flags) and
|
||||||
(left.resultdef.size=resultdef.size) and
|
(left.resultdef.size=resultdef.size) and
|
||||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||||
is_cbool(resultdef) and
|
|
||||||
not is_pasbool(left.resultdef) then
|
|
||||||
begin
|
begin
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
location.size:=def_cgsize(resultdef);
|
location.size:=def_cgsize(resultdef);
|
||||||
|
@ -102,14 +102,11 @@ implementation
|
|||||||
secondpass(left);
|
secondpass(left);
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
{ bytebool(byte) or wordbool(word) or longbool(longint) must }
|
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||||
{ be accepted for var parameters, and must not change the }
|
{ must not change the ordinal value }
|
||||||
{ the ordinal value }
|
|
||||||
if (nf_explicit in flags) and
|
if (nf_explicit in flags) and
|
||||||
(left.resultdef.size=resultdef.size) and
|
(left.resultdef.size=resultdef.size) and
|
||||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
|
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||||
is_cbool(resultdef) and
|
|
||||||
not is_pasbool(left.resultdef) then
|
|
||||||
begin
|
begin
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
location.size:=def_cgsize(resultdef);
|
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