Program: 28209
Project: 28209
Buggy source:
/** 
 * Try to fold comparison nodes, e.g ==
 */
@SuppressWarnings("String_Node_Str") private Node tryFoldComparison(Node n,Node left,Node right){
  if (!NodeUtil.isLiteralValue(left) || !NodeUtil.isLiteralValue(right)) {
    if (n.getType() != Token.GT && n.getType() != Token.LT) {
      return n;
    }
  }
  int op=n.getType();
  boolean result;
  boolean rightLiteral=NodeUtil.isLiteralValue(right);
  boolean undefinedRight=((Token.NAME == right.getType() && right.getString().equals("String_Node_Str")) || (Token.VOID == right.getType() && NodeUtil.isLiteralValue(right.getFirstChild())));
switch (left.getType()) {
case Token.VOID:
    if (!NodeUtil.isLiteralValue(left.getFirstChild())) {
      return n;
    }
 else     if (!rightLiteral) {
      return n;
    }
 else {
      boolean nullRight=(Token.NULL == right.getType());
      boolean equivalent=undefinedRight || nullRight;
switch (op) {
case Token.EQ:
        result=equivalent;
      break;
case Token.NE:
    result=!equivalent;
  break;
case Token.SHEQ:
result=undefinedRight;
break;
case Token.SHNE:
result=!undefinedRight;
break;
case Token.LT:
case Token.GT:
case Token.LE:
case Token.GE:
result=false;
break;
default :
return n;
}
}
break;
case Token.NULL:
if (undefinedRight) {
result=(op == Token.EQ);
break;
}
case Token.TRUE:
case Token.FALSE:
if (undefinedRight) {
result=false;
break;
}
case Token.THIS:
int tt=right.getType();
if (tt != Token.THIS && tt != Token.TRUE && tt != Token.FALSE && tt != Token.NULL) {
return n;
}
switch (op) {
case Token.SHEQ:
case Token.EQ:
result=left.getType() == right.getType();
break;
case Token.SHNE:
case Token.NE:
result=left.getType() != right.getType();
break;
default :
return n;
}
break;
case Token.STRING:
if (undefinedRight) {
result=false;
break;
}
if (Token.STRING != right.getType()) {
return n;
}
switch (op) {
case Token.SHEQ:
case Token.EQ:
result=left.getString().equals(right.getString());
break;
case Token.SHNE:
case Token.NE:
result=!left.getString().equals(right.getString());
break;
default :
return n;
}
break;
case Token.NUMBER:
if (undefinedRight) {
result=false;
break;
}
if (Token.NUMBER != right.getType()) {
return n;
}
double lv=left.getDouble();
double rv=right.getDouble();
switch (op) {
case Token.SHEQ:
case Token.EQ:
result=lv == rv;
break;
case Token.SHNE:
case Token.NE:
result=lv != rv;
break;
case Token.LE:
result=lv <= rv;
break;
case Token.LT:
result=lv < rv;
break;
case Token.GE:
result=lv >= rv;
break;
case Token.GT:
result=lv > rv;
break;
default :
return n;
}
break;
case Token.NAME:
if (rightLiteral) {
boolean undefinedLeft=(left.getString().equals("String_Node_Str"));
if (undefinedLeft) {
boolean nullRight=(Token.NULL == right.getType());
boolean equivalent=undefinedRight || nullRight;
switch (op) {
case Token.EQ:
result=equivalent;
break;
case Token.NE:
result=!equivalent;
break;
case Token.SHEQ:
result=undefinedRight;
break;
case Token.SHNE:
result=!undefinedRight;
break;
case Token.LT:
case Token.GT:
case Token.LE:
case Token.GE:
result=false;
break;
default :
return n;
}
break;
}
}
if (Token.NAME != right.getType()) {
return n;
}
String ln=left.getString();
String rn=right.getString();
if (!ln.equals(rn)) {
return n;
}
switch (op) {
case Token.LT:
case Token.GT:
result=false;
break;
default :
return n;
}
break;
default :
return n;
}
Node newNode=new Node(result ? Token.TRUE : Token.FALSE);
n.getParent().replaceChild(n,newNode);
reportCodeChange();
return newNode;
}

Fixed version (ground truth):
/** 
 * Try to fold comparison nodes, e.g ==
 */
@SuppressWarnings("String_Node_Str") private Node tryFoldComparison(Node n,Node left,Node right){
  if (!NodeUtil.isLiteralValue(left,false) || !NodeUtil.isLiteralValue(right,false)) {
    if (n.getType() != Token.GT && n.getType() != Token.LT) {
      return n;
    }
  }
  int op=n.getType();
  boolean result;
  boolean rightLiteral=NodeUtil.isLiteralValue(right,false);
  boolean undefinedRight=((Token.NAME == right.getType() && right.getString().equals("String_Node_Str")) || (Token.VOID == right.getType() && NodeUtil.isLiteralValue(right.getFirstChild(),false)));
switch (left.getType()) {
case Token.VOID:
    if (!NodeUtil.isLiteralValue(left.getFirstChild(),false)) {
      return n;
    }
 else     if (!rightLiteral) {
      return n;
    }
 else {
      boolean nullRight=(Token.NULL == right.getType());
      boolean equivalent=undefinedRight || nullRight;
switch (op) {
case Token.EQ:
        result=equivalent;
      break;
case Token.NE:
    result=!equivalent;
  break;
case Token.SHEQ:
result=undefinedRight;
break;
case Token.SHNE:
result=!undefinedRight;
break;
case Token.LT:
case Token.GT:
case Token.LE:
case Token.GE:
result=false;
break;
default :
return n;
}
}
break;
case Token.NULL:
if (undefinedRight) {
result=(op == Token.EQ);
break;
}
case Token.TRUE:
case Token.FALSE:
if (undefinedRight) {
result=false;
break;
}
case Token.THIS:
int tt=right.getType();
if (tt != Token.THIS && tt != Token.TRUE && tt != Token.FALSE && tt != Token.NULL) {
return n;
}
switch (op) {
case Token.SHEQ:
case Token.EQ:
result=left.getType() == right.getType();
break;
case Token.SHNE:
case Token.NE:
result=left.getType() != right.getType();
break;
default :
return n;
}
break;
case Token.STRING:
if (undefinedRight) {
result=false;
break;
}
if (Token.STRING != right.getType()) {
return n;
}
switch (op) {
case Token.SHEQ:
case Token.EQ:
result=left.getString().equals(right.getString());
break;
case Token.SHNE:
case Token.NE:
result=!left.getString().equals(right.getString());
break;
default :
return n;
}
break;
case Token.NUMBER:
if (undefinedRight) {
result=false;
break;
}
if (Token.NUMBER != right.getType()) {
return n;
}
double lv=left.getDouble();
double rv=right.getDouble();
switch (op) {
case Token.SHEQ:
case Token.EQ:
result=lv == rv;
break;
case Token.SHNE:
case Token.NE:
result=lv != rv;
break;
case Token.LE:
result=lv <= rv;
break;
case Token.LT:
result=lv < rv;
break;
case Token.GE:
result=lv >= rv;
break;
case Token.GT:
result=lv > rv;
break;
default :
return n;
}
break;
case Token.NAME:
if (rightLiteral) {
boolean undefinedLeft=(left.getString().equals("String_Node_Str"));
if (undefinedLeft) {
boolean nullRight=(Token.NULL == right.getType());
boolean equivalent=undefinedRight || nullRight;
switch (op) {
case Token.EQ:
result=equivalent;
break;
case Token.NE:
result=!equivalent;
break;
case Token.SHEQ:
result=undefinedRight;
break;
case Token.SHNE:
result=!undefinedRight;
break;
case Token.LT:
case Token.GT:
case Token.LE:
case Token.GE:
result=false;
break;
default :
return n;
}
break;
}
}
if (Token.NAME != right.getType()) {
return n;
}
String ln=left.getString();
String rn=right.getString();
if (!ln.equals(rn)) {
return n;
}
switch (op) {
case Token.LT:
case Token.GT:
result=false;
break;
default :
return n;
}
break;
default :
return n;
}
Node newNode=new Node(result ? Token.TRUE : Token.FALSE);
n.getParent().replaceChild(n,newNode);
reportCodeChange();
return newNode;
}