T
tm
Hello,
I discovered a compiler bug in lcc-win32 under Windows XP.
The || and && operators work wrong when -O is used.
The following program shows the bug:
-------------------- Begin file testlcc.c --------------------
/* Compile with:
* lc -O -g5 -A testlcc.c -o testlcc.exe
*/
#include "stdio.h"
typedef enum {ILLEGALCHAR, EOFCHAR, LETTERCHAR, DIGITCHAR,
UNDERLINECHAR, SHARPCHAR, QUOTATIONCHAR, APOSTROPHECHAR,
LEFTPARENCHAR, PARENCHAR, SPECIALCHAR, SPACECHAR,
NEWLINECHAR} charclass;
typedef int booltype;
charclass ch_class[256 - EOF];
booltype ch_op[256 - EOF];
#define char_class(CHARACTER) ch_class [((int)(CHARACTER)) - EOF]
#define op_char(CHARACTER) ch_op [((int)(CHARACTER)) - EOF]
void get_ident (unsigned char *name, unsigned int length)
{
printf("length:\n%d # should be: 1\n", length);
printf("name[0]:\n'%c' (%d) # should be: '$' (36)\n",
name[0], name[0]);
printf("op_char(name[0]):\n%d # should be: 1\n",
op_char(name[0]));
printf("char_class(name[0]):\n%2d # should be: 10\n",
char_class(name[0]));
printf("char_class(name[0])==LEFTPARENCHAR:\n");
printf("%d # should be: 0\n",
char_class(name[0])==LEFTPARENCHAR);
printf("op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR:\n");
printf("%d # should be: 1\n",
op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR);
printf("char_class(name[0])==PARENCHAR:\n");
printf("%d # should be: 0\n",
char_class(name[0])==PARENCHAR);
printf("op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR || "
"char_class(name[0])==PARENCHAR:\n");
printf("%d # should be 1\n",
op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR);
printf("length==1 && (op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR || "
"char_class(name[0])==PARENCHAR):\n");
printf("%d # should be 1\n",
length==1 && (op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR));
}
int main (int argc, char *argv[])
{
char_class('$') = SPECIALCHAR;
op_char('$') = 1;
get_ident("$", 1);
}
-------------------- End file testlcc.c --------------------
When I compile with
lc -O -g5 -A testlcc.c -o testlcc.exe
and start testlcc.exe, I get the following output:
length:
1 # should be: 1
name[0]:
'$' (36) # should be: '$' (36)
op_char(name[0]):
1 # should be: 1
char_class(name[0]):
10 # should be: 10
char_class(name[0])==LEFTPARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR:
0 # should be: 1
char_class(name[0])==PARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR:
0 # should be 1
length==1 && (op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
|| char_class(name[0])==PARENCHAR):
0 # should be 1
--------------------
The correct result can be obtained with gcc:
gcc testlcc.c -o testlcc
1 # should be: 1
name[0]:
'$' (36) # should be: '$' (36)
op_char(name[0]):
1 # should be: 1
char_class(name[0]):
10 # should be: 10
char_class(name[0])==LEFTPARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR:
1 # should be: 1
char_class(name[0])==PARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR:
1 # should be 1
length==1 && (op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
|| char_class(name[0])==PARENCHAR):
1 # should be 1
--------------------
I hope this helps to find and correct the compiler bug.
Greetings Thomas Mertes
--
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
I discovered a compiler bug in lcc-win32 under Windows XP.
The || and && operators work wrong when -O is used.
The following program shows the bug:
-------------------- Begin file testlcc.c --------------------
/* Compile with:
* lc -O -g5 -A testlcc.c -o testlcc.exe
*/
#include "stdio.h"
typedef enum {ILLEGALCHAR, EOFCHAR, LETTERCHAR, DIGITCHAR,
UNDERLINECHAR, SHARPCHAR, QUOTATIONCHAR, APOSTROPHECHAR,
LEFTPARENCHAR, PARENCHAR, SPECIALCHAR, SPACECHAR,
NEWLINECHAR} charclass;
typedef int booltype;
charclass ch_class[256 - EOF];
booltype ch_op[256 - EOF];
#define char_class(CHARACTER) ch_class [((int)(CHARACTER)) - EOF]
#define op_char(CHARACTER) ch_op [((int)(CHARACTER)) - EOF]
void get_ident (unsigned char *name, unsigned int length)
{
printf("length:\n%d # should be: 1\n", length);
printf("name[0]:\n'%c' (%d) # should be: '$' (36)\n",
name[0], name[0]);
printf("op_char(name[0]):\n%d # should be: 1\n",
op_char(name[0]));
printf("char_class(name[0]):\n%2d # should be: 10\n",
char_class(name[0]));
printf("char_class(name[0])==LEFTPARENCHAR:\n");
printf("%d # should be: 0\n",
char_class(name[0])==LEFTPARENCHAR);
printf("op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR:\n");
printf("%d # should be: 1\n",
op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR);
printf("char_class(name[0])==PARENCHAR:\n");
printf("%d # should be: 0\n",
char_class(name[0])==PARENCHAR);
printf("op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR || "
"char_class(name[0])==PARENCHAR:\n");
printf("%d # should be 1\n",
op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR);
printf("length==1 && (op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR || "
"char_class(name[0])==PARENCHAR):\n");
printf("%d # should be 1\n",
length==1 && (op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR));
}
int main (int argc, char *argv[])
{
char_class('$') = SPECIALCHAR;
op_char('$') = 1;
get_ident("$", 1);
}
-------------------- End file testlcc.c --------------------
When I compile with
lc -O -g5 -A testlcc.c -o testlcc.exe
and start testlcc.exe, I get the following output:
length:
1 # should be: 1
name[0]:
'$' (36) # should be: '$' (36)
op_char(name[0]):
1 # should be: 1
char_class(name[0]):
10 # should be: 10
char_class(name[0])==LEFTPARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR:
0 # should be: 1
char_class(name[0])==PARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR:
0 # should be 1
length==1 && (op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
|| char_class(name[0])==PARENCHAR):
0 # should be 1
--------------------
The correct result can be obtained with gcc:
gcc testlcc.c -o testlcc
1 # should be: 1
name[0]:
'$' (36) # should be: '$' (36)
op_char(name[0]):
1 # should be: 1
char_class(name[0]):
10 # should be: 10
char_class(name[0])==LEFTPARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR:
1 # should be: 1
char_class(name[0])==PARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR:
1 # should be 1
length==1 && (op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
|| char_class(name[0])==PARENCHAR):
1 # should be 1
--------------------
I hope this helps to find and correct the compiler bug.
Greetings Thomas Mertes
--
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.