SDA SE Wiki

Software Engineering for Smart Data Analytics & Smart Data Analytics for Software Engineering

User Tools

Site Tools


Bug Cor 1

Inspired by

Original Description

“This cast will always throw a ClassCastException. FindBugs tracks type information from instanceof checks, and also uses more precise information about the types of values returned from methods and loaded from fields. Thus, it may have more precise information that just the declared type of a variable, and can use this to determine that a cast will always throw an exception at runtime.” – 2013-10-13

Detailed Description

A common need in strongly typed languages is to convert a value of a certain type into a different type. If the destination type is not equal to or is not a supertype of the source type, a ClassCastException will be thrown.

In most instances, the Java Compiler is unable to validate whether the cast is valid, since the values being cast usually change in runtime. In some cases, however, it is possible to deduct the type of the value to be cast, extracting information from instance of checks, return types of methods and types of fields (results obtained through Points-to Analysis might also be used), which allows impossible casts to be detected prior to runtime.

1. conversions type categories:

A specific conversion from type S to type T allows an expression of type S to be treated at compile time as if it had type T instead. For convenience of description, the specific conversions that are possible in the Java programming language are grouped into several broad categories:

1.1. Identity conversions

A conversion from a type to that same type is permitted for any type.

1.2. Widening primitive conversions

  • byte to short, int, long, float, or double
  • short to int, long, float, or double
  • char to int, long, float, or double
  • int to long, float, or double
  • long to float or double
  • float to double

A widening primitive conversion does not lose information about the overall magnitude of a numeric value.

1.3. Narrowing primitive conversions

  • short to byte or char
  • char to byte or short
  • int to byte, short, or char
  • long to byte, short, char, or int
  • float to byte, short, char, int, or long
  • double to byte, short, char, int, long, or float

A narrowing primitive conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range.

1.4. Widening and Narrowing Primitive Conversion

The following conversion combines both widening and narrowing primitive conversions:

• byte to char

First, the byte is converted to an int via widening primitive conversion and then the resulting int is converted to a char by narrowing primitive conversion .

1.5. Widening Reference Conversion

A widening reference conversion exists from any reference type S to any reference type T, provided S is a subtype) of T.

1.6. Narrowing reference conversions

Six kinds of conversions are called the narrowing reference conversions:

  • From any reference type S to any reference type T, provided that S is a proper super type of T.
  • From any class type C to any non-parameterized interface type K, provided that C is not final and does not implement K.
  • From any interface type J to any non-parameterized class type C that is not final.
  • From any interface type J to any non-parameterized interface type K, provided that J is not a sub interface of K.
  • From the interface types Clone able and java.io.Serializable to any array type T [].
  • From any array type SC [] to any array type TC [], provided that SC and TC are reference types and there is a narrowing reference

conversion from SC to TC.

1.7. Boxing conversions

Boxing conversion converts expressions of primitive type to corresponding expressions of reference type. Specifically, the following nine conversions are called the boxing conversions:

  • From type boolean to type Boolean
  • From type byte to type Byte
  • From type short to type Short
  • From type char to type Character
  • From type int to type Integer
  • From type long to type Long
  • From type float to type Float
  • From type double to type Double
  • From the null type to the null type

1.8. Unboxing conversions

Unboxing conversion converts expressions of reference type to corresponding expressions of primitive type. Specifically, the following eight conversions are called the unboxing conversions:

  • From type Boolean to type boolean
  • From type Byte to type byte
  • From type Short to type short
  • From type Character to type char
  • From type Integer to type int
  • From type Long to type long
  • From type Float to type float
  • From type Double to type double

1.9. Unchecked conversions

Let G name a generic type declaration with n type parameters. There is an unchecked conversion from the raw class or interface type G to any parameterized type of the form G<T1,…,Tn>. There is an unchecked conversion from the raw array type G[ ] to any array type type of the formG<T1,…,Tn>[ ].

1.10. Capture conversions 1.11. String conversions 1.12. Forbidden Conversions 1.13. Value set conversions

2. Conversion methods:

There are different methods for conversion such as assignment conversion, method invocation conversion, string conversion, casting coversion and etc.

2.1. Casting Conversion Casting conversion is applied to the operand of a cast operator :the type of the operand expression must be converted to the type explicitly named by the cast operator. Casting contexts allow the use of one of:

  • an identity conversion ( 1.1 )
  • a widening primitive conversion( 1.2)
  • a narrowing primitive conversion( 1.3 )
  • a widening and narrowing primitive conversion( 1.4 )
  • a widening reference conversion( 1.5 ) optionally followed by either an unboxing conversion( 1.8 ) or an unchecked conversion( 1.9 )
  • a narrowing reference conversion( 1.6 ) optionally followed by either an unboxing conversion( 1.8 ) or an unchecked conversion(1.9 )
  • a boxing conversion( 1.7 ) optionally followed by a widening reference conversion(1.5 )
  • an unboxing conversion (1.8) optionally followed by a widening primitive conversion( 1.2 ).

Each conversion is signified by a symbol:

  • - signifies no casting conversion allowed
  • ≈ signifies identity conversion(1.1)
  • ω signifies widening primitive conversion(1.2)
  • η signifies narrowing primitive conversion(1.3)
  • ωη signifies widening and narrowing primitive conversion(1.4)
  • ⇑ signifies widening reference conversion(1.5)
  • ⇓ signifies narrowing reference conversion(1.6)
  • ⊡ signifies boxing conversion(1.7)
  • ⊔ signifies unboxing conversion(1.8)

Casting conversions to reference types

source :http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

Here we've tried to deal with this bug but it's a hug area so our detector is not so complete as we face different prolbems such as for each object,which can have different real type base on the latest assignment to that so it is sometime hard to find the real type or maybe impossible.

Sample Problem Scenario

<code Java> public class ImpossibleCast {

public static Float find() {
	Object m = buildDouble();
	Float g = (Float) m; //Double to Float
	return g;
}
      public static Float find(Object test) { 
              double doubleVar = 3.14E5
              test= doubleVar;
	Float var = (Float) test; //double to Float
	return var;
}

} </Code>

Sample False-Positive Scenario

<code Java> public class FalseImpossibleCast {

public static float find() {
  Object m = builddouble();
  float g = (float) m; //double to float
  return g;
}

} </Code>

Evaluation Results

Benchmark project Precision Recall
FB JT Delta FB JT Delta
Project … …% …% …% …% …% …%
Project … …% …% …% …% …% …%

FB = FindBugs, JT = JTransformer, Delta = JTransformer - FindBugs

teaching/labs/mdse/2013/bug_descriptions/jt-bug-cor1.txt · Last modified: 2018/05/09 01:59 (external edit)

SEWiki, © 2023