Skip to content

Commit 5e54406

Browse files
Merge pull request #38 from diffblue/sv-comp23
SVCOMP'23 updates
2 parents 7973361 + 0ac3897 commit 5e54406

24 files changed

+13607
-33
lines changed

src/main/java/java/lang/Class.java

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,58 @@
3939

4040
import org.cprover.CProver;
4141

42+
/**
43+
* Instances of the class {@code Class} represent classes and
44+
* interfaces in a running Java application. An enum is a kind of
45+
* class and an annotation is a kind of interface. Every array also
46+
* belongs to a class that is reflected as a {@code Class} object
47+
* that is shared by all arrays with the same element type and number
48+
* of dimensions. The primitive Java types ({@code boolean},
49+
* {@code byte}, {@code char}, {@code short},
50+
* {@code int}, {@code long}, {@code float}, and
51+
* {@code double}), and the keyword {@code void} are also
52+
* represented as {@code Class} objects.
53+
*
54+
* <p> {@code Class} has no public constructor. Instead {@code Class}
55+
* objects are constructed automatically by the Java Virtual Machine as classes
56+
* are loaded and by calls to the {@code defineClass} method in the class
57+
* loader.
58+
*
59+
* <p> The following example uses a {@code Class} object to print the
60+
* class name of an object:
61+
*
62+
* <blockquote><pre>
63+
* void printClassName(Object obj) {
64+
* System.out.println("The class of " + obj +
65+
* " is " + obj.getClass().getName());
66+
* }
67+
* </pre></blockquote>
68+
*
69+
* <p> It is also possible to get the {@code Class} object for a named
70+
* type (or for void) using a class literal. See Section 15.8.2 of
71+
* <cite>The Java&trade; Language Specification</cite>.
72+
* For example:
73+
*
74+
* <blockquote>
75+
* {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
76+
* </blockquote>
77+
*
78+
* @param <T> the type of the class modeled by this {@code Class}
79+
* object. For example, the type of {@code String.class} is {@code
80+
* Class<String>}. Use {@code Class<?>} if the class being modeled is
81+
* unknown.
82+
*
83+
* @author unascribed
84+
* @see java.lang.ClassLoader#defineClass(byte[], int, int)
85+
* @since JDK1.0
86+
*
87+
* @diffblue.limitedSupport
88+
* Generated tests that create an instance of Class will be incorrect:
89+
* <ul>
90+
* <li>IllegalAccessError error when attempting to set the java.lang.class via reflection</li>
91+
* <li>When JBMC mocks java.lang.Class, it causes IllegalAccessError</li>
92+
* </ul>
93+
*/
4294
public final class Class<T> {
4395

4496
private Class() {}
@@ -55,6 +107,13 @@ private Class() {}
55107
private boolean cproverIsMemberClass;
56108
private boolean cproverIsEnum;
57109

110+
// TODO: these fields are to enforce singleton semantics of
111+
// Class objects as returned by Object.getClass() and Class.forName()
112+
// The size is currently hard-coded which may lead to incorrect results.
113+
// A map could be used here in future.
114+
private static String[] cproverClassNames = new String[8];
115+
private static Class<?>[] cproverClassInstances = new Class<?>[8];
116+
58117
public String toString() {
59118
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
60119
+ getName();
@@ -111,9 +170,25 @@ public String toGenericString() {
111170
// forName method. The goal is to correctly model combinations of forName
112171
// and getName, but precisely following the JDK behaviour is more involved.
113172
public static Class<?> forName(String className) {
114-
Class c=new Class();
115-
c.name=className;
116-
return c;
173+
CProver.notModelled();
174+
throw new AssertionError();
175+
/*
176+
String foundName = null;
177+
for (int i = 0; i < cproverClassNames.length; ++i) {
178+
String currentName = cproverClassNames[i];
179+
if (currentName == null) {
180+
Class<?> c = new Class();
181+
c.name = className;
182+
cproverClassNames[i] = className;
183+
cproverClassInstances[i] = c;
184+
return c;
185+
}
186+
if (className.equals(currentName)) {
187+
return cproverClassInstances[i];
188+
}
189+
}
190+
return CProver.nondetWithoutNullForNotModelled();
191+
*/
117192
}
118193

119194
public static Class<?> forName(String name, boolean initialize,
@@ -205,7 +280,7 @@ ClassLoader getClassLoader0() {
205280
// DIFFBLUE MODEL LIBRARY The real java.lang.Class stores a
206281
// `private final ClassLoader classLoader` which is initialised by the
207282
// jvm rather than by the constructor of this object.
208-
// TODO test-gen should understand this method natively.
283+
// TODO JBMC should understand this method natively.
209284
return null;
210285
}
211286

@@ -453,6 +528,7 @@ private static boolean desiredAssertionStatus0(Class<?> clazz) {
453528
protected void cproverNondetInitialize() {
454529
CProver.assume(name != null);
455530
CProver.assume(enumConstantDirectory == null);
531+
CProver.assume(classValueMap == null);
456532
}
457533

458534
// DIFFBLUE MODEL LIBRARY
@@ -607,6 +683,13 @@ public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMe
607683
return new Method(this, name, parameterTypes);
608684
}
609685

686+
// DIFFBLUE MODEL LIBRARY
687+
// This field is never read in our model. We include them because ClassValue
688+
// (in the java library, not our models) references it, so it is needed to
689+
// make ClassValue compile.
690+
// transient ClassValue.ClassValueMap classValueMap;
691+
transient ClassValue.ClassValueMap classValueMap = null;
692+
610693
/**
611694
* Returns the {@code Class} representing the component type of an
612695
* array. If this class does not represent an array class this method
@@ -615,10 +698,12 @@ public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMe
615698
* @return the {@code Class} representing the component type of this
616699
* class if this class is an array
617700
* @see java.lang.reflect.Array
618-
* @since 1.1
701+
* @since JDK1.1
702+
* @diffblue.noSupport
619703
*/
704+
// public native Class<?> getComponentType();
620705
public Class<?> getComponentType() {
621706
CProver.notModelled();
622-
return CProver.nondetWithoutNullForNotModelled();
707+
return CProver.nondetWithNullForNotModelled();
623708
}
624709
}

src/main/java/java/lang/Double.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ public static int hashCode(double value) {
816816
* @diffblue.fullSupport
817817
*
818818
* Until the native method doubleToRawLongBits(D) is implemented in
819-
* CBMC, this model will allow test generation for checking equality
819+
* CBMC, this model will allow JBMC for checking equality
820820
* between two Doubles.
821821
*/
822822
public boolean equals(Object obj) {

src/main/java/java/lang/Float.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ public static int hashCode(float value) {
716716
* @diffblue.fullSupport
717717
*
718718
* Until the native method floatToRawIntBits(F) is implemented in
719-
* CBMC, this model will allow test generation for checking equality
719+
* CBMC, this model will allow JBMC for checking equality
720720
* between two Floats.
721721
*/
722722
public boolean equals(Object obj) {

src/main/java/java/lang/Math.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,10 @@ public static double log10(double a) {
364364
* result of sqrt is equal to the original number, which is not always
365365
* true. As a result, the solver will return UNSAT in many cases.
366366
* For instance, {@code Math.sqrt(2.0)} will cause the solver to be UNSAT.
367-
* Reported in: TG-5598
368367
*
369368
* Also, there are precision issues on very small numbers. For instance,
370369
* for values between 0 and {@code 0x0.0000000000001p-900}, the sqrt method
371370
* is likely to not be equal to the result of the real Math.sqrt method.
372-
* Reported in: TG-5602
373371
*/
374372
public static double sqrt(double a) {
375373
// return StrictMath.sqrt(a); // default impl. delegates to StrictMath

src/main/java/java/lang/String.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,8 +2996,7 @@ public String replaceAll(String regex, String replacement)
29962996
{
29972997
// return Pattern.compile(regex).matcher(this).replaceAll(replacement);
29982998
// DIFFBLUE MODELS LIBRARY: we assume the expression is just a string literal
2999-
CProver.assume(
3000-
regex.indexOf('[') == -1 &&
2999+
if (regex.indexOf('[') == -1 &&
30013000
regex.indexOf(']') == -1 &&
30023001
regex.indexOf('.') == -1 &&
30033002
regex.indexOf('\\') == -1 &&
@@ -3010,8 +3009,12 @@ public String replaceAll(String regex, String replacement)
30103009
regex.indexOf('}') == -1 &&
30113010
regex.indexOf('|') == -1 &&
30123011
regex.indexOf('(') == -1 &&
3013-
regex.indexOf(')') == -1);
3014-
return replace(regex, replacement);
3012+
regex.indexOf(')') == -1) {
3013+
return replace(regex, replacement);
3014+
} else {
3015+
CProver.notModelled();
3016+
return CProver.nondetWithNullForNotModelled();
3017+
}
30153018
}
30163019

30173020
/**
@@ -4330,7 +4333,7 @@ public static String valueOf(float f) {
43304333
*/
43314334
public static String valueOf(double d) {
43324335
// string solver only knows how to convert floats to string
4333-
return CProverString.toString(d);
4336+
return CProverString.toString((float)d);
43344337
// return Double.toString(d);
43354338
}
43364339

src/main/java/java/lang/StringBuffer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ public synchronized void setCharAt(int index, char ch) {
333333

334334
/**
335335
* @diffblue.limitedSupport
336-
* This method can be slow to generate tests due to TG-2866 and is
336+
* This method can be slow to generate tests due to an issue and is
337337
* also limited by which {@code toString()} methods have been modelled.
338338
*/
339339
@Override

src/main/java/java/lang/StringBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public StringBuilder(CharSequence seq) {
156156

157157
/**
158158
* @diffblue.limitedSupport
159-
* This method can be slow to generate tests due to TG-2866 and is
159+
* This method can be slow to generate tests due to an issue and is
160160
* also limited by which {@code toString()} methods have been modelled.
161161
*/
162162
@Override

0 commit comments

Comments
 (0)