adlint 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)