adlint 3.0.8 → 3.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +295 -0
- data/MANIFEST +9 -0
- data/NEWS +25 -4
- data/etc/mesg.d/c_builtin/en_US/messages.yml +1 -1
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +1 -1
- data/etc/mesg.d/core/en_US/messages.yml +1 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
- data/features/code_check/E0008.feature +20 -0
- data/features/code_check/W0093.feature +1 -1
- data/features/code_check/W0097.feature +30 -0
- data/features/code_check/W0100.feature +66 -0
- data/features/code_check/W0422.feature +157 -0
- data/features/code_check/W0459.feature +118 -0
- data/features/code_check/W0461.feature +115 -0
- data/features/code_check/W0610.feature +59 -0
- data/features/code_check/W0612.feature +29 -0
- data/features/code_check/W0613.feature +33 -0
- data/features/code_check/W0704.feature +25 -0
- data/features/code_check/W0705.feature +33 -0
- data/features/code_check/W1050.feature +43 -0
- data/features/code_check/W1071.feature +30 -0
- data/features/code_check/W9001.feature +24 -0
- data/lib/adlint/cc1/branch.rb +32 -9
- data/lib/adlint/cc1/builtin.rb +2 -2
- data/lib/adlint/cc1/conv.rb +33 -33
- data/lib/adlint/cc1/ctrlexpr.rb +30 -30
- data/lib/adlint/cc1/domain.rb +12 -4
- data/lib/adlint/cc1/environ.rb +2 -1
- data/lib/adlint/cc1/expr.rb +135 -125
- data/lib/adlint/cc1/format.rb +3 -3
- data/lib/adlint/cc1/interp.rb +123 -109
- data/lib/adlint/cc1/lexer.rb +44 -40
- data/lib/adlint/cc1/mediator.rb +2 -2
- data/lib/adlint/cc1/object.rb +121 -36
- data/lib/adlint/cc1/option.rb +1 -0
- data/lib/adlint/cc1/parser.rb +874 -845
- data/lib/adlint/cc1/parser.y +22 -2
- data/lib/adlint/cc1/syntax.rb +37 -18
- data/lib/adlint/cc1/type.rb +3 -3
- data/lib/adlint/cc1/value.rb +58 -50
- data/lib/adlint/cpp/lexer.rb +5 -1
- data/lib/adlint/cpp/macro.rb +30 -30
- data/lib/adlint/cpp/subst.rb +4 -4
- data/lib/adlint/exam/c_builtin/cc1_check.rb +172 -172
- data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +11 -11
- data/lib/adlint/exam/c_builtin/cpp_check.rb +2 -2
- data/lib/adlint/memo.rb +13 -13
- data/lib/adlint/prelude.rb +2 -2
- data/lib/adlint/version.rb +2 -2
- data/share/doc/developers_guide_ja.html +7 -5
- data/share/doc/developers_guide_ja.texi +5 -3
- data/share/doc/users_guide_en.html +3 -3
- data/share/doc/users_guide_en.texi +1 -1
- data/share/doc/users_guide_ja.html +3 -3
- data/share/doc/users_guide_ja.texi +1 -1
- metadata +11 -2
data/lib/adlint/cc1/format.rb
CHANGED
@@ -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
|
-
|
2850
|
-
uniq_set =
|
2851
|
-
|
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
|
data/lib/adlint/cc1/interp.rb
CHANGED
@@ -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, :
|
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, :
|
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,
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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
|
-
|
423
|
+
rslt = nil
|
423
424
|
branched_eval(nil, FINAL) do
|
424
|
-
|
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
|
-
|
430
|
+
rslt = node.accept(interpreter_for(node))
|
430
431
|
end
|
431
|
-
|
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:
|
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
|
-
|
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(
|
819
|
-
unless
|
820
|
-
if
|
821
|
-
|
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
|
-
|
824
|
+
orig_ary_type.length = inits.size
|
824
825
|
end
|
825
|
-
|
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
|
-
|
1001
|
-
if
|
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
|
-
|
1006
|
-
|
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(
|
1009
|
-
notify_sequence_point_reached(SequencePoint.new(
|
1010
|
-
ctrlexpr =
|
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
|
-
|
1035
|
-
if
|
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
|
-
|
1040
|
-
|
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(
|
1043
|
-
notify_sequence_point_reached(SequencePoint.new(
|
1044
|
-
ctrlexpr =
|
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
|
-
|
1079
|
-
|
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
|
-
|
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(
|
1091
|
-
|
1092
|
-
|
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(
|
1095
|
+
leave_iteration_statement(orig_ctrlexpr)
|
1096
1096
|
end
|
1097
1097
|
when ctrlexpr_val.may_be_true?
|
1098
1098
|
begin
|
1099
|
-
enter_iteration_statement(
|
1100
|
-
|
1101
|
-
|
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(
|
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
|
-
|
1118
|
+
orig_ctrlexpr, * = node.deduct_controlling_expression
|
1120
1119
|
|
1121
1120
|
begin
|
1122
|
-
enter_iteration_statement(
|
1123
|
-
|
1124
|
-
|
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(
|
1125
|
+
leave_iteration_statement(orig_ctrlexpr)
|
1128
1126
|
end
|
1129
1127
|
|
1130
|
-
|
1131
|
-
|
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
|
-
|
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,
|
1154
|
+
interpret_for_body_statement(node, true)
|
1166
1155
|
when ctrlexpr_val.may_be_true?
|
1167
|
-
interpret_for_body_statement(node,
|
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
|
-
|
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,
|
1179
|
+
interpret_for_body_statement(node, true)
|
1200
1180
|
when ctrlexpr_val.may_be_true?
|
1201
|
-
interpret_for_body_statement(node,
|
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
|
1262
|
-
|
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(
|
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,
|
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,
|
1329
|
+
var.narrow_value_domain!(Operator::GE, orig_val)
|
1329
1330
|
when :decrease
|
1330
|
-
var.narrow_value_domain!(Operator::LE,
|
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
|
-
|
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
|
-
|
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
|
-
|
1719
|
+
rslt_var = then_var
|
1719
1720
|
when else_var
|
1720
|
-
|
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
|
-
|
1725
|
+
rslt_var = create_tmpvar
|
1725
1726
|
end
|
1726
1727
|
|
1727
|
-
notify_conditional_expr_evaled(node, ctrlexpr_var,
|
1728
|
-
|
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
|