Details
-
Bug
-
Resolution: Won't Fix
-
Medium
-
3.2.0
-
None
-
Severity 2 - Major
Description
For a declaration like this:
public <T> T getFeatureValue(); ... if (client.getFeatureValue()) {
the instrumented line gets instrumented like:
_CLR3_1_113f23f2hnz3nmqe.R.inc(5146);if ((((client.getFeatureValue())&&(CLR3_1_113f23f2hnz3nmqe.R.iget(5147)!=0|true))||(_CLR3_1_113f23f2hnz3nmqe.R.iget(5148)==0&false))) {{
which leads to compilation error:
error: bad operand types for binary operator '&&'
Reason:
Javac performs autoboxing of the if condition. However it cannot deal properly if the same generic value is used with && or || operators. It looks like if javac wraps the entire if condition, not a single element.
Look at the example:
public class BranchCoverageWithAutoboxing { interface Data { public <T> T getValue(); } public boolean testGetValue(Data source) { if (source.getValue()) { // Implicit conversion to Boolean via autoboxing return true; } return false; } public boolean testGetValueWithBoolean(Data source) { if (source.getValue() && true) { // Error: Operator && cannot be applied to java.lang.Object, boolean return true; } return false; } public boolean testGetValueWithWrappedBoolean(Data source) { if (Boolean.valueOf(source.getValue().toString()) && true) { // Explicit conversion, compilation is successful return true; } return false; } }
Workaround:
Don't rely on boolean autoboxing and change a generic type to Boolean.
or
Extract expression being autoboxed to a local variable and evaluate before "if". Use the variable in "if".
// original: if (source.getValue) // fixed: Boolean b = source.getValue(); if (b)
or
surround problematic code block with "///CLOVER:OFF" and "///CLOVER:ON" inline comments (note that three slashes are used)