[PATCH] D71973: [clang-tidy] Add bugprone-suspicious-memory-comparison check
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 10 08:34:28 PST 2020
aaron.ballman added inline comments.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp:30
+ uint64_t ComparedBits, uint64_t &TotalSize) {
+ const auto IsNotEmptyBase = [](const CXXBaseSpecifier &Base) {
+ return !Base.getType()->getAsCXXRecordDecl()->isEmpty();
----------------
Drop top-level `const` qualifiers on locals (it's not a style we typically use), elsewhere as well.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp:82-83
+
+static bool hasPadding(const ASTContext &Ctx, const RecordDecl *RD,
+ uint64_t ComparedBits) {
+ assert(RD && RD->isCompleteDefinition() &&
----------------
I am surprised that we have to do this much manual work, I would have expected this to be something that `RecordLayout` would handle for us. I am a bit worried about this manual work being split in a few places because we're likely to get it wrong in at least one of them. For instance, this doesn't seem to be taking into account things like `[[no_unique_address]]` or alignment when considering the layout of fields.
I sort of wonder if we should try using the `RecordLayout` class to do this work instead, even if that requires larger changes.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp:130
+ const Type *PointeeType = ArgType->getPointeeOrArrayElementType();
+ assert(PointeeType != nullptr && "PointeeType should always be available.");
+
----------------
Can you add a test case like this:
```
struct S {
operator void *() const;
};
S s;
memcmp(s, s, sizeof(s));
```
to ensure that this assertion doesn't trigger?
================
Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp:133-134
+ if (PointeeType->isRecordType()) {
+ const RecordDecl *RD = PointeeType->getAsRecordDecl()->getDefinition();
+ if (RD != nullptr) {
+ if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
----------------
Sink the declaration into the if conditional to limit its scope.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp:140
+ "type %0; consider using a comparison operator instead")
+ << PointeeType->getAsTagDecl()->getQualifiedNameAsString();
+ break;
----------------
You can pass in `PointeeType->getAsTagDecl()` -- the diagnostic printer will automatically get the correct name from any `NamedDecl`.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp:148
+ "consider comparing the fields manually")
+ << PointeeType->getAsTagDecl()->getQualifiedNameAsString();
+ break;
----------------
Same here as above.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D71973/new/
https://reviews.llvm.org/D71973
More information about the cfe-commits
mailing list