adlint 3.0.8 → 3.0.10

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 (56) hide show
  1. data/ChangeLog +295 -0
  2. data/MANIFEST +9 -0
  3. data/NEWS +25 -4
  4. data/etc/mesg.d/c_builtin/en_US/messages.yml +1 -1
  5. data/etc/mesg.d/c_builtin/ja_JP/messages.yml +1 -1
  6. data/etc/mesg.d/core/en_US/messages.yml +1 -1
  7. data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
  8. data/features/code_check/E0008.feature +20 -0
  9. data/features/code_check/W0093.feature +1 -1
  10. data/features/code_check/W0097.feature +30 -0
  11. data/features/code_check/W0100.feature +66 -0
  12. data/features/code_check/W0422.feature +157 -0
  13. data/features/code_check/W0459.feature +118 -0
  14. data/features/code_check/W0461.feature +115 -0
  15. data/features/code_check/W0610.feature +59 -0
  16. data/features/code_check/W0612.feature +29 -0
  17. data/features/code_check/W0613.feature +33 -0
  18. data/features/code_check/W0704.feature +25 -0
  19. data/features/code_check/W0705.feature +33 -0
  20. data/features/code_check/W1050.feature +43 -0
  21. data/features/code_check/W1071.feature +30 -0
  22. data/features/code_check/W9001.feature +24 -0
  23. data/lib/adlint/cc1/branch.rb +32 -9
  24. data/lib/adlint/cc1/builtin.rb +2 -2
  25. data/lib/adlint/cc1/conv.rb +33 -33
  26. data/lib/adlint/cc1/ctrlexpr.rb +30 -30
  27. data/lib/adlint/cc1/domain.rb +12 -4
  28. data/lib/adlint/cc1/environ.rb +2 -1
  29. data/lib/adlint/cc1/expr.rb +135 -125
  30. data/lib/adlint/cc1/format.rb +3 -3
  31. data/lib/adlint/cc1/interp.rb +123 -109
  32. data/lib/adlint/cc1/lexer.rb +44 -40
  33. data/lib/adlint/cc1/mediator.rb +2 -2
  34. data/lib/adlint/cc1/object.rb +121 -36
  35. data/lib/adlint/cc1/option.rb +1 -0
  36. data/lib/adlint/cc1/parser.rb +874 -845
  37. data/lib/adlint/cc1/parser.y +22 -2
  38. data/lib/adlint/cc1/syntax.rb +37 -18
  39. data/lib/adlint/cc1/type.rb +3 -3
  40. data/lib/adlint/cc1/value.rb +58 -50
  41. data/lib/adlint/cpp/lexer.rb +5 -1
  42. data/lib/adlint/cpp/macro.rb +30 -30
  43. data/lib/adlint/cpp/subst.rb +4 -4
  44. data/lib/adlint/exam/c_builtin/cc1_check.rb +172 -172
  45. data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +11 -11
  46. data/lib/adlint/exam/c_builtin/cpp_check.rb +2 -2
  47. data/lib/adlint/memo.rb +13 -13
  48. data/lib/adlint/prelude.rb +2 -2
  49. data/lib/adlint/version.rb +2 -2
  50. data/share/doc/developers_guide_ja.html +7 -5
  51. data/share/doc/developers_guide_ja.texi +5 -3
  52. data/share/doc/users_guide_en.html +3 -3
  53. data/share/doc/users_guide_en.texi +1 -1
  54. data/share/doc/users_guide_ja.html +3 -3
  55. data/share/doc/users_guide_ja.texi +1 -1
  56. metadata +11 -2
@@ -2846,9 +2846,9 @@ module Cc1 #:nodoc:
2846
2846
  # NOTE: The `-' character in the scanset causes implementation-defined
2847
2847
  # behavior. So, AdLint treats the `-' character as an ordinary
2848
2848
  # character in the scanset.
2849
- org_set = scanset.chop.chars.to_a
2850
- uniq_set = org_set.uniq
2851
- org_set.size == uniq_set.size
2849
+ orig_set = scanset.chop.chars.to_a
2850
+ uniq_set = orig_set.uniq
2851
+ orig_set.size == uniq_set.size
2852
2852
  end
2853
2853
  end
2854
2854
  private_constant :Conversion_bracket
@@ -183,18 +183,19 @@ module Cc1 #:nodoc:
183
183
  def_plugin_and_notifier :implicit_function_declared, :obj_spec, :fun
184
184
 
185
185
  # NOTE: Notified when the interpreter evaluates a sizeof-expression.
186
- def_plugin_and_notifier :sizeof_expr_evaled, :expr, :ope_var, :res_var
186
+ def_plugin_and_notifier :sizeof_expr_evaled, :expr, :ope_var, :rslt_var
187
187
 
188
188
  # NOTE: Notified when the interpreter evaluates a sizeof-type-expression.
189
- def_plugin_and_notifier :sizeof_type_expr_evaled, :expr, :type, :res_var
189
+ def_plugin_and_notifier :sizeof_type_expr_evaled, :expr, :type, :rslt_var
190
190
 
191
191
  # NOTE: Notified when the interpreter evaluates a cast-expression.
192
- def_plugin_and_notifier :explicit_conv_performed, :expr, :org_var, :res_var
192
+ def_plugin_and_notifier :explicit_conv_performed,
193
+ :expr, :orig_var, :rslt_var
193
194
 
194
195
  # NOTE: Notified when the interpreter performs an implicit conversion while
195
196
  # evaluating an expression.
196
197
  def_plugin_and_notifier :implicit_conv_performed,
197
- :init_or_expr, :org_var, :res_var
198
+ :init_or_expr, :orig_var, :rslt_var
198
199
 
199
200
  # NOTE: Notified when the interpreter performs an address derivation while
200
201
  # address-expression evaluation and array or function address
@@ -205,62 +206,62 @@ module Cc1 #:nodoc:
205
206
  # NOTE: Notified when the interpreter evaluates an
206
207
  # array-subscript-expression.
207
208
  def_plugin_and_notifier :array_subscript_expr_evaled,
208
- :expr, :ary_or_ptr, :subs, :ary_var, :res_var
209
+ :expr, :ary_or_ptr, :subs, :ary_var, :rslt_var
209
210
 
210
211
  # NOTE: Notified when the interpreter evaluates a function-call-expression.
211
212
  def_plugin_and_notifier :function_call_expr_evaled,
212
- :expr, :fun, :arg_vars, :res_var
213
+ :expr, :fun, :arg_vars, :rslt_var
213
214
 
214
215
  # NOTE: Notified when the interpreter evaluates an
215
216
  # unary-arithmetic-expression.
216
217
  def_plugin_and_notifier :unary_arithmetic_expr_evaled,
217
- :expr, :ope_var, :res_var
218
+ :expr, :ope_var, :rslt_var
218
219
 
219
220
  # NOTE: Notified when the interpreter evaluates a
220
221
  # multiplicative-expression.
221
222
  def_plugin_and_notifier :multiplicative_expr_evaled,
222
- :expr, :lhs_var, :rhs_var, :res_var
223
+ :expr, :lhs_var, :rhs_var, :rslt_var
223
224
 
224
225
  # NOTE: Notified when the interpreter evaluates an additive-expression.
225
226
  def_plugin_and_notifier :additive_expr_evaled,
226
- :expr, :lhs_var, :rhs_var, :res_var
227
+ :expr, :lhs_var, :rhs_var, :rslt_var
227
228
 
228
229
  # NOTE: Notified when the interpreter evaluates a shift-expression.
229
230
  def_plugin_and_notifier :shift_expr_evaled,
230
- :expr, :lhs_var, :rhs_var, :res_var
231
+ :expr, :lhs_var, :rhs_var, :rslt_var
231
232
 
232
233
  # NOTE: Notified when the interpreter evaluates a relational-expression.
233
234
  def_plugin_and_notifier :relational_expr_evaled,
234
- :expr, :lhs_var, :rhs_var, :res_var
235
+ :expr, :lhs_var, :rhs_var, :rslt_var
235
236
 
236
237
  # NOTE: Notified when the interpreter evaluates an equality-expression.
237
238
  def_plugin_and_notifier :equality_expr_evaled,
238
- :expr, :lhs_var, :rhs_var, :res_var
239
+ :expr, :lhs_var, :rhs_var, :rslt_var
239
240
 
240
241
  # NOTE: Notified when the interpreter evaluates a bitwise and-expression.
241
242
  def_plugin_and_notifier :and_expr_evaled,
242
- :expr, :lhs_var, :rhs_var, :res_var
243
+ :expr, :lhs_var, :rhs_var, :rslt_var
243
244
 
244
245
  # NOTE: Notified when the interpreter evaluates an exclusive-or-expression.
245
246
  def_plugin_and_notifier :exclusive_or_expr_evaled,
246
- :expr, :lhs_var, :rhs_var, :res_var
247
+ :expr, :lhs_var, :rhs_var, :rslt_var
247
248
 
248
249
  # NOTE: Notified when the interpreter evaluates a bitwise
249
250
  # inclusive-or-expression.
250
251
  def_plugin_and_notifier :inclusive_or_expr_evaled,
251
- :expr, :lhs_var, :rhs_var, :res_var
252
+ :expr, :lhs_var, :rhs_var, :rslt_var
252
253
 
253
254
  # NOTE: Notified when the interpreter evaluates a logical-and-expression.
254
255
  def_plugin_and_notifier :logical_and_expr_evaled,
255
- :expr, :lhs_var, :rhs_var, :res_var
256
+ :expr, :lhs_var, :rhs_var, :rslt_var
256
257
 
257
258
  # NOTE: Notified when the interpreter evaluates a logical-or-expression.
258
259
  def_plugin_and_notifier :logical_or_expr_evaled,
259
- :expr, :lhs_var, :rhs_var, :res_var
260
+ :expr, :lhs_var, :rhs_var, :rslt_var
260
261
 
261
262
  # NOTE: Notified when the interpreter evaluates a conditional-expression.
262
263
  def_plugin_and_notifier :conditional_expr_evaled,
263
- :expr, :ctrlexpr_var, :res_var
264
+ :expr, :ctrlexpr_var, :rslt_var
264
265
 
265
266
  # NOTE: Notified when the interpreter evaluates an address-expression.
266
267
  def_plugin_and_notifier :address_expr_evaled, :expr, :obj, :ptr_var
@@ -278,22 +279,22 @@ module Cc1 #:nodoc:
278
279
  # NOTE: Notified when the interpreter evaluates a
279
280
  # prefix-increment-expression.
280
281
  def_plugin_and_notifier :prefix_increment_expr_evaled,
281
- :expr, :ope_var, :org_val
282
+ :expr, :ope_var, :orig_val
282
283
 
283
284
  # NOTE: Notified when the interpreter evaluates a
284
285
  # postfix-increment-expression.
285
286
  def_plugin_and_notifier :postfix_increment_expr_evaled,
286
- :expr, :ope_var, :res_var
287
+ :expr, :ope_var, :rslt_var
287
288
 
288
289
  # NOTE: Notified when the interpreter evaluates a
289
290
  # prefix-decrement-expression.
290
291
  def_plugin_and_notifier :prefix_decrement_expr_evaled,
291
- :expr, :ope_var, :org_val
292
+ :expr, :ope_var, :orig_val
292
293
 
293
294
  # NOTE: Notified when the interpreter evaluates a
294
295
  # postfix-decrement-expression.
295
296
  def_plugin_and_notifier :postfix_decrement_expr_evaled,
296
- :expr, :ope_var, :res_var
297
+ :expr, :ope_var, :rslt_var
297
298
 
298
299
  # NOTE: Notified when the interpreter evaluates a
299
300
  # simple-assignment-expression or a compound-assignment-expression.
@@ -419,16 +420,16 @@ module Cc1 #:nodoc:
419
420
  def execute(node, *opts)
420
421
  @options_stack.push(cur_opts + opts)
421
422
  if quiet_without_side_effect?
422
- result = nil
423
+ rslt = nil
423
424
  branched_eval(nil, FINAL) do
424
- result = node.accept(interpreter_for(node))
425
+ rslt = node.accept(interpreter_for(node))
425
426
  # NOTE: To rollback latest variable value versions.
426
427
  BreakEvent.of_return.throw
427
428
  end
428
429
  else
429
- result = node.accept(interpreter_for(node))
430
+ rslt = node.accept(interpreter_for(node))
430
431
  end
431
- result
432
+ rslt
432
433
  ensure
433
434
  @options_stack.pop
434
435
  end
@@ -573,10 +574,10 @@ module Cc1 #:nodoc:
573
574
  init_var, init_conved = evaluate_initializer(node)
574
575
  var = define_variable(node, init_conved.value.to_defined_value)
575
576
  else
576
- # NOTE: Define variable first in order to correctly evaluate
577
+ # NOTE: Declare variable first in order to correctly evaluate
577
578
  # sizeof-expression that refers to the defining variable in the
578
579
  # initializer.
579
- define_variable(node) unless variable_named(node.identifier.value)
580
+ declare_variable(node)
580
581
  init_var, init_conved = evaluate_initializer(node)
581
582
  var = define_variable(node, init_conved.value.to_defined_value)
582
583
  end
@@ -815,14 +816,14 @@ module Cc1 #:nodoc:
815
816
  end
816
817
  end
817
818
 
818
- def deduct_array_length_from_initializers(org_ary_type, inits)
819
- unless org_ary_type.length
820
- if org_ary_type.user?
821
- org_ary_type = org_ary_type.dup
819
+ def deduct_array_length_from_initializers(orig_ary_type, inits)
820
+ unless orig_ary_type.length
821
+ if orig_ary_type.user?
822
+ orig_ary_type = orig_ary_type.dup
822
823
  end
823
- org_ary_type.length = inits.size
824
+ orig_ary_type.length = inits.size
824
825
  end
825
- org_ary_type
826
+ orig_ary_type
826
827
  end
827
828
 
828
829
  def interpreter
@@ -997,17 +998,17 @@ module Cc1 #:nodoc:
997
998
 
998
999
  node.executed = true
999
1000
 
1000
- org_ctrlexpr = node.expression
1001
- if org_ctrlexpr == effective_ctrlexpr
1001
+ orig_ctrlexpr = node.expression
1002
+ if orig_ctrlexpr == effective_ctrlexpr
1002
1003
  ctrlexpr_val = scalar_value_of_arbitrary
1003
1004
  ctrlexpr = nil
1004
1005
  else
1005
- ctrlexpr_var = object_to_variable(interpret(org_ctrlexpr),
1006
- org_ctrlexpr)
1006
+ ctrlexpr_obj = interpret(orig_ctrlexpr)
1007
+ ctrlexpr_var = object_to_variable(ctrlexpr_obj, orig_ctrlexpr)
1007
1008
  ctrlexpr_val = value_of(ctrlexpr_var)
1008
- notify_variable_value_referred(org_ctrlexpr, ctrlexpr_var)
1009
- notify_sequence_point_reached(SequencePoint.new(org_ctrlexpr))
1010
- ctrlexpr = org_ctrlexpr.to_normalized_logical
1009
+ notify_variable_value_referred(orig_ctrlexpr, ctrlexpr_var)
1010
+ notify_sequence_point_reached(SequencePoint.new(orig_ctrlexpr))
1011
+ ctrlexpr = orig_ctrlexpr.to_normalized_logical
1011
1012
  end
1012
1013
  notify_if_ctrlexpr_evaled(node, ctrlexpr_val)
1013
1014
 
@@ -1031,17 +1032,17 @@ module Cc1 #:nodoc:
1031
1032
 
1032
1033
  node.executed = true
1033
1034
 
1034
- org_ctrlexpr = node.expression
1035
- if org_ctrlexpr == effective_ctrlexpr
1035
+ orig_ctrlexpr = node.expression
1036
+ if orig_ctrlexpr == effective_ctrlexpr
1036
1037
  ctrlexpr_val = scalar_value_of_arbitrary
1037
1038
  ctrlexpr = nil
1038
1039
  else
1039
- ctrlexpr_var = object_to_variable(interpret(org_ctrlexpr),
1040
- org_ctrlexpr)
1040
+ ctrlexpr_obj = interpret(orig_ctrlexpr)
1041
+ ctrlexpr_var = object_to_variable(ctrlexpr_obj, orig_ctrlexpr)
1041
1042
  ctrlexpr_val = value_of(ctrlexpr_var)
1042
- notify_variable_value_referred(org_ctrlexpr, ctrlexpr_var)
1043
- notify_sequence_point_reached(SequencePoint.new(org_ctrlexpr))
1044
- ctrlexpr = org_ctrlexpr.to_normalized_logical
1043
+ notify_variable_value_referred(orig_ctrlexpr, ctrlexpr_var)
1044
+ notify_sequence_point_reached(SequencePoint.new(orig_ctrlexpr))
1045
+ ctrlexpr = orig_ctrlexpr.to_normalized_logical
1045
1046
  end
1046
1047
  notify_if_else_ctrlexpr_evaled(node, ctrlexpr_val)
1047
1048
 
@@ -1075,33 +1076,31 @@ module Cc1 #:nodoc:
1075
1076
 
1076
1077
  widen_varying_variable_value_domain(node)
1077
1078
 
1078
- ctrlexpr_var = object_to_variable(interpret(node.expression),
1079
- node.expression)
1079
+ ctrlexpr_obj = interpret(node.expression)
1080
+ ctrlexpr_var = object_to_variable(ctrlexpr_obj, node.expression)
1080
1081
  ctrlexpr_val = value_of(ctrlexpr_var)
1081
1082
  notify_variable_value_referred(node.expression, ctrlexpr_var)
1082
1083
  notify_sequence_point_reached(SequencePoint.new(node.expression))
1083
1084
  notify_while_ctrlexpr_evaled(node, ctrlexpr_val)
1084
1085
 
1085
- org_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
1086
+ orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
1086
1087
 
1087
1088
  case
1088
1089
  when ctrlexpr_val.must_be_true?
1089
1090
  begin
1090
- enter_iteration_statement(org_ctrlexpr)
1091
- branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
1092
- interpret(node.statement)
1093
- end
1091
+ enter_iteration_statement(orig_ctrlexpr)
1092
+ branch_opts = [ITERATION, NARROWING, FINAL, IMPLICIT_COND, COMPLETE]
1093
+ branched_eval(ctrlexpr, *branch_opts) { interpret(node.statement) }
1094
1094
  ensure
1095
- leave_iteration_statement(org_ctrlexpr)
1095
+ leave_iteration_statement(orig_ctrlexpr)
1096
1096
  end
1097
1097
  when ctrlexpr_val.may_be_true?
1098
1098
  begin
1099
- enter_iteration_statement(org_ctrlexpr)
1100
- branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND) do
1101
- interpret(node.statement)
1102
- end
1099
+ enter_iteration_statement(orig_ctrlexpr)
1100
+ branch_opts = [ITERATION, NARROWING, FINAL, IMPLICIT_COND]
1101
+ branched_eval(ctrlexpr, *branch_opts) { interpret(node.statement) }
1103
1102
  ensure
1104
- leave_iteration_statement(org_ctrlexpr)
1103
+ leave_iteration_statement(orig_ctrlexpr)
1105
1104
  end
1106
1105
  end
1107
1106
  ensure
@@ -1116,19 +1115,18 @@ module Cc1 #:nodoc:
1116
1115
 
1117
1116
  widen_varying_variable_value_domain(node)
1118
1117
 
1119
- org_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
1118
+ orig_ctrlexpr, * = node.deduct_controlling_expression
1120
1119
 
1121
1120
  begin
1122
- enter_iteration_statement(org_ctrlexpr)
1123
- branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
1124
- interpret(node.statement)
1125
- end
1121
+ enter_iteration_statement(orig_ctrlexpr)
1122
+ branch_opts = [ITERATION, NARROWING, FINAL, IMPLICIT_COND, COMPLETE]
1123
+ branched_eval(nil, *branch_opts) { interpret(node.statement) }
1126
1124
  ensure
1127
- leave_iteration_statement(org_ctrlexpr)
1125
+ leave_iteration_statement(orig_ctrlexpr)
1128
1126
  end
1129
1127
 
1130
- ctrlexpr_var = object_to_variable(interpret(node.expression),
1131
- node.expression)
1128
+ ctrlexpr_obj = interpret(node.expression)
1129
+ ctrlexpr_var = object_to_variable(ctrlexpr_obj, node.expression)
1132
1130
  ctrlexpr_val = value_of(ctrlexpr_var)
1133
1131
  notify_variable_value_referred(node.expression, ctrlexpr_var)
1134
1132
  notify_sequence_point_reached(SequencePoint.new(node.expression))
@@ -1145,16 +1143,7 @@ module Cc1 #:nodoc:
1145
1143
 
1146
1144
  node.initial_statement.accept(self)
1147
1145
 
1148
- widen_varying_variable_value_domain(node)
1149
- org_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
1150
-
1151
- node.condition_statement.executed = true
1152
- if explicit_ctrlexpr = node.condition_statement.expression
1153
- ctrlexpr_var = object_to_variable(interpret(explicit_ctrlexpr),
1154
- explicit_ctrlexpr)
1155
- ctrlexpr_val = value_of(ctrlexpr_var)
1156
- notify_variable_value_referred(explicit_ctrlexpr, ctrlexpr_var)
1157
- notify_sequence_point_reached(SequencePoint.new(explicit_ctrlexpr))
1146
+ if ctrlexpr_val = interpret_for_ctrlexpr(node)
1158
1147
  notify_for_ctrlexpr_evaled(node, ctrlexpr_val)
1159
1148
  else
1160
1149
  ctrlexpr_val = scalar_value_of_true
@@ -1162,9 +1151,9 @@ module Cc1 #:nodoc:
1162
1151
 
1163
1152
  case
1164
1153
  when ctrlexpr_val.must_be_true?
1165
- interpret_for_body_statement(node, org_ctrlexpr, ctrlexpr, true)
1154
+ interpret_for_body_statement(node, true)
1166
1155
  when ctrlexpr_val.may_be_true?
1167
- interpret_for_body_statement(node, org_ctrlexpr, ctrlexpr, false)
1156
+ interpret_for_body_statement(node, false)
1168
1157
  end
1169
1158
  ensure
1170
1159
  notify_for_stmt_ended(node)
@@ -1179,16 +1168,7 @@ module Cc1 #:nodoc:
1179
1168
  node.executed = true
1180
1169
  notify_c99_for_stmt_started(node)
1181
1170
 
1182
- widen_varying_variable_value_domain(node)
1183
- org_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
1184
-
1185
- node.condition_statement.executed = true
1186
- if explicit_ctrlexpr = node.condition_statement.expression
1187
- ctrlexpr_var = object_to_variable(interpret(explicit_ctrlexpr),
1188
- explicit_ctrlexpr)
1189
- ctrlexpr_val = value_of(ctrlexpr_var)
1190
- notify_variable_value_referred(explicit_ctrlexpr, ctrlexpr_var)
1191
- notify_sequence_point_reached(SequencePoint.new(explicit_ctrlexpr))
1171
+ if ctrlexpr_val = interpret_for_ctrlexpr(node)
1192
1172
  notify_c99_for_ctrlexpr_evaled(node, ctrlexpr_val)
1193
1173
  else
1194
1174
  ctrlexpr_val = scalar_value_of_true
@@ -1196,9 +1176,9 @@ module Cc1 #:nodoc:
1196
1176
 
1197
1177
  case
1198
1178
  when ctrlexpr_val.must_be_true?
1199
- interpret_for_body_statement(node, org_ctrlexpr, ctrlexpr, true)
1179
+ interpret_for_body_statement(node, true)
1200
1180
  when ctrlexpr_val.may_be_true?
1201
- interpret_for_body_statement(node, org_ctrlexpr, ctrlexpr, false)
1181
+ interpret_for_body_statement(node, false)
1202
1182
  end
1203
1183
  end
1204
1184
  ensure
@@ -1258,15 +1238,36 @@ module Cc1 #:nodoc:
1258
1238
  end
1259
1239
 
1260
1240
  private
1261
- def interpret_for_body_statement(node, org_ctrlexpr, ctrlexpr, complete)
1262
- enter_iteration_statement(org_ctrlexpr)
1241
+ def interpret_for_ctrlexpr(node)
1242
+ node.condition_statement.executed = true
1243
+
1244
+ if ctrlexpr = node.condition_statement.expression
1245
+ ctrlexpr_obj = interpret(ctrlexpr, QUIET)
1246
+ ctrlexpr_var = object_to_variable(ctrlexpr_obj, ctrlexpr)
1247
+ ctrlexpr_val = value_of(ctrlexpr_var)
1263
1248
 
1249
+ widen_varying_variable_value_domain(node)
1250
+ ctrlexpr_var = interpret(ctrlexpr)
1251
+
1252
+ notify_variable_value_referred(ctrlexpr, ctrlexpr_var)
1253
+ notify_sequence_point_reached(SequencePoint.new(ctrlexpr))
1254
+ else
1255
+ widen_varying_variable_value_domain(node)
1256
+ end
1257
+
1258
+ ctrlexpr_val
1259
+ end
1260
+
1261
+ def interpret_for_body_statement(node, complete)
1264
1262
  if complete
1265
- branch_opts = [NARROWING, FINAL, IMPLICIT_COND, COMPLETE]
1263
+ branch_opts = [ITERATION, NARROWING, FINAL, IMPLICIT_COND, COMPLETE]
1266
1264
  else
1267
- branch_opts = [NARROWING, FINAL, IMPLICIT_COND]
1265
+ branch_opts = [ITERATION, NARROWING, FINAL, IMPLICIT_COND]
1268
1266
  end
1269
1267
 
1268
+ orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
1269
+ enter_iteration_statement(orig_ctrlexpr)
1270
+
1270
1271
  branched_eval(ctrlexpr, *branch_opts) do
1271
1272
  interpret(node.body_statement)
1272
1273
  interpret(node.expression) if node.expression
@@ -1289,7 +1290,7 @@ module Cc1 #:nodoc:
1289
1290
  end
1290
1291
  end
1291
1292
  ensure
1292
- leave_iteration_statement(org_ctrlexpr)
1293
+ leave_iteration_statement(orig_ctrlexpr)
1293
1294
  end
1294
1295
 
1295
1296
  def uninitialize_block_local_variables(generic_labeled_stmt)
@@ -1322,12 +1323,12 @@ module Cc1 #:nodoc:
1322
1323
  end
1323
1324
  end
1324
1325
 
1325
- varying_vars.each do |var, org_val|
1326
+ varying_vars.each do |var, orig_val|
1326
1327
  case deduct_variable_varying_path(var, iteration_stmt)
1327
1328
  when :increase
1328
- var.narrow_value_domain!(Operator::GE, org_val)
1329
+ var.narrow_value_domain!(Operator::GE, orig_val)
1329
1330
  when :decrease
1330
- var.narrow_value_domain!(Operator::LE, org_val)
1331
+ var.narrow_value_domain!(Operator::LE, orig_val)
1331
1332
  end
1332
1333
  end
1333
1334
  end
@@ -1680,7 +1681,8 @@ module Cc1 #:nodoc:
1680
1681
  checkpoint(node.location)
1681
1682
 
1682
1683
  ctrlexpr = node.condition
1683
- ctrlexpr_var = object_to_variable(interpret(ctrlexpr), ctrlexpr)
1684
+ ctrlexpr_obj = interpret(ctrlexpr)
1685
+ ctrlexpr_var = object_to_variable(ctrlexpr_obj, ctrlexpr)
1684
1686
  ctrlexpr_val = value_of(ctrlexpr_var)
1685
1687
  notify_variable_value_referred(ctrlexpr, ctrlexpr_var)
1686
1688
  notify_sequence_point_reached(ctrlexpr.subsequent_sequence_point)
@@ -1706,8 +1708,7 @@ module Cc1 #:nodoc:
1706
1708
 
1707
1709
  case
1708
1710
  when then_var && else_var
1709
- res_val = then_var.value.single_value_unified_with(else_var.value)
1710
- res_var = create_tmpvar(then_var.type, res_val)
1711
+ rslt_var = unify_then_and_else_var(then_var, else_var)
1711
1712
  # FIXME: Not to over-warn about discarding a function return value.
1712
1713
  # Because the unified result is a new temporary variable, it is
1713
1714
  # impossible to relate a reference of the unified result and a
@@ -1715,22 +1716,35 @@ module Cc1 #:nodoc:
1715
1716
  notify_variable_value_referred(node, then_var)
1716
1717
  notify_variable_value_referred(node, else_var)
1717
1718
  when then_var
1718
- res_var = then_var
1719
+ rslt_var = then_var
1719
1720
  when else_var
1720
- res_var = else_var
1721
+ rslt_var = else_var
1721
1722
  else
1722
1723
  # FIXME: Nevertheless, the then-expression is not reachable, the branch
1723
1724
  # execution check may fail in evaluation of the else branch.
1724
- res_var = create_tmpvar
1725
+ rslt_var = create_tmpvar
1725
1726
  end
1726
1727
 
1727
- notify_conditional_expr_evaled(node, ctrlexpr_var, res_var)
1728
- res_var
1728
+ notify_conditional_expr_evaled(node, ctrlexpr_var, rslt_var)
1729
+ rslt_var
1729
1730
  ensure
1730
1731
  if seqp = node.subsequent_sequence_point
1731
1732
  notify_sequence_point_reached(seqp)
1732
1733
  end
1733
1734
  end
1735
+
1736
+ def unify_then_and_else_var(then_var, else_var)
1737
+ if then_var.type.pointer? || else_var.type.pointer?
1738
+ case
1739
+ when pointee_of(then_var)
1740
+ return then_var
1741
+ when pointee_of(else_var)
1742
+ return else_var
1743
+ end
1744
+ end
1745
+ create_tmpvar(then_var.type,
1746
+ then_var.value.single_value_unified_with(else_var.value))
1747
+ end
1734
1748
  end
1735
1749
 
1736
1750
  end