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/ctrlexpr.rb
CHANGED
@@ -47,8 +47,8 @@ module C #:nodoc:
|
|
47
47
|
# +-> ValueDomainManipulator
|
48
48
|
# | <-- ValueDomainNarrower
|
49
49
|
# | <-- ValueDomainWidener
|
50
|
-
# | <--
|
51
|
-
# | <--
|
50
|
+
# | <-- NilValueDomainNarrower
|
51
|
+
# | <-- NilValueDomainWidener
|
52
52
|
# |
|
53
53
|
# +-> ValueDomainNarrowing
|
54
54
|
# <-- ValueComparison
|
@@ -59,15 +59,15 @@ module C #:nodoc:
|
|
59
59
|
class ControllingExpression
|
60
60
|
include SyntaxNodeCollector
|
61
61
|
|
62
|
-
def initialize(interpreter, branch,
|
63
|
-
@interpreter
|
64
|
-
@branch
|
65
|
-
@
|
62
|
+
def initialize(interpreter, branch, target_expr = nil)
|
63
|
+
@interpreter = interpreter
|
64
|
+
@branch = branch
|
65
|
+
@target_expr = target_expr
|
66
66
|
@manipulators = []
|
67
67
|
end
|
68
68
|
|
69
|
-
def ensure_true_by_narrowing(
|
70
|
-
target_expr =
|
69
|
+
def ensure_true_by_narrowing(alt_expr = nil)
|
70
|
+
target_expr = alt_expr ? alt_expr : @target_expr
|
71
71
|
|
72
72
|
if target_expr
|
73
73
|
new_manip = ValueDomainNarrower.new(@interpreter, target_expr)
|
@@ -82,16 +82,15 @@ module C #:nodoc:
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
else
|
85
|
-
new_manip =
|
86
|
-
WithoutExpressionValueDomainNarrower.new(@interpreter, @branch.group)
|
85
|
+
new_manip = NilValueDomainNarrower.new(@interpreter, @branch.group)
|
87
86
|
end
|
88
87
|
|
89
88
|
@manipulators.push(new_manip)
|
90
89
|
new_manip
|
91
90
|
end
|
92
91
|
|
93
|
-
def ensure_true_by_widening(
|
94
|
-
target_expr =
|
92
|
+
def ensure_true_by_widening(alt_expr = nil)
|
93
|
+
target_expr = alt_expr ? alt_expr : @target_expr
|
95
94
|
|
96
95
|
if target_expr
|
97
96
|
new_manip = ValueDomainWidener.new(@interpreter, target_expr)
|
@@ -106,8 +105,7 @@ module C #:nodoc:
|
|
106
105
|
end
|
107
106
|
end
|
108
107
|
else
|
109
|
-
new_manip =
|
110
|
-
WithoutExpressionValueDomainWidener.new(@interpreter, @branch.group)
|
108
|
+
new_manip = NilValueDomainWidener.new(@interpreter, @branch.group)
|
111
109
|
end
|
112
110
|
|
113
111
|
@manipulators.push(new_manip)
|
@@ -133,7 +131,7 @@ module C #:nodoc:
|
|
133
131
|
def complexly_compounded?
|
134
132
|
# NOTE: This method determines whether the controlling expression is too
|
135
133
|
# complex to thin value domains of controlling variables.
|
136
|
-
@
|
134
|
+
@target_expr && !collect_logical_and_expressions(@target_expr).empty?
|
137
135
|
end
|
138
136
|
end
|
139
137
|
|
@@ -141,23 +139,23 @@ module C #:nodoc:
|
|
141
139
|
include InterpreterMediator
|
142
140
|
include NotifierMediator
|
143
141
|
include Conversion
|
144
|
-
include
|
142
|
+
include ExpressionEvaluator::Impl
|
145
143
|
include MonitorUtil
|
146
144
|
|
147
|
-
def initialize(interpreter,
|
148
|
-
@interpreter
|
149
|
-
@
|
145
|
+
def initialize(interpreter, target_expr)
|
146
|
+
@interpreter = interpreter
|
147
|
+
@target_expr = target_expr
|
150
148
|
@affected_variables = []
|
151
|
-
@narrowing
|
152
|
-
@value_memory
|
149
|
+
@narrowing = nil
|
150
|
+
@value_memory = nil
|
153
151
|
end
|
154
152
|
|
155
153
|
attr_reader :interpreter
|
156
154
|
attr_reader :affected_variables
|
157
155
|
|
158
156
|
def prepare!
|
159
|
-
if @
|
160
|
-
@narrowing = @
|
157
|
+
if @target_expr
|
158
|
+
@narrowing = @target_expr.accept(self)
|
161
159
|
@narrowing.execute!
|
162
160
|
end
|
163
161
|
end
|
@@ -170,7 +168,7 @@ module C #:nodoc:
|
|
170
168
|
commit_changes(@narrowing)
|
171
169
|
|
172
170
|
if @narrowing
|
173
|
-
@affected_variables = @narrowing.narrowed_values.
|
171
|
+
@affected_variables = @narrowing.narrowed_values.keys
|
174
172
|
@narrowing = nil
|
175
173
|
end
|
176
174
|
end
|
@@ -183,16 +181,14 @@ module C #:nodoc:
|
|
183
181
|
|
184
182
|
def save!
|
185
183
|
@value_memory = {}
|
186
|
-
@affected_variables.each do |
|
187
|
-
@value_memory[
|
184
|
+
@affected_variables.each do |var|
|
185
|
+
@value_memory[var] = var.value.to_single_value.dup
|
188
186
|
end
|
189
187
|
end
|
190
188
|
|
191
189
|
def restore!
|
192
190
|
if @value_memory
|
193
|
-
@value_memory.each
|
194
|
-
variable.assign!(saved_value)
|
195
|
-
end
|
191
|
+
@value_memory.each { |var, saved_val| var.assign!(saved_val) }
|
196
192
|
@value_memory = nil
|
197
193
|
end
|
198
194
|
end
|
@@ -215,69 +211,52 @@ module C #:nodoc:
|
|
215
211
|
def visit_array_subscript_expression(node)
|
216
212
|
checkpoint(node.location)
|
217
213
|
|
218
|
-
|
219
|
-
|
214
|
+
obj_manip = node.expression.accept(self)
|
215
|
+
subs_manip = node.array_subscript.accept(self)
|
220
216
|
|
221
|
-
DelayedObjectDerivation.new(self, node,
|
222
|
-
base_narrowing, subscript_narrowing) do
|
217
|
+
DelayedObjectDerivation.new(self, node, obj_manip, subs_manip) do
|
223
218
|
checkpoint(node.location)
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
execute_array_subscript_expression(node, base_narrowing.result,
|
229
|
-
subscript_narrowing.result)
|
219
|
+
obj_manip.execute!
|
220
|
+
subs_manip.execute!
|
221
|
+
eval_array_subscript_expr(node, obj_manip.result, subs_manip.result)
|
230
222
|
end
|
231
223
|
end
|
232
224
|
|
233
225
|
def visit_function_call_expression(node)
|
234
226
|
checkpoint(node.location)
|
235
227
|
|
236
|
-
|
237
|
-
|
238
|
-
expr.accept(self)
|
239
|
-
}
|
228
|
+
obj_manip = node.expression.accept(self)
|
229
|
+
arg_manips = node.argument_expressions.map { |expr| expr.accept(self) }
|
240
230
|
|
241
|
-
DelayedObjectDerivation.new(self, node,
|
242
|
-
object_narrowing, *arg_narrowings) do
|
231
|
+
DelayedObjectDerivation.new(self, node, obj_manip, *arg_manips) do
|
243
232
|
checkpoint(node.location)
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
narrowing.execute!; [narrowing.result, narrowing.node]
|
248
|
-
}
|
249
|
-
|
250
|
-
execute_function_call_expression(node, object_narrowing.result, args)
|
233
|
+
obj_manip.execute!
|
234
|
+
args = arg_manips.map { |m| m.execute!; [m.result, m.node] }
|
235
|
+
eval_function_call_expr(node, obj_manip.result, args)
|
251
236
|
end
|
252
237
|
end
|
253
238
|
|
254
239
|
def visit_member_access_by_value_expression(node)
|
255
240
|
checkpoint(node.location)
|
256
241
|
|
257
|
-
|
242
|
+
obj_manip = node.expression.accept(self)
|
258
243
|
|
259
|
-
DelayedObjectDerivation.new(self, node,
|
244
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
260
245
|
checkpoint(node.location)
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
execute_member_access_by_value_expression(
|
265
|
-
node, object_narrowing.result)
|
246
|
+
obj_manip.execute!
|
247
|
+
eval_member_access_by_value_expr(node, obj_manip.result)
|
266
248
|
end
|
267
249
|
end
|
268
250
|
|
269
251
|
def visit_member_access_by_pointer_expression(node)
|
270
252
|
checkpoint(node.location)
|
271
253
|
|
272
|
-
|
254
|
+
obj_manip = node.expression.accept(self)
|
273
255
|
|
274
|
-
DelayedObjectDerivation.new(self, node,
|
256
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
275
257
|
checkpoint(node.location)
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
execute_member_access_by_pointer_expression(
|
280
|
-
node, object_narrowing.result)
|
258
|
+
obj_manip.execute!
|
259
|
+
eval_member_access_by_pointer_expr(node, obj_manip.result)
|
281
260
|
end
|
282
261
|
end
|
283
262
|
|
@@ -287,26 +266,24 @@ module C #:nodoc:
|
|
287
266
|
def visit_postfix_increment_expression(node)
|
288
267
|
checkpoint(node.location)
|
289
268
|
|
290
|
-
|
269
|
+
obj_manip = node.operand.accept(self)
|
291
270
|
|
292
|
-
DelayedObjectDerivation.new(self, node,
|
271
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
293
272
|
checkpoint(node.location)
|
294
|
-
|
295
|
-
|
296
|
-
execute_postfix_increment_expression(node, object_narrowing.result)
|
273
|
+
obj_manip.execute!
|
274
|
+
eval_postfix_increment_expr(node, obj_manip.result)
|
297
275
|
end
|
298
276
|
end
|
299
277
|
|
300
278
|
def visit_postfix_decrement_expression(node)
|
301
279
|
checkpoint(node.location)
|
302
280
|
|
303
|
-
|
281
|
+
obj_manip = node.operand.accept(self)
|
304
282
|
|
305
|
-
DelayedObjectDerivation.new(self, node,
|
283
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
306
284
|
checkpoint(node.location)
|
307
|
-
|
308
|
-
|
309
|
-
execute_postfix_decrement_expression(node, object_narrowing.result)
|
285
|
+
obj_manip.execute!
|
286
|
+
eval_postfix_decrement_expr(node, obj_manip.result)
|
310
287
|
end
|
311
288
|
end
|
312
289
|
|
@@ -315,26 +292,24 @@ module C #:nodoc:
|
|
315
292
|
def visit_prefix_increment_expression(node)
|
316
293
|
checkpoint(node.location)
|
317
294
|
|
318
|
-
|
295
|
+
obj_manip = node.operand.accept(self)
|
319
296
|
|
320
|
-
DelayedObjectDerivation.new(self, node,
|
297
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
321
298
|
checkpoint(node.location)
|
322
|
-
|
323
|
-
|
324
|
-
execute_prefix_increment_expression(node, object_narrowing.result)
|
299
|
+
obj_manip.execute!
|
300
|
+
eval_prefix_increment_expr(node, obj_manip.result)
|
325
301
|
end
|
326
302
|
end
|
327
303
|
|
328
304
|
def visit_prefix_decrement_expression(node)
|
329
305
|
checkpoint(node.location)
|
330
306
|
|
331
|
-
|
307
|
+
obj_manip = node.operand.accept(self)
|
332
308
|
|
333
|
-
DelayedObjectDerivation.new(self, node,
|
309
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
334
310
|
checkpoint(node.location)
|
335
|
-
|
336
|
-
|
337
|
-
execute_prefix_decrement_expression(node, object_narrowing.result)
|
311
|
+
obj_manip.execute!
|
312
|
+
eval_prefix_decrement_expr(node, obj_manip.result)
|
338
313
|
end
|
339
314
|
end
|
340
315
|
|
@@ -343,28 +318,24 @@ module C #:nodoc:
|
|
343
318
|
def visit_indirection_expression(node)
|
344
319
|
checkpoint(node.location)
|
345
320
|
|
346
|
-
|
321
|
+
obj_manip = node.operand.accept(self)
|
347
322
|
|
348
|
-
DelayedObjectDerivation.new(self, node,
|
323
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
349
324
|
checkpoint(node.location)
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
execute_indirection_expression(node, object_narrowing.result)
|
325
|
+
obj_manip.execute!
|
326
|
+
eval_indirection_expr(node, obj_manip.result)
|
354
327
|
end
|
355
328
|
end
|
356
329
|
|
357
330
|
def visit_unary_arithmetic_expression(node)
|
358
331
|
checkpoint(node.location)
|
359
332
|
|
360
|
-
|
333
|
+
obj_manip = node.operand.accept(self)
|
361
334
|
|
362
|
-
DelayedObjectDerivation.new(self, node,
|
335
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
363
336
|
checkpoint(node.location)
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
execute_unary_arithmetic_expression(node, object_narrowing.result)
|
337
|
+
obj_manip.execute!
|
338
|
+
eval_unary_arithmetic_expr(node, obj_manip.result)
|
368
339
|
end
|
369
340
|
end
|
370
341
|
|
@@ -376,153 +347,121 @@ module C #:nodoc:
|
|
376
347
|
def visit_cast_expression(node)
|
377
348
|
checkpoint(node.location)
|
378
349
|
|
379
|
-
|
350
|
+
obj_manip = node.operand.accept(self)
|
380
351
|
|
381
|
-
DelayedObjectDerivation.new(self, node,
|
352
|
+
DelayedObjectDerivation.new(self, node, obj_manip) do
|
382
353
|
checkpoint(node.location)
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
execute_cast_expression(node, object_narrowing.result)
|
354
|
+
obj_manip.execute!
|
355
|
+
eval_cast_expr(node, obj_manip.result)
|
387
356
|
end
|
388
357
|
end
|
389
358
|
|
390
359
|
def visit_multiplicative_expression(node)
|
391
360
|
checkpoint(node.location)
|
392
361
|
|
393
|
-
|
394
|
-
|
362
|
+
lhs_manip = node.lhs_operand.accept(self)
|
363
|
+
rhs_manip = node.rhs_operand.accept(self)
|
395
364
|
|
396
|
-
DelayedObjectDerivation.new(self, node,
|
365
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
397
366
|
checkpoint(node.location)
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
execute_multiplicative_expression(
|
403
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
367
|
+
lhs_manip.execute!
|
368
|
+
rhs_manip.execute!
|
369
|
+
eval_multiplicative_expr(node, lhs_manip.result, rhs_manip.result)
|
404
370
|
end
|
405
371
|
end
|
406
372
|
|
407
373
|
def visit_additive_expression(node)
|
408
374
|
checkpoint(node.location)
|
409
375
|
|
410
|
-
|
411
|
-
|
376
|
+
lhs_manip = node.lhs_operand.accept(self)
|
377
|
+
rhs_manip = node.rhs_operand.accept(self)
|
412
378
|
|
413
|
-
DelayedObjectDerivation.new(self, node,
|
379
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
414
380
|
checkpoint(node.location)
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
execute_additive_expression(
|
420
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
381
|
+
lhs_manip.execute!
|
382
|
+
rhs_manip.execute!
|
383
|
+
eval_additive_expr(node, lhs_manip.result, rhs_manip.result)
|
421
384
|
end
|
422
385
|
end
|
423
386
|
|
424
387
|
def visit_shift_expression(node)
|
425
388
|
checkpoint(node.location)
|
426
389
|
|
427
|
-
|
428
|
-
|
390
|
+
lhs_manip = node.lhs_operand.accept(self)
|
391
|
+
rhs_manip = node.rhs_operand.accept(self)
|
429
392
|
|
430
|
-
DelayedObjectDerivation.new(self, node,
|
393
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
431
394
|
checkpoint(node.location)
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
execute_shift_expression(
|
437
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
395
|
+
lhs_manip.execute!
|
396
|
+
rhs_manip.execute!
|
397
|
+
eval_shift_expr(node, lhs_manip.result, rhs_manip.result)
|
438
398
|
end
|
439
399
|
end
|
440
400
|
|
441
401
|
def visit_relational_expression(node)
|
442
402
|
checkpoint(node.location)
|
443
|
-
|
444
|
-
|
445
|
-
rhs_narrowing = node.rhs_operand.accept(self)
|
446
|
-
|
447
|
-
ValueComparison.new(self, node, lhs_narrowing, rhs_narrowing)
|
403
|
+
ValueComparison.new(self, node, node.lhs_operand.accept(self),
|
404
|
+
node.rhs_operand.accept(self))
|
448
405
|
end
|
449
406
|
|
450
407
|
def visit_equality_expression(node)
|
451
408
|
checkpoint(node.location)
|
452
|
-
|
453
|
-
|
454
|
-
rhs_narrowing = node.rhs_operand.accept(self)
|
455
|
-
|
456
|
-
ValueComparison.new(self, node, lhs_narrowing, rhs_narrowing)
|
409
|
+
ValueComparison.new(self, node, node.lhs_operand.accept(self),
|
410
|
+
node.rhs_operand.accept(self))
|
457
411
|
end
|
458
412
|
|
459
413
|
def visit_and_expression(node)
|
460
414
|
checkpoint(node.location)
|
461
415
|
|
462
|
-
|
463
|
-
|
416
|
+
lhs_manip = node.lhs_operand.accept(self)
|
417
|
+
rhs_manip = node.rhs_operand.accept(self)
|
464
418
|
|
465
|
-
DelayedObjectDerivation.new(self, node,
|
419
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
466
420
|
checkpoint(node.location)
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
execute_and_expression(node,
|
472
|
-
lhs_narrowing.result, rhs_narrowing.result)
|
421
|
+
lhs_manip.execute!
|
422
|
+
rhs_manip.execute!
|
423
|
+
eval_and_expr(node, lhs_manip.result, rhs_manip.result)
|
473
424
|
end
|
474
425
|
end
|
475
426
|
|
476
427
|
def visit_exclusive_or_expression(node)
|
477
428
|
checkpoint(node.location)
|
478
429
|
|
479
|
-
|
480
|
-
|
430
|
+
lhs_manip = node.lhs_operand.accept(self)
|
431
|
+
rhs_manip = node.rhs_operand.accept(self)
|
481
432
|
|
482
|
-
DelayedObjectDerivation.new(self, node,
|
433
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
483
434
|
checkpoint(node.location)
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
execute_exclusive_or_expression(
|
489
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
435
|
+
lhs_manip.execute!
|
436
|
+
rhs_manip.execute!
|
437
|
+
eval_exclusive_or_expr(node, lhs_manip.result, rhs_manip.result)
|
490
438
|
end
|
491
439
|
end
|
492
440
|
|
493
441
|
def visit_inclusive_or_expression(node)
|
494
442
|
checkpoint(node.location)
|
495
443
|
|
496
|
-
|
497
|
-
|
444
|
+
lhs_manip = node.lhs_operand.accept(self)
|
445
|
+
rhs_manip = node.rhs_operand.accept(self)
|
498
446
|
|
499
|
-
DelayedObjectDerivation.new(self, node,
|
447
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
500
448
|
checkpoint(node.location)
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
execute_inclusive_or_expression(
|
506
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
449
|
+
lhs_manip.execute!
|
450
|
+
rhs_manip.execute!
|
451
|
+
eval_inclusive_or_expr(node, lhs_manip.result, rhs_manip.result)
|
507
452
|
end
|
508
453
|
end
|
509
454
|
|
510
455
|
def visit_logical_and_expression(node)
|
511
456
|
checkpoint(node.location)
|
512
|
-
|
513
|
-
|
514
|
-
rhs_narrowing = node.rhs_operand.accept(self)
|
515
|
-
|
516
|
-
LogicalAnd.new(self, node, lhs_narrowing, rhs_narrowing)
|
457
|
+
LogicalAnd.new(self, node, node.lhs_operand.accept(self),
|
458
|
+
node.rhs_operand.accept(self))
|
517
459
|
end
|
518
460
|
|
519
461
|
def visit_logical_or_expression(node)
|
520
462
|
checkpoint(node.location)
|
521
|
-
|
522
|
-
|
523
|
-
rhs_narrowing = node.rhs_operand.accept(self)
|
524
|
-
|
525
|
-
LogicalOr.new(self, node, lhs_narrowing, rhs_narrowing)
|
463
|
+
LogicalOr.new(self, node, node.lhs_operand.accept(self),
|
464
|
+
node.rhs_operand.accept(self))
|
526
465
|
end
|
527
466
|
|
528
467
|
def_strict_object_derivation :visit_conditional_expression
|
@@ -530,77 +469,67 @@ module C #:nodoc:
|
|
530
469
|
def visit_simple_assignment_expression(node)
|
531
470
|
checkpoint(node.location)
|
532
471
|
|
533
|
-
|
534
|
-
|
472
|
+
lhs_manip = node.lhs_operand.accept(self)
|
473
|
+
rhs_manip = node.rhs_operand.accept(self)
|
535
474
|
|
536
|
-
DelayedObjectDerivation.new(self, node,
|
475
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
537
476
|
checkpoint(node.location)
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
execute_simple_assignment_expression(
|
543
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
477
|
+
lhs_manip.execute!
|
478
|
+
rhs_manip.execute!
|
479
|
+
eval_simple_assignment_expr(node, lhs_manip.result, rhs_manip.result)
|
544
480
|
end
|
545
481
|
end
|
546
482
|
|
547
483
|
def visit_compound_assignment_expression(node)
|
548
484
|
checkpoint(node.location)
|
549
485
|
|
550
|
-
|
551
|
-
|
486
|
+
lhs_manip = node.lhs_operand.accept(self)
|
487
|
+
rhs_manip = node.rhs_operand.accept(self)
|
552
488
|
|
553
|
-
DelayedObjectDerivation.new(self, node,
|
489
|
+
DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
|
554
490
|
checkpoint(node.location)
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
execute_compound_assignment_expression(
|
560
|
-
node, lhs_narrowing.result, rhs_narrowing.result)
|
491
|
+
lhs_manip.execute!
|
492
|
+
rhs_manip.execute!
|
493
|
+
eval_compound_assignment_expr(node, lhs_manip.result, rhs_manip.result)
|
561
494
|
end
|
562
495
|
end
|
563
496
|
|
564
497
|
def visit_comma_separated_expression(node)
|
565
498
|
checkpoint(node.location)
|
566
499
|
|
567
|
-
|
500
|
+
obj_manips = node.expressions.map { |expr| expr.accept(self) }
|
568
501
|
|
569
|
-
DelayedObjectDerivation.new(self, node, *
|
502
|
+
DelayedObjectDerivation.new(self, node, *obj_manips) do
|
570
503
|
checkpoint(node.location)
|
571
|
-
|
572
|
-
object_narrowings.map { |narrowing|
|
573
|
-
narrowing.execute!
|
574
|
-
narrowing.result
|
575
|
-
}.last
|
504
|
+
obj_manips.map { |manip| manip.execute!; manip.result }.last
|
576
505
|
end
|
577
506
|
end
|
578
507
|
|
579
508
|
private
|
580
|
-
def commit_changes(
|
509
|
+
def commit_changes(manip)
|
581
510
|
subclass_responsibility
|
582
511
|
end
|
583
512
|
end
|
584
513
|
|
585
514
|
class ValueDomainNarrower < ValueDomainManipulator
|
586
515
|
private
|
587
|
-
def commit_changes(
|
588
|
-
|
589
|
-
|
516
|
+
def commit_changes(manip)
|
517
|
+
manip.narrowed_values.each do |var, val|
|
518
|
+
var.narrow_value_domain!(Operator::EQ, val)
|
590
519
|
end
|
591
520
|
end
|
592
521
|
end
|
593
522
|
|
594
523
|
class ValueDomainWidener < ValueDomainManipulator
|
595
524
|
private
|
596
|
-
def commit_changes(
|
597
|
-
|
598
|
-
|
525
|
+
def commit_changes(manip)
|
526
|
+
manip.narrowed_values.each do |var, val|
|
527
|
+
var.widen_value_domain!(Operator::EQ, val)
|
599
528
|
end
|
600
529
|
end
|
601
530
|
end
|
602
531
|
|
603
|
-
class
|
532
|
+
class NilValueDomainNarrower < ValueDomainManipulator
|
604
533
|
def initialize(interpreter, branch_group)
|
605
534
|
super(interpreter, nil)
|
606
535
|
@branch_group = branch_group
|
@@ -611,16 +540,15 @@ module C #:nodoc:
|
|
611
540
|
end
|
612
541
|
|
613
542
|
private
|
614
|
-
def commit_changes(
|
615
|
-
@branch_group.all_controlling_variables.each do |
|
616
|
-
|
617
|
-
variable.type.arbitrary_value)
|
543
|
+
def commit_changes(*)
|
544
|
+
@branch_group.all_controlling_variables.each do |var|
|
545
|
+
var.narrow_value_domain!(Operator::EQ, var.type.arbitrary_value)
|
618
546
|
end
|
619
547
|
true
|
620
548
|
end
|
621
549
|
end
|
622
550
|
|
623
|
-
class
|
551
|
+
class NilValueDomainWidener < ValueDomainManipulator
|
624
552
|
def initialize(interpreter, branch_group)
|
625
553
|
super(interpreter, nil)
|
626
554
|
@branch_group = branch_group
|
@@ -631,10 +559,9 @@ module C #:nodoc:
|
|
631
559
|
end
|
632
560
|
|
633
561
|
private
|
634
|
-
def commit_changes(
|
635
|
-
@branch_group.all_controlling_variables.each do |
|
636
|
-
|
637
|
-
variable.type.arbitrary_value)
|
562
|
+
def commit_changes(*)
|
563
|
+
@branch_group.all_controlling_variables.each do |var|
|
564
|
+
var.widen_value_domain!(Operator::EQ, var.type.arbitrary_value)
|
638
565
|
end
|
639
566
|
true
|
640
567
|
end
|
@@ -645,39 +572,39 @@ module C #:nodoc:
|
|
645
572
|
include NotifierMediator
|
646
573
|
include Conversion
|
647
574
|
|
648
|
-
def initialize(
|
649
|
-
@manipulator
|
650
|
-
@node
|
651
|
-
@children
|
575
|
+
def initialize(manip, node, *children)
|
576
|
+
@manipulator = manip
|
577
|
+
@node = node
|
578
|
+
@children = children
|
652
579
|
@original_values = {}
|
653
580
|
@narrowed_values = {}
|
654
|
-
@result
|
581
|
+
@result = nil
|
655
582
|
end
|
656
583
|
|
657
584
|
attr_reader :node
|
658
585
|
attr_reader :narrowed_values
|
659
586
|
attr_reader :result
|
660
587
|
|
661
|
-
def load_original_values!(
|
662
|
-
@original_values =
|
663
|
-
@children.each { |child| child.load_original_values!(
|
588
|
+
def load_original_values!(manip)
|
589
|
+
@original_values = manip.narrowed_values
|
590
|
+
@children.each { |child| child.load_original_values!(manip) }
|
664
591
|
end
|
665
592
|
|
666
593
|
def execute!
|
667
594
|
@result = do_narrowing
|
668
|
-
@children.each do |
|
669
|
-
@narrowed_values =
|
595
|
+
@children.each do |manip|
|
596
|
+
@narrowed_values = manip.narrowed_values.merge(@narrowed_values)
|
670
597
|
end
|
671
598
|
ensure
|
672
|
-
if
|
673
|
-
notify_sequence_point_reached(
|
599
|
+
if seqp = node.subsequent_sequence_point
|
600
|
+
notify_sequence_point_reached(seqp)
|
674
601
|
end
|
675
602
|
end
|
676
603
|
|
677
|
-
def ensure_result_equal_to(
|
604
|
+
def ensure_result_equal_to(val)
|
678
605
|
if @result.variable? && @result.designated_by_lvalue?
|
679
|
-
if @result.value.scalar? &&
|
680
|
-
ensure_relation(@result, Operator::EQ,
|
606
|
+
if @result.value.scalar? && val.scalar?
|
607
|
+
ensure_relation(@result, Operator::EQ, val)
|
681
608
|
end
|
682
609
|
end
|
683
610
|
end
|
@@ -690,61 +617,57 @@ module C #:nodoc:
|
|
690
617
|
subclass_responsibility
|
691
618
|
end
|
692
619
|
|
693
|
-
def do_logical_arithmetic_conversion(node,
|
694
|
-
|
695
|
-
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
620
|
+
def do_logical_arithmetic_conversion(node, lhs_var, rhs_var)
|
621
|
+
lhs_conved, rhs_conved = do_usual_arithmetic_conversion(lhs_var, rhs_var)
|
696
622
|
|
697
|
-
unless
|
698
|
-
notify_implicit_conv_performed(node.lhs_operand,
|
699
|
-
lhs_variable, lhs_result)
|
623
|
+
unless lhs_conved == lhs_var
|
624
|
+
notify_implicit_conv_performed(node.lhs_operand, lhs_var, lhs_conved)
|
700
625
|
end
|
701
626
|
|
702
|
-
unless
|
703
|
-
notify_implicit_conv_performed(node.rhs_operand,
|
704
|
-
rhs_variable, rhs_result)
|
627
|
+
unless rhs_conved == rhs_var
|
628
|
+
notify_implicit_conv_performed(node.rhs_operand, rhs_var, rhs_conved)
|
705
629
|
end
|
706
630
|
|
707
|
-
return
|
631
|
+
return lhs_conved, rhs_conved
|
708
632
|
end
|
709
633
|
|
710
|
-
def ensure_relation(
|
634
|
+
def ensure_relation(var, op, val)
|
711
635
|
# NOTE: To avoid over-narrowing.
|
712
|
-
if
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
update_narrowed_value(variable, target_value)
|
636
|
+
if val.definite? or var.value.contain?(val) && !val.contain?(var.value)
|
637
|
+
target_val = save_original_value(var).dup
|
638
|
+
target_val.narrow_domain!(op, val)
|
639
|
+
update_narrowed_value(var, target_val)
|
717
640
|
end
|
718
641
|
end
|
719
642
|
|
720
|
-
def save_original_value(
|
721
|
-
@original_values[
|
643
|
+
def save_original_value(var)
|
644
|
+
@original_values[var.to_named_variable] ||= var.value.dup
|
722
645
|
end
|
723
646
|
|
724
|
-
def original_value_of(
|
725
|
-
@original_values[
|
647
|
+
def original_value_of(var)
|
648
|
+
@original_values[var.to_named_variable]
|
726
649
|
end
|
727
650
|
|
728
|
-
def update_narrowed_value(
|
729
|
-
@narrowed_values[
|
651
|
+
def update_narrowed_value(var, new_val)
|
652
|
+
@narrowed_values[var.to_named_variable] = new_val
|
730
653
|
end
|
731
654
|
|
732
|
-
def narrowing_merge!(
|
733
|
-
|
734
|
-
|
655
|
+
def narrowing_merge!(lhs_manip, rhs_manip)
|
656
|
+
lhs_vals = lhs_manip.narrowed_values
|
657
|
+
rhs_vals = rhs_manip.narrowed_values
|
735
658
|
|
736
|
-
@narrowed_values =
|
659
|
+
@narrowed_values = lhs_vals.merge(rhs_vals) { |key, lhs_val, rhs_val|
|
737
660
|
result = lhs_val.dup
|
738
661
|
result.narrow_domain!(Operator::EQ, rhs_val)
|
739
662
|
result
|
740
663
|
}
|
741
664
|
end
|
742
665
|
|
743
|
-
def widening_merge!(
|
744
|
-
|
745
|
-
|
666
|
+
def widening_merge!(lhs_manip, rhs_manip)
|
667
|
+
lhs_vals = lhs_manip.narrowed_values
|
668
|
+
rhs_vals = rhs_manip.narrowed_values
|
746
669
|
|
747
|
-
@narrowed_values =
|
670
|
+
@narrowed_values = lhs_vals.merge(rhs_vals) { |key, lhs_val, rhs_val|
|
748
671
|
result = lhs_val.dup
|
749
672
|
result.widen_domain!(Operator::EQ, rhs_val)
|
750
673
|
result
|
@@ -760,45 +683,48 @@ module C #:nodoc:
|
|
760
683
|
end
|
761
684
|
|
762
685
|
class ValueComparison < ValueDomainNarrowing
|
763
|
-
def initialize(
|
686
|
+
def initialize(manip, node, lhs_manip, rhs_manip)
|
764
687
|
super
|
765
|
-
@operator
|
766
|
-
@
|
767
|
-
@
|
688
|
+
@operator = ComparisonOperator.new(node.operator)
|
689
|
+
@lhs_manip = lhs_manip
|
690
|
+
@rhs_manip = rhs_manip
|
768
691
|
end
|
769
692
|
|
770
693
|
private
|
771
694
|
def do_narrowing
|
772
|
-
@
|
773
|
-
lhs_var = object_to_variable(@
|
695
|
+
@lhs_manip.execute!
|
696
|
+
lhs_var = object_to_variable(@lhs_manip.result)
|
774
697
|
|
775
|
-
@
|
776
|
-
rhs_var = object_to_variable(@
|
698
|
+
@rhs_manip.execute!
|
699
|
+
rhs_var = object_to_variable(@rhs_manip.result)
|
777
700
|
|
778
701
|
unless lhs_var.type.scalar? && rhs_var.type.scalar?
|
779
|
-
return
|
702
|
+
return create_tempvar(int_type)
|
780
703
|
end
|
781
704
|
|
782
705
|
unless lhs_var.value.scalar? && rhs_var.value.scalar?
|
783
|
-
return
|
706
|
+
return create_tempvar(int_type)
|
784
707
|
end
|
785
708
|
|
786
|
-
|
709
|
+
lhs_conved, rhs_conved =
|
787
710
|
do_logical_arithmetic_conversion(@node, lhs_var, rhs_var)
|
788
711
|
|
712
|
+
lhs_val = lhs_conved.value
|
713
|
+
rhs_val = rhs_conved.value
|
714
|
+
|
789
715
|
case @operator
|
790
716
|
when Operator::EQ
|
791
|
-
result =
|
717
|
+
result = create_tempvar(int_type, lhs_val == rhs_val)
|
792
718
|
when Operator::NE
|
793
|
-
result =
|
719
|
+
result = create_tempvar(int_type, lhs_val != rhs_val)
|
794
720
|
when Operator::LT
|
795
|
-
result =
|
721
|
+
result = create_tempvar(int_type, lhs_val < rhs_val)
|
796
722
|
when Operator::GT
|
797
|
-
result =
|
723
|
+
result = create_tempvar(int_type, lhs_val > rhs_val)
|
798
724
|
when Operator::LE
|
799
|
-
result =
|
725
|
+
result = create_tempvar(int_type, lhs_val <= rhs_val)
|
800
726
|
when Operator::GE
|
801
|
-
result =
|
727
|
+
result = create_tempvar(int_type, lhs_val >= rhs_val)
|
802
728
|
else
|
803
729
|
__NOTREACHED__
|
804
730
|
end
|
@@ -808,18 +734,18 @@ module C #:nodoc:
|
|
808
734
|
|
809
735
|
case @operator
|
810
736
|
when Operator::EQ, Operator::NE
|
811
|
-
notify_equality_expr_evaled(@node,
|
737
|
+
notify_equality_expr_evaled(@node, lhs_conved, rhs_conved, result)
|
812
738
|
when Operator::LT, Operator::GT, Operator::LE, Operator::GE
|
813
|
-
notify_relational_expr_evaled(@node,
|
739
|
+
notify_relational_expr_evaled(@node, lhs_conved, rhs_conved, result)
|
814
740
|
else
|
815
741
|
__NOTREACHED__
|
816
742
|
end
|
817
743
|
|
818
744
|
case
|
819
|
-
when
|
820
|
-
ensure_relation(
|
821
|
-
when
|
822
|
-
ensure_relation(
|
745
|
+
when lhs_conved.designated_by_lvalue?
|
746
|
+
ensure_relation(lhs_conved, @operator, rhs_val)
|
747
|
+
when rhs_conved.designated_by_lvalue?
|
748
|
+
ensure_relation(rhs_conved, @operator.for_commutation, lhs_val)
|
823
749
|
else
|
824
750
|
# NOTE: Domain of the rvalue should not be narrowed.
|
825
751
|
end
|
@@ -829,19 +755,19 @@ module C #:nodoc:
|
|
829
755
|
end
|
830
756
|
|
831
757
|
class LogicalAnd < ValueDomainNarrowing
|
832
|
-
def initialize(
|
758
|
+
def initialize(manip, node, lhs_manip, rhs_manip)
|
833
759
|
super
|
834
|
-
@
|
835
|
-
@
|
760
|
+
@lhs_manip = lhs_manip
|
761
|
+
@rhs_manip = rhs_manip
|
836
762
|
end
|
837
763
|
|
838
764
|
private
|
839
765
|
def do_narrowing
|
840
|
-
@
|
841
|
-
@
|
842
|
-
|
766
|
+
@lhs_manip.execute!
|
767
|
+
@lhs_manip.ensure_result_equal_to(ScalarValue.of_true)
|
768
|
+
lhs_var = object_to_variable(@lhs_manip.result)
|
843
769
|
|
844
|
-
# NOTE: The ISO C99 standard
|
770
|
+
# NOTE: The ISO C99 standard says;
|
845
771
|
#
|
846
772
|
# 6.5.13 Logical AND operator
|
847
773
|
#
|
@@ -854,50 +780,51 @@ module C #:nodoc:
|
|
854
780
|
notify_sequence_point_reached(SequencePoint.new(@node.lhs_operand))
|
855
781
|
|
856
782
|
# TODO: Must look about the short-circuit evaluation.
|
857
|
-
@
|
858
|
-
@
|
859
|
-
@
|
860
|
-
|
783
|
+
@rhs_manip.load_original_values!(@lhs_manip)
|
784
|
+
@rhs_manip.execute!
|
785
|
+
@rhs_manip.ensure_result_equal_to(ScalarValue.of_true)
|
786
|
+
rhs_var = object_to_variable(@rhs_manip.result)
|
861
787
|
|
862
788
|
notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))
|
863
789
|
|
864
|
-
narrowing_merge!(@
|
865
|
-
notify_variable_value_referred(@node,
|
866
|
-
notify_variable_value_referred(@node,
|
790
|
+
narrowing_merge!(@lhs_manip, @rhs_manip)
|
791
|
+
notify_variable_value_referred(@node, lhs_var)
|
792
|
+
notify_variable_value_referred(@node, rhs_var)
|
867
793
|
|
868
|
-
unless
|
869
|
-
return
|
794
|
+
unless lhs_var.type.scalar? && rhs_var.type.scalar?
|
795
|
+
return create_tempvar(int_type)
|
870
796
|
end
|
871
797
|
|
872
|
-
unless
|
873
|
-
return
|
798
|
+
unless lhs_var.value.scalar? && rhs_var.value.scalar?
|
799
|
+
return create_tempvar(int_type)
|
874
800
|
end
|
875
801
|
|
876
|
-
|
877
|
-
do_logical_arithmetic_conversion(@node,
|
802
|
+
lhs_conved, rhs_conved =
|
803
|
+
do_logical_arithmetic_conversion(@node, lhs_var, rhs_var)
|
804
|
+
|
805
|
+
lhs_val = lhs_conved.value
|
806
|
+
rhs_val = rhs_conved.value
|
878
807
|
|
879
|
-
result =
|
880
|
-
|
881
|
-
notify_logical_and_expr_evaled(@node,
|
882
|
-
lhs_converted, rhs_converted, result)
|
808
|
+
result = create_tempvar(int_type, lhs_val.logical_and(rhs_val))
|
809
|
+
notify_logical_and_expr_evaled(@node, lhs_conved, rhs_conved, result)
|
883
810
|
result
|
884
811
|
end
|
885
812
|
end
|
886
813
|
|
887
814
|
class LogicalOr < ValueDomainNarrowing
|
888
|
-
def initialize(
|
815
|
+
def initialize(manip, node, lhs_manip, rhs_manip)
|
889
816
|
super
|
890
|
-
@
|
891
|
-
@
|
817
|
+
@lhs_manip = lhs_manip
|
818
|
+
@rhs_manip = rhs_manip
|
892
819
|
end
|
893
820
|
|
894
821
|
private
|
895
822
|
def do_narrowing
|
896
|
-
@
|
897
|
-
@
|
898
|
-
|
823
|
+
@lhs_manip.execute!
|
824
|
+
@lhs_manip.ensure_result_equal_to(ScalarValue.of_true)
|
825
|
+
lhs_var = object_to_variable(@lhs_manip.result)
|
899
826
|
|
900
|
-
# NOTE: The ISO C99 standard
|
827
|
+
# NOTE: The ISO C99 standard says;
|
901
828
|
#
|
902
829
|
# 6.5.14 Logical OR operator
|
903
830
|
#
|
@@ -912,46 +839,47 @@ module C #:nodoc:
|
|
912
839
|
# TODO: Must look about the short-circuit evaluation.
|
913
840
|
# FIXME: Base value of the RHS narrowing should be updated to ensure that
|
914
841
|
# the LHS condition is false.
|
915
|
-
@
|
916
|
-
@
|
917
|
-
|
842
|
+
@rhs_manip.execute!
|
843
|
+
@rhs_manip.ensure_result_equal_to(ScalarValue.of_true)
|
844
|
+
rhs_var = object_to_variable(@rhs_manip.result)
|
918
845
|
|
919
846
|
notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))
|
920
847
|
|
921
|
-
widening_merge!(@
|
922
|
-
notify_variable_value_referred(@node,
|
923
|
-
notify_variable_value_referred(@node,
|
848
|
+
widening_merge!(@lhs_manip, @rhs_manip)
|
849
|
+
notify_variable_value_referred(@node, lhs_var)
|
850
|
+
notify_variable_value_referred(@node, rhs_var)
|
924
851
|
|
925
|
-
unless
|
926
|
-
return
|
852
|
+
unless lhs_var.type.scalar? && rhs_var.type.scalar?
|
853
|
+
return create_tempvar(int_type)
|
927
854
|
end
|
928
855
|
|
929
|
-
unless
|
930
|
-
return
|
856
|
+
unless lhs_var.value.scalar? && rhs_var.value.scalar?
|
857
|
+
return create_tempvar(int_type)
|
931
858
|
end
|
932
859
|
|
933
|
-
|
934
|
-
do_logical_arithmetic_conversion(@node,
|
860
|
+
lhs_conved, rhs_conved =
|
861
|
+
do_logical_arithmetic_conversion(@node, lhs_var, rhs_var)
|
862
|
+
|
863
|
+
lhs_val = lhs_conved.value
|
864
|
+
rhs_val = rhs_conved.value
|
935
865
|
|
936
|
-
result =
|
937
|
-
|
938
|
-
notify_logical_or_expr_evaled(@node,
|
939
|
-
lhs_converted, rhs_converted, result)
|
866
|
+
result = create_tempvar(int_type, lhs_val.logical_or(rhs_val))
|
867
|
+
notify_logical_or_expr_evaled(@node, lhs_conved, rhs_conved, result)
|
940
868
|
result
|
941
869
|
end
|
942
870
|
end
|
943
871
|
|
944
872
|
class StrictObjectDerivation < ValueDomainNarrowing
|
945
|
-
def initialize(
|
946
|
-
super(
|
873
|
+
def initialize(manip, node)
|
874
|
+
super(manip, node)
|
947
875
|
@object = interpret(node)
|
948
876
|
end
|
949
877
|
|
950
878
|
private
|
951
879
|
def do_narrowing
|
952
880
|
if @object.variable? && @object.named?
|
953
|
-
if
|
954
|
-
@object = PhantomVariable.new(@object,
|
881
|
+
if orig_val = original_value_of(@object)
|
882
|
+
@object = PhantomVariable.new(@object, orig_val)
|
955
883
|
end
|
956
884
|
end
|
957
885
|
@object
|
@@ -959,8 +887,8 @@ module C #:nodoc:
|
|
959
887
|
end
|
960
888
|
|
961
889
|
class DelayedObjectDerivation < ValueDomainNarrowing
|
962
|
-
def initialize(
|
963
|
-
super(
|
890
|
+
def initialize(manip, node, *children, &block)
|
891
|
+
super(manip, node, *children)
|
964
892
|
@block = block
|
965
893
|
end
|
966
894
|
|
@@ -971,36 +899,29 @@ module C #:nodoc:
|
|
971
899
|
end
|
972
900
|
|
973
901
|
class PhantomVariable < AliasVariable
|
974
|
-
def initialize(
|
975
|
-
super(
|
976
|
-
|
977
|
-
@
|
978
|
-
@phantom_value =
|
979
|
-
phantom_value ? phantom_value : named_variable.memory.read.dup
|
902
|
+
def initialize(named_var, phantom_val = nil)
|
903
|
+
super(named_var)
|
904
|
+
@base_var = named_var
|
905
|
+
@phantom_val = phantom_val ? phantom_val : named_var.memory.read.dup
|
980
906
|
end
|
981
907
|
|
982
908
|
def value
|
983
|
-
@
|
909
|
+
@phantom_val
|
984
910
|
end
|
985
911
|
|
986
|
-
def assign!(
|
987
|
-
@
|
912
|
+
def assign!(val)
|
913
|
+
@phantom_val = val
|
988
914
|
end
|
989
915
|
|
990
916
|
def to_named_variable
|
991
|
-
@
|
917
|
+
@base_var.to_named_variable
|
992
918
|
end
|
993
919
|
|
994
920
|
def pretty_print(pp)
|
995
|
-
Summary.new(object_id, name, type, @
|
921
|
+
Summary.new(object_id, name, type, @phantom_val).pretty_print(pp)
|
996
922
|
end
|
997
923
|
|
998
924
|
Summary = Struct.new(:object_id, :name, :type, :value)
|
999
|
-
|
1000
|
-
private
|
1001
|
-
def modifiable_value
|
1002
|
-
@phantom_value
|
1003
|
-
end
|
1004
925
|
end
|
1005
926
|
|
1006
927
|
end
|