[comp.lang.c] Two bugs in Microware C

knudsen@ihwpt.UUCP (02/05/87)

There are two bugs in Microware's Level I C compiler
and assembler.  I need to do more research on these
(film at 10), but I'll post what I know now.

BUG #1
The first bug bit a few months back and bit again
this week.  It concerns using GOTOs under all of the
following conditions (all true at once):
(1) The goto jumped out of { }, maybe two levels.
(2) It jumped backwards (yeah, I know...)
(3) It jumped to a label which was the first executable
    statement in the function.

Symptoms are that the function works fine, until you stop
re-cycling with the goto and return, at which point
anything can happen, including confetti all over the
Coco screen and a power-down reboot of OS9.

One symptom was the "walking" local variables,
meaning that given:

foo() {
	int i, j, k;
	char buff[10];
refoo:
	i = 3;	/* very 1st line of executable */
	/* more code */
	printf("buff is at $%4x\n", (int) buff);
	if(whatever) {
		/* more */
		if(whammo)
			goto refoo;
	}
	return(k);
}

each time refoo recycles, the memory address of buff moves
by the same amount!
My theory is that condition (3) above is important, and that
the compiler erroneously puts the label ahead of the
compiler-supplied code that allocates stack space for
automatic variables (eg, LEAS -8,S).
But if I remember right, the address walked the wrong way,
ie, upwards!

Alternately maybe the execution of IF or SWITCH constructs
pushes some temps on the stack that don't get cleaned up
when the goto hops out.  This may be a way to encourage
structured programming, but it ain't K & R!

I'll soon use the -ac options to look at the assembler code
output from the compiler, but my source is pretty big.

BUG #2
Microware C doesn't like to refer to literal memory addresses.
If I want to read location FF90, it's perfectly legal to say:
	x = *((char *) 0xFF90);
The compiler accepts it and in fact puts out correct assembler:
	LDB	-112	*really ff90 in 2's comp decimal
However, the assembler must not believe what it sees,
since the compiled code doesn't work.  Probably the assembler
re-interprets ("corrects") this to:
	LDB	$-112	*or is that #-112?
ie, load immediate.

C.asm doesn't even give me any warnings about absolute locations;
it just "fixes" my code!  I haven't used debug or dump to see what
actually gets assembled.

My program works OK if I use a pointer variable:
	char *p;
	p = (char *) 0xff90;
	x = *p;
so I know the error isn't in my program logic.

Any comments?  I'll pass on details as they happen.
	--mike k
-- 
Mike J Knudsen    ...ihnp4!ihwpt!knudsen
"It's like trying to get to sleep at the Intergalactic
Spaceport Hotel -- waiting for the being in the room above
to drop the Nth shoe, and you don't even know what N is."