adlint 2.6.0 → 2.6.2
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 +122 -0
- data/MANIFEST +1 -0
- data/NEWS +23 -4
- data/README +1 -1
- data/Rakefile +1 -1
- data/etc/mesg.d/c_builtin/en_US/messages.yml +8 -8
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +8 -8
- 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/W0599.feature +71 -0
- data/lib/adlint/c/builtin.rb +1 -1
- data/lib/adlint/c/const.rb +60 -60
- data/lib/adlint/c/conv.rb +3 -3
- data/lib/adlint/c/ctrlexpr.rb +278 -357
- data/lib/adlint/c/expr.rb +1232 -1637
- data/lib/adlint/c/format.rb +26 -26
- data/lib/adlint/c/interp.rb +339 -391
- data/lib/adlint/c/mediator.rb +1 -2
- data/lib/adlint/c/object.rb +8 -9
- data/lib/adlint/c/seqp.rb +1 -1
- data/lib/adlint/c/syntax.rb +6 -6
- data/lib/adlint/c/type.rb +8 -8
- data/lib/adlint/cpp/eval.rb +1 -1
- data/lib/adlint/cpp/macro.rb +4 -4
- data/lib/adlint/cpp/util.rb +1 -1
- data/lib/adlint/exam/c_builtin/c_check.rb +93 -95
- data/lib/adlint/exam/c_builtin/ld_check.rb +4 -4
- data/lib/adlint/traits.rb +7 -16
- data/lib/adlint/util.rb +12 -0
- data/lib/adlint/version.rb +2 -2
- data/share/doc/developers_guide_ja.html +3 -3
- data/share/doc/developers_guide_ja.texi +1 -1
- data/share/doc/users_guide_en.html +32 -32
- data/share/doc/users_guide_en.texi +30 -30
- data/share/doc/users_guide_ja.html +32 -32
- data/share/doc/users_guide_ja.texi +30 -30
- metadata +4 -3
data/lib/adlint/c/interp.rb
CHANGED
@@ -44,9 +44,9 @@ module AdLint #:nodoc:
|
|
44
44
|
module C #:nodoc:
|
45
45
|
|
46
46
|
class Program
|
47
|
-
def initialize(
|
48
|
-
@interpreter =
|
49
|
-
@translation_unit =
|
47
|
+
def initialize(interp, trans_unit)
|
48
|
+
@interpreter = interp
|
49
|
+
@translation_unit = trans_unit
|
50
50
|
end
|
51
51
|
|
52
52
|
def execute
|
@@ -56,8 +56,8 @@ module C #:nodoc:
|
|
56
56
|
end
|
57
57
|
|
58
58
|
class ExecutionDriver < SyntaxTreeVisitor
|
59
|
-
def initialize(
|
60
|
-
@interpreter =
|
59
|
+
def initialize(interp)
|
60
|
+
@interpreter = interp
|
61
61
|
end
|
62
62
|
|
63
63
|
def visit_declaration(node) @interpreter.execute(node) end
|
@@ -112,308 +112,276 @@ module C #:nodoc:
|
|
112
112
|
private_class_method :def_plugin_and_notifier
|
113
113
|
|
114
114
|
# NOTE: Notified when the interpreter evaluates a variable-declaration.
|
115
|
-
def_plugin_and_notifier :variable_declared,
|
116
|
-
:variable_declaration, :variable
|
115
|
+
def_plugin_and_notifier :variable_declared, :var_dcl, :var
|
117
116
|
|
118
117
|
# NOTE: Notified when the interpreter evaluates a variable-definition.
|
119
|
-
def_plugin_and_notifier :variable_defined, :
|
118
|
+
def_plugin_and_notifier :variable_defined, :var_def, :var
|
120
119
|
|
121
120
|
# NOTE: Notified when the interpreter evaluates an initializer of
|
122
121
|
# variable-definition.
|
123
|
-
def_plugin_and_notifier :variable_initialized,
|
124
|
-
:variable_definition, :variable, :init_variable
|
122
|
+
def_plugin_and_notifier :variable_initialized, :var_def, :var, :init_var
|
125
123
|
|
126
124
|
# NOTE: Notified when the interpreter evaluates a function-declaration.
|
127
|
-
def_plugin_and_notifier :function_declared,
|
128
|
-
:function_declaration, :function
|
125
|
+
def_plugin_and_notifier :function_declared, :func_dcl, :func
|
129
126
|
|
130
127
|
# NOTE: Notified when the interpreter evaluates a function-definition.
|
131
|
-
def_plugin_and_notifier :function_defined, :
|
128
|
+
def_plugin_and_notifier :function_defined, :func_def, :func
|
132
129
|
|
133
130
|
# NOTE: Notified when the interpreter evaluates a struct-type-declaration.
|
134
|
-
def_plugin_and_notifier :struct_declared, :
|
131
|
+
def_plugin_and_notifier :struct_declared, :struct_type_dcl
|
135
132
|
|
136
133
|
# NOTE: Notified when the interpreter evaluates a union-type-declaration.
|
137
|
-
def_plugin_and_notifier :union_declared, :
|
134
|
+
def_plugin_and_notifier :union_declared, :union_type_dcl
|
138
135
|
|
139
136
|
# NOTE: Notified when the interpreter evaluates a enum-type-declaration.
|
140
|
-
def_plugin_and_notifier :enum_declared, :
|
137
|
+
def_plugin_and_notifier :enum_declared, :enum_type_dcl
|
141
138
|
|
142
139
|
# NOTE: Notified when the interpreter evaluates a typedef-declaration.
|
143
|
-
def_plugin_and_notifier :typedef_declared, :
|
140
|
+
def_plugin_and_notifier :typedef_declared, :typedef_dcl
|
144
141
|
|
145
142
|
# NOTE: Notified when the interpreter starts execution of a
|
146
143
|
# function-definition.
|
147
|
-
def_plugin_and_notifier :function_started, :
|
144
|
+
def_plugin_and_notifier :function_started, :func_def, :func
|
148
145
|
|
149
146
|
# NOTE: Notified when the interpreter ends execution of a
|
150
147
|
# function-definition.
|
151
|
-
def_plugin_and_notifier :function_ended, :
|
148
|
+
def_plugin_and_notifier :function_ended, :func_def, :func
|
152
149
|
|
153
150
|
# NOTE: Notified when the interpreter evaluates a parameter-definition at
|
154
151
|
# beginning of execution of a function-definition.
|
155
|
-
def_plugin_and_notifier :parameter_defined,
|
156
|
-
:parameter_definition, :variable
|
152
|
+
def_plugin_and_notifier :parameter_defined, :param_def, :var
|
157
153
|
|
158
154
|
# NOTE: Notified when the interpreter evaluates an expression which results
|
159
155
|
# a named variable.
|
160
|
-
def_plugin_and_notifier :variable_referred, :
|
156
|
+
def_plugin_and_notifier :variable_referred, :expr, :var
|
161
157
|
|
162
158
|
# NOTE: Notified when the interpreter evaluates an expression which results
|
163
159
|
# a constant temporary variable.
|
164
|
-
def_plugin_and_notifier :constant_referred, :
|
160
|
+
def_plugin_and_notifier :constant_referred, :const_spec, :var
|
165
161
|
|
166
162
|
# NOTE: Notified when the interpreter refers to a value of a variable while
|
167
163
|
# evaluating an expression.
|
168
|
-
def_plugin_and_notifier :variable_value_referred, :
|
164
|
+
def_plugin_and_notifier :variable_value_referred, :expr, :var
|
169
165
|
|
170
166
|
# NOTE: Notified when the interpreter overwrites a value of a variable
|
171
167
|
# while evaluating an expression.
|
172
|
-
def_plugin_and_notifier :variable_value_updated, :
|
168
|
+
def_plugin_and_notifier :variable_value_updated, :expr, :var
|
173
169
|
|
174
170
|
# NOTE: Notified when the interpreter refers to a function object while
|
175
171
|
# evaluating an expression.
|
176
|
-
def_plugin_and_notifier :function_referred, :
|
172
|
+
def_plugin_and_notifier :function_referred, :expr, :func
|
177
173
|
|
178
174
|
# NOTE: Notified when the interpreter evaluates a sizeof-expression.
|
179
175
|
def_plugin_and_notifier :sizeof_expr_evaled,
|
180
|
-
:
|
176
|
+
:expr, :operand_var, :result_var
|
181
177
|
|
182
178
|
# NOTE: Notified when the interpreter evaluates a sizeof-type-expression.
|
183
|
-
def_plugin_and_notifier :sizeof_type_expr_evaled,
|
184
|
-
:expression, :type, :result_variable
|
179
|
+
def_plugin_and_notifier :sizeof_type_expr_evaled, :expr, :type, :result_var
|
185
180
|
|
186
181
|
# NOTE: Notified when the interpreter evaluates a cast-expression.
|
187
182
|
def_plugin_and_notifier :explicit_conv_performed,
|
188
|
-
:
|
183
|
+
:expr, :orig_var, :result_var
|
189
184
|
|
190
185
|
# NOTE: Notified when the interpreter performs an implicit type conversion
|
191
186
|
# while evaluating an expression.
|
192
187
|
def_plugin_and_notifier :implicit_conv_performed,
|
193
|
-
:
|
194
|
-
:result_variable
|
188
|
+
:init_or_expr, :orig_var, :result_var
|
195
189
|
|
196
190
|
# NOTE: Notified when the interpreter evaluates an
|
197
191
|
# array-subscript-expression.
|
198
192
|
def_plugin_and_notifier :array_subscript_expr_evaled,
|
199
|
-
:
|
200
|
-
:array_or_pointer_variable, :subscript_variable,
|
201
|
-
:array_variable, :result_variable
|
193
|
+
:expr, :ary_or_ptr, :subs, :ary_var, :result_var
|
202
194
|
|
203
195
|
# NOTE: Notified when the interpreter evaluates a function-call-expression.
|
204
196
|
def_plugin_and_notifier :function_call_expr_evaled,
|
205
|
-
:
|
206
|
-
:arg_variables, :result_variable
|
197
|
+
:expr, :func, :arg_vars, :result_var
|
207
198
|
|
208
199
|
# NOTE: Notified when the interpreter evaluates an
|
209
200
|
# unary-arithmetic-expression.
|
210
201
|
def_plugin_and_notifier :unary_arithmetic_expr_evaled,
|
211
|
-
:
|
212
|
-
:result_variable
|
202
|
+
:expr, :operand_var, :result_var
|
213
203
|
|
214
204
|
# NOTE: Notified when the interpreter evaluates a
|
215
205
|
# multiplicative-expression.
|
216
206
|
def_plugin_and_notifier :multiplicative_expr_evaled,
|
217
|
-
:
|
218
|
-
:rhs_variable, :result_variable
|
207
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
219
208
|
|
220
209
|
# NOTE: Notified when the interpreter evaluates an additive-expression.
|
221
210
|
def_plugin_and_notifier :additive_expr_evaled,
|
222
|
-
:
|
223
|
-
:result_variable
|
211
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
224
212
|
|
225
213
|
# NOTE: Notified when the interpreter evaluates a shift-expression.
|
226
214
|
def_plugin_and_notifier :shift_expr_evaled,
|
227
|
-
:
|
228
|
-
:result_variable
|
215
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
229
216
|
|
230
217
|
# NOTE: Notified when the interpreter evaluates a relational-expression.
|
231
218
|
def_plugin_and_notifier :relational_expr_evaled,
|
232
|
-
:
|
233
|
-
:rhs_variable, :result_variable
|
219
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
234
220
|
|
235
221
|
# NOTE: Notified when the interpreter evaluates an equality-expression.
|
236
222
|
def_plugin_and_notifier :equality_expr_evaled,
|
237
|
-
:
|
238
|
-
:result_variable
|
223
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
239
224
|
|
240
225
|
# NOTE: Notified when the interpreter evaluates a bitwise and-expression.
|
241
226
|
def_plugin_and_notifier :and_expr_evaled,
|
242
|
-
:
|
243
|
-
:result_variable
|
227
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
244
228
|
|
245
229
|
# NOTE: Notified when the interpreter evaluates an exclusive-or-expression.
|
246
230
|
def_plugin_and_notifier :exclusive_or_expr_evaled,
|
247
|
-
:
|
248
|
-
:rhs_variable, :result_variable
|
231
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
249
232
|
|
250
233
|
# NOTE: Notified when the interpreter evaluates a bitwise
|
251
234
|
# inclusive-or-expression.
|
252
235
|
def_plugin_and_notifier :inclusive_or_expr_evaled,
|
253
|
-
:
|
254
|
-
:rhs_variable, :result_variable
|
236
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
255
237
|
|
256
238
|
# NOTE: Notified when the interpreter evaluates a logical-and-expression.
|
257
239
|
def_plugin_and_notifier :logical_and_expr_evaled,
|
258
|
-
:
|
259
|
-
:rhs_variable, :result_variable
|
240
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
260
241
|
|
261
242
|
# NOTE: Notified when the interpreter evaluates a logical-or-expression.
|
262
243
|
def_plugin_and_notifier :logical_or_expr_evaled,
|
263
|
-
:
|
264
|
-
:rhs_variable, :result_variable
|
244
|
+
:expr, :lhs_var, :rhs_var, :result_var
|
265
245
|
|
266
246
|
# NOTE: Notified when the interpreter evaluates a conditional-expression.
|
267
247
|
def_plugin_and_notifier :conditional_expr_evaled,
|
268
|
-
:
|
269
|
-
:result_variable
|
248
|
+
:expr, :ctrlexpr_var, :result_var
|
270
249
|
|
271
250
|
# NOTE: Notified when the interpreter evaluates an address-expression.
|
272
|
-
def_plugin_and_notifier :address_expr_evaled,
|
273
|
-
:address_expression, :object, :pointer_variable
|
251
|
+
def_plugin_and_notifier :address_expr_evaled, :expr, :obj, :ptr_var
|
274
252
|
|
275
253
|
# NOTE: Notified when the interpreter evaluates an indirection-expression.
|
276
254
|
def_plugin_and_notifier :indirection_expr_evaled,
|
277
|
-
:
|
278
|
-
:dereferenced_variable
|
255
|
+
:expr, :ptr_var, :derefed_var
|
279
256
|
|
280
257
|
# NOTE: Notified when the interpreter evaluates a
|
281
258
|
# member-access-by-value-expression or a
|
282
259
|
# member-access-by-pointer-expression.
|
283
260
|
def_plugin_and_notifier :member_access_expr_evaled,
|
284
|
-
:
|
285
|
-
:member_variable
|
261
|
+
:expr, :outer_var, :inner_var
|
286
262
|
|
287
263
|
# NOTE: Notified when the interpreter evaluates a
|
288
264
|
# prefix-increment-expression.
|
289
265
|
def_plugin_and_notifier :prefix_increment_expr_evaled,
|
290
|
-
:
|
291
|
-
:original_value
|
266
|
+
:expr, :operand_var, :orig_val
|
292
267
|
|
293
268
|
# NOTE: Notified when the interpreter evaluates a
|
294
269
|
# postfix-increment-expression.
|
295
270
|
def_plugin_and_notifier :postfix_increment_expr_evaled,
|
296
|
-
:
|
297
|
-
:result_variable
|
271
|
+
:expr, :operand_var, :result_var
|
298
272
|
|
299
273
|
# NOTE: Notified when the interpreter evaluates a
|
300
274
|
# prefix-decrement-expression.
|
301
275
|
def_plugin_and_notifier :prefix_decrement_expr_evaled,
|
302
|
-
:
|
303
|
-
:original_value
|
276
|
+
:expr, :operand_var, :orig_val
|
304
277
|
|
305
278
|
# NOTE: Notified when the interpreter evaluates a
|
306
279
|
# postfix-decrement-expression.
|
307
280
|
def_plugin_and_notifier :postfix_decrement_expr_evaled,
|
308
|
-
:
|
309
|
-
:result_variable
|
281
|
+
:expr, :operand_var, :result_var
|
310
282
|
|
311
283
|
# NOTE: Notified when the interpreter evaluates a
|
312
284
|
# simple-assignment-expression or a compound-assignment-expression.
|
313
|
-
def_plugin_and_notifier :assignment_expr_evaled,
|
314
|
-
:assignment_expression, :lhs_variable,
|
315
|
-
:rhs_variable
|
285
|
+
def_plugin_and_notifier :assignment_expr_evaled, :expr, :lhs_var, :rhs_var
|
316
286
|
|
317
287
|
# NOTE: Notified when the interpreter starts execution of a
|
318
288
|
# expression-statement.
|
319
|
-
def_plugin_and_notifier :expression_stmt_started, :
|
289
|
+
def_plugin_and_notifier :expression_stmt_started, :stmt
|
320
290
|
|
321
291
|
# NOTE: Notified when the interpreter ends execution of a
|
322
292
|
# expression-statement.
|
323
|
-
def_plugin_and_notifier :expression_stmt_ended, :
|
293
|
+
def_plugin_and_notifier :expression_stmt_ended, :stmt
|
324
294
|
|
325
295
|
# NOTE: Notified when the interpreter starts execution of a
|
326
296
|
# switch-statement.
|
327
|
-
def_plugin_and_notifier :switch_stmt_started, :
|
297
|
+
def_plugin_and_notifier :switch_stmt_started, :stmt
|
328
298
|
|
329
299
|
# NOTE: Notified when the interpreter ends execution of a switch-statement.
|
330
|
-
def_plugin_and_notifier :switch_stmt_ended, :
|
300
|
+
def_plugin_and_notifier :switch_stmt_ended, :stmt
|
331
301
|
|
332
302
|
# NOTE: Notified when the interpreter starts execution of a
|
333
303
|
# while-statement.
|
334
|
-
def_plugin_and_notifier :while_stmt_started, :
|
304
|
+
def_plugin_and_notifier :while_stmt_started, :stmt
|
335
305
|
|
336
306
|
# NOTE: Notified when the interpreter ends execution of a while-statement.
|
337
|
-
def_plugin_and_notifier :while_stmt_ended, :
|
307
|
+
def_plugin_and_notifier :while_stmt_ended, :stmt
|
338
308
|
|
339
309
|
# NOTE: Notified when the interpreter starts execution of a do-statement.
|
340
|
-
def_plugin_and_notifier :do_stmt_started, :
|
310
|
+
def_plugin_and_notifier :do_stmt_started, :stmt
|
341
311
|
|
342
312
|
# NOTE: Notified when the interpreter ends execution of a do-statement.
|
343
|
-
def_plugin_and_notifier :do_stmt_ended, :
|
313
|
+
def_plugin_and_notifier :do_stmt_ended, :stmt
|
344
314
|
|
345
315
|
# NOTE: Notified when the interpreter starts execution of a for-statement.
|
346
|
-
def_plugin_and_notifier :for_stmt_started, :
|
316
|
+
def_plugin_and_notifier :for_stmt_started, :stmt
|
347
317
|
|
348
318
|
# NOTE: Notified when the interpreter ends execution of a for-statement.
|
349
|
-
def_plugin_and_notifier :for_stmt_ended, :
|
319
|
+
def_plugin_and_notifier :for_stmt_ended, :stmt
|
350
320
|
|
351
321
|
# NOTE: Notified when the interpreter starts execution of a
|
352
322
|
# c99-for-statement.
|
353
|
-
def_plugin_and_notifier :c99_for_stmt_started, :
|
323
|
+
def_plugin_and_notifier :c99_for_stmt_started, :stmt
|
354
324
|
|
355
325
|
# NOTE: Notified when the interpreter ends execution of a
|
356
326
|
# c99-for-statement.
|
357
|
-
def_plugin_and_notifier :c99_for_stmt_ended, :
|
327
|
+
def_plugin_and_notifier :c99_for_stmt_ended, :stmt
|
358
328
|
|
359
329
|
# NOTE: Notified when the interpreter evaluates a goto-statement.
|
360
|
-
def_plugin_and_notifier :goto_stmt_evaled, :
|
330
|
+
def_plugin_and_notifier :goto_stmt_evaled, :stmt, :label_name
|
361
331
|
|
362
332
|
# NOTE: Notified when the interpreter evaluates a return-statement.
|
363
|
-
def_plugin_and_notifier :return_stmt_evaled,
|
364
|
-
:return_statement, :result_variable
|
333
|
+
def_plugin_and_notifier :return_stmt_evaled, :stmt, :result_var
|
365
334
|
|
366
335
|
# NOTE: Notified when the interpreter evaluates an implicit return.
|
367
336
|
def_plugin_and_notifier :implicit_return_evaled
|
368
337
|
|
369
338
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
370
339
|
# the if-statement.
|
371
|
-
def_plugin_and_notifier :if_ctrlexpr_evaled, :
|
340
|
+
def_plugin_and_notifier :if_ctrlexpr_evaled, :if_stmt, :ctrlexpr_val
|
372
341
|
|
373
342
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
374
343
|
# the if-else-statement.
|
375
344
|
def_plugin_and_notifier :if_else_ctrlexpr_evaled,
|
376
|
-
:
|
345
|
+
:if_else_stmt, :ctrlexpr_val
|
377
346
|
|
378
347
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
379
348
|
# the switch-statement.
|
380
349
|
def_plugin_and_notifier :switch_ctrlexpr_evaled,
|
381
|
-
:
|
350
|
+
:switch_stmt, :ctrlexpr_var
|
382
351
|
|
383
352
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
384
353
|
# the case-labeled-statement.
|
385
354
|
def_plugin_and_notifier :case_ctrlexpr_evaled,
|
386
|
-
:
|
355
|
+
:case_labeled_stmt, :ctrlexpr_var
|
387
356
|
|
388
357
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
389
358
|
# the while-statement.
|
390
359
|
def_plugin_and_notifier :while_ctrlexpr_evaled,
|
391
|
-
:while_statement, :
|
360
|
+
:while_statement, :ctrlexpr_val
|
392
361
|
|
393
362
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
394
363
|
# the do-statement.
|
395
|
-
def_plugin_and_notifier :do_ctrlexpr_evaled, :
|
364
|
+
def_plugin_and_notifier :do_ctrlexpr_evaled, :do_stmt, :ctrlexpr_val
|
396
365
|
|
397
366
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
398
367
|
# the for-statement.
|
399
|
-
def_plugin_and_notifier :for_ctrlexpr_evaled,
|
400
|
-
:for_statement, :ctrlexpr_value
|
368
|
+
def_plugin_and_notifier :for_ctrlexpr_evaled, :for_stmt, :ctrlexpr_val
|
401
369
|
|
402
370
|
# NOTE: Notified when the interpreter evaluates a controlling expression of
|
403
371
|
# the c99-for-statement.
|
404
372
|
def_plugin_and_notifier :c99_for_ctrlexpr_evaled,
|
405
|
-
:
|
373
|
+
:c99_for_stmt, :ctrlexpr_val
|
406
374
|
|
407
375
|
# NOTE: Notified when the interpreter defines a generic-label.
|
408
|
-
def_plugin_and_notifier :label_defined, :
|
376
|
+
def_plugin_and_notifier :label_defined, :generic_labeled_stmt
|
409
377
|
|
410
378
|
# NOTE: Notified when the interpreter starts execution of a
|
411
379
|
# compound-statement.
|
412
|
-
def_plugin_and_notifier :block_started, :
|
380
|
+
def_plugin_and_notifier :block_started, :compound_stmt
|
413
381
|
|
414
382
|
# NOTE: Notified when the interpreter ends execution of a
|
415
383
|
# compound-statement.
|
416
|
-
def_plugin_and_notifier :block_ended, :
|
384
|
+
def_plugin_and_notifier :block_ended, :compound_stmt
|
417
385
|
|
418
386
|
# NOTE: Notified when the interpreter forks execution paths of a
|
419
387
|
# function-definition.
|
@@ -425,16 +393,16 @@ module C #:nodoc:
|
|
425
393
|
|
426
394
|
# NOTE: Notified when the interpreter starts execution of a
|
427
395
|
# translation-unit.
|
428
|
-
def_plugin_and_notifier :translation_unit_started, :
|
396
|
+
def_plugin_and_notifier :translation_unit_started, :trans_unit
|
429
397
|
|
430
398
|
# NOTE: Notified when the interpreter ends execution of a translation-unit.
|
431
|
-
def_plugin_and_notifier :translation_unit_ended, :
|
399
|
+
def_plugin_and_notifier :translation_unit_ended, :trans_unit
|
432
400
|
|
433
401
|
# NOTE: Notified when the control reaches to a sequence-point.
|
434
|
-
def_plugin_and_notifier :sequence_point_reached, :
|
402
|
+
def_plugin_and_notifier :sequence_point_reached, :seqp
|
435
403
|
|
436
|
-
def execute(node, *
|
437
|
-
@options_stack.push(current_options +
|
404
|
+
def execute(node, *opts)
|
405
|
+
@options_stack.push(current_options + opts)
|
438
406
|
if quiet_without_side_effect?
|
439
407
|
result = nil
|
440
408
|
branched_eval(nil, FINAL) do
|
@@ -450,28 +418,27 @@ module C #:nodoc:
|
|
450
418
|
@options_stack.pop
|
451
419
|
end
|
452
420
|
|
453
|
-
def object_to_variable(
|
421
|
+
def object_to_variable(obj)
|
454
422
|
case
|
455
|
-
when
|
456
|
-
|
457
|
-
when
|
458
|
-
|
459
|
-
pointer_value_of(object))
|
423
|
+
when obj.function?
|
424
|
+
create_tempvar(pointer_type(obj.type), pointer_value_of(obj))
|
425
|
+
when obj.type.array?
|
426
|
+
create_tempvar(pointer_type(obj.type.base_type), pointer_value_of(obj))
|
460
427
|
else
|
461
|
-
|
428
|
+
obj
|
462
429
|
end
|
463
430
|
end
|
464
431
|
|
465
|
-
def value_of(
|
466
|
-
if
|
467
|
-
pointer_value_of(
|
432
|
+
def value_of(obj)
|
433
|
+
if obj.type.array? || obj.type.function?
|
434
|
+
pointer_value_of(obj)
|
468
435
|
else
|
469
|
-
|
436
|
+
obj.value.to_single_value
|
470
437
|
end
|
471
438
|
end
|
472
439
|
|
473
|
-
def pointer_value_of(
|
474
|
-
ScalarValue.of(
|
440
|
+
def pointer_value_of(obj)
|
441
|
+
ScalarValue.of(obj.binding.memory.address)
|
475
442
|
end
|
476
443
|
|
477
444
|
def quiet?
|
@@ -509,12 +476,12 @@ module C #:nodoc:
|
|
509
476
|
@active_function_stack.last
|
510
477
|
end
|
511
478
|
|
512
|
-
def _enter_function(
|
479
|
+
def _enter_function(func_def)
|
513
480
|
# NOTE: This method is called only from FunctionInterpreter.
|
514
|
-
@active_function_stack.push(
|
481
|
+
@active_function_stack.push(func_def)
|
515
482
|
end
|
516
483
|
|
517
|
-
def _leave_function(
|
484
|
+
def _leave_function(*)
|
518
485
|
# NOTE: This method is called only from FunctionInterpreter.
|
519
486
|
@active_function_stack.pop
|
520
487
|
end
|
@@ -566,15 +533,12 @@ module C #:nodoc:
|
|
566
533
|
checkpoint(node.location)
|
567
534
|
|
568
535
|
resolve_unresolved_type(node)
|
569
|
-
|
570
|
-
|
571
|
-
decl.mark_as_referred_by(node.identifier)
|
536
|
+
node.type.declarations.each do |dcl|
|
537
|
+
dcl.mark_as_referred_by(node.identifier)
|
572
538
|
end
|
573
539
|
|
574
|
-
|
575
|
-
|
576
|
-
notify_function_declared(node, function)
|
577
|
-
|
540
|
+
func = declare_function(node)
|
541
|
+
notify_function_declared(node, func)
|
578
542
|
evaluate_sequence_point(node.init_declarator.declarator)
|
579
543
|
end
|
580
544
|
|
@@ -582,14 +546,12 @@ module C #:nodoc:
|
|
582
546
|
checkpoint(node.location)
|
583
547
|
|
584
548
|
resolve_unresolved_type(node)
|
585
|
-
|
586
|
-
|
587
|
-
decl.mark_as_referred_by(node.identifier)
|
549
|
+
node.type.declarations.each do |dcl|
|
550
|
+
dcl.mark_as_referred_by(node.identifier)
|
588
551
|
end
|
589
552
|
|
590
|
-
|
591
|
-
notify_variable_declared(node,
|
592
|
-
|
553
|
+
var = declare_variable(node)
|
554
|
+
notify_variable_declared(node, var)
|
593
555
|
evaluate_sequence_point(node.declarator)
|
594
556
|
end
|
595
557
|
|
@@ -597,18 +559,16 @@ module C #:nodoc:
|
|
597
559
|
checkpoint(node.location)
|
598
560
|
|
599
561
|
resolve_unresolved_type(node)
|
600
|
-
|
601
|
-
|
602
|
-
decl.mark_as_referred_by(node.identifier)
|
562
|
+
node.type.declarations.each do |dcl|
|
563
|
+
dcl.mark_as_referred_by(node.identifier)
|
603
564
|
end
|
604
565
|
|
605
566
|
if node.initializer
|
606
|
-
init_var,
|
607
|
-
|
608
|
-
|
567
|
+
init_var, init_conved = evaluate_initializer(node)
|
568
|
+
var = define_variable(node, init_conved.value.to_defined_value)
|
609
569
|
notify_variable_value_referred(node, init_var)
|
610
|
-
notify_variable_defined(node,
|
611
|
-
notify_variable_initialized(node,
|
570
|
+
notify_variable_defined(node, var)
|
571
|
+
notify_variable_initialized(node, var, init_var)
|
612
572
|
else
|
613
573
|
notify_variable_defined(node, define_variable(node))
|
614
574
|
end
|
@@ -620,7 +580,6 @@ module C #:nodoc:
|
|
620
580
|
checkpoint(node.location)
|
621
581
|
|
622
582
|
resolve_unresolved_type(node)
|
623
|
-
|
624
583
|
notify_struct_declared(node)
|
625
584
|
end
|
626
585
|
|
@@ -628,25 +587,24 @@ module C #:nodoc:
|
|
628
587
|
checkpoint(node.location)
|
629
588
|
|
630
589
|
resolve_unresolved_type(node)
|
631
|
-
|
632
590
|
notify_union_declared(node)
|
633
591
|
end
|
634
592
|
|
635
593
|
def visit_enum_type_declaration(node)
|
636
594
|
checkpoint(node)
|
637
595
|
|
638
|
-
if
|
639
|
-
|
640
|
-
|
641
|
-
if
|
642
|
-
|
643
|
-
if
|
644
|
-
|
596
|
+
if enums = node.enum_specifier.enumerators
|
597
|
+
seq = 0
|
598
|
+
enums.each do |enum|
|
599
|
+
if expr = enum.expression
|
600
|
+
obj = interpret(expr)
|
601
|
+
if obj.variable? && obj.value.scalar?
|
602
|
+
enum.value = obj.value.unique_sample
|
645
603
|
end
|
646
604
|
end
|
647
|
-
|
648
|
-
define_enumerator(
|
649
|
-
|
605
|
+
enum.value ||= seq
|
606
|
+
define_enumerator(enum)
|
607
|
+
seq = enum.value + 1
|
650
608
|
end
|
651
609
|
end
|
652
610
|
|
@@ -657,13 +615,11 @@ module C #:nodoc:
|
|
657
615
|
checkpoint(node.location)
|
658
616
|
|
659
617
|
resolve_unresolved_type(node)
|
660
|
-
|
661
|
-
|
662
|
-
decl.mark_as_referred_by(node.identifier)
|
618
|
+
node.type.real_type.declarations.each do |dcl|
|
619
|
+
dcl.mark_as_referred_by(node.identifier)
|
663
620
|
end
|
664
621
|
|
665
622
|
notify_typedef_declared(node)
|
666
|
-
|
667
623
|
evaluate_sequence_point(node.init_declarator.declarator)
|
668
624
|
|
669
625
|
Analyzer.current.info("user type `#{node.identifier.value}' " +
|
@@ -671,38 +627,38 @@ module C #:nodoc:
|
|
671
627
|
end
|
672
628
|
|
673
629
|
private
|
674
|
-
def evaluate_initializer(
|
630
|
+
def evaluate_initializer(var_def)
|
675
631
|
init_interp = InitializerInterpreter.new(interpreter)
|
676
|
-
|
632
|
+
var, conved = init_interp.execute(var_def)
|
677
633
|
|
678
634
|
# NOTE: An implicit conversion and size deduction of an incomplete array
|
679
635
|
# have been done by InitializerInterpreter.
|
680
636
|
|
681
637
|
# NOTE: For the case of array variable definition with a
|
682
638
|
# string-literal-specifier as the initializer.
|
683
|
-
if
|
684
|
-
unless
|
685
|
-
|
639
|
+
if var_def.type.array? && var.type.pointer?
|
640
|
+
unless ary = pointee_of(var) and ary.type.array?
|
641
|
+
ary = create_tempvar(var_def.type)
|
686
642
|
end
|
687
|
-
deduct_array_length_from_array_variable(
|
688
|
-
|
643
|
+
deduct_array_length_from_array_variable(var_def, ary)
|
644
|
+
var = conved = ary
|
689
645
|
end
|
690
646
|
|
691
|
-
return
|
647
|
+
return var, conved
|
692
648
|
end
|
693
649
|
|
694
|
-
def deduct_array_length_from_array_variable(
|
695
|
-
unless
|
696
|
-
if
|
697
|
-
|
650
|
+
def deduct_array_length_from_array_variable(var_def, ary)
|
651
|
+
unless var_def.type.length
|
652
|
+
if var_def.type.user?
|
653
|
+
var_def.type = var_def.type.dup
|
698
654
|
end
|
699
|
-
|
655
|
+
var_def.type.length = ary.type.length
|
700
656
|
end
|
701
657
|
end
|
702
658
|
|
703
|
-
def evaluate_sequence_point(
|
704
|
-
if
|
705
|
-
notify_sequence_point_reached(
|
659
|
+
def evaluate_sequence_point(full_dcl)
|
660
|
+
if seqp = full_dcl.subsequent_sequence_point
|
661
|
+
notify_sequence_point_reached(seqp)
|
706
662
|
end
|
707
663
|
end
|
708
664
|
end
|
@@ -713,70 +669,63 @@ module C #:nodoc:
|
|
713
669
|
include Conversion
|
714
670
|
include MonitorUtil
|
715
671
|
|
716
|
-
def initialize(
|
717
|
-
@interpreter =
|
672
|
+
def initialize(interp)
|
673
|
+
@interpreter = interp
|
718
674
|
end
|
719
675
|
|
720
|
-
def execute(
|
721
|
-
checkpoint(
|
676
|
+
def execute(var_def)
|
677
|
+
checkpoint(var_def.initializer.location)
|
722
678
|
|
723
679
|
case
|
724
|
-
when
|
680
|
+
when expr = var_def.initializer.expression
|
725
681
|
# NOTE: An implicit conversion is already notified in
|
726
682
|
# #evaluate_expression.
|
727
|
-
return evaluate_expression(
|
728
|
-
when
|
729
|
-
|
683
|
+
return evaluate_expression(expr, var_def.type)
|
684
|
+
when inits = var_def.initializer.initializers
|
685
|
+
var = evaluate_initializers(inits, var_def.type)
|
730
686
|
|
731
687
|
# NOTE: Size deduction of an incomplete array type have been done by
|
732
688
|
# #evaluate_initializers.
|
733
|
-
if
|
734
|
-
|
689
|
+
if var_def.type.array? && var.type.array?
|
690
|
+
var_def.type = var.type unless var_def.type.length
|
735
691
|
end
|
736
692
|
|
737
|
-
if
|
738
|
-
|
693
|
+
if var.type.same_as?(var_def.type)
|
694
|
+
conved = var
|
739
695
|
else
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
notify_implicit_conv_performed(initializer, variable, converted)
|
696
|
+
conved = do_conversion(var, var_def.type) ||
|
697
|
+
create_tempvar(var_def.type)
|
698
|
+
notify_implicit_conv_performed(inits, var, conved)
|
744
699
|
end
|
745
700
|
else
|
746
|
-
|
701
|
+
var = conved = create_tempvar(var_def.type)
|
747
702
|
end
|
748
703
|
|
749
|
-
return
|
704
|
+
return var, conved
|
750
705
|
end
|
751
706
|
|
752
707
|
private
|
753
|
-
def evaluate_expression(
|
754
|
-
checkpoint(
|
755
|
-
|
756
|
-
object = interpret(expression)
|
708
|
+
def evaluate_expression(expr, type)
|
709
|
+
checkpoint(expr.location)
|
757
710
|
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
end
|
711
|
+
obj = interpret(expr)
|
712
|
+
var = object_to_variable(obj)
|
713
|
+
notify_implicit_conv_performed(expr, obj, var) unless var == obj
|
762
714
|
|
763
|
-
if
|
764
|
-
|
715
|
+
if var.type.same_as?(type)
|
716
|
+
conved = var
|
765
717
|
else
|
766
|
-
|
767
|
-
notify_implicit_conv_performed(
|
718
|
+
conved = do_conversion(var, type) || create_tempvar(type)
|
719
|
+
notify_implicit_conv_performed(expr, var, conved)
|
768
720
|
end
|
769
721
|
|
770
|
-
return
|
722
|
+
return var, conved
|
771
723
|
end
|
772
724
|
|
773
|
-
def evaluate_initializers(
|
774
|
-
if type.union?
|
775
|
-
end
|
776
|
-
|
725
|
+
def evaluate_initializers(inits, type)
|
777
726
|
case
|
778
727
|
when type.union?
|
779
|
-
# NOTE: The ISO C99 standard
|
728
|
+
# NOTE: The ISO C99 standard says;
|
780
729
|
#
|
781
730
|
# 6.7.8 Initialization
|
782
731
|
#
|
@@ -793,14 +742,14 @@ module C #:nodoc:
|
|
793
742
|
# (recursively) according to these rules;
|
794
743
|
# -- if it is a union, the first named member is initialized
|
795
744
|
# (recursively) according to these rules.
|
796
|
-
if
|
797
|
-
|
798
|
-
return
|
745
|
+
if fst_memb = type.members.first
|
746
|
+
fst_obj = evaluate_initializers(inits, fst_memb.type)
|
747
|
+
return create_tempvar(type, value_of(fst_obj))
|
799
748
|
else
|
800
|
-
return
|
749
|
+
return create_tempvar(type)
|
801
750
|
end
|
802
751
|
when type.array?
|
803
|
-
# NOTE: The ISO C99 standard
|
752
|
+
# NOTE: The ISO C99 standard says;
|
804
753
|
#
|
805
754
|
# 6.7.2.1 Structure and union specifiers
|
806
755
|
#
|
@@ -819,22 +768,22 @@ module C #:nodoc:
|
|
819
768
|
# deducted in initialization. It is treated as a pointer.
|
820
769
|
#
|
821
770
|
# NOTE: ISO C90 does not support flexible array members.
|
822
|
-
type = deduct_array_length_from_initializers(type,
|
823
|
-
|
771
|
+
type = deduct_array_length_from_initializers(type, inits)
|
772
|
+
memb_types = [type.unqualify.base_type] * type.impl_length
|
824
773
|
when type.struct?
|
825
|
-
|
774
|
+
memb_types = type.members.map { |memb| memb.type }
|
826
775
|
else
|
827
|
-
|
776
|
+
memb_types = [type]
|
828
777
|
end
|
829
778
|
|
830
|
-
|
831
|
-
if
|
832
|
-
checkpoint(
|
779
|
+
vals = memb_types.zip(inits).map { |memb_type, init|
|
780
|
+
if init
|
781
|
+
checkpoint(init.location)
|
833
782
|
case
|
834
|
-
when
|
835
|
-
value_of(evaluate_expression(
|
836
|
-
when
|
837
|
-
value_of(evaluate_initializers(
|
783
|
+
when expr = init.expression
|
784
|
+
value_of(evaluate_expression(expr, memb_type).last)
|
785
|
+
when inits = init.initializers
|
786
|
+
value_of(evaluate_initializers(inits, memb_type))
|
838
787
|
else
|
839
788
|
memb_type.undefined_value
|
840
789
|
end
|
@@ -845,22 +794,22 @@ module C #:nodoc:
|
|
845
794
|
|
846
795
|
case
|
847
796
|
when type.array?
|
848
|
-
|
797
|
+
create_tempvar(type, ArrayValue.new(vals))
|
849
798
|
when type.composite?
|
850
|
-
|
799
|
+
create_tempvar(type, CompositeValue.new(vals))
|
851
800
|
else
|
852
|
-
|
801
|
+
create_tempvar(type, vals.first)
|
853
802
|
end
|
854
803
|
end
|
855
804
|
|
856
|
-
def deduct_array_length_from_initializers(
|
857
|
-
unless
|
858
|
-
if
|
859
|
-
|
805
|
+
def deduct_array_length_from_initializers(orig_ary_type, inits)
|
806
|
+
unless orig_ary_type.length
|
807
|
+
if orig_ary_type.user?
|
808
|
+
orig_ary_type = orig_ary_type.dup
|
860
809
|
end
|
861
|
-
|
810
|
+
orig_ary_type.length = inits.size
|
862
811
|
end
|
863
|
-
|
812
|
+
orig_ary_type
|
864
813
|
end
|
865
814
|
|
866
815
|
def interpreter
|
@@ -880,19 +829,18 @@ module C #:nodoc:
|
|
880
829
|
checkpoint(node.location)
|
881
830
|
|
882
831
|
resolve_unresolved_type(node)
|
883
|
-
|
884
|
-
node.type.declarations.each do |decl|
|
832
|
+
node.type.declarations.each do |dcl|
|
885
833
|
if identifier = node.identifier
|
886
|
-
|
834
|
+
dcl.mark_as_referred_by(identifier)
|
887
835
|
else
|
888
|
-
|
836
|
+
dcl.mark_as_referred_by(node.head_token)
|
889
837
|
end
|
890
838
|
end
|
891
839
|
|
892
840
|
if node.identifier
|
893
|
-
|
894
|
-
|
895
|
-
notify_parameter_defined(node,
|
841
|
+
var = define_variable(node.to_variable_definition,
|
842
|
+
node.type.parameter_value)
|
843
|
+
notify_parameter_defined(node, var)
|
896
844
|
end
|
897
845
|
end
|
898
846
|
end
|
@@ -916,16 +864,16 @@ module C #:nodoc:
|
|
916
864
|
|
917
865
|
reset_environment
|
918
866
|
resolve_unresolved_type(node)
|
919
|
-
|
920
|
-
notify_function_defined(node,
|
867
|
+
func = lookup_or_define_function(node)
|
868
|
+
notify_function_defined(node, func)
|
921
869
|
|
922
870
|
begin
|
923
871
|
interpreter._enter_function(node)
|
924
872
|
scoped_eval do
|
925
|
-
notify_function_started(node,
|
873
|
+
notify_function_started(node, func)
|
926
874
|
notify_block_started(node.function_body)
|
927
875
|
|
928
|
-
node.parameter_definitions.each { |
|
876
|
+
node.parameter_definitions.each { |param_def| interpret(param_def) }
|
929
877
|
|
930
878
|
BreakEvent.catch do
|
931
879
|
node.function_body.block_items.each { |item| interpret(item) }
|
@@ -933,27 +881,27 @@ module C #:nodoc:
|
|
933
881
|
end
|
934
882
|
|
935
883
|
notify_block_ended(node.function_body)
|
936
|
-
notify_function_ended(node,
|
884
|
+
notify_function_ended(node, func)
|
937
885
|
end
|
938
886
|
ensure
|
939
887
|
interpreter._leave_function(node)
|
940
888
|
end
|
941
889
|
end
|
942
890
|
|
943
|
-
def lookup_or_define_function(
|
944
|
-
|
945
|
-
|
891
|
+
def lookup_or_define_function(func_def)
|
892
|
+
func_def.type.declarations.each do |dcl|
|
893
|
+
dcl.mark_as_referred_by(func_def.identifier)
|
946
894
|
end
|
947
895
|
|
948
|
-
if
|
949
|
-
|
950
|
-
|
896
|
+
if func = function_named(func_def.identifier.value)
|
897
|
+
func.declarations_and_definitions.each do |dcl_or_def|
|
898
|
+
dcl_or_def.mark_as_referred_by(func_def.identifier)
|
951
899
|
end
|
952
|
-
|
900
|
+
func.declarations_and_definitions.push(func_def)
|
953
901
|
else
|
954
|
-
|
902
|
+
func = define_explicit_function(func_def)
|
955
903
|
end
|
956
|
-
|
904
|
+
func
|
957
905
|
end
|
958
906
|
end
|
959
907
|
|
@@ -985,8 +933,8 @@ module C #:nodoc:
|
|
985
933
|
|
986
934
|
node.executed = true
|
987
935
|
ctrlexpr = node.expression
|
988
|
-
|
989
|
-
notify_case_ctrlexpr_evaled(node,
|
936
|
+
ctrlexpr_var = object_to_variable(interpret(ctrlexpr, QUIET))
|
937
|
+
notify_case_ctrlexpr_evaled(node, ctrlexpr_var)
|
990
938
|
|
991
939
|
interpret(node.statement)
|
992
940
|
end
|
@@ -1005,7 +953,7 @@ module C #:nodoc:
|
|
1005
953
|
scoped_eval do
|
1006
954
|
begin
|
1007
955
|
notify_block_started(node)
|
1008
|
-
node.block_items.each { |
|
956
|
+
node.block_items.each { |item| interpret(item) }
|
1009
957
|
ensure
|
1010
958
|
notify_block_ended(node)
|
1011
959
|
end
|
@@ -1030,20 +978,20 @@ module C #:nodoc:
|
|
1030
978
|
|
1031
979
|
orig_ctrlexpr = node.expression
|
1032
980
|
if orig_ctrlexpr == effective_ctrlexpr
|
1033
|
-
|
981
|
+
ctrlexpr_val = ScalarValue.of_arbitrary
|
1034
982
|
ctrlexpr = nil
|
1035
983
|
else
|
1036
|
-
|
984
|
+
ctrlexpr_val = value_of(interpret(orig_ctrlexpr))
|
1037
985
|
ctrlexpr = orig_ctrlexpr.to_normalized_logical
|
1038
986
|
end
|
1039
|
-
notify_if_ctrlexpr_evaled(node,
|
987
|
+
notify_if_ctrlexpr_evaled(node, ctrlexpr_val)
|
1040
988
|
|
1041
989
|
case
|
1042
|
-
when
|
990
|
+
when ctrlexpr_val.must_be_true?
|
1043
991
|
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
1044
992
|
interpret(node.statement)
|
1045
993
|
end
|
1046
|
-
when
|
994
|
+
when ctrlexpr_val.may_be_true?
|
1047
995
|
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND) do
|
1048
996
|
interpret(node.statement)
|
1049
997
|
end
|
@@ -1060,21 +1008,21 @@ module C #:nodoc:
|
|
1060
1008
|
|
1061
1009
|
orig_ctrlexpr = node.expression
|
1062
1010
|
if orig_ctrlexpr == effective_ctrlexpr
|
1063
|
-
|
1011
|
+
ctrlexpr_val = ScalarValue.of_arbitrary
|
1064
1012
|
ctrlexpr = nil
|
1065
1013
|
else
|
1066
|
-
|
1014
|
+
ctrlexpr_val = value_of(interpret(orig_ctrlexpr))
|
1067
1015
|
ctrlexpr = orig_ctrlexpr.to_normalized_logical
|
1068
1016
|
end
|
1069
|
-
notify_if_else_ctrlexpr_evaled(node,
|
1017
|
+
notify_if_else_ctrlexpr_evaled(node, ctrlexpr_val)
|
1070
1018
|
|
1071
1019
|
case
|
1072
|
-
when
|
1020
|
+
when ctrlexpr_val.must_be_true?
|
1073
1021
|
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
1074
1022
|
interpret(node.then_statement)
|
1075
1023
|
end
|
1076
1024
|
return
|
1077
|
-
when
|
1025
|
+
when ctrlexpr_val.may_be_true?
|
1078
1026
|
branched_eval(ctrlexpr, NARROWING, IMPLICIT_COND) do
|
1079
1027
|
interpret(node.then_statement)
|
1080
1028
|
end
|
@@ -1098,13 +1046,13 @@ module C #:nodoc:
|
|
1098
1046
|
|
1099
1047
|
widen_varying_variable_value_domain(node)
|
1100
1048
|
|
1101
|
-
|
1102
|
-
notify_while_ctrlexpr_evaled(node,
|
1049
|
+
ctrlexpr_val = value_of(interpret(node.expression))
|
1050
|
+
notify_while_ctrlexpr_evaled(node, ctrlexpr_val)
|
1103
1051
|
|
1104
1052
|
orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
|
1105
1053
|
|
1106
1054
|
case
|
1107
|
-
when
|
1055
|
+
when ctrlexpr_val.must_be_true?
|
1108
1056
|
begin
|
1109
1057
|
enter_iteration_statement(orig_ctrlexpr)
|
1110
1058
|
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
@@ -1113,7 +1061,7 @@ module C #:nodoc:
|
|
1113
1061
|
ensure
|
1114
1062
|
leave_iteration_statement(orig_ctrlexpr)
|
1115
1063
|
end
|
1116
|
-
when
|
1064
|
+
when ctrlexpr_val.may_be_true?
|
1117
1065
|
begin
|
1118
1066
|
enter_iteration_statement(orig_ctrlexpr)
|
1119
1067
|
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND) do
|
@@ -1146,8 +1094,8 @@ module C #:nodoc:
|
|
1146
1094
|
leave_iteration_statement(orig_ctrlexpr)
|
1147
1095
|
end
|
1148
1096
|
|
1149
|
-
|
1150
|
-
notify_do_ctrlexpr_evaled(node,
|
1097
|
+
ctrlexpr_val = value_of(interpret(node.expression))
|
1098
|
+
notify_do_ctrlexpr_evaled(node, ctrlexpr_val)
|
1151
1099
|
ensure
|
1152
1100
|
notify_do_stmt_ended(node)
|
1153
1101
|
end
|
@@ -1165,16 +1113,16 @@ module C #:nodoc:
|
|
1165
1113
|
|
1166
1114
|
node.condition_statement.executed = true
|
1167
1115
|
if explicit_ctrlexpr = node.condition_statement.expression
|
1168
|
-
|
1169
|
-
notify_for_ctrlexpr_evaled(node,
|
1116
|
+
ctrlexpr_val = value_of(interpret(explicit_ctrlexpr))
|
1117
|
+
notify_for_ctrlexpr_evaled(node, ctrlexpr_val)
|
1170
1118
|
else
|
1171
|
-
|
1119
|
+
ctrlexpr_val = ScalarValue.of_true
|
1172
1120
|
end
|
1173
1121
|
|
1174
1122
|
case
|
1175
|
-
when
|
1123
|
+
when ctrlexpr_val.must_be_true?
|
1176
1124
|
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, true)
|
1177
|
-
when
|
1125
|
+
when ctrlexpr_val.may_be_true?
|
1178
1126
|
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, false)
|
1179
1127
|
end
|
1180
1128
|
ensure
|
@@ -1195,16 +1143,16 @@ module C #:nodoc:
|
|
1195
1143
|
|
1196
1144
|
node.condition_statement.executed = true
|
1197
1145
|
if explicit_ctrlexpr = node.condition_statement.expression
|
1198
|
-
|
1199
|
-
notify_c99_for_ctrlexpr_evaled(node,
|
1146
|
+
ctrlexpr_val = value_of(interpret(explicit_ctrlexpr))
|
1147
|
+
notify_c99_for_ctrlexpr_evaled(node, ctrlexpr_val)
|
1200
1148
|
else
|
1201
|
-
|
1149
|
+
ctrlexpr_val = ScalarValue.of_true
|
1202
1150
|
end
|
1203
1151
|
|
1204
1152
|
case
|
1205
|
-
when
|
1153
|
+
when ctrlexpr_val.must_be_true?
|
1206
1154
|
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, true)
|
1207
|
-
when
|
1155
|
+
when ctrlexpr_val.may_be_true?
|
1208
1156
|
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, false)
|
1209
1157
|
end
|
1210
1158
|
end
|
@@ -1244,29 +1192,29 @@ module C #:nodoc:
|
|
1244
1192
|
BreakEvent.of_return.throw
|
1245
1193
|
end
|
1246
1194
|
|
1247
|
-
|
1248
|
-
|
1249
|
-
unless
|
1250
|
-
notify_implicit_conv_performed(node.expression,
|
1195
|
+
obj = interpret(node.expression)
|
1196
|
+
var = object_to_variable(obj)
|
1197
|
+
unless var == obj
|
1198
|
+
notify_implicit_conv_performed(node.expression, obj, var)
|
1251
1199
|
end
|
1252
1200
|
|
1253
|
-
notify_variable_value_referred(node.expression,
|
1201
|
+
notify_variable_value_referred(node.expression, var)
|
1254
1202
|
|
1255
|
-
if
|
1256
|
-
return_type =
|
1257
|
-
if
|
1258
|
-
|
1203
|
+
if active_func = interpreter._active_function and
|
1204
|
+
return_type = active_func.type.return_type
|
1205
|
+
if var.type.same_as?(return_type)
|
1206
|
+
conved = var
|
1259
1207
|
else
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
notify_implicit_conv_performed(node.expression, variable, converted)
|
1208
|
+
conved = do_conversion(var, return_type) ||
|
1209
|
+
create_tempvar(return_type)
|
1210
|
+
notify_implicit_conv_performed(node.expression, var, conved)
|
1264
1211
|
end
|
1265
1212
|
else
|
1266
|
-
|
1213
|
+
conved = var
|
1267
1214
|
end
|
1268
1215
|
|
1269
|
-
|
1216
|
+
notify_sequence_point_reached(SequencePoint.new(node))
|
1217
|
+
notify_return_stmt_evaled(node, var)
|
1270
1218
|
BreakEvent.of_return.throw
|
1271
1219
|
end
|
1272
1220
|
|
@@ -1275,12 +1223,12 @@ module C #:nodoc:
|
|
1275
1223
|
enter_iteration_statement(orig_ctrlexpr)
|
1276
1224
|
|
1277
1225
|
if complete
|
1278
|
-
|
1226
|
+
branch_opts = [NARROWING, FINAL, IMPLICIT_COND, COMPLETE]
|
1279
1227
|
else
|
1280
|
-
|
1228
|
+
branch_opts = [NARROWING, FINAL, IMPLICIT_COND]
|
1281
1229
|
end
|
1282
1230
|
|
1283
|
-
branched_eval(ctrlexpr, *
|
1231
|
+
branched_eval(ctrlexpr, *branch_opts) do
|
1284
1232
|
interpret(node.body_statement)
|
1285
1233
|
interpret(node.expression) if node.expression
|
1286
1234
|
|
@@ -1302,58 +1250,57 @@ module C #:nodoc:
|
|
1302
1250
|
leave_iteration_statement(orig_ctrlexpr)
|
1303
1251
|
end
|
1304
1252
|
|
1305
|
-
def uninitialize_block_local_variables(
|
1306
|
-
|
1307
|
-
return if
|
1253
|
+
def uninitialize_block_local_variables(generic_labeled_stmt)
|
1254
|
+
related_goto_stmts = generic_labeled_stmt.referrers
|
1255
|
+
return if related_goto_stmts.empty?
|
1308
1256
|
|
1309
|
-
local_variables.each do |
|
1310
|
-
|
1257
|
+
local_variables.each do |var|
|
1258
|
+
var_def = var.declarations_and_definitions.first
|
1311
1259
|
|
1312
|
-
|
1313
|
-
|
1260
|
+
anterior_goto_stmts = related_goto_stmts.select { |goto_stmt|
|
1261
|
+
goto_stmt.location.line_no < var_def.location.line_no
|
1314
1262
|
}
|
1315
1263
|
|
1316
|
-
unless
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1264
|
+
unless anterior_goto_stmts.empty?
|
1265
|
+
var.value.enter_versioning_group
|
1266
|
+
var.value.begin_versioning
|
1267
|
+
var.uninitialize!
|
1268
|
+
var.value.end_versioning
|
1269
|
+
var.value.leave_versioning_group(true)
|
1322
1270
|
end
|
1323
1271
|
end
|
1324
1272
|
end
|
1325
1273
|
|
1326
|
-
def widen_varying_variable_value_domain(
|
1274
|
+
def widen_varying_variable_value_domain(iteration_stmt)
|
1327
1275
|
varying_vars = {}
|
1328
|
-
|
1329
|
-
if
|
1330
|
-
varying_vars[
|
1331
|
-
|
1332
|
-
variable.type.arbitrary_value)
|
1276
|
+
iteration_stmt.varying_variable_names.each do |name|
|
1277
|
+
if var = variable_named(name)
|
1278
|
+
varying_vars[var] = var.value.dup
|
1279
|
+
var.widen_value_domain!(Operator::EQ, var.type.arbitrary_value)
|
1333
1280
|
end
|
1334
1281
|
end
|
1335
1282
|
|
1336
|
-
varying_vars.each do |
|
1337
|
-
case deduct_variable_varying_path(
|
1283
|
+
varying_vars.each do |var, orig_val|
|
1284
|
+
case deduct_variable_varying_path(var, iteration_stmt)
|
1338
1285
|
when :increase
|
1339
|
-
|
1286
|
+
var.narrow_value_domain!(Operator::GE, orig_val)
|
1340
1287
|
when :decrease
|
1341
|
-
|
1288
|
+
var.narrow_value_domain!(Operator::LE, orig_val)
|
1342
1289
|
end
|
1343
1290
|
end
|
1344
1291
|
end
|
1345
1292
|
|
1346
|
-
def deduct_variable_varying_path(
|
1347
|
-
histogram =
|
1293
|
+
def deduct_variable_varying_path(var, iteration_stmt)
|
1294
|
+
histogram = iteration_stmt.varying_expressions.map { |expr|
|
1348
1295
|
case expr
|
1349
1296
|
when SimpleAssignmentExpression
|
1350
|
-
deduct_ctrl_var_path_by_simple_assignment_expr(
|
1297
|
+
deduct_ctrl_var_path_by_simple_assignment_expr(var, expr)
|
1351
1298
|
when CompoundAssignmentExpression
|
1352
|
-
deduct_ctrl_var_path_by_compound_assignment_expr(
|
1299
|
+
deduct_ctrl_var_path_by_compound_assignment_expr(var, expr)
|
1353
1300
|
when PrefixIncrementExpression, PostfixIncrementExpression
|
1354
|
-
expr.operand.identifier.value ==
|
1301
|
+
expr.operand.identifier.value == var.name ? :increase : nil
|
1355
1302
|
when PrefixDecrementExpression, PostfixDecrementExpression
|
1356
|
-
expr.operand.identifier.value ==
|
1303
|
+
expr.operand.identifier.value == var.name ? :decrease : nil
|
1357
1304
|
else
|
1358
1305
|
nil
|
1359
1306
|
end
|
@@ -1366,22 +1313,19 @@ module C #:nodoc:
|
|
1366
1313
|
end
|
1367
1314
|
end
|
1368
1315
|
|
1369
|
-
def deduct_ctrl_var_path_by_simple_assignment_expr(
|
1370
|
-
return nil unless expr.lhs_operand.identifier.value ==
|
1316
|
+
def deduct_ctrl_var_path_by_simple_assignment_expr(var, expr)
|
1317
|
+
return nil unless expr.lhs_operand.identifier.value == var.name
|
1371
1318
|
|
1372
1319
|
additive_exprs = collect_additive_expressions(expr.rhs_operand)
|
1373
1320
|
histogram = additive_exprs.map { |additive_expr|
|
1374
1321
|
if additive_expr.lhs_operand.kind_of?(ObjectSpecifier)
|
1375
1322
|
lhs_name = additive_expr.lhs_operand.identifier.value
|
1376
1323
|
end
|
1377
|
-
|
1378
1324
|
if additive_expr.rhs_operand.kind_of?(ObjectSpecifier)
|
1379
1325
|
rhs_name = additive_expr.rhs_operand.identifier.value
|
1380
1326
|
end
|
1381
1327
|
|
1382
|
-
unless lhs_name ==
|
1383
|
-
next nil
|
1384
|
-
end
|
1328
|
+
next nil unless lhs_name == var.name || rhs_name == var.name
|
1385
1329
|
|
1386
1330
|
case additive_expr.operator.type
|
1387
1331
|
when "+"
|
@@ -1400,8 +1344,8 @@ module C #:nodoc:
|
|
1400
1344
|
end
|
1401
1345
|
end
|
1402
1346
|
|
1403
|
-
def deduct_ctrl_var_path_by_compound_assignment_expr(
|
1404
|
-
return nil unless expr.lhs_operand.identifier.value ==
|
1347
|
+
def deduct_ctrl_var_path_by_compound_assignment_expr(var, expr)
|
1348
|
+
return nil unless expr.lhs_operand.identifier.value == var.name
|
1405
1349
|
|
1406
1350
|
case expr.operator.type
|
1407
1351
|
when "+="
|
@@ -1441,32 +1385,34 @@ module C #:nodoc:
|
|
1441
1385
|
notify_switch_stmt_started(node)
|
1442
1386
|
|
1443
1387
|
ctrlexpr = node.expression
|
1444
|
-
|
1445
|
-
notify_switch_ctrlexpr_evaled(node,
|
1446
|
-
|
1447
|
-
execute_switch_body(ctrlexpr_result, node.statement)
|
1388
|
+
ctrlexpr_var = object_to_variable(interpret(ctrlexpr))
|
1389
|
+
notify_switch_ctrlexpr_evaled(node, ctrlexpr_var)
|
1448
1390
|
|
1391
|
+
execute_switch_body(ctrlexpr_var, node.statement)
|
1449
1392
|
notify_switch_stmt_ended(node)
|
1450
1393
|
end
|
1451
1394
|
|
1452
1395
|
private
|
1453
|
-
def execute_switch_body(
|
1396
|
+
def execute_switch_body(var, node)
|
1454
1397
|
checkpoint(node.location)
|
1455
1398
|
|
1456
1399
|
node.executed = true
|
1457
1400
|
scoped_eval do
|
1458
1401
|
begin
|
1459
1402
|
notify_block_started(node)
|
1460
|
-
execute_switch_branches(
|
1403
|
+
execute_switch_branches(var, node.block_items)
|
1461
1404
|
ensure
|
1462
1405
|
notify_block_ended(node)
|
1463
1406
|
end
|
1464
1407
|
end
|
1465
1408
|
end
|
1466
1409
|
|
1467
|
-
def execute_switch_branches(
|
1468
|
-
|
1469
|
-
|
1410
|
+
def execute_switch_branches(var, block_items)
|
1411
|
+
if complete?(block_items)
|
1412
|
+
base_opts = [SMOTHER_BREAK, IMPLICIT_COND, NARROWING, COMPLETE]
|
1413
|
+
else
|
1414
|
+
base_opts = [SMOTHER_BREAK, IMPLICIT_COND, NARROWING]
|
1415
|
+
end
|
1470
1416
|
|
1471
1417
|
index = 0
|
1472
1418
|
while block_item = block_items[index]
|
@@ -1478,9 +1424,12 @@ module C #:nodoc:
|
|
1478
1424
|
|
1479
1425
|
case block_item
|
1480
1426
|
when CaseLabeledStatement, DefaultLabeledStatement
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1427
|
+
if final_branch?(block_items, index)
|
1428
|
+
opts = base_opts + [FINAL]
|
1429
|
+
else
|
1430
|
+
opts = base_opts.dup
|
1431
|
+
end
|
1432
|
+
index = execute_branch(block_item, block_items, index + 1, opts)
|
1484
1433
|
break unless index
|
1485
1434
|
else
|
1486
1435
|
interpret(block_item)
|
@@ -1489,22 +1438,22 @@ module C #:nodoc:
|
|
1489
1438
|
end
|
1490
1439
|
end
|
1491
1440
|
|
1492
|
-
def execute_branch(
|
1493
|
-
ctrlexpr =
|
1494
|
-
|
1441
|
+
def execute_branch(labeled_stmt, block_items, index, branch_opts)
|
1442
|
+
ctrlexpr = labeled_stmt.normalized_expression
|
1443
|
+
ctrlexpr_val = value_of(interpret(ctrlexpr, QUIET))
|
1495
1444
|
|
1496
1445
|
case
|
1497
|
-
when
|
1498
|
-
|
1499
|
-
when
|
1446
|
+
when ctrlexpr_val.must_be_true?
|
1447
|
+
branch_opts.push(FINAL, COMPLETE)
|
1448
|
+
when ctrlexpr_val.must_be_false?
|
1500
1449
|
# NOTE: To end the current branch group of switch-statement if this
|
1501
1450
|
# case-clause is the final one.
|
1502
|
-
branched_eval(ctrlexpr, *
|
1451
|
+
branched_eval(ctrlexpr, *branch_opts) {}
|
1503
1452
|
return seek_next_branch(block_items, index)
|
1504
1453
|
end
|
1505
1454
|
|
1506
|
-
branched_eval(ctrlexpr, *
|
1507
|
-
interpret(
|
1455
|
+
branched_eval(ctrlexpr, *branch_opts) do |branch|
|
1456
|
+
interpret(labeled_stmt)
|
1508
1457
|
while block_item = block_items[index]
|
1509
1458
|
while block_item.kind_of?(GenericLabeledStatement)
|
1510
1459
|
block_item.executed = true
|
@@ -1515,9 +1464,9 @@ module C #:nodoc:
|
|
1515
1464
|
case block_item
|
1516
1465
|
when CaseLabeledStatement, DefaultLabeledStatement
|
1517
1466
|
# NOTE: Fall through!
|
1518
|
-
prepare_fall_through(branch,
|
1519
|
-
|
1520
|
-
branch.add_options(*
|
1467
|
+
prepare_fall_through(branch, branch_opts, block_item)
|
1468
|
+
branch_opts.push(FINAL) if final_branch?(block_items, index)
|
1469
|
+
branch.add_options(*branch_opts)
|
1521
1470
|
end
|
1522
1471
|
interpret(block_item)
|
1523
1472
|
index += 1
|
@@ -1526,21 +1475,20 @@ module C #:nodoc:
|
|
1526
1475
|
BreakEvent.of_break.throw
|
1527
1476
|
end
|
1528
1477
|
|
1529
|
-
|
1530
|
-
nil : seek_next_branch(block_items, index)
|
1478
|
+
branch_opts.include?(FINAL) ? nil : seek_next_branch(block_items, index)
|
1531
1479
|
end
|
1532
1480
|
|
1533
|
-
def prepare_fall_through(branch,
|
1481
|
+
def prepare_fall_through(branch, branch_opts, labeled_stmt)
|
1534
1482
|
value_domain_manip = nil
|
1535
1483
|
|
1536
1484
|
branch.restart_versioning do
|
1537
|
-
ctrlexpr =
|
1538
|
-
|
1485
|
+
ctrlexpr = labeled_stmt.normalized_expression
|
1486
|
+
ctrlexpr_val = value_of(interpret(ctrlexpr, QUIET))
|
1539
1487
|
|
1540
1488
|
case
|
1541
|
-
when
|
1542
|
-
|
1543
|
-
when
|
1489
|
+
when ctrlexpr_val.must_be_true?
|
1490
|
+
branch_opts.push(FINAL, COMPLETE)
|
1491
|
+
when ctrlexpr_val.must_be_false?
|
1544
1492
|
return
|
1545
1493
|
end
|
1546
1494
|
|
@@ -1617,8 +1565,8 @@ module C #:nodoc:
|
|
1617
1565
|
def #{method_name}(node)
|
1618
1566
|
super
|
1619
1567
|
ensure
|
1620
|
-
if
|
1621
|
-
notify_sequence_point_reached(
|
1568
|
+
if seqp = node.subsequent_sequence_point
|
1569
|
+
notify_sequence_point_reached(seqp)
|
1622
1570
|
end
|
1623
1571
|
end
|
1624
1572
|
EOS
|
@@ -1668,18 +1616,18 @@ module C #:nodoc:
|
|
1668
1616
|
checkpoint(node.location)
|
1669
1617
|
|
1670
1618
|
ctrlexpr = node.condition
|
1671
|
-
|
1672
|
-
|
1619
|
+
ctrlexpr_var = interpret(ctrlexpr, QUIET)
|
1620
|
+
ctrlexpr_val = value_of(ctrlexpr_var)
|
1673
1621
|
|
1674
1622
|
then_var = nil
|
1675
|
-
if
|
1623
|
+
if ctrlexpr_val.may_be_true?
|
1676
1624
|
branched_eval(ctrlexpr, NARROWING) do
|
1677
1625
|
then_var = object_to_variable(interpret(node.then_expression))
|
1678
1626
|
end
|
1679
1627
|
end
|
1680
1628
|
|
1681
1629
|
else_var = nil
|
1682
|
-
if
|
1630
|
+
if ctrlexpr_val.may_be_false?
|
1683
1631
|
branched_eval(nil, NARROWING, FINAL, COMPLETE) do
|
1684
1632
|
else_var = object_to_variable(interpret(node.else_expression))
|
1685
1633
|
end
|
@@ -1690,7 +1638,7 @@ module C #:nodoc:
|
|
1690
1638
|
case
|
1691
1639
|
when then_var && else_var
|
1692
1640
|
result_val = then_var.value.single_value_unified_with(else_var.value)
|
1693
|
-
|
1641
|
+
result_var = create_tempvar(then_var.type, result_val)
|
1694
1642
|
# FIXME: Not to over-warn about discarding a function return value.
|
1695
1643
|
# Because the unified result is a new temporary variable, it is
|
1696
1644
|
# impossible to relate a reference of the unified result and a
|
@@ -1698,20 +1646,20 @@ module C #:nodoc:
|
|
1698
1646
|
notify_variable_value_referred(node, then_var)
|
1699
1647
|
notify_variable_value_referred(node, else_var)
|
1700
1648
|
when then_var
|
1701
|
-
|
1649
|
+
result_var = then_var
|
1702
1650
|
when else_var
|
1703
|
-
|
1651
|
+
result_var = else_var
|
1704
1652
|
else
|
1705
1653
|
# FIXME: Nevertheless, the then-expression is not reachable, the branch
|
1706
1654
|
# execution check may fail in evaluation of the else branch.
|
1707
|
-
|
1655
|
+
result_var = create_tempvar
|
1708
1656
|
end
|
1709
1657
|
|
1710
|
-
notify_conditional_expr_evaled(node,
|
1711
|
-
|
1658
|
+
notify_conditional_expr_evaled(node, ctrlexpr_var, result_var)
|
1659
|
+
result_var
|
1712
1660
|
ensure
|
1713
|
-
if
|
1714
|
-
notify_sequence_point_reached(
|
1661
|
+
if seqp = node.subsequent_sequence_point
|
1662
|
+
notify_sequence_point_reached(seqp)
|
1715
1663
|
end
|
1716
1664
|
end
|
1717
1665
|
end
|