*/
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
register int ch, nch;
- int nlflag = 0;
token_nmb++;
for (;;) {
ch = GetChar();
- if (vch = hex_val(ch), vch == -1)
+ if ((vch = hex_val(ch)) == -1)
break;
hex = hex * 16 + vch;
}
register struct expr **e1p, **e2p;
{
/* 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)
- function2pointer(*e1p);
- if ((*e2p)->ex_type->tp_fund == FUNCTION)
- function2pointer(*e2p);
- if ((*e1p)->ex_type->tp_fund == POINTER)
- ch3pointer(e2p, oper, (*e1p)->ex_type);
- else if ((*e2p)->ex_type->tp_fund == POINTER)
- ch3pointer(e1p, oper, (*e2p)->ex_type);
- else if ((*e1p)->ex_type == (*e2p)->ex_type
- && (*e1p)->ex_type->tp_fund == ENUM) {}
+ register struct expr *e1 = *e1p, *e2 = *e2p;
+ struct expr *tmpexpr;
+
+ if (e1->ex_type->tp_fund == POINTER
+ && is_cp_cst(e1)
+ && e1->VL_VALUE == 0) {
+ tmpexpr = e1;
+ e1 = e2;
+ e2 = tmpexpr;
+ }
+ 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 == ':'
- && (*e1p)->ex_type->tp_fund == VOID
- && (*e2p)->ex_type->tp_fund == VOID) {}
+ && e1->ex_type->tp_fund == VOID
+ && e2->ex_type->tp_fund == VOID) {}
else
arithbalance(e1p, oper, e2p);
}
(*expp)->ex_type = void_type;
return;
}
- if ((*expp)->ex_type->tp_fund == FUNCTION)
+ if ((*expp)->ex_type->tp_fund == FUNCTION) {
function2pointer(*expp);
+ }
if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp);
if ((*expp)->ex_class == String)
case '=':
case CASTAB:
case RETURN:
+ case ':':
if (tp->tp_up && oldtp->tp_up) {
if (tp->tp_up->tp_fund == VOID
&& oldtp->tp_up->tp_fund != FUNCTION) {
&& tp->tp_up->tp_fund != FUNCTION) {
break; /* switch */
}
+ if (oldtp->tp_up->tp_fund == VOID
+ && is_cp_cst(*expp)
+ && (*expp)->VL_VALUE == (arith)0)
+ break; /* switch */
}
/* falltrough */
default:
if (oper == CASTAB)
- expr_warning(*expp, "incompatible pointers");
+ expr_strict(*expp, "incompatible pointers in call");
else
- expr_warning(*expp, "incompatible pointers in %s",
+ expr_strict(*expp, "incompatible pointers in %s",
symbol2str(oper));
break;
case CAST: break;
break;
case '(': /* 3.3.2.2 */
-#if 1
- if ( expp_tp->tp_fund == POINTER &&
- expp_tp->tp_up->tp_fund == FUNCTION
- ) {
+ if (expp_tp->tp_fund == POINTER
+ && expp_tp->tp_up->tp_fund == FUNCTION) {
ch3mon('*', expp);
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) {
expr_error(*expp, "call of non-function (%s)",
symbol2str(expp_tp->tp_fund));
*expp = new_oper(error_type,
*expp, '(', (struct expr *)0);
}
-#endif
else
*expp = new_oper(expp_tp->tp_up,
*expp, '(', expr);
break;
case PARCOMMA: /* 3.3.2.2 */
- if (expp_tp->tp_fund == FUNCTION)
- function2pointer(*expp);
*expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
break;
break;
case ':':
- if ( is_struct_or_union(expp_tp->tp_fund)
- || is_struct_or_union(expr->ex_type->tp_fund)
- ) {
+ if (is_struct_or_union(expp_tp->tp_fund)
+ || is_struct_or_union(expr->ex_type->tp_fund)) {
if (!equal_type(expp_tp, expr->ex_type, -1))
expr_error(*expp, "illegal balance");
}
- else
+ else
relbalance(expp, oper, &expr);
#ifdef LINT
if ( (is_cp_cst(*expp) && is_cp_cst(expr))
else if (is_fp_cst(expr) && is_fp_cst(ex))
fltcstbin(expp, oper, expr);
else {
- *expp = (commutative && expr->ex_depth >= ex->ex_depth) ?
- new_oper(ex->ex_type, expr, oper, ex) :
- new_oper(ex->ex_type, ex, oper, expr);
+ *expp = (commutative && (expr->ex_depth >= ex->ex_depth
+ || is_cp_cst(ex)))
+ ? new_oper(ex->ex_type, expr, oper, ex)
+ : new_oper(ex->ex_type, ex, oper, expr);
}
}
(arith)((*expp)->SG_LEN) :
size_of_type((*expp)->ex_type,
symbol2str((*expp)->ex_type->tp_fund))
- , INT);
+ , ULONG);
expr->ex_flags |= EX_SIZEOF;
free_expression(*expp);
*expp = expr;
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp)
{
- *expp = intexpr(size_of_type(tp, "type"), INT);
+ *expp = intexpr(size_of_type(tp, "type"), ULONG);
(*expp)->ex_flags |= EX_SIZEOF;
}
|
{
register int ch;
register int garbage = 0;
+#ifndef NOPP
+ register int delim = 0;
+#endif
while ((ch = GetChar()) != '\n') {
#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()) == '*'
&& !InputLevel
) {
if (!is_wsp(ch))
garbage = 1;
}
+#ifndef NOPP
+ if (delim) strict("unclosed opening %c", delim);
+#endif
++LineNumber;
return garbage;
}