clad icon indicating copy to clipboard operation
clad copied to clipboard

Fix extra lines generated when using clad::array.

Open sudo-panda opened this issue 2 years ago • 2 comments

Clad uses the isUnusedResult function to check for unneccessary statements and remove them from the generated code.

Since the array subscript expression of clad::array calls it's operator overload the function isUnusedResult is not able to determine that statement is not required.

double arr(3);
arr[1]; // <- isUnusedResult returns true for this statement

clad::array a(3);
a[1]; // <- isUnusedResult returns false for this statement but it should return true

To fix this isUnusedResult needs to be modified to return true for such statements.

sudo-panda avatar Jan 12 '22 14:01 sudo-panda

@vgvassilev can i fix this issue

rajeck1234 avatar Mar 11 '23 13:03 rajeck1234

Hello @vgvassilev @parth-07 , please give me feedback.

To fix this issue, we need to modify the isUnusedResult function in the Clad library to correctly identify the array subscript operator overload as an unnecessary statement. One approach to do this is to check if the expression passed to isUnusedResult is of type clad::array and if it is, return true if the statement is a subscript operation.

Here's a modified implementation of the isUnusedResult function with the necessary changes:

  if (!E)
    return false;

  if (isa<CastExpr>(E))
    return isUnusedResult(cast<CastExpr>(E)->getSubExpr());

  if (isa<CallExpr>(E)) {
    if (auto CE = dyn_cast<CallExpr>(E))
      if (auto callee = CE->getCalleeDecl())
        if (auto FD = dyn_cast<clang::FunctionDecl>(callee))
          return isUnusedFunction(FD->getNameAsString());

    return false;
  }

  if (isa<UnaryOperator>(E))
    return isUnusedResult(cast<UnaryOperator>(E)->getSubExpr());

  if (isa<BinaryOperator>(E))
    return isUnusedResult(cast<BinaryOperator>(E)->getLHS()) &&
           isUnusedResult(cast<BinaryOperator>(E)->getRHS());

  if (isa<ConditionalOperator>(E))
    return isUnusedResult(cast<ConditionalOperator>(E)->getTrueExpr()) &&
           isUnusedResult(cast<ConditionalOperator>(E)->getFalseExpr());

  if (isa<MemberExpr>(E))
    return isUnusedResult(cast<MemberExpr>(E)->getBase());

  if (isa<ArraySubscriptExpr>(E))
    return isa<clad::array>(cast<ArraySubscriptExpr>(E)->getBase());

  return E->isUnusedResultAFAIK();
}

In this modified implementation, we are checking if the expression is an ArraySubscriptExpr, and if it is, we are returning true if the base of the expression is a clad::array.

With this modification, the isUnusedResult function should correctly identify unnecessary statements even when using the clad::array type.

ro4i7 avatar Mar 11 '23 15:03 ro4i7