Uploaded image for project: 'Clover'
  1. Clover
  2. CLOV-1389

Instrumentation of a branch condition with a generic type leads to javac compilation error

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Fix
    • Medium
    • n/a
    • 3.2.0
    • Instrumentation
    • 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)

      Attachments

        Activity

          People

            Unassigned Unassigned
            mparfianowicz Marek Parfianowicz
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: