This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Replace memcpy by std::copy
Needs RevisionPublic

Authored by Blackhart on Jun 14 2019, 2:48 AM.

Details

Summary

This patch will:

  • replace all occurrence of the C "memcpy" function by "std::copy".
  • reorder its arguments.
  • insert the "algorithm" header if needed.

Diff Detail

Event Timeline

Blackhart created this revision.Jun 14 2019, 2:48 AM
Blackhart created this object with edit policy "Blackhart (Thomas Manceau)".Jun 14 2019, 2:48 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 14 2019, 2:48 AM
Blackhart edited the summary of this revision. (Show Details)Jun 14 2019, 2:54 AM
Blackhart changed the edit policy from "Blackhart (Thomas Manceau)" to "All Users".Jun 14 2019, 2:57 AM
Blackhart updated this revision to Diff 204757.Jun 14 2019, 6:32 AM

Missing tests.

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
120

please add all the missing newlines

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
2–3

should be something like

//===--- ReplaceMemcpyByStdCopy.h - clang-tidy -----------------*- C++-*-===//
Blackhart updated this revision to Diff 204758.Jun 14 2019, 6:36 AM

Add missing "override" keywords

Blackhart updated this revision to Diff 204759.Jun 14 2019, 6:43 AM

Fix file comments typo

Blackhart updated this revision to Diff 204768.Jun 14 2019, 7:47 AM
Blackhart marked 2 inline comments as done.
Blackhart set the repository for this revision to rCTE Clang Tools Extra.Jun 14 2019, 7:49 AM
Blackhart updated this revision to Diff 204770.Jun 14 2019, 8:17 AM

Modernize memcpy only if C++20 is enabled

Modernize memcpy only if C++20 is enabled

... why?
This is also missing documentation,releasenotes changes.

Modernize memcpy only if C++20 is enabled

... why?
This is also missing documentation,releasenotes changes.

According with the C++ reference, std::copy is only available since C++20.
There is another std::copy signature available since C++17, but it needs an extra parameter. I can implement it also.
https://en.cppreference.com/w/cpp/algorithm/copy

I'm working on the unit tests and I'll make documentation/releasenotes after that.

Thanks for reviewing @lebedev.ri ;)

Modernize memcpy only if C++20 is enabled

... why?
This is also missing documentation,releasenotes changes.

According with the C++ reference, std::copy is only available since C++20.

I don't see it there, can you quote?
https://godbolt.org/z/q2ryJi

There is another std::copy signature available since C++17, but it needs an extra parameter. I can implement it also.
https://en.cppreference.com/w/cpp/algorithm/copy

I'm working on the unit tests and I'll make documentation/releasenotes after that.

Thanks for reviewing @lebedev.ri ;)

This might not be currently ideal recommendation since std::copy produces memmove with -O3.

New check must be mentioned in Release Notes and its documentation provided.

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
69

Return type could not be deduced from same statement, so please don't use auto.

77

Will be good idea to use std::array and its size instead of numerical constant.

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
27

Should be override and = default. See modernize-use-override and modernize-use-equals-default.

Modernize memcpy only if C++20 is enabled

... why?
This is also missing documentation,releasenotes changes.

According with the C++ reference, std::copy is only available since C++20.

I don't see it there, can you quote?
https://godbolt.org/z/q2ryJi

There is another std::copy signature available since C++17, but it needs an extra parameter. I can implement it also.
https://en.cppreference.com/w/cpp/algorithm/copy

I'm working on the unit tests and I'll make documentation/releasenotes after that.

Thanks for reviewing @lebedev.ri ;)

Sorry, I misread the reference. It's "until" C++20.
So from C++ birth to today ...

I'll revert my changes.

This might not be currently ideal recommendation since std::copy produces memmove with -O3.

What do you recommend ?
There is a way to disable this modernization if the user compile with the -O3 flag ?

Blackhart updated this revision to Diff 204920.Jun 15 2019, 8:03 AM

Revert "Modernize memcpy only if C++20 is enabled"

Blackhart updated this revision to Diff 204922.EditedJun 15 2019, 8:10 AM

Add override keyword to the destructor and let the compiler generate its definition

Blackhart updated this revision to Diff 204924.Jun 15 2019, 8:16 AM
Blackhart marked an inline comment as done.

Remove "auto" keyword when type is created from same statement

Blackhart updated this revision to Diff 204925.Jun 15 2019, 8:22 AM
Blackhart marked an inline comment as done.

Use "std::array" instead of the raw array

Eugene.Zelenko added inline comments.Jun 15 2019, 8:25 AM
clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
12

Please remove unnecessary empty line.

87

Please use arg,size() instead of 3.

Blackhart updated this revision to Diff 204926.Jun 15 2019, 8:33 AM
Blackhart marked an inline comment as done.
  • Remove unnessecary empty line
  • Use "array.size()" instead of numerical constant
Blackhart updated this revision to Diff 204930.Jun 15 2019, 9:50 AM
Blackhart marked 2 inline comments as done.
  • Update releasenotes
  • Add documentation
Blackhart updated this revision to Diff 204932.Jun 15 2019, 9:55 AM
clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
42

I think this could be determined from .clang-format.

clang-tools-extra/docs/ReleaseNotes.rst
204 ↗(On Diff #204932)

Please move into new checks list (in alphabetical order).

207 ↗(On Diff #204932)

Replaces. Please use double back-ticks to highlight language constructs.

clang-tools-extra/docs/clang-tidy/checks/modernize-replace-memcpy-by-stdcopy.rst
6 ↗(On Diff #204932)

Please make first sentance same as in Release Notes.

35 ↗(On Diff #204932)

I think this could be determined from project's .clang-format.

Blackhart updated this revision to Diff 205331.Jun 18 2019, 7:07 AM
  • Reorder release note changes
  • Update documentation

Hello,

I've updated the documentation with more informations about the transformations the check do.

I'm not very confident in writing documentation in english.
Please review it and submit me your change requests.

Eugene.Zelenko added inline comments.Jun 18 2019, 7:14 AM
clang-tools-extra/docs/ReleaseNotes.rst
192 ↗(On Diff #205331)

Please remove This check. Same in first statement in documentation.

Still missing tests

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
35–36

Why these restrictions?

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
27

I don't think you need this one

Blackhart updated this revision to Diff 205341.Jun 18 2019, 7:30 AM
Blackhart marked 3 inline comments as done.

Remove "this check" from documentation and release note

Blackhart updated this revision to Diff 205354.Jun 18 2019, 7:59 AM
Blackhart marked 4 inline comments as done.

You need tests for this check. Please harden them against macro-interference as well. I think the transformation should happen as function call that return Optional and if any failure happens the diagnostic can still be emitted.

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
28

this assertion is not necessary. Finder is always not-null.

34

please match on ::memcpy and ::std::memcpy.

54

this assertion is not necessary, as you only match on one thing and that means it exists. (otherwise everything is broken already).

Thinking about it more, i have some negative reservations about this :/

As it can be seen form https://godbolt.org/z/3BZmCM, it seems any and every(?) alternative C++ algorithm
replacement is a performance pessimization in the general case, because memcpy requires/'guarantees'
that there must be no overlap between source and destination ranges,
while there is no such restriction for C++ algorithms (=> they will get optimized into memmove).
That is unless optimizer also manages to prove that it is safe to optimize memmove into memcpy there.
(Extra bloat if(num != 0) memmove is also not always good)

if(num != 0) memmove is missed optimization opportunity. Such branch can be removed (if profitable).

LegalizeAdulthood added inline comments.
clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
19

In English, it's more idiomatic to say "Replace memcpy with std::copy",
but perhaps an even better name for this check is modernize-use-std-copy.
This opens the door to future improvements that recognize hand-written
for loops that are essentially just invocations of std::copy or std::copy_n.
(Recently I was considering writing a check like that while reviewing some
code at work that was full of hand-written for loops that just copied elements
from one container to another.)

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
12

Please remove unnecessary empty line.

Where is this in the LLVM coding style guide?

36

I erroneously had this in some checks I had written; it prevents fixits
from being applied to user supplied header files and is undesirable.

I would suggest removing both the isExpansionInSystemHeader and
isExpansionInMainFile narrowing matchers.

71

In the clang code base, they prefer not to use const on local variables
unless the local is a pointer to a const object and even then, it's only
the pointed-to object that is declared const not the pointer itself.

79

LLVM naming convention is CapCamelCase for variables.
See here and variables declared on lines 85, 86, 91, etc.

92

Prefer int over uint8_t here as there is no requirement for
a type of a specific bit width. The explicit return type is also
unnecessary, but please consult the LLVM style guide to make
sure you're following any prescriptions for lambdas.

Additionally, ArgCount doesn't feel like the right name for this
parameter. It's not the count of anything, it's an index into the
arguments, so just Arg feels better.

100

I think it would be worthwhile to probe the AST of the argument here and see if it is
already of the form N*sizeof(T).

This can probably be handled by enhancing the matchers on the argument so that you
aren't probing the AST in procedural code.

clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
27

Should be override and = default

Why do you need to override it if you're just using the compiler's default?

clang-tools-extra/docs/clang-tidy/checks/modernize-replace-memcpy-by-stdcopy.rst
33 ↗(On Diff #205354)

Please use a line length in the .rst files that is consistent with the LLVM line length
for code files.

LegalizeAdulthood requested changes to this revision.Mar 22 2023, 10:31 AM
This revision now requires changes to proceed.Mar 22 2023, 10:31 AM
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: PiotrZSL. · View Herald Transcript