adlint 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/AUTHORS +3 -2
  2. data/ChangeLog +208 -63
  3. data/MANIFEST +4 -0
  4. data/NEWS +24 -5
  5. data/etc/conf.d/fallback/traits.erb +1 -1
  6. data/etc/conf.d/i686-cygwin/traits-gcc_4.3.4.erb +1 -1
  7. data/etc/conf.d/i686-devkit/traits-gcc_4.5.2.erb +1 -1
  8. data/etc/conf.d/i686-linux/traits-gcc_4.5.1.erb +1 -1
  9. data/etc/conf.d/i686-mingw/traits-gcc_4.6.1.erb +1 -1
  10. data/etc/mesg.d/en_US/messages.yml +3 -3
  11. data/etc/mesg.d/ja_JP/messages.yml +4 -4
  12. data/lib/adlint/c/builtin.rb +3 -3
  13. data/lib/adlint/c/ctrlexpr.rb +7 -11
  14. data/lib/adlint/c/expr.rb +548 -363
  15. data/lib/adlint/c/interp.rb +233 -525
  16. data/lib/adlint/c/mediator.rb +1 -0
  17. data/lib/adlint/c/message.rb +144 -1
  18. data/lib/adlint/c/object.rb +15 -6
  19. data/lib/adlint/c/parser.rb +170 -128
  20. data/lib/adlint/c/parser.y +36 -0
  21. data/lib/adlint/c/phase.rb +4 -0
  22. data/lib/adlint/c/seqp.rb +72 -0
  23. data/lib/adlint/c/syntax.rb +254 -3
  24. data/lib/adlint/c.rb +1 -0
  25. data/lib/adlint/cpp/code.rb +2 -2
  26. data/lib/adlint/cpp/eval.rb +29 -13
  27. data/lib/adlint/cpp/message.rb +71 -70
  28. data/lib/adlint/cpp/message_shima.rb +100 -0
  29. data/lib/adlint/cpp/phase.rb +4 -0
  30. data/lib/adlint/cpp/syntax.rb +5 -1
  31. data/lib/adlint/cpp.rb +1 -0
  32. data/lib/adlint/message.rb +6 -3
  33. data/lib/adlint/traits.rb +1 -1
  34. data/lib/adlint/version.rb +5 -5
  35. data/share/demo/Makefile +3 -1
  36. data/share/demo/bad_line/bad_line.c +27 -0
  37. data/share/demo/sequence_point/sequence_point.c +31 -0
  38. data/share/doc/adlint_on_vim_en.png +0 -0
  39. data/share/doc/adlint_on_vim_ja.png +0 -0
  40. data/share/doc/developers_guide_ja.html +3 -3
  41. data/share/doc/developers_guide_ja.texi +1 -1
  42. data/share/doc/users_guide_en.html +3118 -41
  43. data/share/doc/users_guide_en.texi +3090 -37
  44. data/share/doc/users_guide_ja.html +3120 -47
  45. data/share/doc/users_guide_ja.texi +3106 -65
  46. data/share/sample/ctags-5.8/adlint/GNUmakefile +13 -1
  47. data/share/sample/ctags-5.8/adlint/adlint_cinit.h +14 -2
  48. data/share/sample/ctags-5.8/adlint/adlint_pinit.h +14 -4
  49. data/share/sample/ctags-5.8/adlint/adlint_traits.yml +14 -1
  50. data/share/sample/flex-2.5.35/adlint/GNUmakefile +13 -1
  51. data/share/sample/flex-2.5.35/adlint/adlint_cinit.h +14 -2
  52. data/share/sample/flex-2.5.35/adlint/adlint_pinit.h +14 -4
  53. data/share/sample/flex-2.5.35/adlint/adlint_traits.yml +14 -1
  54. metadata +6 -2
data/lib/adlint/c/expr.rb CHANGED
@@ -40,10 +40,46 @@ module C #:nodoc:
40
40
  # NOTE: Host class of this module must include InterpreterMediator,
41
41
  # NotifierMediator and Conversion.
42
42
 
43
+ def execute_object_specifier(node)
44
+ if variable = variable_named(node.identifier.value)
45
+ variable.declarations_and_definitions.each do |decl_or_def|
46
+ decl_or_def.mark_as_referred_by(node.identifier)
47
+ end
48
+ if variable.type.array?
49
+ # NOTE: Array object is referred to derive the start address.
50
+ # NOTE: Kill this notification not to confuse the W0459 and W0460
51
+ # detections of the expression-statement `a[i] = 0;' when
52
+ # contents of `a' is not initialized.
53
+ # _notify_variable_value_referred(node, variable)
54
+ variable = temporary_variable(pointer_type(variable.type.base_type),
55
+ pointer_value_of(variable))
56
+ end
57
+ _notify_object_referred(node, variable)
58
+ return variable
59
+ end
60
+
61
+ if function = function_named(node.identifier.value)
62
+ function.declarations_and_definitions.each do |decl_or_def|
63
+ decl_or_def.mark_as_referred_by(node.identifier)
64
+ end
65
+ _notify_object_referred(node, function)
66
+ return function
67
+ end
68
+
69
+ if enumerator = enumerator_named(node.identifier.value)
70
+ enumerator.mark_as_referred_by(node.identifier)
71
+ return temporary_variable(int_type, ScalarValue.of(enumerator.value))
72
+ end
73
+
74
+ define_implicit_function(node.identifier.value)
75
+ end
76
+ module_function :execute_object_specifier
77
+
43
78
  def execute_array_subscript_expression(node, object, subscript)
44
79
  unless object.variable? && (object.type.array? || object.type.pointer?)
45
80
  return temporary_variable
46
81
  end
82
+ _notify_variable_value_referred(node, object)
47
83
 
48
84
  array_or_pointer = object
49
85
 
@@ -54,6 +90,7 @@ module C #:nodoc:
54
90
  subscript.value.exist?
55
91
  return temporary_variable(result_type)
56
92
  end
93
+ _notify_variable_value_referred(node, subscript)
57
94
 
58
95
  case
59
96
  when array_or_pointer.type.array?
@@ -81,10 +118,7 @@ module C #:nodoc:
81
118
  # FIXME: Domain of the subscript may have multiple values.
82
119
  subscript_value = int_subscript.value.unique_sample
83
120
  if array and inner_variable = array.inner_variable_at(subscript_value)
84
- notify_variable_referred(node, inner_variable)
85
- unless variable_reassigning?
86
- notify_variable_value_referred(node, inner_variable)
87
- end
121
+ _notify_object_referred(node, inner_variable)
88
122
  if inner_variable.type.array?
89
123
  result = temporary_variable(result_type,
90
124
  pointer_value_of(inner_variable))
@@ -99,6 +133,7 @@ module C #:nodoc:
99
133
  int_subscript, array, result)
100
134
  result
101
135
  end
136
+ module_function :execute_array_subscript_expression
102
137
 
103
138
  def execute_function_call_expression(node, object, args)
104
139
  if object.function?
@@ -115,8 +150,22 @@ module C #:nodoc:
115
150
  return temporary_variable
116
151
  end
117
152
  end
153
+ _notify_variable_value_referred(node, object)
154
+
155
+ args.each { |arg, expr| _notify_variable_value_referred(expr, arg) }
118
156
 
119
- result = function.call(interpreter, args)
157
+ # NOTE: The ISO C99 standard saids;
158
+ #
159
+ # 6.5.2.2 Function calls
160
+ #
161
+ # Semantics
162
+ #
163
+ # 10 The order of evaluation of the function designator, the actual
164
+ # arguments, and subexpressions within the actual arguments is
165
+ # unspecified, but there is a sequence point before the actual call.
166
+ notify_sequence_point_reached(SequencePoint.new(node)) unless args.empty?
167
+
168
+ result = function.call(interpreter, node, args)
120
169
  unless function.builtin?
121
170
  notify_function_call_expr_evaled(node, function,
122
171
  args.map { |arg, expr| arg }, result)
@@ -124,24 +173,23 @@ module C #:nodoc:
124
173
 
125
174
  result
126
175
  end
176
+ module_function :execute_function_call_expression
127
177
 
128
178
  def execute_member_access_by_value_expression(node, object)
129
179
  unless object.variable? && object.type.composite?
130
180
  return temporary_variable
131
181
  end
132
-
133
182
  variable = object
183
+
134
184
  member_variable = variable.inner_variable_named(node.identifier.value)
185
+ _notify_variable_value_referred(node, variable)
135
186
 
136
187
  # NOTE: `member_variable' is nil when this expression represents the
137
188
  # direct member access extension.
138
189
  notify_member_access_expr_evaled(node, variable, member_variable)
139
190
 
140
191
  if member_variable
141
- notify_variable_referred(node, member_variable)
142
- unless variable_reassigning?
143
- notify_variable_value_referred(node, member_variable)
144
- end
192
+ _notify_object_referred(node, member_variable)
145
193
  if member_variable.type.array?
146
194
  type = pointer_type(member_variable.type.base_type)
147
195
  return temporary_variable(type, pointer_value_of(member_variable))
@@ -151,6 +199,7 @@ module C #:nodoc:
151
199
  temporary_variable
152
200
  end
153
201
  end
202
+ module_function :execute_member_access_by_value_expression
154
203
 
155
204
  def execute_member_access_by_pointer_expression(node, object)
156
205
  unqualified_type = object.type.unqualify
@@ -159,8 +208,8 @@ module C #:nodoc:
159
208
  unqualified_type.base_type.composite?
160
209
  return temporary_variable
161
210
  end
162
-
163
211
  pointer = object
212
+
164
213
  if pointee = pointee_of(pointer)
165
214
  if pointee.type.array?
166
215
  if first_element = pointee.inner_variable_at(0)
@@ -170,10 +219,7 @@ module C #:nodoc:
170
219
  end
171
220
  end
172
221
  end
173
-
174
- if variable_reassigning?
175
- notify_variable_value_referred(node, pointer)
176
- end
222
+ _notify_variable_value_referred(node, pointer)
177
223
 
178
224
  if pointee && pointee.type.composite?
179
225
  member_variable = pointee.inner_variable_named(node.identifier.value)
@@ -187,10 +233,7 @@ module C #:nodoc:
187
233
  notify_member_access_expr_evaled(node, pointer, member_variable)
188
234
 
189
235
  if member_variable
190
- notify_variable_referred(node, member_variable)
191
- unless variable_reassigning?
192
- notify_variable_value_referred(node, member_variable)
193
- end
236
+ _notify_object_referred(node, member_variable)
194
237
  if member_variable.type.array?
195
238
  type = pointer_type(member_variable.type.base_type)
196
239
  return temporary_variable(type, pointer_value_of(member_variable))
@@ -200,166 +243,169 @@ module C #:nodoc:
200
243
  temporary_variable
201
244
  end
202
245
  end
246
+ module_function :execute_member_access_by_pointer_expression
203
247
 
204
248
  def execute_postfix_increment_expression(node, object)
205
- if object.variable?
206
- variable = object
249
+ return temporary_variable unless object.variable? && object.type.scalar?
250
+ variable = object
207
251
 
208
- if variable.type.scalar?
209
- result = temporary_variable(variable.type, variable.value.dup)
210
- if variable.value.scalar?
211
- variable.assign!(variable.value + ScalarValue.of(1))
212
- end
213
- else
214
- result = temporary_variable
215
- end
252
+ result = temporary_variable(variable.type, variable.value.dup)
216
253
 
217
- notify_postfix_increment_expr_evaled(node, variable, result)
218
- notify_variable_value_updated(node, variable)
254
+ # NOTE: Value of the variable is referred at this point. But value
255
+ # reference should not be notified not to confuse sequence-point
256
+ # warning detections.
257
+ # _notify_variable_value_referred(node, variable)
219
258
 
220
- result
221
- else
222
- temporary_variable
259
+ if variable.value.scalar?
260
+ variable.assign!(variable.value + ScalarValue.of(1))
261
+ _notify_variable_value_updated(node, variable)
223
262
  end
263
+
264
+ notify_postfix_increment_expr_evaled(node, variable, result)
265
+
266
+ result
224
267
  end
268
+ module_function :execute_postfix_increment_expression
225
269
 
226
270
  def execute_postfix_decrement_expression(node, object)
227
- if object.variable?
228
- variable = object
271
+ return temporary_variable unless object.variable? && object.type.scalar?
272
+ variable = object
229
273
 
230
- if variable.type.scalar?
231
- result = temporary_variable(variable.type, variable.value.dup)
232
- if variable.value.scalar?
233
- variable.assign!(variable.value - ScalarValue.of(1))
234
- end
235
- else
236
- result = temporary_variable
237
- end
274
+ result = temporary_variable(variable.type, variable.value.dup)
238
275
 
239
- notify_postfix_decrement_expr_evaled(node, variable, result)
240
- notify_variable_value_updated(node, variable)
276
+ # NOTE: Value of the variable is referred at this point. But value
277
+ # reference should not be notified not to confuse sequence-point
278
+ # warnings detections.
279
+ # _notify_variable_value_referred(node, variable)
241
280
 
242
- result
243
- else
244
- temporary_variable
281
+ if variable.value.scalar?
282
+ variable.assign!(variable.value - ScalarValue.of(1))
283
+ _notify_variable_value_updated(node, variable)
245
284
  end
285
+
286
+ notify_postfix_decrement_expr_evaled(node, variable, result)
287
+
288
+ result
246
289
  end
290
+ module_function :execute_postfix_decrement_expression
247
291
 
248
292
  def execute_prefix_increment_expression(node, object)
249
- if object.variable?
250
- variable = object
293
+ return temporary_variable unless object.variable? && object.type.scalar?
294
+ variable = object
251
295
 
252
- if variable.type.scalar?
253
- original_value = variable.value.dup
254
- if variable.value.scalar?
255
- variable.assign!(variable.value + ScalarValue.of(1))
256
- end
257
- else
258
- original_value = variable.value.dup
259
- end
296
+ original_value = variable.value.dup
260
297
 
261
- notify_prefix_increment_expr_evaled(node, variable, original_value)
262
- notify_variable_value_updated(node, variable)
298
+ # NOTE: Value of the variable is referred at this point. But value
299
+ # reference should not be notified not to confuse sequence-point
300
+ # warnings detections.
301
+ # _notify_variable_value_referred(node, variable)
263
302
 
264
- variable
265
- else
266
- temporary_variable
303
+ if variable.value.scalar?
304
+ variable.assign!(variable.value + ScalarValue.of(1))
305
+ _notify_variable_value_updated(node, variable)
267
306
  end
307
+
308
+ notify_prefix_increment_expr_evaled(node, variable, original_value)
309
+
310
+ variable
268
311
  end
312
+ module_function :execute_prefix_increment_expression
269
313
 
270
314
  def execute_prefix_decrement_expression(node, object)
271
- if object.variable?
272
- variable = object
315
+ return temporary_variable unless object.variable? && object.type.scalar?
316
+ variable = object
273
317
 
274
- if variable.type.scalar?
275
- original_value = variable.value.dup
276
- if variable.value.scalar?
277
- variable.assign!(variable.value - ScalarValue.of(1))
278
- end
279
- else
280
- original_value = variable.value.dup
281
- end
318
+ original_value = variable.value.dup
282
319
 
283
- notify_prefix_decrement_expr_evaled(node, variable, original_value)
284
- notify_variable_value_updated(node, variable)
320
+ # NOTE: Value of the variable is referred at this point. But value
321
+ # reference should not be notified not to confuse sequence-point
322
+ # warning detections.
323
+ # _notify_variable_value_referred(node, variable)
285
324
 
286
- variable
287
- else
288
- temporary_variable
325
+ if variable.value.scalar?
326
+ variable.assign!(variable.value - ScalarValue.of(1))
327
+ _notify_variable_value_updated(node, variable)
289
328
  end
290
- end
291
329
 
292
- def execute_indirection_expression(node, object)
293
- if object.variable?
294
- variable = object
330
+ notify_prefix_decrement_expr_evaled(node, variable, original_value)
295
331
 
296
- return temporary_variable unless variable.type.pointer?
332
+ variable
333
+ end
334
+ module_function :execute_prefix_decrement_expression
297
335
 
298
- pointer = object
299
- unqualified_type = pointer.type.unqualify
336
+ def execute_address_expression(node, object)
337
+ # NOTE: An address-expression does not read the value of the object. But
338
+ # value reference should be notified to emphasize global variable
339
+ # cross-references.
340
+ _notify_variable_value_referred(node, object)
300
341
 
301
- pointee = pointee_of(pointer)
302
- if variable_reassigning?
303
- notify_variable_value_referred(node, pointer)
304
- end
342
+ temporary_variable(pointer_type(object.type), pointer_value_of(object))
343
+ end
344
+ module_function :execute_address_expression
305
345
 
306
- case
307
- when pointee
308
- if pointee.type.array?
309
- if first_element = pointee.inner_variable_at(0)
310
- pointee = first_element
311
- else
312
- pointee = temporary_variable(unqualified_type.base_type)
313
- end
314
- end
346
+ def execute_indirection_expression(node, object)
347
+ return temporary_variable unless object.variable? && object.type.pointer?
348
+ pointer = object
315
349
 
316
- unless variable_reassigning?
317
- notify_variable_value_referred(node, pointee) if pointee.variable?
318
- end
350
+ unqualified_type = pointer.type.unqualify
351
+ pointee = pointee_of(pointer)
352
+ _notify_variable_value_referred(node, pointer)
319
353
 
320
- unless unqualified_type.base_type.same_as?(pointee.type)
321
- pointee =
322
- do_conversion(pointee, unqualified_type.base_type) ||
323
- temporary_variable(unqualified_type.base_type)
354
+ case
355
+ when pointee
356
+ _notify_object_referred(node, pointee)
357
+ if pointee.type.array?
358
+ if first_element = pointee.inner_variable_at(0)
359
+ pointee = first_element
360
+ else
361
+ pointee = temporary_variable(unqualified_type.base_type)
324
362
  end
325
- when unqualified_type.base_type.function?
326
- pointee = define_anonymous_function(unqualified_type.base_type)
327
- else
328
- pointee = temporary_variable(unqualified_type.base_type)
329
363
  end
330
364
 
331
- notify_indirection_expr_evaled(node, variable, pointee)
332
- return pointee
365
+ unless unqualified_type.base_type.same_as?(pointee.type)
366
+ pointee =
367
+ do_conversion(pointee, unqualified_type.base_type) ||
368
+ temporary_variable(unqualified_type.base_type)
369
+ end
370
+ when unqualified_type.base_type.function?
371
+ pointee = define_anonymous_function(unqualified_type.base_type)
372
+ else
373
+ pointee = temporary_variable(unqualified_type.base_type)
333
374
  end
334
375
 
335
- temporary_variable
376
+ notify_indirection_expr_evaled(node, pointer, pointee)
377
+
378
+ pointee
336
379
  end
380
+ module_function :execute_indirection_expression
337
381
 
338
382
  def execute_unary_arithmetic_expression(node, object)
339
- if object.variable? && object.type.scalar?
340
- variable = object
383
+ variable = object_to_variable(object)
384
+ return temporary_variable unless variable.type.scalar?
341
385
 
342
- if variable.value.scalar?
343
- case node.operator.type
344
- when "+"
345
- result = temporary_variable(variable.type, +variable.value)
346
- when "-"
347
- result = temporary_variable(variable.type, -variable.value)
348
- when "~"
349
- result = temporary_variable(variable.type, ~variable.value)
350
- when "!"
351
- result = temporary_variable(int_type, !variable.value)
352
- else
353
- # NOTREACHED
354
- end
386
+ unless variable == object
387
+ notify_implicit_conv_performed(node.operand, object, variable)
388
+ end
355
389
 
356
- notify_unary_arithmetic_expr_evaled(node, variable, result)
357
- return result
358
- end
390
+ case node.operator.type
391
+ when "+"
392
+ result = temporary_variable(variable.type, +variable.value)
393
+ when "-"
394
+ result = temporary_variable(variable.type, -variable.value)
395
+ when "~"
396
+ result = temporary_variable(variable.type, ~variable.value)
397
+ when "!"
398
+ result = temporary_variable(int_type, !variable.value)
399
+ else
400
+ # NOTREACHED
359
401
  end
402
+ _notify_variable_value_referred(node, variable)
360
403
 
361
- temporary_variable
404
+ notify_unary_arithmetic_expr_evaled(node, variable, result)
405
+
406
+ result
362
407
  end
408
+ module_function :execute_unary_arithmetic_expression
363
409
 
364
410
  def execute_cast_expression(node, object)
365
411
  resolve_unresolved_type(node.type_name)
@@ -370,23 +416,26 @@ module C #:nodoc:
370
416
  temporary_variable(node.type_name.type)
371
417
 
372
418
  notify_explicit_conv_performed(node, variable, converted)
419
+
373
420
  converted
374
421
  end
422
+ module_function :execute_cast_expression
375
423
 
376
424
  def execute_multiplicative_expression(node, lhs_object, rhs_object)
377
- if lhs_object.function? || rhs_object.function?
378
- return temporary_variable
379
- end
425
+ lhs_variable = object_to_variable(lhs_object)
426
+ return temporary_variable unless lhs_variable.type.scalar?
380
427
 
381
- lhs_variable = lhs_object
382
- rhs_variable = rhs_object
383
-
384
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
385
- return temporary_variable
428
+ unless lhs_variable == lhs_object
429
+ notify_implicit_conv_performed(node.lhs_operand,
430
+ lhs_object, lhs_variable)
386
431
  end
387
432
 
388
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
389
- return temporary_variable
433
+ rhs_variable = object_to_variable(rhs_object)
434
+ return temporary_variable unless rhs_variable.type.scalar?
435
+
436
+ unless rhs_variable == rhs_object
437
+ notify_implicit_conv_performed(node.rhs_operand,
438
+ rhs_object, rhs_variable)
390
439
  end
391
440
 
392
441
  lhs_converted, rhs_converted =
@@ -423,26 +472,30 @@ module C #:nodoc:
423
472
  else
424
473
  # NOTREACHED
425
474
  end
475
+ _notify_variable_value_referred(node, lhs_variable)
476
+ _notify_variable_value_referred(node, rhs_variable)
426
477
 
427
- notify_multiplicative_expr_evaled(node,
428
- lhs_variable, rhs_variable, result)
478
+ notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
479
+ result)
429
480
  result
430
481
  end
482
+ module_function :execute_multiplicative_expression
431
483
 
432
484
  def execute_additive_expression(node, lhs_object, rhs_object)
433
- if lhs_object.function? || rhs_object.function?
434
- return temporary_variable
435
- end
485
+ lhs_variable = object_to_variable(lhs_object)
486
+ return temporary_variable unless lhs_variable.type.scalar?
436
487
 
437
- lhs_variable = lhs_object
438
- rhs_variable = rhs_object
439
-
440
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
441
- return temporary_variable
488
+ unless lhs_variable == lhs_object
489
+ notify_implicit_conv_performed(node.lhs_operand,
490
+ lhs_object, lhs_variable)
442
491
  end
443
492
 
444
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
445
- return temporary_variable
493
+ rhs_variable = object_to_variable(rhs_object)
494
+ return temporary_variable unless rhs_variable.type.scalar?
495
+
496
+ unless rhs_variable == rhs_object
497
+ notify_implicit_conv_performed(node.rhs_operand,
498
+ rhs_object, rhs_variable)
446
499
  end
447
500
 
448
501
  lhs_converted, rhs_converted =
@@ -472,25 +525,30 @@ module C #:nodoc:
472
525
  else
473
526
  # NOTREACHED
474
527
  end
528
+ _notify_variable_value_referred(node, lhs_variable)
529
+ _notify_variable_value_referred(node, rhs_variable)
475
530
 
476
531
  notify_additive_expr_evaled(node, lhs_variable, rhs_variable, result)
532
+
477
533
  result
478
534
  end
535
+ module_function :execute_additive_expression
479
536
 
480
537
  def execute_shift_expression(node, lhs_object, rhs_object)
481
- if lhs_object.function? || rhs_object.function?
482
- return temporary_variable
483
- end
538
+ lhs_variable = object_to_variable(lhs_object)
539
+ return temporary_variable unless lhs_variable.type.scalar?
484
540
 
485
- lhs_variable = lhs_object
486
- rhs_variable = rhs_object
487
-
488
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
489
- return temporary_variable
541
+ unless lhs_variable == lhs_object
542
+ notify_implicit_conv_performed(node.lhs_operand,
543
+ lhs_object, lhs_variable)
490
544
  end
491
545
 
492
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
493
- return temporary_variable
546
+ rhs_variable = object_to_variable(rhs_object)
547
+ return temporary_variable unless rhs_variable.type.scalar?
548
+
549
+ unless rhs_variable == rhs_object
550
+ notify_implicit_conv_performed(node.rhs_operand,
551
+ rhs_object, rhs_variable)
494
552
  end
495
553
 
496
554
  # NOTE: The ISO C99 standard saids;
@@ -528,25 +586,144 @@ module C #:nodoc:
528
586
  else
529
587
  # NOTREACHED
530
588
  end
589
+ _notify_variable_value_referred(node, lhs_variable)
590
+ _notify_variable_value_referred(node, rhs_variable)
531
591
 
532
592
  notify_shift_expr_evaled(node, lhs_variable, rhs_variable, result)
593
+
533
594
  result
534
595
  end
596
+ module_function :execute_shift_expression
535
597
 
536
- def execute_and_expression(node, lhs_object, rhs_object)
537
- if lhs_object.function? || rhs_object.function?
538
- return temporary_variable
598
+ def execute_relational_expression(node, lhs_object, rhs_object)
599
+ lhs_variable = object_to_variable(lhs_object)
600
+ unless lhs_variable.type.scalar?
601
+ return temporary_variable(int_type, ScalarValue.of_arbitrary)
539
602
  end
540
603
 
541
- lhs_variable = lhs_object
542
- rhs_variable = rhs_object
604
+ unless lhs_variable == lhs_object
605
+ notify_implicit_conv_performed(node.lhs_operand,
606
+ lhs_object, lhs_variable)
607
+ end
543
608
 
544
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
545
- return temporary_variable
609
+ rhs_variable = object_to_variable(rhs_object)
610
+ unless rhs_variable.type.scalar?
611
+ return temporary_variable(int_type, ScalarValue.of_arbitrary)
546
612
  end
547
613
 
548
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
549
- return temporary_variable
614
+ unless rhs_variable == rhs_object
615
+ notify_implicit_conv_performed(node.rhs_operand,
616
+ rhs_object, rhs_variable)
617
+ end
618
+
619
+ lhs_converted, rhs_converted =
620
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
621
+
622
+ unless lhs_variable == lhs_converted
623
+ notify_implicit_conv_performed(node.lhs_operand,
624
+ lhs_variable, lhs_converted)
625
+ end
626
+
627
+ unless rhs_variable == rhs_converted
628
+ notify_implicit_conv_performed(node.rhs_operand,
629
+ rhs_variable, rhs_converted)
630
+ end
631
+
632
+ case node.operator.type
633
+ when "<"
634
+ result = temporary_variable(int_type,
635
+ lhs_converted.value < rhs_converted.value)
636
+ when ">"
637
+ result = temporary_variable(int_type,
638
+ lhs_converted.value > rhs_converted.value)
639
+ when "<="
640
+ result = temporary_variable(int_type,
641
+ lhs_converted.value <= rhs_converted.value)
642
+ when ">="
643
+ result = temporary_variable(int_type,
644
+ lhs_converted.value >= rhs_converted.value)
645
+ else
646
+ # NOTREACHED
647
+ result = temporary_variable(int_type, ScalarValue.of_arbitrary)
648
+ end
649
+ _notify_variable_value_referred(node, lhs_variable)
650
+ _notify_variable_value_referred(node, rhs_variable)
651
+
652
+ notify_relational_expr_evaled(node, lhs_variable, rhs_variable, result)
653
+
654
+ result
655
+ end
656
+ module_function :execute_relational_expression
657
+
658
+ def execute_equality_expression(node, lhs_object, rhs_object)
659
+ lhs_variable = object_to_variable(lhs_object)
660
+ unless lhs_variable.type.scalar?
661
+ return temporary_variable(int_type, ScalarValue.of_arbitrary)
662
+ end
663
+
664
+ unless lhs_variable == lhs_object
665
+ notify_implicit_conv_performed(node.lhs_operand,
666
+ lhs_object, lhs_variable)
667
+ end
668
+
669
+ rhs_variable = object_to_variable(rhs_object)
670
+ unless rhs_variable.type.scalar?
671
+ return temporary_variable(int_type, ScalarValue.of_arbitrary)
672
+ end
673
+
674
+ unless rhs_variable == rhs_object
675
+ notify_implicit_conv_performed(node.rhs_operand,
676
+ rhs_object, rhs_variable)
677
+ end
678
+
679
+ lhs_converted, rhs_converted =
680
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
681
+
682
+ unless lhs_variable == lhs_converted
683
+ notify_implicit_conv_performed(node.lhs_operand,
684
+ lhs_variable, lhs_converted)
685
+ end
686
+
687
+ unless rhs_variable == rhs_converted
688
+ notify_implicit_conv_performed(node.rhs_operand,
689
+ rhs_variable, rhs_converted)
690
+ end
691
+
692
+ case node.operator.type
693
+ when "=="
694
+ result = temporary_variable(int_type,
695
+ lhs_converted.value == rhs_converted.value)
696
+ when "!="
697
+ result = temporary_variable(int_type,
698
+ lhs_converted.value != rhs_converted.value)
699
+ else
700
+ # NOTREACHED
701
+ result = temporary_variable(int_type, ScalarValue.of_arbitrary)
702
+ end
703
+ _notify_variable_value_referred(node, lhs_variable)
704
+ _notify_variable_value_referred(node, rhs_variable)
705
+
706
+ notify_equality_expr_evaled(node, lhs_variable, rhs_variable, result)
707
+
708
+ result
709
+ end
710
+ module_function :execute_equality_expression
711
+
712
+ def execute_and_expression(node, lhs_object, rhs_object)
713
+ lhs_variable = object_to_variable(lhs_object)
714
+ return temporary_variable unless lhs_variable.type.scalar?
715
+
716
+ unless lhs_variable == lhs_object
717
+ notify_implicit_conv_performed(node.lhs_operand,
718
+ lhs_object, lhs_variable)
719
+ end
720
+
721
+ rhs_variable = object_to_variable(rhs_object)
722
+ return temporary_variable unless rhs_variable.type.scalar?
723
+
724
+ unless rhs_variable == rhs_object
725
+ notify_implicit_conv_performed(node.rhs_operand,
726
+ rhs_object, rhs_variable)
550
727
  end
551
728
 
552
729
  lhs_converted, rhs_converted =
@@ -566,25 +743,30 @@ module C #:nodoc:
566
743
  # min-max of the variable type.
567
744
  result = temporary_variable(lhs_converted.type,
568
745
  lhs_converted.value & rhs_converted.value)
746
+ _notify_variable_value_referred(node, lhs_variable)
747
+ _notify_variable_value_referred(node, rhs_variable)
569
748
 
570
749
  notify_and_expr_evaled(node, lhs_variable, rhs_variable, result)
750
+
571
751
  result
572
752
  end
753
+ module_function :execute_and_expression
573
754
 
574
755
  def execute_exclusive_or_expression(node, lhs_object, rhs_object)
575
- if lhs_object.function? || rhs_object.function?
576
- return temporary_variable
577
- end
756
+ lhs_variable = object_to_variable(lhs_object)
757
+ return temporary_variable unless lhs_variable.type.scalar?
578
758
 
579
- lhs_variable = lhs_object
580
- rhs_variable = rhs_object
581
-
582
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
583
- return temporary_variable
759
+ unless lhs_variable == lhs_object
760
+ notify_implicit_conv_performed(node.lhs_operand,
761
+ lhs_object, lhs_variable)
584
762
  end
585
763
 
586
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
587
- return temporary_variable
764
+ rhs_variable = object_to_variable(rhs_object)
765
+ return temporary_variable unless rhs_variable.type.scalar?
766
+
767
+ unless rhs_variable == rhs_object
768
+ notify_implicit_conv_performed(node.rhs_operand,
769
+ rhs_object, rhs_variable)
588
770
  end
589
771
 
590
772
  lhs_converted, rhs_converted =
@@ -604,25 +786,30 @@ module C #:nodoc:
604
786
  # min-max of the variable type.
605
787
  result = temporary_variable(lhs_converted.type,
606
788
  lhs_converted.value ^ rhs_converted.value)
789
+ _notify_variable_value_referred(node, lhs_variable)
790
+ _notify_variable_value_referred(node, rhs_variable)
607
791
 
608
792
  notify_exclusive_or_expr_evaled(node, lhs_variable, rhs_variable, result)
793
+
609
794
  result
610
795
  end
796
+ module_function :execute_exclusive_or_expression
611
797
 
612
798
  def execute_inclusive_or_expression(node, lhs_object, rhs_object)
613
- if lhs_object.function? || rhs_object.function?
614
- return temporary_variable
615
- end
799
+ lhs_variable = object_to_variable(lhs_object)
800
+ return temporary_variable unless lhs_variable.type.scalar?
616
801
 
617
- lhs_variable = lhs_object
618
- rhs_variable = rhs_object
619
-
620
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
621
- return temporary_variable
802
+ unless lhs_variable == lhs_object
803
+ notify_implicit_conv_performed(node.lhs_operand,
804
+ lhs_object, lhs_variable)
622
805
  end
623
806
 
624
- unless lhs_variable.value.scalar? && rhs_variable.type.scalar?
625
- return temporary_variable
807
+ rhs_variable = object_to_variable(rhs_object)
808
+ return temporary_variable unless rhs_variable.type.scalar?
809
+
810
+ unless rhs_variable == rhs_object
811
+ notify_implicit_conv_performed(node.rhs_operand,
812
+ rhs_object, rhs_variable)
626
813
  end
627
814
 
628
815
  lhs_converted, rhs_converted =
@@ -642,17 +829,18 @@ module C #:nodoc:
642
829
  # min-max of the variable type.
643
830
  result = temporary_variable(lhs_converted.type,
644
831
  lhs_converted.value | rhs_converted.value)
832
+ _notify_variable_value_referred(node, lhs_variable)
833
+ _notify_variable_value_referred(node, rhs_variable)
645
834
 
646
835
  notify_inclusive_or_expr_evaled(node, lhs_variable, rhs_variable, result)
836
+
647
837
  result
648
838
  end
839
+ module_function :execute_inclusive_or_expression
649
840
 
650
841
  def execute_simple_assignment_expression(node, lhs_object, rhs_object)
651
- if lhs_object.variable?
652
- lhs_variable = lhs_object
653
- else
654
- return lhs_object
655
- end
842
+ return lhs_object unless lhs_object.variable?
843
+ lhs_variable = lhs_object
656
844
 
657
845
  rhs_variable = object_to_variable(rhs_object)
658
846
  unless rhs_variable == rhs_object
@@ -676,29 +864,29 @@ module C #:nodoc:
676
864
  # instantiated in value-coercing.
677
865
  # So, value-aliasing never occurs.
678
866
  lhs_variable.assign!(rhs_converted.value.to_defined_value)
867
+ _notify_variable_value_referred(node, rhs_variable)
868
+ _notify_variable_value_updated(node, lhs_variable)
869
+
679
870
  notify_assignment_expr_evaled(node, lhs_variable, rhs_converted)
680
- notify_variable_value_updated(node, lhs_variable)
681
871
 
682
872
  lhs_variable
683
873
  end
874
+ module_function :execute_simple_assignment_expression
684
875
 
685
876
  def execute_compound_assignment_expression(node, lhs_object, rhs_object)
686
- if lhs_object.variable?
687
- lhs_variable = lhs_object
688
- else
689
- return lhs_object
877
+ unless lhs_object.variable? && lhs_object.type.scalar?
878
+ return temporary_variable
690
879
  end
880
+ lhs_variable = lhs_object
691
881
 
692
882
  rhs_variable = object_to_variable(rhs_object)
883
+ return temporary_variable unless rhs_variable.type.scalar?
884
+
693
885
  unless rhs_variable == rhs_object
694
886
  notify_implicit_conv_performed(node.rhs_operand,
695
887
  rhs_object, rhs_variable)
696
888
  end
697
889
 
698
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
699
- return lhs_variable
700
- end
701
-
702
890
  case node.operator.type
703
891
  when "*="
704
892
  execute_mul_then_assign_expression(node, lhs_variable, rhs_variable)
@@ -722,10 +910,9 @@ module C #:nodoc:
722
910
  execute_ior_then_assign_expression(node, lhs_variable, rhs_variable)
723
911
  end
724
912
 
725
- notify_variable_value_updated(node, lhs_variable)
726
-
727
913
  lhs_variable
728
914
  end
915
+ module_function :execute_compound_assignment_expression
729
916
 
730
917
  def execute_mul_then_assign_expression(node, lhs_variable, rhs_variable)
731
918
  lhs_converted, rhs_converted =
@@ -747,6 +934,13 @@ module C #:nodoc:
747
934
  result_value = lhs_converted.value
748
935
  end
749
936
 
937
+ # NOTE: Value of the lhs_variable is referred at this point. But value
938
+ # reference should not be notified not to confuse sequence-point
939
+ # warning detections.
940
+ # _notify_variable_value_referred(node, lhs_variable)
941
+
942
+ _notify_variable_value_referred(node, rhs_variable)
943
+
750
944
  result_variable = temporary_variable(lhs_converted.type, result_value)
751
945
 
752
946
  notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
@@ -765,8 +959,11 @@ module C #:nodoc:
765
959
  # NOTE: Domain of the arithmetic result value will be restricted by
766
960
  # min-max of the variable type.
767
961
  lhs_variable.assign!(result_converted.value)
962
+ _notify_variable_value_updated(node, lhs_variable)
963
+
768
964
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
769
965
  end
966
+ module_function :execute_mul_then_assign_expression
770
967
 
771
968
  def execute_div_then_assign_expression(node, lhs_variable, rhs_variable)
772
969
  lhs_converted, rhs_converted =
@@ -789,6 +986,13 @@ module C #:nodoc:
789
986
  result_value = lhs_converted.value
790
987
  end
791
988
 
989
+ # NOTE: Value of the lhs_variable is referred at this point. But value
990
+ # reference should not be notified not to confuse sequence-point
991
+ # warning detections.
992
+ # _notify_variable_value_referred(node, lhs_variable)
993
+
994
+ _notify_variable_value_referred(node, rhs_variable)
995
+
792
996
  result_variable = temporary_variable(lhs_converted.type, result_value)
793
997
 
794
998
  notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
@@ -807,8 +1011,11 @@ module C #:nodoc:
807
1011
  # NOTE: Domain of the arithmetic result value will be restricted by
808
1012
  # min-max of the variable type.
809
1013
  lhs_variable.assign!(result_converted.value)
1014
+ _notify_variable_value_updated(node, lhs_variable)
1015
+
810
1016
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
811
1017
  end
1018
+ module_function :execute_div_then_assign_expression
812
1019
 
813
1020
  def execute_mod_then_assign_expression(node, lhs_variable, rhs_variable)
814
1021
  lhs_converted, rhs_converted =
@@ -831,6 +1038,13 @@ module C #:nodoc:
831
1038
  result_value = lhs_converted.value
832
1039
  end
833
1040
 
1041
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1042
+ # reference should not be notified not to confuse sequence-point
1043
+ # warning detections.
1044
+ # _notify_variable_value_referred(node, lhs_variable)
1045
+
1046
+ _notify_variable_value_referred(node, rhs_variable)
1047
+
834
1048
  result_variable = temporary_variable(lhs_converted.type, result_value)
835
1049
 
836
1050
  notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
@@ -849,8 +1063,11 @@ module C #:nodoc:
849
1063
  # NOTE: Domain of the arithmetic result value will be restricted by
850
1064
  # min-max of the variable type.
851
1065
  lhs_variable.assign!(result_converted.value)
1066
+ _notify_variable_value_updated(node, lhs_variable)
1067
+
852
1068
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
853
1069
  end
1070
+ module_function :execute_mod_then_assign_expression
854
1071
 
855
1072
  def execute_add_then_assign_expression(node, lhs_variable, rhs_variable)
856
1073
  lhs_converted, rhs_converted =
@@ -872,6 +1089,13 @@ module C #:nodoc:
872
1089
  result_value = lhs_converted.value
873
1090
  end
874
1091
 
1092
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1093
+ # reference should not be notified not to confuse sequence-point
1094
+ # warning detections.
1095
+ # _notify_variable_value_referred(node, lhs_variable)
1096
+
1097
+ _notify_variable_value_referred(node, rhs_variable)
1098
+
875
1099
  result_variable = temporary_variable(lhs_converted.type, result_value)
876
1100
 
877
1101
  notify_additive_expr_evaled(node, lhs_variable, rhs_variable,
@@ -890,8 +1114,11 @@ module C #:nodoc:
890
1114
  # NOTE: Domain of the arithmetic result value will be restricted by
891
1115
  # min-max of the variable type.
892
1116
  lhs_variable.assign!(result_converted.value)
1117
+ _notify_variable_value_updated(node, lhs_variable)
1118
+
893
1119
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
894
1120
  end
1121
+ module_function :execute_add_then_assign_expression
895
1122
 
896
1123
  def execute_sub_then_assign_expression(node, lhs_variable, rhs_variable)
897
1124
  lhs_converted, rhs_converted =
@@ -913,6 +1140,13 @@ module C #:nodoc:
913
1140
  result_value = lhs_converted.value
914
1141
  end
915
1142
 
1143
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1144
+ # reference should not be notified not to confuse sequence-point
1145
+ # warning detections.
1146
+ # _notify_variable_value_referred(node, lhs_variable)
1147
+
1148
+ _notify_variable_value_referred(node, rhs_variable)
1149
+
916
1150
  result_variable = temporary_variable(lhs_converted.type, result_value)
917
1151
 
918
1152
  notify_additive_expr_evaled(node, lhs_variable, rhs_variable,
@@ -931,8 +1165,11 @@ module C #:nodoc:
931
1165
  # NOTE: Domain of the arithmetic result value will be restricted by
932
1166
  # min-max of the variable type.
933
1167
  lhs_variable.assign!(result_converted.value)
1168
+ _notify_variable_value_updated(node, lhs_variable)
1169
+
934
1170
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
935
1171
  end
1172
+ module_function :execute_sub_then_assign_expression
936
1173
 
937
1174
  def execute_shl_then_assign_expression(node, lhs_variable, rhs_variable)
938
1175
  # NOTE: The ISO C99 standard saids;
@@ -962,6 +1199,13 @@ module C #:nodoc:
962
1199
  result_value = lhs_converted.value
963
1200
  end
964
1201
 
1202
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1203
+ # reference should not be notified not to confuse sequence-point
1204
+ # warning detections.
1205
+ # _notify_variable_value_referred(node, lhs_variable)
1206
+
1207
+ _notify_variable_value_referred(node, rhs_variable)
1208
+
965
1209
  result_variable = temporary_variable(lhs_converted.type, result_value)
966
1210
 
967
1211
  notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
@@ -980,7 +1224,11 @@ module C #:nodoc:
980
1224
  # NOTE: Domain of the arithmetic result value will be restricted by
981
1225
  # min-max of the variable type.
982
1226
  lhs_variable.assign!(result_converted.value)
1227
+ _notify_variable_value_updated(node, lhs_variable)
1228
+
1229
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
983
1230
  end
1231
+ module_function :execute_shl_then_assign_expression
984
1232
 
985
1233
  def execute_shr_then_assign_expression(node, lhs_variable, rhs_variable)
986
1234
  # NOTE: The ISO C99 standard saids;
@@ -1010,6 +1258,13 @@ module C #:nodoc:
1010
1258
  result_value = lhs_converted.value
1011
1259
  end
1012
1260
 
1261
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1262
+ # reference should not be notified not to confuse sequence-point
1263
+ # warning detections.
1264
+ # _notify_variable_value_referred(node, lhs_variable)
1265
+
1266
+ _notify_variable_value_referred(node, rhs_variable)
1267
+
1013
1268
  result_variable = temporary_variable(lhs_converted.type, result_value)
1014
1269
 
1015
1270
  notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
@@ -1028,7 +1283,11 @@ module C #:nodoc:
1028
1283
  # NOTE: Domain of the arithmetic result value will be restricted by
1029
1284
  # min-max of the variable type.
1030
1285
  lhs_variable.assign!(result_converted.value)
1286
+ _notify_variable_value_updated(node, lhs_variable)
1287
+
1288
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1031
1289
  end
1290
+ module_function :execute_shr_then_assign_expression
1032
1291
 
1033
1292
  def execute_and_then_assign_expression(node, lhs_variable, rhs_variable)
1034
1293
  lhs_converted, rhs_converted =
@@ -1050,6 +1309,13 @@ module C #:nodoc:
1050
1309
  result_value = lhs_converted.value
1051
1310
  end
1052
1311
 
1312
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1313
+ # reference should not be notified not to confuse sequence-point
1314
+ # warning detections.
1315
+ # _notify_variable_value_referred(node, lhs_variable)
1316
+
1317
+ _notify_variable_value_referred(node, rhs_variable)
1318
+
1053
1319
  result_variable = temporary_variable(lhs_converted.type, result_value)
1054
1320
 
1055
1321
  notify_and_expr_evaled(node, lhs_variable, rhs_variable, result_variable)
@@ -1067,8 +1333,11 @@ module C #:nodoc:
1067
1333
  # NOTE: Domain of the arithmetic result value will be restricted by
1068
1334
  # min-max of the variable type.
1069
1335
  lhs_variable.assign!(result_converted.value)
1336
+ _notify_variable_value_updated(node, lhs_variable)
1337
+
1070
1338
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1071
1339
  end
1340
+ module_function :execute_and_then_assign_expression
1072
1341
 
1073
1342
  def execute_xor_then_assign_expression(node, lhs_variable, rhs_variable)
1074
1343
  lhs_converted, rhs_converted =
@@ -1090,6 +1359,13 @@ module C #:nodoc:
1090
1359
  result_value = lhs_converted.value
1091
1360
  end
1092
1361
 
1362
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1363
+ # reference should not be notified not to confuse sequence-point
1364
+ # warning detections.
1365
+ # _notify_variable_value_referred(node, lhs_variable)
1366
+
1367
+ _notify_variable_value_referred(node, rhs_variable)
1368
+
1093
1369
  result_variable = temporary_variable(lhs_converted.type, result_value)
1094
1370
 
1095
1371
  notify_exclusive_or_expr_evaled(node, lhs_variable, rhs_variable,
@@ -1108,8 +1384,11 @@ module C #:nodoc:
1108
1384
  # NOTE: Domain of the arithmetic result value will be restricted by
1109
1385
  # min-max of the variable type.
1110
1386
  lhs_variable.assign!(result_converted.value)
1387
+ _notify_variable_value_updated(node, lhs_variable)
1388
+
1111
1389
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1112
1390
  end
1391
+ module_function :execute_xor_then_assign_expression
1113
1392
 
1114
1393
  def execute_ior_then_assign_expression(node, lhs_variable, rhs_variable)
1115
1394
  lhs_converted, rhs_converted =
@@ -1131,6 +1410,13 @@ module C #:nodoc:
1131
1410
  result_value = lhs_converted.value
1132
1411
  end
1133
1412
 
1413
+ # NOTE: Value of the lhs_variable is referred at this point. But value
1414
+ # reference should not be notified not to confuse sequence-point
1415
+ # warning detections.
1416
+ # _notify_variable_value_referred(node, lhs_variable)
1417
+
1418
+ _notify_variable_value_referred(node, rhs_variable)
1419
+
1134
1420
  result_variable = temporary_variable(lhs_converted.type, result_value)
1135
1421
 
1136
1422
  notify_inclusive_or_expr_evaled(node, lhs_variable, rhs_variable,
@@ -1149,44 +1435,63 @@ module C #:nodoc:
1149
1435
  # NOTE: Domain of the arithmetic result value will be restricted by
1150
1436
  # min-max of the variable type.
1151
1437
  lhs_variable.assign!(result_converted.value)
1438
+ _notify_variable_value_updated(node, lhs_variable)
1439
+
1152
1440
  notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1153
1441
  end
1442
+ module_function :execute_ior_then_assign_expression
1154
1443
 
1155
- def variable_reassigning_context(&block)
1156
- expr_context_stack.push(:variable_reassigning)
1157
- yield
1158
- ensure
1159
- expr_context_stack.pop
1444
+ def _notify_object_referred(node, object)
1445
+ case object
1446
+ when Variable
1447
+ interpreter.notify_variable_referred(node, object)
1448
+ when Function
1449
+ interpreter.notify_function_referred(node, object)
1450
+ end
1160
1451
  end
1452
+ module_function :_notify_object_referred
1161
1453
 
1162
- def variable_reassigning?
1163
- expr_context_stack.last == :variable_reassigning
1164
- end
1454
+ def _notify_variable_value_referred(node, object)
1455
+ if object.kind_of?(InnerVariable)
1456
+ # NOTE: When a value of the inner-variable of array or composite object
1457
+ # is referred, the outmost variable's value is notified to be
1458
+ # referred.
1459
+ object = object.owner
1460
+ object = object.owner while object.kind_of?(InnerVariable)
1461
+ end
1165
1462
 
1166
- def function_calling_context(&block)
1167
- expr_context_stack.push(:function_calling)
1168
- yield
1169
- ensure
1170
- expr_context_stack.pop
1463
+ if object.variable?
1464
+ interpreter.notify_variable_value_referred(node, object)
1465
+ end
1171
1466
  end
1467
+ module_function :_notify_variable_value_referred
1172
1468
 
1173
- def function_calling?
1174
- expr_context_stack.last == :function_calling
1175
- end
1469
+ def _notify_variable_value_updated(node, object)
1470
+ if object.kind_of?(InnerVariable)
1471
+ # NOTE: When a value of the inner-variable of array or composite object
1472
+ # is updated, the outmost variable's value is notified to be
1473
+ # updated.
1474
+ object = object.owner
1475
+ object = object.owner while object.kind_of?(InnerVariable)
1476
+ end
1176
1477
 
1177
- def expr_context_stack
1178
- @expr_context_stack ||= []
1478
+ if object.variable?
1479
+ interpreter.notify_variable_value_updated(node, object)
1480
+ end
1179
1481
  end
1482
+ module_function :_notify_variable_value_updated
1180
1483
 
1181
- def char_array_value(string_literal)
1484
+ def _char_array_value(string_literal)
1182
1485
  chars = string_literal.chars.map { |ch| ScalarValue.of(ch.ord) }
1183
1486
  ArrayValue.new(chars + [ScalarValue.of("\0".ord)])
1184
1487
  end
1488
+ module_function :_char_array_value
1185
1489
 
1186
- def wchar_array_value(string_literal)
1490
+ def _wchar_array_value(string_literal)
1187
1491
  chars = string_literal.chars.map { |ch| ScalarValue.of(ch.ord) }
1188
1492
  ArrayValue.new(chars + [ScalarValue.of("\0".ord)])
1189
1493
  end
1494
+ module_function :_wchar_array_value
1190
1495
  end
1191
1496
 
1192
1497
  module ExpressionEvaluator
@@ -1207,37 +1512,7 @@ module C #:nodoc:
1207
1512
  def visit_object_specifier(node)
1208
1513
  checkpoint(node.location)
1209
1514
 
1210
- if variable = variable_named(node.identifier.value)
1211
- notify_variable_referred(node, variable)
1212
- unless variable_reassigning?
1213
- notify_variable_value_referred(node, variable)
1214
- end
1215
- variable.declarations_and_definitions.each do |decl_or_def|
1216
- decl_or_def.mark_as_referred_by(node.identifier)
1217
- end
1218
- if variable.type.array?
1219
- variable = temporary_variable(pointer_type(variable.type.base_type),
1220
- pointer_value_of(variable))
1221
- end
1222
- return variable
1223
- end
1224
-
1225
- if function = function_named(node.identifier.value)
1226
- unless function_calling?
1227
- notify_function_referred(node, function)
1228
- end
1229
- function.declarations_and_definitions.each do |decl_or_def|
1230
- decl_or_def.mark_as_referred_by(node.identifier)
1231
- end
1232
- return function
1233
- end
1234
-
1235
- if enumerator = enumerator_named(node.identifier.value)
1236
- enumerator.mark_as_referred_by(node.identifier)
1237
- return temporary_variable(int_type, ScalarValue.of(enumerator.value))
1238
- end
1239
-
1240
- define_implicit_function(node.identifier.value)
1515
+ execute_object_specifier(node)
1241
1516
  end
1242
1517
 
1243
1518
  def visit_constant_specifier(node)
@@ -1257,10 +1532,10 @@ module C #:nodoc:
1257
1532
  case node.literal.value
1258
1533
  when /\A"(.*)"\z/
1259
1534
  array = temporary_variable(array_type(char_type, $1.length + 1),
1260
- char_array_value($1))
1535
+ _char_array_value($1))
1261
1536
  when /\AL"(.*)"\z/i
1262
1537
  array = temporary_variable(array_type(wchar_type, $1.length + 1),
1263
- wchar_array_value($1))
1538
+ _wchar_array_value($1))
1264
1539
  else
1265
1540
  return temporary_variable(pointer_type(char_type))
1266
1541
  end
@@ -1293,7 +1568,7 @@ module C #:nodoc:
1293
1568
  def visit_function_call_expression(node)
1294
1569
  checkpoint(node.location)
1295
1570
 
1296
- object = function_calling_context { node.expression.accept(self) }
1571
+ object = node.expression.accept(self)
1297
1572
  args = node.argument_expressions.map { |expr| [expr.accept(self), expr] }
1298
1573
 
1299
1574
  execute_function_call_expression(node, object, args)
@@ -1332,7 +1607,7 @@ module C #:nodoc:
1332
1607
  def visit_postfix_increment_expression(node)
1333
1608
  checkpoint(node.location)
1334
1609
 
1335
- object = variable_reassigning_context { node.operand.accept(self) }
1610
+ object = node.operand.accept(self)
1336
1611
 
1337
1612
  execute_postfix_increment_expression(node, object)
1338
1613
  end
@@ -1340,7 +1615,7 @@ module C #:nodoc:
1340
1615
  def visit_postfix_decrement_expression(node)
1341
1616
  checkpoint(node.location)
1342
1617
 
1343
- object = variable_reassigning_context { node.operand.accept(self) }
1618
+ object = node.operand.accept(self)
1344
1619
 
1345
1620
  execute_postfix_decrement_expression(node, object)
1346
1621
  end
@@ -1355,7 +1630,7 @@ module C #:nodoc:
1355
1630
  def visit_prefix_increment_expression(node)
1356
1631
  checkpoint(node.location)
1357
1632
 
1358
- object = variable_reassigning_context { node.operand.accept(self) }
1633
+ object = node.operand.accept(self)
1359
1634
 
1360
1635
  execute_prefix_increment_expression(node, object)
1361
1636
  end
@@ -1363,7 +1638,7 @@ module C #:nodoc:
1363
1638
  def visit_prefix_decrement_expression(node)
1364
1639
  checkpoint(node.location)
1365
1640
 
1366
- object = variable_reassigning_context { node.operand.accept(self) }
1641
+ object = node.operand.accept(self)
1367
1642
 
1368
1643
  execute_prefix_decrement_expression(node, object)
1369
1644
  end
@@ -1372,7 +1647,8 @@ module C #:nodoc:
1372
1647
  checkpoint(node.location)
1373
1648
 
1374
1649
  object = node.operand.accept(self)
1375
- temporary_variable(pointer_type(object.type), pointer_value_of(object))
1650
+
1651
+ execute_address_expression(node, object)
1376
1652
  end
1377
1653
 
1378
1654
  def visit_indirection_expression(node)
@@ -1445,7 +1721,6 @@ module C #:nodoc:
1445
1721
  checkpoint(node.location)
1446
1722
 
1447
1723
  object = node.operand.accept(self)
1448
-
1449
1724
  execute_cast_expression(node, object)
1450
1725
  end
1451
1726
 
@@ -1482,53 +1757,7 @@ module C #:nodoc:
1482
1757
  lhs_object = node.lhs_operand.accept(self)
1483
1758
  rhs_object = node.rhs_operand.accept(self)
1484
1759
 
1485
- if lhs_object.function? || rhs_object.function?
1486
- return temporary_variable(int_type)
1487
- end
1488
-
1489
- lhs_variable = lhs_object
1490
- rhs_variable = rhs_object
1491
-
1492
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
1493
- return temporary_variable(int_type)
1494
- end
1495
-
1496
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
1497
- return temporary_variable(int_type)
1498
- end
1499
-
1500
- lhs_converted, rhs_converted =
1501
- do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1502
-
1503
- unless lhs_variable == lhs_converted
1504
- notify_implicit_conv_performed(node.lhs_operand,
1505
- lhs_variable, lhs_converted)
1506
- end
1507
-
1508
- unless rhs_variable == rhs_converted
1509
- notify_implicit_conv_performed(node.rhs_operand,
1510
- rhs_variable, rhs_converted)
1511
- end
1512
-
1513
- case node.operator.type
1514
- when "<"
1515
- result = temporary_variable(int_type,
1516
- lhs_converted.value < rhs_converted.value)
1517
- when ">"
1518
- result = temporary_variable(int_type,
1519
- lhs_converted.value > rhs_converted.value)
1520
- when "<="
1521
- result = temporary_variable(int_type,
1522
- lhs_converted.value <= rhs_converted.value)
1523
- when ">="
1524
- result = temporary_variable(int_type,
1525
- lhs_converted.value >= rhs_converted.value)
1526
- else
1527
- # NOTREACHED
1528
- end
1529
-
1530
- notify_relational_expr_evaled(node, lhs_converted, rhs_converted, result)
1531
- result
1760
+ execute_relational_expression(node, lhs_object, rhs_object)
1532
1761
  end
1533
1762
 
1534
1763
  def visit_equality_expression(node)
@@ -1537,47 +1766,7 @@ module C #:nodoc:
1537
1766
  lhs_object = node.lhs_operand.accept(self)
1538
1767
  rhs_object = node.rhs_operand.accept(self)
1539
1768
 
1540
- if lhs_object.function? || rhs_object.function?
1541
- return temporary_variable(int_type)
1542
- end
1543
-
1544
- lhs_variable = lhs_object
1545
- rhs_variable = rhs_object
1546
-
1547
- unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
1548
- return temporary_variable(int_type)
1549
- end
1550
-
1551
- unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
1552
- return temporary_variable(int_type)
1553
- end
1554
-
1555
- lhs_converted, rhs_converted =
1556
- do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1557
-
1558
- unless lhs_variable == lhs_converted
1559
- notify_implicit_conv_performed(node.lhs_operand,
1560
- lhs_variable, lhs_converted)
1561
- end
1562
-
1563
- unless rhs_variable == rhs_converted
1564
- notify_implicit_conv_performed(node.rhs_operand,
1565
- rhs_variable, rhs_converted)
1566
- end
1567
-
1568
- case node.operator.type
1569
- when "=="
1570
- result = temporary_variable(int_type,
1571
- lhs_converted.value == rhs_converted.value)
1572
- when "!="
1573
- result = temporary_variable(int_type,
1574
- lhs_converted.value != rhs_converted.value)
1575
- else
1576
- # NOTREACHED
1577
- end
1578
-
1579
- notify_equality_expr_evaled(node, lhs_converted, rhs_converted, result)
1580
- result
1769
+ execute_equality_expression(node, lhs_object, rhs_object)
1581
1770
  end
1582
1771
 
1583
1772
  def visit_and_expression(node)
@@ -1695,9 +1884,7 @@ module C #:nodoc:
1695
1884
  def visit_simple_assignment_expression(node)
1696
1885
  checkpoint(node.location)
1697
1886
 
1698
- lhs_object = variable_reassigning_context {
1699
- node.lhs_operand.accept(self)
1700
- }
1887
+ lhs_object = node.lhs_operand.accept(self)
1701
1888
  rhs_object = node.rhs_operand.accept(self)
1702
1889
 
1703
1890
  execute_simple_assignment_expression(node, lhs_object, rhs_object)
@@ -1706,9 +1893,7 @@ module C #:nodoc:
1706
1893
  def visit_compound_assignment_expression(node)
1707
1894
  checkpoint(node.location)
1708
1895
 
1709
- lhs_object = variable_reassigning_context {
1710
- node.lhs_operand.accept(self)
1711
- }
1896
+ lhs_object = node.lhs_operand.accept(self)
1712
1897
  rhs_object = node.rhs_operand.accept(self)
1713
1898
 
1714
1899
  execute_compound_assignment_expression(node, lhs_object, rhs_object)