C9201005:C 6.0 May Product Incorrect Code with _fastcall Calls

ID Number: Q80114

6.00 6.00a 6.00ax | 6.00 6.00a

MS-DOS | OS/2

buglist6.00 buglist6.00a buglist6.00ax fixlist7.00

Summary:

PROBLEM ID: C9201005

SYMPTOMS

The Microsoft C Compiler versions 6.0, 6.0a, and 6.0ax may produce

bad code for functions that call only _fastcall functions when

compiling under large (/AL), compact (/AC), or huge (/AH) memory

model and when using any optimizations.

RESOLUTION

To work around this problem, do one of the following:

- Compile without optimizations (/Od).

- Declare local variables.

- Turn stack checking on.

- Use small (/AS) or medium (/AM) memory model.

STATUS

Microsoft has confirmed this to be a problem in Microsoft C version

6.0, 6.0a, and 6.0ax. This problem was corrected in C/C++ version

7.0.

More Information:

This problem occurs only when the function has no local variables and

is compiled with stack checking off. Also, it occurs only if the

_fastcall functions are followed by some function call that will cause

variables to be placed on the stack, such as a function pointer call.

The code generated is incorrect because the stack is not being set up

upon entry to the function. Because the stack is being cleaned up upon

exit, calling this function will corrupt the stack. The sample code

below illustrates this problem.

Sample Code

-----------

/* Compiler options needed: /AL

*/

#pragma check_stack( off )

void _fastcall fast_function( unsigned char a,

unsigned char b,

unsigned char c );

void ( _fastcall * fun_ptr )( void );

void _cdecl function()

{

/* bp does not get pushed onto the stack.

*/

fast_function( 24, 0, 24 );

/*

mov al,24

sub dl,dl

mov bl,al

call FAR PTR @fast_function

*/

fun_ptr();

/*

mov es,WORD PTR $T20000

mov ax,WORD PTR es:_fun_ptr

mov dx,WORD PTR es:_fun_ptr+2

mov WORD PTR [bp-2],dx

mov WORD PTR [bp-4],ax

call DWORD PTR [bp-4]

*/

}

/*

bp gets popped off the stack, but we never pushed it.

mov sp,bp

pop bp

ret

nop

*/

Additional reference words: 6.00 6.00a 6.00ax