[clang-tools-extra] r311651 - [clang-tidy] bugprone-undefined-memory-manipulation: include type into the message
Alexander Kornienko via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 24 05:11:05 PDT 2017
Author: alexfh
Date: Thu Aug 24 05:11:05 2017
New Revision: 311651
URL: http://llvm.org/viewvc/llvm-project?rev=311651&view=rev
Log:
[clang-tidy] bugprone-undefined-memory-manipulation: include type into the message
Having the actual type in the message helps a lot understanding warnings in templates ;)
+ fix a false negative for type aliases.
Modified:
clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp
Modified: clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp?rev=311651&r1=311650&r2=311651&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp Thu Aug 24 05:11:05 2017
@@ -26,7 +26,8 @@ AST_MATCHER(CXXRecordDecl, isNotTriviall
void UndefinedMemoryManipulationCheck::registerMatchers(MatchFinder *Finder) {
const auto NotTriviallyCopyableObject =
- hasType(pointsTo(cxxRecordDecl(isNotTriviallyCopyable())));
+ hasType(ast_matchers::hasCanonicalType(
+ pointsTo(cxxRecordDecl(isNotTriviallyCopyable()))));
// Check whether destination object is not TriviallyCopyable.
// Applicable to all three memory manipulation functions.
@@ -47,13 +48,21 @@ void UndefinedMemoryManipulationCheck::r
void UndefinedMemoryManipulationCheck::check(
const MatchFinder::MatchResult &Result) {
- if (const auto *Destination = Result.Nodes.getNodeAs<CallExpr>("dest")) {
- diag(Destination->getLocStart(), "undefined behavior, destination "
- "object is not TriviallyCopyable");
+ if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("dest")) {
+ QualType DestType = Call->getArg(0)->IgnoreImplicit()->getType();
+ if (!DestType->getPointeeType().isNull())
+ DestType = DestType->getPointeeType();
+ diag(Call->getLocStart(), "undefined behavior, destination object type %0 "
+ "is not TriviallyCopyable")
+ << DestType;
}
- if (const auto *Source = Result.Nodes.getNodeAs<CallExpr>("src")) {
- diag(Source->getLocStart(), "undefined behavior, source object is not "
- "TriviallyCopyable");
+ if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("src")) {
+ QualType SourceType = Call->getArg(1)->IgnoreImplicit()->getType();
+ if (!SourceType->getPointeeType().isNull())
+ SourceType = SourceType->getPointeeType();
+ diag(Call->getLocStart(),
+ "undefined behavior, source object type %0 is not TriviallyCopyable")
+ << SourceType;
}
}
Modified: clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp?rev=311651&r1=311650&r2=311651&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp Thu Aug 24 05:11:05 2017
@@ -10,6 +10,7 @@ using ::memmove;
using ::memset;
}
+namespace types {
// TriviallyCopyable types:
struct Plain {
int n;
@@ -55,88 +56,115 @@ struct VirtualBase : virtual Base {
// Incomplete type, assume it is TriviallyCopyable.
struct NoDef;
-void f(NoDef *s) {
+} // end namespace types
+
+void f(types::NoDef *s) {
memset(s, 0, 5);
}
template <typename T>
void memset_temp(T *b) {
memset(b, 0, sizeof(T));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc' is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
}
template <typename S, typename T>
void memcpy_temp(S *a, T *b) {
memcpy(a, b, sizeof(T));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
}
template <typename S, typename T>
void memmove_temp(S *a, T *b) {
memmove(a, b, sizeof(T));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+}
+
+namespace aliases {
+using Copy2 = types::Copy;
+typedef types::Move Move2;
}
void notTriviallyCopyable() {
- Plain p; // TriviallyCopyable for variety
- Destruct d;
- Copy c;
- Move m;
- VirtualFunc vf;
- VirtualBase vb;
+ types::Plain p; // TriviallyCopyable for variety
+ types::Destruct d;
+ types::Copy c;
+ types::Move m;
+ types::VirtualFunc vf;
+ types::VirtualBase vb;
memset(&vf, 0, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
memset(&d, 0, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
memset(&c, 0, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
std::memset(&m, 0, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
::memset(&vb, 0, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
memcpy(&p, &vf, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
memcpy(&p, &d, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Destruct'
memcpy(&c, &p, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
std::memcpy(&m, &p, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
::memcpy(&vb, &p, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
memmove(&vf, &p, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
memmove(&d, &p, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
memmove(&p, &c, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
std::memmove(&p, &m, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Move'
::memmove(&p, &vb, sizeof(int));
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualBase'
#define MEMSET memset(&vf, 0, sizeof(int));
MEMSET
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
#define MEMCPY memcpy(&d, &p, sizeof(int));
MEMCPY
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
#define MEMMOVE memmove(&p, &c, sizeof(int));
MEMMOVE
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
- memset_temp<VirtualFunc>(&vf);
- memcpy_temp<Plain, VirtualFunc>(&p, &vf);
- memmove_temp<Plain, VirtualFunc>(&p, &vf);
+ memset_temp<types::VirtualFunc>(&vf);
+ memcpy_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+ memmove_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+
+ aliases::Copy2 c2;
+ aliases::Move2 m2;
+ memset(&c2, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+ memset(&m2, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Move2'
+
+ typedef aliases::Copy2 Copy3;
+ typedef aliases::Copy2 *PCopy2;
+ typedef Copy3 *PCopy3;
+ Copy3 c3;
+ PCopy2 pc2;
+ PCopy3 pc3;
+ memset(&c3, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
+ memset(pc2, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+ memset(pc3, 0, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
}
void triviallyCopyable() {
- Plain p;
- Base base;
- Derived derived;
+ types::Plain p;
+ types::Base base;
+ types::Derived derived;
int i = 5;
int ia[3] = {1, 2, 3};
@@ -144,7 +172,7 @@ void triviallyCopyable() {
float fa[3] = {1.1, 2.2, 3.3};
bool b = false;
bool ba[2] = {true, false};
- E e = X;
+ types::E e = types::X;
p.n = 2;
memset(&p, 0, sizeof(int));
More information about the cfe-commits
mailing list