This is an archive of the discontinued LLVM Phabricator instance.

[analyzer][StdLibraryFunctionsChecker] Remove strcasecmp
ClosedPublic

Authored by martong on Sep 7 2020, 8:11 AM.

Details

Summary

There are 2 reasons to remove strcasecmp and strncasecmp.

  1. They are also modeled in CStringChecker and the related argumentum contraints are checked there.
  2. The argument constraints are checked in CStringChecker::evalCall. This is fundamentally flawed, they should be checked in checkPreCall. Even if we set up CStringChecker as a weak dependency for StdLibraryFunctionsChecker then the latter reports the warning always. Besides, CStringChecker fails to discover the constraint violation before the call, so, its evalCall returns with true and then StdCLibraryFunctions also tries to evaluate, this causes an assertion in CheckerManager.

Either we fix CStringChecker to handle the call prerequisites in
checkPreCall, or we must not evaluate any pure functions in
StdCLibraryFunctions that are also handled in CStringChecker.
We do the latter in this patch.

Diff Detail

Event Timeline

martong created this revision.Sep 7 2020, 8:11 AM
martong requested review of this revision.Sep 7 2020, 8:11 AM

I completely agree with you.
I plan to further refactor the CStringChecker, but the related patches are pretty much stuck :D

I think this workaround is fine for now.
You might as well extend the corresponding parts of the CStringChecker to make the modelling more precise.
It shouldn't be much of a hassle.
What do you say about that?

clang/test/Analysis/std-c-library-functions-arg-cstring-dependency.c
13

I'm not sure if this is required.

martong marked an inline comment as done.Sep 7 2020, 9:06 AM

I completely agree with you.
I plan to further refactor the CStringChecker, but the related patches are pretty much stuck :D

I think this workaround is fine for now.
You might as well extend the corresponding parts of the CStringChecker to make the modelling more precise.
It shouldn't be much of a hassle.
What do you say about that?

I think the modeling is well done and precise. I mean, it seems like all of the constraints that I am removing here are handled in CStringChecker. It checks the pointer arguments whether they are null. Also, the length is checked in case of strncasecmp, here:

if (IsBounded) {
  // Get the max number of characters to compare.
  const Expr *lenExpr = CE->getArg(2);
  SVal lenVal = state->getSVal(lenExpr, LCtx);

  // If the length is known, we can get the right substrings.
  if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) {
    // Create substrings of each to compare the prefix.
    LeftStrRef = LeftStrRef.substr(0, (size_t)len->getZExtValue());
    RightStrRef = RightStrRef.substr(0, (size_t)len->getZExtValue());
    canComputeResult = true;
  }
} else { .... }

So, the problem is rather that the constraint check should be done in checkPreCall, but that should be in an NFC refactoring.

@steakhal Ping.

I completely agree with you.

So, how should we proceed? :)

steakhal accepted this revision.Sep 9 2020, 11:13 AM

So, the problem is rather that the constraint check should be done in checkPreCall, but that should be in an NFC refactoring.

You are right, but we can not fix everything at once. There are quite a few changes under review related to the CStringChecker already.

I completely agree with you.

So, how should we proceed? :)

I'm fine with taking this reponsibilty out from the StdLibraryFunctionsChecker.

This revision is now accepted and ready to land.Sep 9 2020, 11:13 AM
This revision was landed with ongoing or failed builds.Sep 10 2020, 3:31 AM
This revision was automatically updated to reflect the committed changes.