[fpc-pascal]Bug with "Level 2 Optimizations"

Marcel Martin mm10 at ellipsa.net
Thu Jun 17 04:48:09 CEST 2004


Hello, 

Here is a bug (?) of the compiler (FP 1.9.4) when setting Level 2 
Optimizations. I post it here since I don't believe it is possible 
to use the bug report form. (I work with Win98, AMD 2600+) 

Types used in the code.

type
  TBigInt = record
    Digits: PDigits;    // pointer to a digit array (digits are
longwords)
    Capacity: Longint;  // memory size (in longwords) of Digits^
    Size: Longint;      // number of digits currently used in Digits^
    Negative: Boolean;  // TRUE if and only if negative (0 is
non-negative)
  end;
  PBigInt = ^TBigInt;

//------------------------------------------------------------------------------
// Set A^.Size equal to NewSize
// ! The returned BigInt may be no more normalized. The calling proc has
to
// manage the normalization.
//------------------------------------------------------------------------------
procedure BigIntSetSize(A: PBigInt; NewSize: Longint);
begin
  Assert(Longword(NewSize) <= ucMAXSIZE32); // check both < 0 and > max

  with A^ do
  begin
    if NewSize > Capacity then BigIntSetCapacity(A,NewSize)
    else
    if NewSize < Size then
    begin
      nx_fill(@Digits^[NewSize],Size-NewSize,0); // fill with 0s
      if NewSize = 0 then Negative := false;
    end;
    Size := NewSize;
  end;
end;

//////////////////////// compiled without optimization (the code works)
# [325] begin
NXINTEGERS_BIGINTSETSIZE$PBIGINT$LONGINT:
# Temps allocated between ebp-16 and ebp-8
	pushl	%ebp
	movl	%esp,%ebp
	subl	$16,%esp
	movl	%ebx,-16(%ebp)
	movl	%esi,-12(%ebp)
# Para A located at ebp-4
# Para NewSize located at ebp-8
	movl	%eax,-4(%ebp)
	movl	%edx,-8(%ebp)
# [328] with A^ do
	movl	-4(%ebp),%ebx   -> EBX := A
	movl	%ebx,%eax
# [330] if NewSize > Capacity then BigIntSetCapacity(A,NewSize)
	movl	4(%eax),%eax
	cmpl	-8(%ebp),%eax
	jl	.L316
	jmp	.L317
.L316:
	movl	-8(%ebp),%edx
	movl	-4(%ebp),%eax
	call	NXINTEGERS_BIGINTSETCAPACITY$PBIGINT$LONGINT
	jmp	.L322
.L317:
	movl	%ebx,%eax        -> EAX := EBX = A
# [332] if NewSize < Size then
	movl	8(%eax),%eax     -> EAX := A^.SIZE
	cmpl	-8(%ebp),%eax  

//////////////////////// compiled with Optimizations 2
# [325] begin
NXINTEGERS_BIGINTSETSIZE$PBIGINT$LONGINT:
# Temps allocated between ebp-16 and ebp-8
	pushl	%ebp
	movl	%esp,%ebp
	subl	$16,%esp
	movl	%ebx,-16(%ebp)
	movl	%esi,-12(%ebp)
# Para A located at ebp-4
# Para NewSize located at ebp-8
	movl	%eax,-4(%ebp)
	movl	%edx,-8(%ebp)
# [330] if NewSize > Capacity then BigIntSetCapacity(A,NewSize)
	movl	4(%eax),%ebx    -> EBX IS SET WITH "A^.CAPACITY"
	cmpl	%edx,%ebx
	jnl	.L317           -> JUMP WITH EBX = A^.CAPACITY (INSTEAD OF A)
	movl	%eax,%ebx       -> EBX := A, SHOULD BE WRITTEN BEFORE 'jnl .L317'
	call	NXINTEGERS_BIGINTSETCAPACITY$PBIGINT$LONGINT
	jmp	.L322
.L317:
# [332] if NewSize < Size then
	movl	8(%ebx),%eax    -> EBX <> A, ACCESS VIOLATION
	cmpl	-8(%ebp),%eax

I hope this is sufficient so that you can find the bug. I couldn't
provide more source code, I just started to adapt my libraries to 
Free Pascal and, at the moment, almost nothing is debugged.

-- 
mm
http://www.ellipsa.net/




More information about the fpc-pascal mailing list