This is an archive of the discontinued LLVM Phabricator instance.

[libc] Add strchr implementation.
ClosedPublic

Authored by cgyurgyik on Jul 7 2020, 3:40 PM.

Details

Summary

[libc] Adds strchr implementation with unit tests. Fixes signed character bug in memchr.

Diff Detail

Event Timeline

cgyurgyik created this revision.Jul 7 2020, 3:40 PM
cgyurgyik updated this revision to Diff 276245.Jul 7 2020, 3:44 PM
cgyurgyik added reviewers: sivachandra, PaulkaToast.
cgyurgyik updated this revision to Diff 276285.Jul 7 2020, 5:50 PM
PaulkaToast added inline comments.Jul 9 2020, 1:20 PM
libc/src/string/strchr.cpp
23

nit: you could put continue here but not strictly necessary (:

sivachandra added inline comments.Jul 10 2020, 1:02 AM
libc/src/string/strchr.cpp
19

Whats the benefit of doing this check? Wouldn't the return statement already handle this case?

22

To prevent the behavior of this function to depend on the signedness of the char type, unsigned values should be compared. It should be exactly like in the memchr implementation. But, I just went looking and it looks like you removed casting c to unsigned char over there. Left a note about this over there as well.

libc/test/src/string/strchr_test.cpp
38

Instead of a separate test set, test this in all of the above tests?

63

You should probably put the test here under ShouldFindFirstOfDuplicates above.

cgyurgyik updated this revision to Diff 276997.Jul 10 2020, 5:14 AM
cgyurgyik marked 4 inline comments as done.

Fix cast to unsigned char in memchr

libc/src/string/strchr.cpp
19

It would, but using strlen requires only a single comparison with 0 while the loop below requires a comparison with 0 and a comparison with ch.

22

Fixed memchr and added a test as well.

23

I will leave it like this for consistency, and I find it slightly more elegant without the continue statement. If you are strongly opposed I can change it.

libc/test/src/string/strchr_test.cpp
38

Is there a benefit to doing this? I want to keep different behavioral components as separate as possible, so that if someone breaks behavior X, only unit test for behavior X breaks, rather than all tests. WDYT?

Since the scope of this change has widened, please update the commit message accordingly. Also, if you are not using arcanist, add the link to the phabricator review page in the commit message. You will have to do this on this review page as well as in your local commit.

libc/src/string/strchr.cpp
19

I would expect that a much higher percentage of calls to strchr would be with a non-zero c. In which case, this seems like an optimization for a very special case. For the higher percentage case, it would be an additional conditional.

libc/test/src/string/strchr_test.cpp
38

That the source should not change is required in all cases. Likewise, that the result is correct is required in all cases. So, checking that source does not change separately seems incomplete.

cgyurgyik marked 3 inline comments as done.
cgyurgyik edited the summary of this revision. (Show Details)

Since the scope of this change has widened, please update the commit message accordingly. Also, if you are not using arcanist, add the link to the phabricator review page in the commit message. You will have to do this on this review page as well as in your local commit.

Done.

libc/src/string/strchr.cpp
19

Removed.

sivachandra accepted this revision.Jul 10 2020, 11:16 AM
sivachandra added inline comments.
libc/src/string/strchr.cpp
18

The comparison should be for two values with the same sign. So, this should be:

unsigned char *str = const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(src));

When returning, reinterpret_cast it back to char *.

This revision is now accepted and ready to land.Jul 10 2020, 11:16 AM
cgyurgyik marked an inline comment as done.
This revision was automatically updated to reflect the committed changes.