Skip to content

Commit 22de73a

Browse files
committed
Merge branch 'develop' of https://github.com/diffblue/cbmc into JohnDumbell/Update-Assertion-Validation
2 parents 6d4bd46 + 0b17511 commit 22de73a

File tree

70 files changed

+638
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+638
-177
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
[CProver Wiki](http://www.cprover.org/wiki)
55

6+
[CProver Documentation](http://cprover.diffblue.com)
7+
68
About
79
=====
810

doc/architectural/cprover-architecture-overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
\author Martin Brain, Peter Schrammel
55

6-
# Overview of CPROVER Directories
6+
\section overview-dirs Overview of CPROVER Directories
77

88
## `src/`
99

@@ -90,7 +90,7 @@ The `–help` option gives instructions for use and the
9090
format of the description files.
9191

9292

93-
# General Information
93+
\section general-info General Information
9494

9595
First off, read the \ref cbmc-user-manual "CBMC User Manual". It describes
9696
how to get, build and use CBMC. This document covers the

doc/satabs-user-manual.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
\ingroup module_hidden
12
\page other_documentation Other Documentation
23

34
\section satabs SATABS

regression/cbmc-java/reachability-slice/test.desc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE symex-driven-lazy-loading-expected-failure
22
A.class
33
--reachability-slice --show-goto-functions --property 'java::A.foo:(I)V.coverage.3' --cover location
44
1001
@@ -9,3 +9,5 @@ A.class
99
--
1010
Note: 1002 might and might not be removed, based on where the assertion for coverage resides.
1111
At the time of writing of this test, 1002 is removed.
12+
13+
Doesn't work with symex-driven lazy loading because the reachability slicer is a whole-program pass.
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE symex-driven-lazy-loading-expected-failure
22
A.class
33
--reachability-slice-fb --show-goto-functions --property 'java::A.foo:(I)V.coverage.3' --cover location
44
1001
@@ -7,3 +7,5 @@ A.class
77
1005
88
--
99
1004
10+
--
11+
Doesn't work with symex-driven lazy loading because the reachability slicer is a whole-program pass.
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
CORE
1+
CORE symex-driven-lazy-loading-expected-failure
22
A.class
33
--reachability-slice --show-goto-functions --cover location
44
1001
55
1002
66
1003
77
1004
88
1005
9+
--
10+
--
11+
Doesn't work with symex-driven lazy loading because the reachability slicer is a whole-program pass.

src/java_bytecode/generic_parameter_specialization_map_keys.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,21 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_pointer(
9999
pointer_type.subtype().get(ID_identifier) ==
100100
pointer_subtype_struct.get(ID_name));
101101

102-
const java_generic_typet &generic_pointer =
103-
to_java_generic_type(pointer_type);
104-
105-
// If the pointer points to an incomplete class, don't treat the generics
106-
if(!pointer_subtype_struct.get_bool(ID_incomplete_class))
102+
// If the pointer points to:
103+
// - an incomplete class or
104+
// - a class that is neither generic nor implicitly generic (this
105+
// may be due to unsupported class signature)
106+
// then ignore the generic types in the pointer and do not add any pairs.
107+
// TODO TG-1996 should decide how mocking and generics should work
108+
// together. Currently an incomplete class is never marked as generic. If
109+
// this changes in TG-1996 then the condition below should be updated.
110+
if(
111+
!pointer_subtype_struct.get_bool(ID_incomplete_class) &&
112+
(is_java_generic_class_type(pointer_subtype_struct) ||
113+
is_java_implicitly_generic_class_type(pointer_subtype_struct)))
107114
{
108-
PRECONDITION(
109-
is_java_generic_class_type(pointer_subtype_struct) ||
110-
is_java_implicitly_generic_class_type(pointer_subtype_struct));
115+
const java_generic_typet &generic_pointer =
116+
to_java_generic_type(pointer_type);
111117
const std::vector<java_generic_parametert> &generic_parameters =
112118
get_all_generic_parameters(pointer_subtype_struct);
113119

@@ -135,14 +141,23 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_symbol(
135141
const symbol_typet &symbol_type,
136142
const typet &symbol_struct)
137143
{
138-
if(is_java_generic_symbol_type(symbol_type))
144+
// If the struct is:
145+
// - an incomplete class or
146+
// - a class that is neither generic nor implicitly generic (this
147+
// may be due to unsupported class signature)
148+
// then ignore the generic types in the symbol_type and do not add any pairs.
149+
// TODO TG-1996 should decide how mocking and generics should work
150+
// together. Currently an incomplete class is never marked as generic. If
151+
// this changes in TG-1996 then the condition below should be updated.
152+
if(
153+
is_java_generic_symbol_type(symbol_type) &&
154+
!symbol_struct.get_bool(ID_incomplete_class) &&
155+
(is_java_generic_class_type(symbol_struct) ||
156+
is_java_implicitly_generic_class_type(symbol_struct)))
139157
{
140-
java_generic_symbol_typet generic_symbol =
158+
const java_generic_symbol_typet &generic_symbol =
141159
to_java_generic_symbol_type(symbol_type);
142160

143-
PRECONDITION(
144-
is_java_generic_class_type(symbol_struct) ||
145-
is_java_implicitly_generic_class_type(symbol_struct));
146161
const std::vector<java_generic_parametert> &generic_parameters =
147162
get_all_generic_parameters(symbol_struct);
148163

src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,12 @@ void java_bytecode_convert_classt::convert(const classt &c)
202202
}
203203
class_type=generic_class_type;
204204
}
205-
catch(unsupported_java_class_signature_exceptiont)
205+
catch(const unsupported_java_class_signature_exceptiont &e)
206206
{
207-
warning() << "we currently don't support parsing for example double "
208-
"bounded, recursive and wild card generics" << eom;
207+
warning() << "Class: " << c.name
208+
<< "\n could not parse signature: " << c.signature.value()
209+
<< "\n " << e.what() << "\n ignoring that the class is generic"
210+
<< eom;
209211
}
210212
}
211213

@@ -253,11 +255,12 @@ void java_bytecode_convert_classt::convert(const classt &c)
253255
base, superclass_ref.value(), qualified_classname);
254256
class_type.add_base(generic_base);
255257
}
256-
catch(unsupported_java_class_signature_exceptiont)
258+
catch(const unsupported_java_class_signature_exceptiont &e)
257259
{
258-
debug() << "unsupported generic superclass signature "
259-
<< id2string(*superclass_ref)
260-
<< " falling back on using the descriptor" << eom;
260+
warning() << "Superclass: " << c.extends << " of class: " << c.name
261+
<< "\n could not parse signature: " << superclass_ref.value()
262+
<< "\n " << e.what()
263+
<< "\n ignoring that the superclass is generic" << eom;
261264
class_type.add_base(base);
262265
}
263266
}
@@ -292,11 +295,12 @@ void java_bytecode_convert_classt::convert(const classt &c)
292295
base, interface_ref.value(), qualified_classname);
293296
class_type.add_base(generic_base);
294297
}
295-
catch(unsupported_java_class_signature_exceptiont)
298+
catch(const unsupported_java_class_signature_exceptiont &e)
296299
{
297-
debug() << "unsupported generic interface signature "
298-
<< id2string(*interface_ref)
299-
<< " falling back on using the descriptor" << eom;
300+
warning() << "Interface: " << interface << " of class: " << c.name
301+
<< "\n could not parse signature: " << interface_ref.value()
302+
<< "\n " << e.what()
303+
<< "\n ignoring that the interface is generic" << eom;
300304
class_type.add_base(base);
301305
}
302306
}

src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,21 @@ code_typet member_type_lazy(
286286
}
287287
else
288288
{
289-
message.warning() << "method: " << class_name << "." << method_name
290-
<< "\n signature: " << signature.value() << "\n descriptor: "
291-
<< descriptor << "\n different number of parameters, reverting to "
292-
"descriptor" << message.eom;
289+
message.warning() << "Method: " << class_name << "." << method_name
290+
<< "\n signature: " << signature.value()
291+
<< "\n descriptor: " << descriptor
292+
<< "\n different number of parameters, reverting to "
293+
"descriptor"
294+
<< message.eom;
293295
}
294296
}
295-
catch(unsupported_java_class_signature_exceptiont &e)
297+
catch(const unsupported_java_class_signature_exceptiont &e)
296298
{
297-
message.warning() << "method: " << class_name << "." << method_name
298-
<< "\n could not parse signature: " << signature.value() << "\n "
299-
<< e.what() << "\n" << " reverting to descriptor: "
300-
<< descriptor << message.eom;
299+
message.warning() << "Method: " << class_name << "." << method_name
300+
<< "\n could not parse signature: " << signature.value()
301+
<< "\n " << e.what() << "\n"
302+
<< " reverting to descriptor: " << descriptor
303+
<< message.eom;
301304
}
302305
}
303306
return to_code_type(member_type_from_descriptor);

src/java_bytecode/java_bytecode_language.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ class java_bytecode_languaget:public languaget
172172

173173
private:
174174
const std::unique_ptr<const select_pointer_typet> pointer_type_selector;
175+
176+
/// Maps synthetic method names on to the particular type of synthetic method
177+
/// (static initializer, initializer wrapper, etc). For full documentation see
178+
/// synthetic_method_map.h
175179
synthetic_methods_mapt synthetic_methods;
176180
stub_global_initializer_factoryt stub_global_initializer_factory;
177181
class_hierarchyt class_hierarchy;

src/java_bytecode/synthetic_methods_map.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*******************************************************************\
22
3-
Module: Java Static Initializers
3+
Module: Synthetic methods map
44
55
Author: Chris Smowton, [email protected]
66
@@ -9,12 +9,31 @@ Author: Chris Smowton, [email protected]
99
#ifndef CPROVER_JAVA_BYTECODE_SYNTHETIC_METHODS_MAP_H
1010
#define CPROVER_JAVA_BYTECODE_SYNTHETIC_METHODS_MAP_H
1111

12+
/// \file
13+
/// Synthetic methods are particular methods internally generated by the
14+
/// Java frontend, including thunks to ensure static initializers are run once
15+
/// and initializers created for unknown / stub types. Compare normal methods,
16+
/// which are translated from Java bytecode. This file provides an
17+
/// enumeration specifying the kind of a particular synthetic method and a
18+
/// common type of a map giving a collection of synthetic methods.
19+
/// Functions stubs and array.clone() functions are also generated by the Java
20+
/// frontend but are not recorded using this framework, but may be in future.
21+
22+
/// Synthetic method kinds.
1223
enum class synthetic_method_typet
1324
{
25+
/// A static initializer wrapper
26+
/// (code of the form `if(!already_run) clinit(); already_run = true;`)
27+
/// These are generated for both user and stub types, to ensure the actual
28+
/// static initializer is only run once on any given path.
1429
STATIC_INITIALIZER_WRAPPER,
30+
/// A generated (synthetic) static initializer function for a stub type.
31+
/// Because we don't have the bytecode for a stub type (by definition), we
32+
/// generate a static initializer function to initialize its static fields.
1533
STUB_CLASS_STATIC_INITIALIZER
1634
};
1735

36+
/// Maps method names on to a synthetic method kind.
1837
typedef std::unordered_map<irep_idt, synthetic_method_typet, irep_id_hash>
1938
synthetic_methods_mapt;
2039

src/jbmc/jbmc_parse_options.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,9 @@ void jbmc_parse_optionst::get_command_line_options(optionst &options)
385385
for(const char *opt :
386386
{ "nondet-static",
387387
"full-slice",
388-
"lazy-methods" })
388+
"lazy-methods",
389+
"reachability-slice",
390+
"reachability-slice-fb" })
389391
{
390392
if(cmdline.isset(opt))
391393
{

unit/goto-programs/goto_program_generics/GenericBases.java

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
1-
// Helper classes
2-
class Wrapper<T> {
3-
public T field;
4-
}
5-
6-
class IntWrapper {
7-
public int i;
8-
}
9-
10-
class TwoWrapper<K, V> {
11-
public K first;
12-
public V second;
13-
}
14-
15-
interface InterfaceWrapper<T> {
16-
public T method(T t);
17-
}
18-
191
// A class extending a generic class instantiated with a standard library class
202
class SuperclassInst extends Wrapper<Integer> {
213
public void foo() {
@@ -24,14 +6,14 @@ public void foo() {
246
}
257

268
// A class extending a generic class instantiated with a user-defined class
27-
class SuperclassInst2 extends Wrapper<IntWrapper> {
9+
class SuperclassInst2 extends Wrapper<IWrapper> {
2810
public void foo() {
2911
this.field.i = 5;
3012
}
3113
}
3214

3315
// A class extending an instantiated nested generic class
34-
class SuperclassInst3 extends Wrapper<Wrapper<IntWrapper>> {
16+
class SuperclassInst3 extends Wrapper<Wrapper<IWrapper>> {
3517
public void foo() {
3618
this.field.field.i = 5;
3719
}
@@ -54,7 +36,7 @@ public void foo() {
5436

5537
// A generic class extending a generic class with both instantiated and
5638
// uninstantiated parameters
57-
class SuperclassMixed<U> extends TwoWrapper<U,IntWrapper> {
39+
class SuperclassMixed<U> extends PairWrapper<U,IWrapper> {
5840
public void foo(U value) {
5941
this.first = value;
6042
this.second.i = 5;
@@ -99,7 +81,7 @@ public void foo(U value) {
9981
}
10082
public Inner inner;
10183

102-
class InnerGen<T> extends TwoWrapper<U,T> {
84+
class InnerGen<T> extends PairWrapper<U,T> {
10385
public void foo(U uvalue, T tvalue) {
10486
this.first = uvalue;
10587
this.second = tvalue;
@@ -113,11 +95,23 @@ class InnerThree extends Inner {
11395
}
11496
class SuperclassInnerUninstTest
11597
{
116-
SuperclassInnerUninst<IntWrapper> f;
98+
SuperclassInnerUninst<IWrapper> f;
11799
public void foo() {
118-
IntWrapper x = new IntWrapper();
100+
IWrapper x = new IWrapper(0);
119101
f.inner.foo(x);
120102
f.inner_gen.foo(x,true);
121103
f.inner_three.foo(x);
122104
}
123105
}
106+
107+
class SuperclassUnsupported extends UnsupportedWrapper1<SuperclassUnsupported> {
108+
public void foo() {
109+
this.field = new SuperclassUnsupported();
110+
}
111+
}
112+
113+
class SuperclassOpaque extends OpaqueWrapper<IWrapper> {
114+
public void foo() {
115+
this.field.i = 5;
116+
}
117+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)