Class: AdLint::Cc1::ValueDomainManipulator

Inherits:
SyntaxTreeVisitor show all
Extended by:
Forwardable
Includes:
Conversion, ExpressionEvaluator::Impl, InterpreterMediator, NotifierMediator, MonitorUtil
Defined in:
lib/adlint/cc1/ctrlexpr.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MonitorUtil

#checkpoint, #monitored_region

Methods included from ExpressionEvaluator::Impl

#eval_additive_expr, #eval_address_expr, #eval_and_expr, #eval_array_subscript_expr, #eval_bit_access_by_pointer_expr, #eval_bit_access_by_value_expr, #eval_cast_expr, #eval_compound_assignment_expr, #eval_compound_literal_expr, #eval_equality_expr, #eval_exclusive_or_expr, #eval_function_call_expr, #eval_inclusive_or_expr, #eval_indirection_expr, #eval_member_access_by_pointer_expr, #eval_member_access_by_value_expr, #eval_multiplicative_expr, #eval_object_specifier, #eval_postfix_decrement_expr, #eval_postfix_increment_expr, #eval_prefix_decrement_expr, #eval_prefix_increment_expr, #eval_relational_expr, #eval_shift_expr, #eval_simple_assignment_expr, #eval_unary_arithmetic_expr

Methods included from Conversion

#do_conversion, #do_default_argument_promotion, #do_integer_promotion, #do_usual_arithmetic_conversion, #untyped_pointer_conversion?

Methods included from InterpreterMediator

#constant_expression?, #current_branch, #interpret, #object_to_pointer, #object_to_variable, #pointer_value_of, #reset_environment, #scalar_value_of, #scalar_value_of_arbitrary, #scalar_value_of_false, #scalar_value_of_null, #scalar_value_of_true, #value_of

Methods included from InterpSyntaxBridge

#_interp_syntax_bridge_

Methods included from InterpObjectBridge

#_interp_object_bridge_

Methods included from ArithmeticAccessor

#arithmetic, #logical_right_shift?

Methods included from FunctionTableMediator

#declare_explicit_function, #declare_implicit_function, #define_anonymous_function, #define_explicit_function

Methods included from VariableTableMediator

#create_tmpvar, #local_variables

Methods included from MemoryPoolMediator

#pointee_of

Methods inherited from SyntaxTreeVisitor

#visit_abbreviated_function_declarator, #visit_address_expression, #visit_alignof_expression, #visit_alignof_type_expression, #visit_ansi_function_declarator, #visit_ansi_function_definition, #visit_array_abstract_declarator, #visit_array_declarator, #visit_bit_access_by_pointer_expression, #visit_bit_access_by_value_expression, #visit_break_statement, #visit_c99_for_statement, #visit_case_labeled_statement, #visit_compound_literal_expression, #visit_compound_statement, #visit_conditional_expression, #visit_constant_specifier, #visit_continue_statement, #visit_declaration, #visit_declaration_specifiers, #visit_default_labeled_statement, #visit_do_statement, #visit_enum_specifier, #visit_enum_type_declaration, #visit_enumerator, #visit_error_expression, #visit_error_statement, #visit_expression_statement, #visit_for_statement, #visit_function_abstract_declarator, #visit_function_declaration, #visit_generic_labeled_statement, #visit_goto_statement, #visit_grouped_abstract_declarator, #visit_grouped_declarator, #visit_grouped_expression, #visit_identifier_declarator, #visit_if_else_statement, #visit_if_statement, #visit_init_declarator, #visit_initializer, #visit_kandr_function_declarator, #visit_kandr_function_definition, #visit_member_declaration, #visit_null_constant_specifier, #visit_object_specifier, #visit_parameter_declaration, #visit_parameter_definition, #visit_parameter_type_list, #visit_pointer_abstract_declarator, #visit_return_statement, #visit_sizeof_expression, #visit_sizeof_type_expression, #visit_specifier_qualifier_list, #visit_standard_type_specifier, #visit_string_literal_specifier, #visit_struct_declaration, #visit_struct_declarator, #visit_struct_specifier, #visit_struct_type_declaration, #visit_switch_statement, #visit_translation_unit, #visit_type_name, #visit_typedef_declaration, #visit_typedef_type_specifier, #visit_typeof_type_specifier, #visit_union_specifier, #visit_union_type_declaration, #visit_variable_declaration, #visit_variable_definition, #visit_while_statement

Constructor Details

#initialize(interp, target_expr) ⇒ ValueDomainManipulator

Returns a new instance of ValueDomainManipulator.



152
153
154
155
156
157
158
# File 'lib/adlint/cc1/ctrlexpr.rb', line 152

def initialize(interp, target_expr)
  @interpreter        = interp
  @target_expr        = target_expr
  @affected_variables = []
  @narrowing          = nil
  @value_memory       = nil
end

Instance Attribute Details

#affected_variablesObject (readonly)

Returns the value of attribute affected_variables.



161
162
163
# File 'lib/adlint/cc1/ctrlexpr.rb', line 161

def affected_variables
  @affected_variables
end

#interpreterObject (readonly)

Returns the value of attribute interpreter.



160
161
162
# File 'lib/adlint/cc1/ctrlexpr.rb', line 160

def interpreter
  @interpreter
end

Instance Method Details

#commit!Object



170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/adlint/cc1/ctrlexpr.rb', line 170

def commit!
  if @narrowing
    @narrowing.ensure_result_equal_to(scalar_value_of_true)
  end

  commit_changes(@narrowing)

  if @narrowing
    @affected_variables = @narrowing.narrowed_values.keys
    @narrowing = nil
  end
end

#prepare!Object



163
164
165
166
167
168
# File 'lib/adlint/cc1/ctrlexpr.rb', line 163

def prepare!
  if @target_expr
    @narrowing = @target_expr.accept(self)
    @narrowing.execute!
  end
end

#restore!Object



196
197
198
199
200
201
# File 'lib/adlint/cc1/ctrlexpr.rb', line 196

def restore!
  if @value_memory
    @value_memory.each { |var, saved_val| var.assign!(saved_val) }
    @value_memory = nil
  end
end

#rollback!Object



183
184
185
186
187
# File 'lib/adlint/cc1/ctrlexpr.rb', line 183

def rollback!
  # NOTE: Rollback narrowed version to cut out the value-domain to enter
  #       the current branch.
  @affected_variables.each { |var| var.value.rollback! }
end

#save!Object



189
190
191
192
193
194
# File 'lib/adlint/cc1/ctrlexpr.rb', line 189

def save!
  @value_memory = {}
  @affected_variables.each do |var|
    @value_memory[var] = var.value.to_single_value.dup
  end
end

#visit_additive_expression(node) ⇒ Object



368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/adlint/cc1/ctrlexpr.rb', line 368

def visit_additive_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_additive_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_and_expression(node) ⇒ Object



406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/adlint/cc1/ctrlexpr.rb', line 406

def visit_and_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_and_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_array_subscript_expression(node) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/adlint/cc1/ctrlexpr.rb', line 218

def visit_array_subscript_expression(node)
  checkpoint(node.location)
  obj_manip  = node.expression.accept(self)
  subs_manip = node.array_subscript.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip, subs_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    subs_manip.execute!
    eval_array_subscript_expr(node, obj_manip.result, subs_manip.result)
  end
end

#visit_cast_expression(node) ⇒ Object



344
345
346
347
348
349
350
351
352
353
# File 'lib/adlint/cc1/ctrlexpr.rb', line 344

def visit_cast_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_cast_expr(node, obj_manip.result)
  end
end

#visit_comma_separated_expression(node) ⇒ Object



485
486
487
488
489
490
491
492
493
# File 'lib/adlint/cc1/ctrlexpr.rb', line 485

def visit_comma_separated_expression(node)
  checkpoint(node.location)
  obj_manips = node.expressions.map { |expr| expr.accept(self) }

  DelayedObjectDerivation.new(self, node, *obj_manips) do
    checkpoint(node.location)
    obj_manips.map { |manip| manip.execute!; manip.result }.last
  end
end

#visit_compound_assignment_expression(node) ⇒ Object



472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/adlint/cc1/ctrlexpr.rb', line 472

def visit_compound_assignment_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_compound_assignment_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_equality_expression(node) ⇒ Object



400
401
402
403
404
# File 'lib/adlint/cc1/ctrlexpr.rb', line 400

def visit_equality_expression(node)
  checkpoint(node.location)
  ValueComparison.new(self, node, node.lhs_operand.accept(self),
                      node.rhs_operand.accept(self))
end

#visit_exclusive_or_expression(node) ⇒ Object



419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/adlint/cc1/ctrlexpr.rb', line 419

def visit_exclusive_or_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_exclusive_or_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_function_call_expression(node) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/adlint/cc1/ctrlexpr.rb', line 231

def visit_function_call_expression(node)
  checkpoint(node.location)
  obj_manip  = node.expression.accept(self)
  arg_manips = node.argument_expressions.map { |expr| expr.accept(self) }

  DelayedObjectDerivation.new(self, node, obj_manip, *arg_manips) do
    checkpoint(node.location)
    obj_manip.execute!
    args = arg_manips.map { |m| m.execute!; [m.result, m.node] }
    eval_function_call_expr(node, obj_manip.result, args)
  end
end

#visit_inclusive_or_expression(node) ⇒ Object



432
433
434
435
436
437
438
439
440
441
442
443
# File 'lib/adlint/cc1/ctrlexpr.rb', line 432

def visit_inclusive_or_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_inclusive_or_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_indirection_expression(node) ⇒ Object



317
318
319
320
321
322
323
324
325
326
# File 'lib/adlint/cc1/ctrlexpr.rb', line 317

def visit_indirection_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_indirection_expr(node, obj_manip.result)
  end
end

#visit_logical_and_expression(node) ⇒ Object



445
446
447
448
449
# File 'lib/adlint/cc1/ctrlexpr.rb', line 445

def visit_logical_and_expression(node)
  checkpoint(node.location)
  LogicalAnd.new(self, node, node.lhs_operand.accept(self),
                 node.rhs_operand.accept(self))
end

#visit_logical_or_expression(node) ⇒ Object



451
452
453
454
455
# File 'lib/adlint/cc1/ctrlexpr.rb', line 451

def visit_logical_or_expression(node)
  checkpoint(node.location)
  LogicalOr.new(self, node, node.lhs_operand.accept(self),
                node.rhs_operand.accept(self))
end

#visit_member_access_by_pointer_expression(node) ⇒ Object



255
256
257
258
259
260
261
262
263
264
# File 'lib/adlint/cc1/ctrlexpr.rb', line 255

def visit_member_access_by_pointer_expression(node)
  checkpoint(node.location)
  obj_manip = node.expression.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_member_access_by_pointer_expr(node, obj_manip.result)
  end
end

#visit_member_access_by_value_expression(node) ⇒ Object



244
245
246
247
248
249
250
251
252
253
# File 'lib/adlint/cc1/ctrlexpr.rb', line 244

def visit_member_access_by_value_expression(node)
  checkpoint(node.location)
  obj_manip = node.expression.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_member_access_by_value_expr(node, obj_manip.result)
  end
end

#visit_multiplicative_expression(node) ⇒ Object



355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/adlint/cc1/ctrlexpr.rb', line 355

def visit_multiplicative_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_multiplicative_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_postfix_decrement_expression(node) ⇒ Object



280
281
282
283
284
285
286
287
288
289
# File 'lib/adlint/cc1/ctrlexpr.rb', line 280

def visit_postfix_decrement_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_postfix_decrement_expr(node, obj_manip.result)
  end
end

#visit_postfix_increment_expression(node) ⇒ Object



269
270
271
272
273
274
275
276
277
278
# File 'lib/adlint/cc1/ctrlexpr.rb', line 269

def visit_postfix_increment_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_postfix_increment_expr(node, obj_manip.result)
  end
end

#visit_prefix_decrement_expression(node) ⇒ Object



304
305
306
307
308
309
310
311
312
313
# File 'lib/adlint/cc1/ctrlexpr.rb', line 304

def visit_prefix_decrement_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_prefix_decrement_expr(node, obj_manip.result)
  end
end

#visit_prefix_increment_expression(node) ⇒ Object



293
294
295
296
297
298
299
300
301
302
# File 'lib/adlint/cc1/ctrlexpr.rb', line 293

def visit_prefix_increment_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_prefix_increment_expr(node, obj_manip.result)
  end
end

#visit_relational_expression(node) ⇒ Object



394
395
396
397
398
# File 'lib/adlint/cc1/ctrlexpr.rb', line 394

def visit_relational_expression(node)
  checkpoint(node.location)
  ValueComparison.new(self, node, node.lhs_operand.accept(self),
                      node.rhs_operand.accept(self))
end

#visit_shift_expression(node) ⇒ Object



381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/adlint/cc1/ctrlexpr.rb', line 381

def visit_shift_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_shift_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_simple_assignment_expression(node) ⇒ Object



459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/adlint/cc1/ctrlexpr.rb', line 459

def visit_simple_assignment_expression(node)
  checkpoint(node.location)
  lhs_manip = node.lhs_operand.accept(self)
  rhs_manip = node.rhs_operand.accept(self)

  DelayedObjectDerivation.new(self, node, lhs_manip, rhs_manip) do
    checkpoint(node.location)
    lhs_manip.execute!
    rhs_manip.execute!
    eval_simple_assignment_expr(node, lhs_manip.result, rhs_manip.result)
  end
end

#visit_unary_arithmetic_expression(node) ⇒ Object



328
329
330
331
332
333
334
335
336
337
# File 'lib/adlint/cc1/ctrlexpr.rb', line 328

def visit_unary_arithmetic_expression(node)
  checkpoint(node.location)
  obj_manip = node.operand.accept(self)

  DelayedObjectDerivation.new(self, node, obj_manip) do
    checkpoint(node.location)
    obj_manip.execute!
    eval_unary_arithmetic_expr(node, obj_manip.result)
  end
end