diff --git a/compiler/defutil.pas b/compiler/defutil.pas index 7b7a944d49..16672641fc 100644 --- a/compiler/defutil.pas +++ b/compiler/defutil.pas @@ -331,6 +331,13 @@ interface { returns true of def is a methodpointer } function is_methodpointer(def : tdef) : boolean; + {# returns the appropriate int type for pointer arithmetic with the given pointer type. + When adding or subtracting a number to/from a pointer, this function returns the + int type to which that number has to be converted, before the operation can be performed. + Normally, this is sinttype, except on i8086, where it takes into account the + special i8086 pointer types (near, far, huge). } + function get_int_type_for_pointer_arithmetic(p : tdef) : tdef; + {$ifdef i8086} {# Returns true if p is a far pointer def } function is_farpointer(p : tdef) : boolean; @@ -1433,6 +1440,17 @@ implementation result:=(def.typ=procvardef) and (po_methodpointer in tprocvardef(def).procoptions); end; + + function get_int_type_for_pointer_arithmetic(p : tdef) : tdef; + begin +{$ifdef i8086} + if is_hugepointer(p) then + result:=s32inttype + else +{$endif i8086} + result:=sinttype; + end; + {$ifdef i8086} { true if p is a far pointer def } function is_farpointer(p : tdef) : boolean; diff --git a/compiler/nadd.pas b/compiler/nadd.pas index acf9e864a7..8b8e7948db 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -1960,7 +1960,7 @@ implementation end else resultdef:=right.resultdef; - inserttypeconv(left,sinttype); + inserttypeconv(left,get_int_type_for_pointer_arithmetic(rd)); if nodetype=addn then begin if not(cs_extsyntax in current_settings.moduleswitches) or @@ -1972,7 +1972,7 @@ implementation (tpointerdef(rd).pointeddef.size>1) then begin left:=caddnode.create(muln,left, - cordconstnode.create(tpointerdef(rd).pointeddef.size,sinttype,true)); + cordconstnode.create(tpointerdef(rd).pointeddef.size,get_int_type_for_pointer_arithmetic(rd),true)); typecheckpass(left); end; end @@ -1991,7 +1991,7 @@ implementation else resultdef:=left.resultdef; - inserttypeconv(right,sinttype); + inserttypeconv(right,get_int_type_for_pointer_arithmetic(ld)); if nodetype in [addn,subn] then begin if (lt=niln) then @@ -2008,7 +2008,7 @@ implementation if (tpointerdef(ld).pointeddef.size>1) then begin right:=caddnode.create(muln,right, - cordconstnode.create(tpointerdef(ld).pointeddef.size,sinttype,true)); + cordconstnode.create(tpointerdef(ld).pointeddef.size,get_int_type_for_pointer_arithmetic(ld),true)); typecheckpass(right); end end else @@ -2016,7 +2016,7 @@ implementation (tarraydef(ld).elementdef.size>1) then begin right:=caddnode.create(muln,right, - cordconstnode.create(tarraydef(ld).elementdef.size,sinttype,true)); + cordconstnode.create(tarraydef(ld).elementdef.size,get_int_type_for_pointer_arithmetic(ld),true)); typecheckpass(right); end; end