Skip to content

C++: Fix some FPs in cpp/missing-check-scanf (third attempt!) #18207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

MathiasVP
Copy link
Contributor

@MathiasVP MathiasVP commented Dec 4, 2024

This PR brings back the changes from #17938 and fixes the performance by inlining the ensures (and to some degree the compares) predicates which became too large after the improvements.

Commit-by-commit review recommended:

  • 20dfbdc reverts the revert
  • 6f73aa5 does a small refactoring which I've been meaning to do for a while now that we can use abstract classes in user-facing classes by using final extensions.
  • 404dd33 and 3bdfdd0 do the actual performance fix: we inline the ensures predicates, and move the cacheing to the implementation predicates. This should that we don't get expensive recomputations and that the user-facing predicates are never materialized.

As an extra bonus, the inlining makes the performance fix added in 19d53fb unnecessary 🎉

After several rounds of join order fixes QA looks good 🎉 (0.55% analysis time difference). You can find the QA run in the backlink if you're curious.

@MathiasVP MathiasVP changed the title C++: Fix some FPs in cpp/missing-check-scanf (_third_ attempt) C++: Fix some FPs in cpp/missing-check-scanf (third attempt!) Dec 4, 2024
@MathiasVP MathiasVP force-pushed the fix-fp-in-missing-check-scanf-fixing-take-3 branch from 9abf985 to b1add73 Compare December 4, 2024 14:55
* Beware making mistaken logical implications here relating `areEqual` and `testIsTrue`.
*/
cached
predicate compares_eq(

Check warning

Code scanning / CodeQL

Missing QLDoc for parameter Warning

The QLDoc has no documentation for value, but the QLDoc mentions testIsTrue
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 913357b


/** Holds if `left < right + k` evaluates to `isLt` given that test is `testIsTrue`. */
cached
predicate compares_lt(

Check warning

Code scanning / CodeQL

Missing QLDoc for parameter Warning

The QLDoc has no documentation for value, but the QLDoc mentions testIsTrue
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 913357b

MathiasVP added a commit to MathiasVP/ql that referenced this pull request Dec 4, 2024
jketema added a commit that referenced this pull request Dec 5, 2024
@MathiasVP MathiasVP force-pushed the fix-fp-in-missing-check-scanf-fixing-take-3 branch from b1add73 to 961599d Compare December 5, 2024 10:46
MathiasVP added a commit to MathiasVP/ql that referenced this pull request Dec 6, 2024
MathiasVP added a commit to MathiasVP/ql that referenced this pull request Dec 6, 2024
MathiasVP added a commit to MathiasVP/ql that referenced this pull request Dec 6, 2024
@MathiasVP MathiasVP force-pushed the fix-fp-in-missing-check-scanf-fixing-take-3 branch 2 times, most recently from 23da208 to ec3b877 Compare December 10, 2024 12:27
@MathiasVP MathiasVP force-pushed the fix-fp-in-missing-check-scanf-fixing-take-3 branch from ec3b877 to 913357b Compare December 16, 2024 14:03
@MathiasVP MathiasVP marked this pull request as ready for review December 16, 2024 14:46
@MathiasVP MathiasVP requested a review from a team as a code owner December 16, 2024 14:46
Comment on lines -152 to -157
GuardCondition() {
exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression())
or
// no binary operators in the IR
this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Contributor Author

@MathiasVP MathiasVP Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before the introduction of final aliases this class couldn't be made abstract (since it would expose a abstract class from our libraries to queries). So instead of having this class be abstract we followed the pattern of:

  1. Specifying each subclass of this "pseudo-abstract" class in the charpred
  2. Provide a subclass that extended this "pseudo-abstract" class and repeated the required charpred to define the subclass.

That is, we've had to do:

class Base {
  Base() {
     myImpl1(this) or myImpl2(this)
  }
}

class MyImpl1 extends Base {
  MyImpl1() {
    myImpl1(this)
  }
}

class MyImpl2 extends Base {
  MyImpl2() {
    myImpl1(this)
  }
}

Now that we have final classes we can get rid of this pattern (as we've done many other places) and actually use abstract classes. And abstract classes don't need this charpred since they're defined as the union of all the subclasses.

That is, we can rewrite the above example to:

private abstract class BaseImpl { } // <--- Note: We can now remove the charpred and only have it in the subclasses

final class Base = BaseImpl;

class MyImpl1 extends BaseImpl {
  MyImpl1() {
    myImpl1(this)
  }
}

class MyImpl2 extends BaseImpl {
  MyImpl2() {
    myImpl1(this)
  }
}

Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes total sense.

Copy link
Contributor

@jketema jketema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional changes after the revert-revert make sense.

@MathiasVP
Copy link
Contributor Author

MathiasVP commented Dec 16, 2024

Thanks a lot, Jeroen! DCA results are in and shows nothing of interest 🎉

@MathiasVP MathiasVP merged commit a3ef0b9 into github:main Dec 16, 2024
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants