File: require_parse_tree.cpp

package info (click to toggle)
cbmc 6.6.0-4
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 153,852 kB
  • sloc: cpp: 386,459; ansic: 114,466; java: 28,405; python: 6,003; yacc: 4,552; makefile: 4,041; lex: 2,487; xml: 2,388; sh: 2,050; perl: 557; pascal: 184; javascript: 163; ada: 36
file content (108 lines) | stat: -rw-r--r-- 3,940 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*******************************************************************\

Module: Unit test utilities

Author: Diffblue Ltd.

\*******************************************************************/

#include "require_parse_tree.h"

#include <testing-utils/use_catch.h>

#include <iterator>

/// Find in the parsed class a specific entry within the
/// lambda_method_handle_map with a matching descriptor. Will fail if no
/// matching lambda entry found.
/// \param parsed_class: the class to inspect
/// \param lambda_method_ref: the reference/descriptor of the lambda method
///   to which this lambda entry points to, must be unique
/// \return
require_parse_tree::lambda_method_handlet
require_parse_tree::require_lambda_entry_for_descriptor(
  const java_bytecode_parse_treet::classt &parsed_class,
  const std::string &lambda_method_ref)
{
  typedef java_bytecode_parse_treet::classt::lambda_method_handle_mapt::
    value_type lambda_method_entryt;

  INFO("Looking for entry with lambda_method_ref: " << lambda_method_ref);
  const irep_idt method_ref_with_prefix =
    "java::" + id2string(lambda_method_ref);

  std::vector<lambda_method_entryt> matches;
  std::copy_if(
    parsed_class.lambda_method_handle_map.begin(),
    parsed_class.lambda_method_handle_map.end(),
    back_inserter(matches),
    [&method_ref_with_prefix](const lambda_method_entryt &entry) { //NOLINT
      return (
        entry.second.get_method_descriptor().get_identifier() ==
        method_ref_with_prefix);
    });
  REQUIRE(matches.size() == 1);
  return matches.at(0).second;
}

/// Finds a specific method in the parsed class with a matching name.
/// \param parsed_class: The class
/// \param method_name: The name of the method to look for
/// \return The methodt structure with the corresponding name
const require_parse_tree::methodt require_parse_tree::require_method(
  const java_bytecode_parse_treet::classt &parsed_class,
  const irep_idt &method_name)
{
  const auto method = std::find_if(
    parsed_class.methods.begin(),
    parsed_class.methods.end(),
    [&method_name](const java_bytecode_parse_treet::methodt &method) {
      return method.name == method_name;
    });

  INFO("Looking for method: " << method_name);
  std::ostringstream found_methods;
  for(const auto &entry : parsed_class.methods)
  {
    found_methods << id2string(entry.name) << std::endl;
  }
  INFO("Found methods:\n" << found_methods.str());

  REQUIRE(method != parsed_class.methods.end());

  return *method;
}

/// Verify whether a given methods instructions match an expectation
/// \param expected_instructions: The expected instructions for a given method
/// \param instructions: The instructions of a method
void require_parse_tree::require_instructions_match_expectation(
  const expected_instructionst &expected_instructions,
  const java_bytecode_parse_treet::methodt::instructionst instructions)
{
  REQUIRE(instructions.size() == expected_instructions.size());
  auto actual_instruction_it = instructions.begin();
  for(const auto &expected_instruction : expected_instructions)
  {
    expected_instruction.require_instructions_equal(*actual_instruction_it);
    ++actual_instruction_it;
  }
}

/// Check whether a given instruction matches an expectation of the instruction
/// \param actual_instruction: The instruction to check
void require_parse_tree::expected_instructiont::require_instructions_equal(
  java_bytecode_parse_treet::instructiont actual_instruction) const
{
  REQUIRE(
    instruction_mnemoic == bytecode_info[actual_instruction.bytecode].mnemonic);
  REQUIRE(instruction_arguments.size() == actual_instruction.args.size());
  auto actual_arg_it = actual_instruction.args.begin();
  for(const exprt &expected_arg : actual_instruction.args)
  {
    INFO("Expected argument" << expected_arg.pretty());
    INFO("Actual argument" << actual_arg_it->pretty());
    REQUIRE(*actual_arg_it == expected_arg);
    ++actual_arg_it;
  }
}