2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: ch7bin.c,v 3.23 1994/06/24 12:02:28 ceriel Exp $ */
6 /* SEMANTIC ANALYSIS (CHAPTER 7RM) -- BINARY OPERATORS */
8 #include "botch_free.h"
19 #include "noRoption.h"
21 extern char options[];
22 extern char *symbol2str();
24 /* This chapter asks for the repeated application of code to handle
25 an operation that may be executed at compile time or at run time,
26 depending on the constancy of the operands.
29 #define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
30 #define non_commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 0)
32 ch7bin(expp, oper, expr)
33 register struct expr **expp;
36 /* apply binary operator oper between *expp and expr.
37 NB: don't swap operands if op is one of the op= operators!!!
41 any2opnd(&expr, oper);
43 case '[': /* RM 7.1 */
44 /* RM 14.3 states that indexing follows the commutative laws */
45 switch ((*expp)->ex_type->tp_fund) {
51 default: /* unindexable */
52 switch (expr->ex_type->tp_fund) {
60 "indexing an object of type %s",
61 symbol2str((*expp)->ex_type->tp_fund));
66 ch7bin(expp, '+', expr);
70 case '(': /* RM 7.1 */
71 if ( (*expp)->ex_type->tp_fund == POINTER &&
72 (*expp)->ex_type->tp_up->tp_fund == FUNCTION
76 warning("function pointer called");
77 #endif /* NOROPTION */
80 switch ((*expp)->ex_type->tp_fund) {
82 *expp = new_oper((*expp)->ex_type->tp_up,
85 default: /* uncallable */
86 expr_error(*expp, "calling an object of type %s",
87 symbol2str((*expp)->ex_type->tp_fund));
88 case ERRONEOUS: /* uncallable but no message */
89 /* leave the expression; it may still serve */
90 free_expression(expr); /* there go the parameters */
93 (*expp)->ex_flags |= EX_SIDEEFFECTS;
96 case PARCOMMA: /* RM 7.1 */
97 if ((*expp)->ex_type->tp_fund == FUNCTION)
98 function2pointer(*expp);
99 *expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
107 opnd2integral(expp, oper);
108 opnd2integral(&expr, oper);
113 arithbalance(expp, oper, &expr);
114 non_commutative_binop(expp, oper, expr);
115 if (oper != '/' && oper != '%') {
116 (*expp)->ex_flags |= EX_SIDEEFFECTS;
123 opnd2integral(expp, oper);
124 opnd2integral(&expr, oper);
127 arithbalance(expp, oper, &expr);
128 commutative_binop(expp, oper, expr);
132 if (expr->ex_type->tp_fund == POINTER) { /* swap operands */
133 struct expr *etmp = expr;
141 if ((*expp)->ex_type->tp_fund == POINTER) {
142 pointer_arithmetic(expp, oper, &expr);
143 if (expr->ex_type->tp_size != (*expp)->ex_type->tp_size)
144 ch7cast(&expr, CAST, (*expp)->ex_type);
145 pointer_binary(expp, oper, expr);
148 arithbalance(expp, oper, &expr);
150 commutative_binop(expp, oper, expr);
152 non_commutative_binop(expp, oper, expr);
155 (*expp)->ex_flags |= EX_SIDEEFFECTS;
163 if ((*expp)->ex_type->tp_fund == POINTER) {
164 if (expr->ex_type->tp_fund == POINTER)
165 pntminuspnt(expp, oper, expr);
167 pointer_arithmetic(expp, oper, &expr);
168 pointer_binary(expp, oper, expr);
172 arithbalance(expp, oper, &expr);
173 non_commutative_binop(expp, oper, expr);
176 (*expp)->ex_flags |= EX_SIDEEFFECTS;
184 opnd2integral(expp, oper);
185 opnd2integral(&expr, oper);
186 arithbalance(expp, oper, &expr); /* ch. 7.5 */
187 ch7cast(&expr, oper, int_type); /* cvt. rightop to int */
188 non_commutative_binop(expp, oper, expr);
189 if (oper != LEFT && oper != RIGHT) {
190 (*expp)->ex_flags |= EX_SIDEEFFECTS;
200 relbalance(expp, oper, &expr);
201 if (oper == EQUAL || oper == NOTEQUAL) {
202 commutative_binop(expp, oper, expr);
204 else non_commutative_binop(expp, oper, expr);
205 (*expp)->ex_type = int_type;
210 opnd2test(expp, oper);
211 opnd2test(&expr, oper);
212 if (is_cp_cst(*expp)) {
213 register struct expr *ex = *expp;
215 /* the following condition is a short-hand for
216 ((oper == AND) && o1) || ((oper == OR) && !o1)
217 where o1 == (*expp)->VL_VALUE;
218 and ((oper == AND) || (oper == OR))
220 if ((oper == AND) == (ex->VL_VALUE != (arith)0))
223 ex->ex_flags |= expr->ex_flags;
224 free_expression(expr);
225 *expp = intexpr((arith)((oper == AND) ? 0 : 1),
228 (*expp)->ex_flags |= ex->ex_flags;
232 if (is_cp_cst(expr)) {
233 /* Note!!!: the following condition is a short-hand for
234 ((oper == AND) && o2) || ((oper == OR) && !o2)
235 where o2 == expr->VL_VALUE
236 and ((oper == AND) || (oper == OR))
238 if ((oper == AND) == (expr->VL_VALUE != (arith)0)) {
239 (*expp)->ex_flags |= expr->ex_flags;
240 free_expression(expr);
244 expr->VL_VALUE = (arith)1;
245 ch7bin(expp, ',', expr);
249 *expp = new_oper(int_type, *expp, oper, expr);
250 (*expp)->ex_flags |= EX_LOGICAL;
254 if ( is_struct_or_union((*expp)->ex_type->tp_fund)
255 || is_struct_or_union(expr->ex_type->tp_fund)
257 if ((*expp)->ex_type != expr->ex_type)
258 expr_error(*expp, "illegal balance");
261 relbalance(expp, oper, &expr);
263 if ( (is_cp_cst(*expp) && is_cp_cst(expr))
264 && (*expp)->VL_VALUE == expr->VL_VALUE
266 hwarning("operands of : are constant and equal");
269 *expp = new_oper((*expp)->ex_type, *expp, oper, expr);
273 opnd2logical(expp, oper);
274 if (is_cp_cst(*expp)) {
276 hwarning("condition in ?: expression is constant");
278 *expp = (*expp)->VL_VALUE ?
279 expr->OP_LEFT : expr->OP_RIGHT;
282 *expp = new_oper(expr->ex_type, *expp, oper, expr);
287 if (is_cp_cst(*expp)) {
289 hwarning("constant expression ignored");
294 *expp = new_oper(expr->ex_type, *expp, oper, expr);
296 (*expp)->ex_flags |= EX_COMMA;
301 pntminuspnt(expp, oper, expr)
302 register struct expr **expp, *expr;
304 /* Subtracting two pointers is so complicated it merits a
307 struct type *up_type = (*expp)->ex_type->tp_up;
309 if (up_type != expr->ex_type->tp_up) {
310 expr_error(*expp, "subtracting incompatible pointers");
311 free_expression(expr);
315 /* we hope the optimizer will eliminate the load-time
318 *expp = new_oper((*expp)->ex_type, *expp, oper, expr);
319 ch7cast(expp, CAST, pa_type); /* ptr-ptr: result has pa_type */
321 intexpr(size_of_type(up_type, "object"), pa_type->tp_fund));
322 ch7cast(expp, CAST, int_type); /* result will be an integer expr */
325 mk_binop(expp, oper, expr, commutative)
327 register struct expr *expr;
329 /* Constructs in *expp the operation indicated by the operands.
330 "commutative" indicates whether "oper" is a commutative
333 register struct expr *ex = *expp;
335 if (is_cp_cst(expr) && is_cp_cst(ex))
336 cstbin(expp, oper, expr);
338 *expp = (commutative &&
339 ( expr->ex_depth > ex->ex_depth ||
340 (expr->ex_flags & EX_SIDEEFFECTS) ||
342 new_oper(ex->ex_type, expr, oper, ex) :
343 new_oper(ex->ex_type, ex, oper, expr);
347 pointer_arithmetic(expp1, oper, expp2)
348 register struct expr **expp1, **expp2;
350 /* prepares the integral expression expp2 in order to
351 apply it to the pointer expression expp1
354 if (any2arith(expp2, oper) == DOUBLE) {
356 "illegal combination of float and pointer");
357 erroneous2int(expp2);
361 intexpr(size_of_type((*expp1)->ex_type->tp_up, "object"),
366 pointer_binary(expp, oper, expr)
367 register struct expr **expp, *expr;
369 /* constructs the pointer arithmetic expression out of
370 a pointer expression, a binary operator and an integral
373 if (is_ld_cst(expr) && is_ld_cst(*expp))
374 cstbin(expp, oper, expr);
376 *expp = new_oper((*expp)->ex_type, *expp, oper, expr);