fixed null-pointer constants and SkipToNewLine()

This commit is contained in:
eck 1989-12-12 12:52:03 +00:00
parent 24a1c0d390
commit b3a142e244
7 changed files with 62 additions and 47 deletions

View file

@ -115,7 +115,6 @@ GetToken(ptok)
*/ */
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1]; char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
register int ch, nch; register int ch, nch;
int nlflag = 0;
token_nmb++; token_nmb++;
@ -590,7 +589,7 @@ quoted(ch)
for (;;) { for (;;) {
ch = GetChar(); ch = GetChar();
if (vch = hex_val(ch), vch == -1) if ((vch = hex_val(ch)) == -1)
break; break;
hex = hex * 16 + vch; hex = hex * 16 + vch;
} }

View file

@ -135,21 +135,31 @@ relbalance(e1p, oper, e2p)
register struct expr **e1p, **e2p; register struct expr **e1p, **e2p;
{ {
/* The expressions *e1p and *e2p are balanced to be operands /* The expressions *e1p and *e2p are balanced to be operands
of the relational operator oper. of the relational operator oper, or the ':'.
Care is taken to switch the operands in case of a
null-pointer constant. This is done so that ch3cast()
allows assignments of a null-pointer to a function
pointer.
*/ */
if ((*e1p)->ex_type->tp_fund == FUNCTION) register struct expr *e1 = *e1p, *e2 = *e2p;
function2pointer(*e1p); struct expr *tmpexpr;
if ((*e2p)->ex_type->tp_fund == FUNCTION)
function2pointer(*e2p); if (e1->ex_type->tp_fund == POINTER
if ((*e1p)->ex_type->tp_fund == POINTER) && is_cp_cst(e1)
ch3pointer(e2p, oper, (*e1p)->ex_type); && e1->VL_VALUE == 0) {
else if ((*e2p)->ex_type->tp_fund == POINTER) tmpexpr = e1;
ch3pointer(e1p, oper, (*e2p)->ex_type); e1 = e2;
else if ((*e1p)->ex_type == (*e2p)->ex_type e2 = tmpexpr;
&& (*e1p)->ex_type->tp_fund == ENUM) {} }
if (e1->ex_type->tp_fund == POINTER)
ch3pointer(e2p, oper, e1->ex_type);
else if (e2->ex_type->tp_fund == POINTER)
ch3pointer(e1p, oper, e2->ex_type);
else if (e1->ex_type == e2->ex_type
&& e1->ex_type->tp_fund == ENUM) {}
else if (oper == ':' else if (oper == ':'
&& (*e1p)->ex_type->tp_fund == VOID && e1->ex_type->tp_fund == VOID
&& (*e2p)->ex_type->tp_fund == VOID) {} && e2->ex_type->tp_fund == VOID) {}
else else
arithbalance(e1p, oper, e2p); arithbalance(e1p, oper, e2p);
} }

View file

@ -177,8 +177,9 @@ ch3cast(expp, oper, tp)
(*expp)->ex_type = void_type; (*expp)->ex_type = void_type;
return; return;
} }
if ((*expp)->ex_type->tp_fund == FUNCTION) if ((*expp)->ex_type->tp_fund == FUNCTION) {
function2pointer(*expp); function2pointer(*expp);
}
if ((*expp)->ex_type->tp_fund == ARRAY) if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp); array2pointer(*expp);
if ((*expp)->ex_class == String) if ((*expp)->ex_class == String)
@ -287,6 +288,7 @@ ch3cast(expp, oper, tp)
case '=': case '=':
case CASTAB: case CASTAB:
case RETURN: case RETURN:
case ':':
if (tp->tp_up && oldtp->tp_up) { if (tp->tp_up && oldtp->tp_up) {
if (tp->tp_up->tp_fund == VOID if (tp->tp_up->tp_fund == VOID
&& oldtp->tp_up->tp_fund != FUNCTION) { && oldtp->tp_up->tp_fund != FUNCTION) {
@ -296,13 +298,17 @@ ch3cast(expp, oper, tp)
&& tp->tp_up->tp_fund != FUNCTION) { && tp->tp_up->tp_fund != FUNCTION) {
break; /* switch */ break; /* switch */
} }
if (oldtp->tp_up->tp_fund == VOID
&& is_cp_cst(*expp)
&& (*expp)->VL_VALUE == (arith)0)
break; /* switch */
} }
/* falltrough */ /* falltrough */
default: default:
if (oper == CASTAB) if (oper == CASTAB)
expr_warning(*expp, "incompatible pointers"); expr_strict(*expp, "incompatible pointers in call");
else else
expr_warning(*expp, "incompatible pointers in %s", expr_strict(*expp, "incompatible pointers in %s",
symbol2str(oper)); symbol2str(oper));
break; break;
case CAST: break; case CAST: break;

View file

@ -70,25 +70,11 @@ ch3bin(expp, oper, expr)
break; break;
case '(': /* 3.3.2.2 */ case '(': /* 3.3.2.2 */
#if 1 if (expp_tp->tp_fund == POINTER
if ( expp_tp->tp_fund == POINTER && && expp_tp->tp_up->tp_fund == FUNCTION) {
expp_tp->tp_up->tp_fund == FUNCTION
) {
ch3mon('*', expp); ch3mon('*', expp);
expp_tp = (*expp)->ex_type; expp_tp = (*expp)->ex_type;
} }
#else
if (expp_tp->tp_fund != POINTER
|| expp->tp_up->tp_fund != FUNCTION) {
expr_error(*expp, "call of non-function (%s)",
symbol2str(expp_tp->tp_fund));
/* leave the expression; it may still serve */
free_expression(expr); /* there go the parameters */
*expp = new_oper(error_type,
*expp, '(', (struct expr *)0);
}
#endif
#if 1
if (expp_tp->tp_fund != FUNCTION) { if (expp_tp->tp_fund != FUNCTION) {
expr_error(*expp, "call of non-function (%s)", expr_error(*expp, "call of non-function (%s)",
symbol2str(expp_tp->tp_fund)); symbol2str(expp_tp->tp_fund));
@ -97,7 +83,6 @@ ch3bin(expp, oper, expr)
*expp = new_oper(error_type, *expp = new_oper(error_type,
*expp, '(', (struct expr *)0); *expp, '(', (struct expr *)0);
} }
#endif
else else
*expp = new_oper(expp_tp->tp_up, *expp = new_oper(expp_tp->tp_up,
*expp, '(', expr); *expp, '(', expr);
@ -105,8 +90,6 @@ ch3bin(expp, oper, expr)
break; break;
case PARCOMMA: /* 3.3.2.2 */ case PARCOMMA: /* 3.3.2.2 */
if (expp_tp->tp_fund == FUNCTION)
function2pointer(*expp);
*expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr); *expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
break; break;
@ -250,8 +233,7 @@ ch3bin(expp, oper, expr)
case ':': case ':':
if (is_struct_or_union(expp_tp->tp_fund) if (is_struct_or_union(expp_tp->tp_fund)
|| is_struct_or_union(expr->ex_type->tp_fund) || is_struct_or_union(expr->ex_type->tp_fund)) {
) {
if (!equal_type(expp_tp, expr->ex_type, -1)) if (!equal_type(expp_tp, expr->ex_type, -1))
expr_error(*expp, "illegal balance"); expr_error(*expp, "illegal balance");
} }
@ -333,9 +315,10 @@ mk_binop(expp, oper, expr, commutative)
else if (is_fp_cst(expr) && is_fp_cst(ex)) else if (is_fp_cst(expr) && is_fp_cst(ex))
fltcstbin(expp, oper, expr); fltcstbin(expp, oper, expr);
else { else {
*expp = (commutative && expr->ex_depth >= ex->ex_depth) ? *expp = (commutative && (expr->ex_depth >= ex->ex_depth
new_oper(ex->ex_type, expr, oper, ex) : || is_cp_cst(ex)))
new_oper(ex->ex_type, ex, oper, expr); ? new_oper(ex->ex_type, expr, oper, ex)
: new_oper(ex->ex_type, ex, oper, expr);
} }
} }

View file

@ -150,7 +150,7 @@ ch3mon(oper, expp)
(arith)((*expp)->SG_LEN) : (arith)((*expp)->SG_LEN) :
size_of_type((*expp)->ex_type, size_of_type((*expp)->ex_type,
symbol2str((*expp)->ex_type->tp_fund)) symbol2str((*expp)->ex_type->tp_fund))
, INT); , ULONG);
expr->ex_flags |= EX_SIZEOF; expr->ex_flags |= EX_SIZEOF;
free_expression(*expp); free_expression(*expp);
*expp = expr; *expp = expr;

View file

@ -146,7 +146,7 @@ size_of(register struct expr **expp;)
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp) cast(&tp)
{ {
*expp = intexpr(size_of_type(tp, "type"), INT); *expp = intexpr(size_of_type(tp, "type"), ULONG);
(*expp)->ex_flags |= EX_SIZEOF; (*expp)->ex_flags |= EX_SIZEOF;
} }
| |

View file

@ -63,10 +63,24 @@ SkipToNewLine()
{ {
register int ch; register int ch;
register int garbage = 0; register int garbage = 0;
#ifndef NOPP
register int delim = 0;
#endif
while ((ch = GetChar()) != '\n') { while ((ch = GetChar()) != '\n') {
#ifndef NOPP #ifndef NOPP
if (ch == '/') { if (delim) {
if (ch == '\\') {
if (GetChar() == '\n') break;
} else if (ch == delim) {
delim = 0;
}
continue;
}
else if (ch == '\'' || ch == '\"') {
delim = ch;
garbage = 1;
} else if (ch == '/') {
if ((ch = GetChar()) == '*' if ((ch = GetChar()) == '*'
&& !InputLevel && !InputLevel
) { ) {
@ -78,6 +92,9 @@ SkipToNewLine()
if (!is_wsp(ch)) if (!is_wsp(ch))
garbage = 1; garbage = 1;
} }
#ifndef NOPP
if (delim) strict("unclosed opening %c", delim);
#endif
++LineNumber; ++LineNumber;
return garbage; return garbage;
} }