Skip to content

Commit b17ed58

Browse files
author
Thomas Kiley
authored
Merge pull request #1555 from thk123/feature/remove-redundant-specalisation-code
[TG-1338] Remove redundant specialisation code
2 parents 9b34cdb + 51133db commit b17ed58

File tree

12 files changed

+96
-121
lines changed

12 files changed

+96
-121
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.

regression/cbmc-java/generics_symtab1/generics.java

-31
This file was deleted.

regression/cbmc-java/generics_symtab1/test.desc

-8
This file was deleted.

src/java_bytecode/generate_java_generic_type.cpp

-43
Original file line numberDiff line numberDiff line change
@@ -126,46 +126,3 @@ irep_idt generate_java_generic_typet::build_generic_tag(
126126

127127
return new_tag_buffer.str();
128128
}
129-
130-
131-
/// Activate the generic instantiation code.
132-
/// \param message_handler
133-
/// \param symbol_table The symbol table so far.
134-
void
135-
instantiate_generics(
136-
message_handlert &message_handler,
137-
symbol_tablet &symbol_table)
138-
{
139-
generate_java_generic_typet instantiate_generic_type(message_handler);
140-
// check out the symbols in the symbol table at this point to see if we
141-
// have a a generic type in.
142-
for(const auto &symbol : symbol_table.symbols)
143-
{
144-
if(symbol.second.type.id()==ID_struct)
145-
{
146-
auto symbol_struct=to_struct_type(symbol.second.type);
147-
auto &components=symbol_struct.components();
148-
149-
for(const auto &component : components)
150-
{
151-
if(is_java_generic_type(component.type()))
152-
{
153-
const auto &type_vars=to_java_generic_type(component.type()).
154-
generic_type_variables();
155-
156-
// Before we can instantiate a generic component, we need
157-
// its type variables to be instantiated parameters
158-
if(all_of(type_vars.cbegin(), type_vars.cend(),
159-
[](const typet &type)
160-
{
161-
return is_java_generic_inst_parameter(type);
162-
}))
163-
{
164-
instantiate_generic_type(
165-
to_java_generic_type(component.type()), symbol_table);
166-
}
167-
}
168-
}
169-
}
170-
}
171-
}

src/java_bytecode/generate_java_generic_type.h

-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,4 @@ class generate_java_generic_typet
3131
message_handlert &message_handler;
3232
};
3333

34-
void instantiate_generics(
35-
message_handlert &message_handler,
36-
symbol_tablet &symbol_table);
37-
3834
#endif // CPROVER_JAVA_BYTECODE_GENERATE_JAVA_GENERIC_TYPE_H

src/java_bytecode/java_bytecode_language.cpp

+1-14
Original file line numberDiff line numberDiff line change
@@ -240,21 +240,8 @@ bool java_bytecode_languaget::typecheck(
240240
get_message_handler());
241241

242242
// now typecheck all
243-
bool res=java_bytecode_typecheck(
243+
return java_bytecode_typecheck(
244244
symbol_table, get_message_handler(), string_refinement_enabled);
245-
// NOTE (FOTIS): There is some unintuitive logic here, where
246-
// java_bytecode_check will return TRUE if typechecking failed, and FALSE
247-
// if everything went well...
248-
if(res)
249-
{
250-
// there is no point in continuing to concretise
251-
// the generic types if typechecking failed.
252-
return res;
253-
}
254-
255-
instantiate_generics(get_message_handler(), symbol_table);
256-
257-
return res;
258245
}
259246

260247
bool java_bytecode_languaget::generate_support_functions(

unit/java_bytecode/generate_concrete_generic_type/generate_java_generic_type.cpp

+31-21
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,33 @@
99

1010
#include <testing-utils/catch.hpp>
1111
#include <testing-utils/load_java_class.h>
12+
#include <testing-utils/require_type.h>
1213

1314
#include <util/symbol_table.h>
1415

1516
#include <java_bytecode/generate_java_generic_type.h>
1617
#include <testing-utils/require_type.h>
18+
#include <testing-utils/generic_utils.h>
1719
#include <util/ui_message.h>
1820

21+
/// Helper function to specalise a generic class from a named component of a
22+
/// named class
23+
/// \param class_name: The name of the class that has a generic component.
24+
/// \param component_name: The name of the generic component
25+
/// \param new_symbol_table: The symbol table to use.
26+
void specialise_generic_from_component(
27+
const irep_idt &class_name,
28+
const irep_idt &component_name,
29+
symbol_tablet &new_symbol_table)
30+
{
31+
const symbolt &harness_symbol = new_symbol_table.lookup_ref(class_name);
32+
const struct_typet::componentt &harness_component =
33+
require_type::require_component(
34+
to_struct_type(harness_symbol.type), component_name);
35+
generic_utils::specialise_generic(
36+
to_java_generic_type(harness_component.type()), new_symbol_table);
37+
}
38+
1939
SCENARIO(
2040
"generate_java_generic_type_from_file",
2141
"[core][java_bytecode][generate_java_generic_type]")
@@ -30,6 +50,9 @@ SCENARIO(
3050
load_java_class("generic_two_fields",
3151
"./java_bytecode/generate_concrete_generic_type");
3252

53+
specialise_generic_from_component(
54+
"java::generic_two_fields", "belem", new_symbol_table);
55+
3356
REQUIRE(new_symbol_table.has_symbol(expected_symbol));
3457
THEN("The class should contain two instantiated fields.")
3558
{
@@ -77,6 +100,9 @@ SCENARIO(
77100
load_java_class("generic_two_parameters",
78101
"./java_bytecode/generate_concrete_generic_type");
79102

103+
specialise_generic_from_component(
104+
"java::generic_two_parameters", "bomb", new_symbol_table);
105+
80106
REQUIRE(new_symbol_table.has_symbol(
81107
"java::generic_two_parameters$KeyValuePair"));
82108
THEN("The class should have two subtypes in the vector of the types of "
@@ -100,27 +126,6 @@ SCENARIO(
100126
}
101127
}
102128

103-
104-
SCENARIO(
105-
"generate_java_generic_type_from_file_uninstantiated_param",
106-
"[core][java_bytecode][generate_java_generic_type]")
107-
{
108-
GIVEN("A generic java type with a field that refers to another generic with"
109-
" an uninstantiated parameter.")
110-
{
111-
symbol_tablet new_symbol_table=
112-
load_java_class("generic_unknown_field",
113-
"./java_bytecode/generate_concrete_generic_type");
114-
115-
// It's illegal to create an instantiation of a field that refers
116-
// to a (still) uninstantiated generic class, so this is checking that
117-
// this hasn't happened.
118-
REQUIRE_FALSE(new_symbol_table.has_symbol
119-
("java::generic_unknown_field$element<T>"));
120-
}
121-
}
122-
123-
124129
SCENARIO(
125130
"generate_java_generic_type_from_file_two_instances",
126131
"[core][java_bytecode][generate_java_generic_type]")
@@ -140,6 +145,11 @@ SCENARIO(
140145
load_java_class("generic_two_instances",
141146
"./java_bytecode/generate_concrete_generic_type");
142147

148+
specialise_generic_from_component(
149+
"java::generic_two_instances", "bool_element", new_symbol_table);
150+
specialise_generic_from_component(
151+
"java::generic_two_instances", "int_element", new_symbol_table);
152+
143153
REQUIRE(new_symbol_table.has_symbol(first_expected_symbol));
144154
auto first_symbol=new_symbol_table.lookup(first_expected_symbol);
145155
REQUIRE(first_symbol->type.id()==ID_struct);

unit/testing-utils/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
SRC = \
22
c_to_expr.cpp \
3+
generic_utils.cpp \
34
load_java_class.cpp \
45
require_expr.cpp \
56
require_goto_statements.cpp \

unit/testing-utils/generic_utils.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include <util/ui_message.h>
10+
#include <java_bytecode/generate_java_generic_type.h>
11+
#include "generic_utils.h"
12+
#include "catch.hpp"
13+
#include "require_type.h"
14+
15+
/// Generic a specalised version of a Java generic class and add it to the
16+
/// symbol table.
17+
/// \param example_type: A reference type that is a specalised generic to use
18+
/// as the base for the specalised version (e.g. a variable of type
19+
/// `Generic<Integer>`
20+
/// \param new_symbol_table: The symbol table to store the new type in
21+
void generic_utils::specialise_generic(
22+
const java_generic_typet &example_type,
23+
symbol_tablet &new_symbol_table)
24+
{
25+
// Should be a fully instantiated generic type
26+
REQUIRE(
27+
std::all_of(
28+
example_type.generic_type_variables().begin(),
29+
example_type.generic_type_variables().end(),
30+
is_java_generic_inst_parameter));
31+
32+
// Generate the specialised version.
33+
ui_message_handlert message_handler;
34+
generate_java_generic_typet instantiate_generic_type(message_handler);
35+
instantiate_generic_type(
36+
to_java_generic_type(example_type), new_symbol_table);
37+
}

unit/testing-utils/generic_utils.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Utility methods for dealing with Java generics in unit tests
11+
12+
#ifndef CPROVER_TESTING_UTILS_GENERIC_UTILS_H
13+
#define CPROVER_TESTING_UTILS_GENERIC_UTILS_H
14+
15+
#include <util/irep.h>
16+
#include <util/symbol_table.h>
17+
18+
// NOLINTNEXTLINE(readability/namespace)
19+
namespace generic_utils
20+
{
21+
void specialise_generic(
22+
const java_generic_typet &example_type,
23+
symbol_tablet &new_symbol_table);
24+
}
25+
26+
#endif // CPROVER_TESTING_UTILS_GENERIC_UTILS_H

0 commit comments

Comments
 (0)