adlint 2.6.0 → 2.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|