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.
- 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
|