This is an archive of the discontinued LLVM Phabricator instance.

[clang][analyzer] Add more wide-character functions to CStringChecker
ClosedPublic

Authored by balazske on Jul 25 2022, 2:46 AM.

Details

Summary

Support for functions wmempcpy, wmemmove, wmemcmp is added to the checker.
The same tests are copied that exist for the non-wide versions, with
non-wide functions and character types changed to the wide version.

Diff Detail

Event Timeline

balazske created this revision.Jul 25 2022, 2:46 AM
Herald added a reviewer: NoQ. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
balazske requested review of this revision.Jul 25 2022, 2:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 25 2022, 2:46 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Other than nits, I think it looks great.

clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
1368

Personally, I dislike bools for this purpose.
Did you consider something like enum CharacterFlavor {Regular, Wide}? It would be more readable in the CallDescription table.

A related question:
Is it better to have a more generic function like this:

void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE,
                                 bool IsRestricted, bool IsMempcpy, bool IsWide) const {
  // void *memmove(void *dst, const void *src, size_t n);
  // The return value is the address of the destination buffer.
  DestinationArgExpr Dest = {CE->getArg(0), 0};
  SourceArgExpr Src = {CE->getArg(1), 1};
  SizeArgExpr Size = {CE->getArg(2), 2};

  evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy,
                 IsWide);
}

(Instead of bool enums can be used.) Or make additional versions of the eval functions and remove the IsWide argument (this is even more code repetition)?

martong accepted this revision.Jul 27 2022, 6:53 AM

A related question:
Is it better to have a more generic function like this:

void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE,
                                 bool IsRestricted, bool IsMempcpy, bool IsWide) const {
  // void *memmove(void *dst, const void *src, size_t n);
  // The return value is the address of the destination buffer.
  DestinationArgExpr Dest = {CE->getArg(0), 0};
  SourceArgExpr Src = {CE->getArg(1), 1};
  SizeArgExpr Size = {CE->getArg(2), 2};

  evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy,
                 IsWide);
}

(Instead of bool enums can be used.) Or make additional versions of the eval functions and remove the IsWide argument (this is even more code repetition)?

I'd strive for the least code repetition. But I consider this just some nice to have sugar.

LGTM

clang/test/Analysis/wstring.c
372–376

This comment is probably outdated (I know it has been copied from bstring.c but still). Perhaps we should have the else branch now not just here but also in bstring.c.

This revision is now accepted and ready to land.Jul 27 2022, 6:53 AM
steakhal added inline comments.Jul 27 2022, 7:33 AM
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
1343

Do you think we should also update these comments?
It no longer matches to only this function.

balazske updated this revision to Diff 448356.Jul 28 2022, 9:04 AM

Change of bool argument to enum, added inline function to get char type.

balazske added inline comments.Jul 28 2022, 9:12 AM
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
1343

These are only for "reference" purpose and already not exact declarations (no restricted). The wide version is similar, does not look not necessary to repeat here.

clang/test/Analysis/wstring.c
372–376

clang_analyzer_eval(n == 0) is TRUE and FALSE, not UNKNOWN here. n can be 0 or non-0 but it is connected to values of a and b too.

steakhal added inline comments.Jul 29 2022, 12:19 AM
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
138–139

If you were using a plain-old enum, it would feel less repetitive.
You are already in the anonymous namespace, so it would not pollute anything anyway.
You could also use std::bind, to make it denser.

175

This line looks dead.

balazske updated this revision to Diff 448546.Jul 29 2022, 1:31 AM
balazske marked an inline comment as done.

Use shorter enum names, remove unneeded line.

balazske added inline comments.Jul 29 2022, 1:32 AM
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
138–139

Every other enum in the file is enum class, I like more to use enum class. But the name can be shortened and constants added because it is used often.

balazske marked 3 inline comments as done.Aug 3 2022, 3:04 AM
martong accepted this revision.Aug 4 2022, 2:59 AM

I think there's only some very minor style nits which are remained, but that should not block this any further. Let's land it.

This revision was landed with ongoing or failed builds.Aug 5 2022, 1:33 AM
This revision was automatically updated to reflect the committed changes.