Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "c_types.h"
33
#include "exp_ops.h"
34
#include "id_ops.h"
35
#include "off_ops.h"
36
#include "type_ops.h"
37
#include "error.h"
38
#include "catalog.h"
39
#include "assign.h"
40
#include "basetype.h"
41
#include "cast.h"
42
#include "construct.h"
43
#include "convert.h"
44
#include "chktype.h"
45
#include "expression.h"
46
#include "identifier.h"
47
#include "initialise.h"
48
#include "literal.h"
49
#include "member.h"
50
#include "operator.h"
51
#include "predict.h"
52
#include "syntax.h"
53
#include "ustring.h"
54
 
55
 
56
/*
57
    CONVERT BY ASSIGNMENT
58
 
59
    This routine converts the expression a to the type t, as if by
60
    assignment.  The cases where t is a class type or a reference are
61
    handled elsewhere.
62
*/
63
 
64
EXP convert_assign
65
    PROTO_N ( ( t, a, err ) )
66
    PROTO_T ( TYPE t X EXP a X ERROR *err )
67
{
68
    EXP e = cast_exp ( t, a, err, CAST_IMPLICIT ) ;
69
    return ( e ) ;
70
}
71
 
72
 
73
/*
74
    CONVERT TO A CLASS TYPE BY ASSIGNMENT
75
 
76
    This routine converts the expression a to the class t, as if by
77
    assignment.  The constructors of t are ignored, only base class
78
    conversions and conversion operators being considered.
79
*/
80
 
81
EXP convert_class
82
    PROTO_N ( ( t, a, err ) )
83
    PROTO_T ( TYPE t X EXP a X ERROR *err )
84
{
85
    EXP e ;
86
    TYPE s = DEREF_type ( exp_type ( a ) ) ;
87
    if ( IS_type_compound ( s ) ) {
88
	e = cast_class_class ( t, a, err, CAST_IMPLICIT, 0 ) ;
89
	if ( !IS_NULL_exp ( e ) ) return ( e ) ;
90
    }
91
    e = convert_conv ( t, a, err, CAST_IMPLICIT ) ;
92
    return ( e ) ;
93
}
94
 
95
 
96
/*
97
    CONSTRUCT A POSTFIX EXPRESSION
98
 
99
    This routine constructs the expressions 'a++' and 'a--'.  Note that
100
    in this and other assignment expressions, a cannot have array type,
101
    so that no bounds checks are appropriate.  The result is an rvalue.
102
*/
103
 
104
EXP make_postfix_exp
105
    PROTO_N ( ( op, a ) )
106
    PROTO_T ( int op X EXP a )
107
{
108
    EXP e ;
109
    TYPE ta ;
110
    ERROR err ;
111
    unsigned ca ;
112
 
113
    /* An assignment is a side effect */
114
    no_side_effects++ ;
115
 
116
    /* Allow for reference conversions */
117
    a = convert_reference ( a, REF_NORMAL ) ;
118
    ta = DEREF_type ( exp_type ( a ) ) ;
119
    ca = type_category ( &ta ) ;
120
 
121
    /* Check for overloading */
122
#if LANGUAGE_CPP
123
    if ( IS_TYPE_OVERLOAD ( ca ) ) {
124
	if ( overload_depth == 0 ) {
125
	    /* Overloads as 'operator op ( a, 0 )' */
126
	    EXP b = make_null_exp ( type_sint ) ;
127
	    e = binary_overload ( op, a, b ) ;
128
	    return ( e ) ;
129
	}
130
	if ( IS_TYPE_CLASS ( ca ) ) goto error_lab ;
131
    }
132
#else
133
    if ( IS_TYPE_CLASS ( ca ) ) goto error_lab ;
134
#endif
135
 
136
    /* Operand should be a modifiable lvalue */
137
    err = check_modifiable ( ta, a ) ;
138
    if ( !IS_NULL_err ( err ) ) {
139
	err = concat_error ( err, ERR_expr_post_incr_mod ( op ) ) ;
140
	report ( crt_loc, err ) ;
141
	err = NULL_err ;
142
    }
143
 
144
    /* Operand can be arithmetic ... */
145
    if ( IS_TYPE_ARITH ( ca ) ) {
146
	EXP b ;
147
	TYPE t ;
148
	TYPE tb ;
149
	OFFSET off = NULL_off ;
150
 
151
	/* Allow for bitfields */
152
	if ( IS_TYPE_BITF ( ca ) ) off = decons_bitf_exp ( &a ) ;
153
 
154
	/* Form the result */
155
	MAKE_exp_dummy ( ta, a, LINK_NONE, off, 0, a ) ;
156
	b = convert_lvalue ( a ) ;
157
	tb = DEREF_type ( exp_type ( b ) ) ;
158
	t = promote_type ( tb ) ;
159
	if ( IS_NULL_off ( off ) ) {
160
	    MAKE_exp_dummy ( tb, b, LINK_NONE, NULL_off, 0, b ) ;
161
	    e = convert_promote ( t, b ) ;
162
	} else {
163
	    b = convert_promote ( t, b ) ;
164
	    MAKE_exp_dummy ( t, b, LINK_NONE, NULL_off, 0, b ) ;
165
	    e = b ;
166
	    tb = t ;
167
	}
168
	if ( check_int_type ( ta, btype_bool ) ) {
169
	    /* Booleans are weird */
170
	    unsigned v = BOOL_TRUE ;
171
	    if ( op == lex_plus_Hplus ) {
172
		report ( crt_loc, ERR_expr_post_incr_bool_inc ( op, ta ) ) ;
173
	    } else {
174
		report ( crt_loc, ERR_expr_post_incr_bool_dec ( op, ta ) ) ;
175
		v = BOOL_FALSE ;
176
	    }
177
	    e = make_bool_exp ( v, exp_int_lit_tag ) ;
178
	} else {
179
	    /* Other types are simple */
180
	    EXP c = make_unit_exp ( t ) ;
181
	    if ( op == lex_plus_Hplus ) {
182
		MAKE_exp_plus ( t, e, c, e ) ;
183
	    } else {
184
		MAKE_exp_minus ( t, e, c, e ) ;
185
	    }
186
	    e = convert_assign ( ta, e, &err ) ;
187
	    if ( !IS_NULL_err ( err ) ) {
188
		err = concat_warning ( err, ERR_expr_ass_conv () ) ;
189
		report ( crt_loc, err ) ;
190
	    }
191
	}
192
	MAKE_exp_postinc ( tb, a, b, e, e ) ;
193
	return ( e ) ;
194
    }
195
 
196
    /* ... or pointer ... */
197
    if ( IS_TYPE_PTR ( ca ) ) {
198
	/* Pointer must be to complete object type */
199
	EXP b ;
200
	OFFSET off ;
201
	TYPE t = check_pointer ( ta, &err ) ;
202
	if ( !IS_NULL_err ( err ) ) {
203
	    err = concat_error ( err, ERR_expr_post_incr_incompl ( op ) ) ;
204
	    report ( crt_loc, err ) ;
205
	}
206
	if ( IS_type_top_etc ( t ) ) t = type_char ;
207
 
208
	/* Create the identities */
209
	MAKE_exp_dummy ( ta, a, LINK_NONE, NULL_off, 0, a ) ;
210
	b = convert_lvalue ( a ) ;
211
	ta = DEREF_type ( exp_type ( b ) ) ;
212
	MAKE_exp_dummy ( ta, b, LINK_NONE, NULL_off, 0, b ) ;
213
 
214
	/* Form the result */
215
	MAKE_off_type ( t, off ) ;
216
	if ( op == lex_minus_Hminus ) MAKE_off_negate ( off, off ) ;
217
	e = make_add_ptr ( ta, b, off ) ;
218
	MAKE_exp_postinc ( ta, a, b, e, e ) ;
219
	return ( e ) ;
220
    }
221
 
222
    /* ... and nothing else */
223
    error_lab : {
224
	if ( !IS_TYPE_ERROR ( ca ) ) {
225
	    report ( crt_loc, ERR_expr_post_incr_op ( op, ta ) ) ;
226
	}
227
    }
228
    e = make_error_exp ( 0 ) ;
229
    return ( e ) ;
230
}
231
 
232
 
233
/*
234
    CREATE A PRE-INCREMENT EXPRESSION
235
 
236
    This routine creates a pre-increment or assignment expression for
237
    the expression a of type t given by the operation b.  If a is a
238
    bitfield then off gives the bitfield offset.  The result is an
239
    lvalue in C++, but an rvalue in C.  There is a slight problem in the
240
    latter case when t is a bitfield: the value is not b, but
241
    convert_bitfield ( b ).  This conversion is left implicit, and is
242
    only made explicit in the TDF output routines.
243
*/
244
 
245
static EXP make_preinc_exp
246
    PROTO_N ( ( t, a, b, off, op ) )
247
    PROTO_T ( TYPE t X EXP a X EXP b X OFFSET off X int op )
248
{
249
    EXP e ;
250
#if LANGUAGE_C
251
    t = rvalue_type ( t ) ;
252
#endif
253
    if ( IS_NULL_off ( off ) ) {
254
	/* Simple case */
255
	if ( op == lex_assign ) {
256
	    MAKE_exp_assign ( t, a, b, e ) ;
257
	} else {
258
	    MAKE_exp_preinc ( t, a, b, op, e ) ;
259
	}
260
    } else {
261
	/* Bitfield case */
262
#if LANGUAGE_C
263
	MAKE_exp_preinc ( t, a, b, op, e ) ;
264
	t = promote_type ( t ) ;
265
#else
266
	TYPE p ;
267
	TYPE s = find_bitfield_type ( t ) ;
268
	MAKE_type_ptr ( cv_none, s, p ) ;
269
	s = lvalue_type ( s ) ;
270
	MAKE_exp_preinc ( s, a, b, op, e ) ;
271
	MAKE_exp_address ( p, e, e ) ;
272
	MAKE_exp_add_ptr ( p, e, off, 0, e ) ;
273
	MAKE_exp_indir ( t, e, e ) ;
274
#endif
275
    }
276
#if LANGUAGE_C
277
    MAKE_exp_contents ( t, e, e ) ;
278
#endif
279
    return ( e ) ;
280
}
281
 
282
 
283
/*
284
    CONSTRUCT A PREFIX EXPRESSION
285
 
286
    This routine constructs the expressions '++a' and '--a'.  The result is
287
    an lvalue in C++ but an rvalue in C.
288
*/
289
 
290
EXP make_prefix_exp
291
    PROTO_N ( ( op, a ) )
292
    PROTO_T ( int op X EXP a )
293
{
294
    EXP e ;
295
    TYPE ta ;
296
    ERROR err ;
297
    unsigned ca ;
298
 
299
    /* An assignment is a side effect */
300
    no_side_effects++ ;
301
 
302
    /* Allow for reference conversions */
303
    a = convert_reference ( a, REF_NORMAL ) ;
304
    ta = DEREF_type ( exp_type ( a ) ) ;
305
    ca = type_category ( &ta ) ;
306
 
307
    /* Check for overloading */
308
#if LANGUAGE_CPP
309
    if ( IS_TYPE_OVERLOAD ( ca ) ) {
310
	if ( overload_depth == 0 ) {
311
	    /* Overloads as 'operator op ( a )' */
312
	    e = unary_overload ( op, a ) ;
313
	    return ( e ) ;
314
	}
315
	if ( IS_TYPE_CLASS ( ca ) ) goto error_lab ;
316
    }
317
#else
318
    if ( IS_TYPE_CLASS ( ca ) ) goto error_lab ;
319
#endif
320
 
321
    /* Operand should be a modifiable lvalue */
322
    err = check_modifiable ( ta, a ) ;
323
    if ( !IS_NULL_err ( err ) ) {
324
	err = concat_error ( err, ERR_expr_pre_incr_mod ( op ) ) ;
325
	report ( crt_loc, err ) ;
326
	err = NULL_err ;
327
    }
328
 
329
    /* Operand can be arithmetic ... */
330
    if ( IS_TYPE_ARITH ( ca ) ) {
331
	EXP c ;
332
	TYPE t ;
333
	OFFSET off = NULL_off ;
334
 
335
	/* Booleans are weird */
336
	if ( check_int_type ( ta, btype_bool ) ) {
337
	    unsigned v = BOOL_TRUE ;
338
	    if ( op == lex_plus_Hplus ) {
339
		report ( crt_loc, ERR_expr_pre_incr_bool_inc ( op, ta ) ) ;
340
	    } else {
341
		report ( crt_loc, ERR_expr_pre_incr_bool_dec ( op, ta ) ) ;
342
		v = BOOL_FALSE ;
343
	    }
344
	    c = make_bool_exp ( v, exp_int_lit_tag ) ;
345
	    e = make_preinc_exp ( ta, a, c, NULL_off, lex_assign ) ;
346
	    return ( e ) ;
347
	}
348
 
349
	/* Allow for bitfields */
350
	if ( IS_TYPE_BITF ( ca ) ) off = decons_bitf_exp ( &a ) ;
351
 
352
	/* Form the result */
353
	MAKE_exp_dummy ( ta, a, LINK_NONE, off, 0, a ) ;
354
	e = convert_lvalue ( a ) ;
355
	t = DEREF_type ( exp_type ( e ) ) ;
356
	t = promote_type ( t ) ;
357
	e = convert_promote ( t, e ) ;
358
	c = make_unit_exp ( t ) ;
359
	if ( op == lex_plus_Hplus ) {
360
	    MAKE_exp_plus ( t, e, c, e ) ;
361
	} else {
362
	    MAKE_exp_minus ( t, e, c, e ) ;
363
	}
364
	e = convert_assign ( ta, e, &err ) ;
365
	if ( !IS_NULL_err ( err ) ) {
366
	    err = concat_warning ( err, ERR_expr_ass_conv () ) ;
367
	    report ( crt_loc, err ) ;
368
	}
369
	e = make_preinc_exp ( ta, a, e, off, op ) ;
370
	return ( e ) ;
371
    }
372
 
373
    /* ... or pointer ... */
374
    if ( IS_TYPE_PTR ( ca ) ) {
375
	/* Pointer must be to complete object type */
376
	OFFSET off ;
377
	TYPE t = check_pointer ( ta, &err ) ;
378
	if ( !IS_NULL_err ( err ) ) {
379
	    err = concat_error ( err, ERR_expr_pre_incr_incompl ( op ) ) ;
380
	    report ( crt_loc, err ) ;
381
	}
382
	if ( IS_type_top_etc ( t ) ) t = type_char ;
383
 
384
	/* Form the result */
385
	MAKE_exp_dummy ( ta, a, LINK_NONE, NULL_off, 0, a ) ;
386
	e = convert_lvalue ( a ) ;
387
	if ( !IS_type_ptr ( ta ) ) ta = DEREF_type ( exp_type ( e ) ) ;
388
	MAKE_off_type ( t, off ) ;
389
	if ( op == lex_minus_Hminus ) MAKE_off_negate ( off, off ) ;
390
	e = make_add_ptr ( ta, e, off ) ;
391
	e = make_preinc_exp ( ta, a, e, NULL_off, op ) ;
392
	return ( e ) ;
393
    }
394
 
395
    /* ... and nothing else */
396
    error_lab : {
397
	if ( !IS_TYPE_ERROR ( ca ) ) {
398
	    report ( crt_loc, ERR_expr_pre_incr_op ( op, ta ) ) ;
399
	}
400
	e = make_error_exp ( LANGUAGE_CPP ) ;
401
	return ( e ) ;
402
    }
403
}
404
 
405
 
406
/*
407
    CONSTRUCT AN ASSIGNMENT EXPRESSION
408
 
409
    This routine constructs the expression 'a = b'.  If c is true then
410
    assignment of classes is done directly rather than via an assignment
411
    operator.  The result is an lvalue in C++ but an rvalue in C.
412
*/
413
 
414
EXP make_assign_exp
415
    PROTO_N ( ( a, b, c ) )
416
    PROTO_T ( EXP a X EXP b X int c )
417
{
418
    EXP e ;
419
    ERROR err ;
420
    TYPE ta, tb ;
421
    unsigned ca, cb ;
422
    int to_class = 0 ;
423
    int op = lex_assign ;
424
    OFFSET off = NULL_off ;
425
 
426
    /* An assignment is a side effect */
427
    no_side_effects++ ;
428
 
429
    /* Apply reference conversion on first operand */
430
    a = convert_reference ( a, REF_NORMAL ) ;
431
    ta = DEREF_type ( exp_type ( a ) ) ;
432
    ca = type_category ( &ta ) ;
433
 
434
    /* Apply reference conversion on second operand */
435
    b = convert_reference ( b, REF_ASSIGN ) ;
436
    tb = DEREF_type ( exp_type ( b ) ) ;
437
    cb = type_category ( &tb ) ;
438
 
439
    /* Check for template parameters */
440
#if LANGUAGE_CPP
441
    if ( IS_TYPE_TEMPL ( ca ) || IS_TYPE_TEMPL ( cb ) ) {
442
	if ( overload_depth == 0 ) {
443
	    e = binary_overload ( op, a, b ) ;
444
	    return ( e ) ;
445
	}
446
    }
447
#endif
448
 
449
    /* Check for overloading (classes only) */
450
    if ( IS_TYPE_CLASS ( ca ) ) {
451
#if LANGUAGE_CPP
452
	if ( c == 0 ) {
453
	    if ( overload_depth == 0 ) {
454
		e = binary_overload ( op, a, b ) ;
455
		return ( e ) ;
456
	    }
457
	    if ( !IS_TYPE_ERROR ( cb ) ) {
458
		/* Find reason for failure */
459
		err = check_incomplete ( ta ) ;
460
		if ( IS_NULL_err ( err ) && IS_type_compound ( ta ) ) {
461
		    CLASS_TYPE ct ;
462
		    IDENTIFIER id ;
463
		    ct = DEREF_ctype ( type_compound_defn ( ta ) ) ;
464
		    id = find_operator ( ct, op ) ;
465
		    if ( !IS_NULL_id ( id ) ) {
466
			err = ERR_over_match_viable_none ( id ) ;
467
		    }
468
		}
469
		err = concat_error ( err, ERR_expr_ass_op ( op, ta, tb ) ) ;
470
		report ( crt_loc, err ) ;
471
	    }
472
	    e = make_error_exp ( LANGUAGE_CPP ) ;
473
	    return ( e ) ;
474
	}
475
#else
476
	UNUSED ( c ) ;
477
	UNUSED ( cb ) ;
478
#endif
479
	to_class = 1 ;
480
    }
481
 
482
    /* First operand should be a modifiable lvalue */
483
    err = check_modifiable ( ta, a ) ;
484
    if ( !IS_NULL_err ( err ) ) {
485
	err = concat_error ( err, ERR_expr_ass_mod ( op ) ) ;
486
	report ( crt_loc, err ) ;
487
    }
488
 
489
    /* Do operand conversion */
490
    err = NULL_err ;
491
    if ( to_class ) {
492
	b = convert_none ( b ) ;
493
	b = convert_class ( ta, b, &err ) ;
494
	b = remove_temporary ( b, a ) ;
495
    } else {
496
	b = convert_assign ( ta, b, &err ) ;
497
    }
498
    if ( !IS_NULL_err ( err ) ) {
499
	err = concat_warning ( err, ERR_expr_ass_conv () ) ;
500
	report ( crt_loc, err ) ;
501
    }
502
 
503
    /* Construct the result */
504
    if ( IS_type_bitfield ( ta ) ) {
505
	off = decons_bitf_exp ( &a ) ;
506
	MAKE_exp_dummy ( ta, a, LINK_NONE, off, 0, a ) ;
507
    }
508
    e = make_preinc_exp ( ta, a, b, off, op ) ;
509
    return ( e ) ;
510
}
511
 
512
 
513
/*
514
    CONSTRUCT A BECOMES EXPRESSION
515
 
516
    This routine constructs the expression 'a op b' where op is one of the
517
    assignment operators, '*=', '/=' etc.  The result is an lvalue in
518
    C++, but an rvalue in C.
519
*/
520
 
521
EXP make_become_exp
522
    PROTO_N ( ( op, a, b ) )
523
    PROTO_T ( int op X EXP a X EXP b )
524
{
525
    EXP e ;
526
    EXP d ;
527
    TYPE td ;
528
    ERROR err ;
529
    TYPE ta, tb ;
530
    unsigned tag ;
531
    unsigned ca, cb ;
532
    OFFSET off = NULL_off ;
533
 
534
    /* An assignment is a side effect */
535
    no_side_effects++ ;
536
 
537
    /* Apply reference conversion on first operand */
538
    a = convert_reference ( a, REF_NORMAL ) ;
539
    ta = DEREF_type ( exp_type ( a ) ) ;
540
    ca = type_category ( &ta ) ;
541
 
542
    /* Apply reference conversion on second operand */
543
    b = convert_reference ( b, REF_NORMAL ) ;
544
    tb = DEREF_type ( exp_type ( b ) ) ;
545
    cb = type_category ( &tb ) ;
546
 
547
    /* Allow for overloading */
548
#if LANGUAGE_CPP
549
    if ( IS_TYPE_OVERLOAD ( ca ) || IS_TYPE_OVERLOAD ( cb ) ) {
550
	if ( overload_depth == 0 ) {
551
	    e = binary_overload ( op, a, b ) ;
552
	    return ( e ) ;
553
	}
554
	if ( IS_TYPE_CLASS ( ca ) ) goto error_lab ;
555
    }
556
#else
557
    if ( IS_TYPE_CLASS ( ca ) ) goto error_lab ;
558
#endif
559
 
560
    /* First operand should be a modifiable lvalue */
561
    err = check_modifiable ( ta, a ) ;
562
    if ( !IS_NULL_err ( err ) ) {
563
	err = concat_error ( err, ERR_expr_ass_mod ( op ) ) ;
564
	report ( crt_loc, err ) ;
565
	err = NULL_err ;
566
    }
567
 
568
    /* Allow for bitfields */
569
    if ( IS_TYPE_BITF ( ca ) ) off = decons_bitf_exp ( &a ) ;
570
 
571
    /* Introduce identity for assignment variable */
572
    td = ta ;
573
    MAKE_exp_dummy ( td, a, LINK_NONE, off, 0, d ) ;
574
    a = convert_lvalue ( d ) ;
575
    ta = DEREF_type ( exp_type ( a ) ) ;
576
    ca = type_category ( &ta ) ;
577
 
578
    /* Do lvalue conversions */
579
    if ( IS_TYPE_ADDRESS ( cb ) ) {
580
	b = convert_lvalue ( b ) ;
581
	tb = DEREF_type ( exp_type ( b ) ) ;
582
	cb = type_category ( &tb ) ;
583
    }
584
 
585
    /* Weed out booleans immediately */
586
    if ( IS_TYPE_INT ( ca ) && check_int_type ( ta, btype_bool ) ) {
587
	report ( crt_loc, ERR_expr_ass_op ( op, ta, tb ) ) ;
588
	e = make_error_exp ( LANGUAGE_CPP ) ;
589
	return ( e ) ;
590
    }
591
 
592
    /* Find the operation type */
593
    switch ( op ) {
594
	case lex_and_Heq_H1 : tag = exp_and_tag ; goto integral_lab ;
595
	case lex_div_Heq : tag = exp_div_tag ; goto arithmetic_lab ;
596
	case lex_lshift_Heq : tag = exp_lshift_tag ; goto shift_lab ;
597
	case lex_minus_Heq : tag = exp_minus_tag ; goto pointer_lab ;
598
	case lex_or_Heq_H1 : tag = exp_or_tag ; goto integral_lab ;
599
	case lex_plus_Heq : tag = exp_plus_tag ; goto pointer_lab ;
600
	case lex_rem_Heq : tag = exp_rem_tag ; goto integral_lab ;
601
	case lex_rshift_Heq : tag = exp_rshift_tag ; goto shift_lab ;
602
	case lex_star_Heq : tag = exp_mult_tag ; goto arithmetic_lab ;
603
	case lex_xor_Heq_H1 : tag = exp_xor_tag ; goto integral_lab ;
604
	default : goto error_lab ;
605
    }
606
 
607
    integral_lab : {
608
	/* Integral operations */
609
	if ( IS_TYPE_INT ( ca ) && IS_TYPE_INT ( cb ) ) {
610
	    TYPE t = arith_type ( ta, tb, a, b ) ;
611
	    a = convert_arith ( t, a, op, 1 ) ;
612
	    b = convert_arith ( t, b, op, 2 ) ;
613
	    if ( op == lex_rem_Heq ) {
614
		IGNORE check_div_exp ( op, a, b ) ;
615
	    }
616
	    MAKE_exp_plus_etc ( tag, t, a, b, e ) ;
617
	    e = convert_assign ( td, e, &err ) ;
618
	    if ( !IS_NULL_err ( err ) ) {
619
		err = concat_warning ( err, ERR_expr_ass_conv () ) ;
620
		report ( crt_loc, err ) ;
621
	    }
622
	    e = make_preinc_exp ( td, d, e, off, op ) ;
623
	    return ( e ) ;
624
	}
625
	goto error_lab ;
626
    }
627
 
628
    arithmetic_lab : {
629
	/* Arithmetic operations */
630
	if ( IS_TYPE_ARITH ( ca ) && IS_TYPE_ARITH ( cb ) ) {
631
	    TYPE t = arith_type ( ta, tb, a, b ) ;
632
	    a = convert_arith ( t, a, op, 1 ) ;
633
	    b = convert_arith ( t, b, op, 2 ) ;
634
	    if ( op == lex_div_Heq ) {
635
		IGNORE check_div_exp ( op, a, b ) ;
636
	    }
637
	    MAKE_exp_plus_etc ( tag, t, a, b, e ) ;
638
	    e = convert_assign ( td, e, &err ) ;
639
	    if ( !IS_NULL_err ( err ) ) {
640
		err = concat_warning ( err, ERR_expr_ass_conv () ) ;
641
		report ( crt_loc, err ) ;
642
	    }
643
	    e = make_preinc_exp ( td, d, e, off, op ) ;
644
	    return ( e ) ;
645
	}
646
	goto error_lab ;
647
    }
648
 
649
    shift_lab : {
650
	/* Shift operations */
651
	if ( IS_TYPE_INT ( ca ) && IS_TYPE_INT ( cb ) ) {
652
	    TYPE pta = promote_type ( ta ) ;
653
	    TYPE ptb = promote_type ( tb ) ;
654
	    a = convert_promote ( pta, a ) ;
655
	    b = convert_promote ( ptb, b ) ;
656
	    IGNORE check_shift_exp ( op, pta, a, b ) ;
657
	    MAKE_exp_plus_etc ( tag, pta, a, b, e ) ;
658
	    e = convert_assign ( td, e, &err ) ;
659
	    if ( !IS_NULL_err ( err ) ) {
660
		err = concat_warning ( err, ERR_expr_ass_conv () ) ;
661
		report ( crt_loc, err ) ;
662
	    }
663
	    e = make_preinc_exp ( td, d, e, off, op ) ;
664
	    return ( e ) ;
665
	}
666
	goto error_lab ;
667
    }
668
 
669
    pointer_lab : {
670
	/* Pointer or arithmetic operations */
671
	if ( IS_TYPE_PTR ( ca ) && IS_TYPE_INT ( cb ) ) {
672
	    OFFSET off1 ;
673
	    int neg = 0 ;
674
	    TYPE t = check_pointer ( ta, &err ) ;
675
	    if ( !IS_NULL_err ( err ) ) {
676
		err = concat_error ( err, ERR_expr_ass_incompl ( op ) ) ;
677
		report ( crt_loc, err ) ;
678
	    }
679
	    if ( op == lex_minus_Heq ) neg = 1 ;
680
	    off1 = make_off_mult ( t, b, neg ) ;
681
	    e = make_add_ptr ( ta, a, off1 ) ;
682
	    e = make_preinc_exp ( td, d, e, NULL_off, op ) ;
683
	    return ( e ) ;
684
	}
685
	goto arithmetic_lab ;
686
    }
687
 
688
    error_lab : {
689
	/* Bad operations */
690
	if ( !IS_TYPE_ERROR ( ca ) && !IS_TYPE_ERROR ( cb ) ) {
691
	    report ( crt_loc, ERR_expr_ass_op ( op, ta, tb ) ) ;
692
	}
693
	e = make_error_exp ( LANGUAGE_CPP ) ;
694
	return ( e ) ;
695
    }
696
}