diff options
author | Felix Berger <flx@google.com> | 2016-03-05 21:17:58 +0000 |
---|---|---|
committer | Felix Berger <flx@google.com> | 2016-03-05 21:17:58 +0000 |
commit | adfdc14832213a80183c7665c2dfdfa466e13fc5 (patch) | |
tree | 3ff5793568f78e25c9497a020fe734d4c554b9fa /clang-tools-extra/test/clang-tidy | |
parent | ac25f2c0737179bb90ec6c29d11ccd8930f78215 (diff) | |
download | bcm5719-llvm-adfdc14832213a80183c7665c2dfdfa466e13fc5.tar.gz bcm5719-llvm-adfdc14832213a80183c7665c2dfdfa466e13fc5.zip |
[clang-tidy] Extend UnnecessaryCopyInitialization check to trigger on non-const copies that can be safely converted to const references.
Summary:
Move code shared between UnnecessaryCopyInitialization and ForRangeCopyCheck into utilities files.
Add more test cases for UnnecessaryCopyInitialization and disable fixes inside of macros.
Reviewers: alexfh
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D17488
llvm-svn: 262781
Diffstat (limited to 'clang-tools-extra/test/clang-tidy')
-rw-r--r-- | clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp index aaaeffd652a..5a4520e0f3b 100644 --- a/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp +++ b/clang-tools-extra/test/clang-tidy/performance-unnecessary-copy-initialization.cpp @@ -4,6 +4,7 @@ struct ExpensiveToCopyType { ExpensiveToCopyType() {} virtual ~ExpensiveToCopyType() {} const ExpensiveToCopyType &reference() const { return *this; } + void nonConstMethod() {} }; struct TrivialToCopyType { @@ -20,6 +21,11 @@ const TrivialToCopyType &TrivialTypeReference() { return *Type; } +void mutate(ExpensiveToCopyType &); +void mutate(ExpensiveToCopyType *); +void useAsConstReference(const ExpensiveToCopyType &); +void useByValue(ExpensiveToCopyType); + void PositiveFunctionCall() { const auto AutoAssigned = ExpensiveTypeReference(); // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' is copy-constructed from a const reference; consider making it a const reference [performance-unnecessary-copy-initialization] @@ -114,11 +120,53 @@ void NegativeStaticLocalVar(const ExpensiveToCopyType &Obj) { static const auto StaticVar = Obj.reference(); } -void NegativeFunctionCallExpensiveTypeNonConstVariable() { +void PositiveFunctionCallExpensiveTypeNonConstVariable() { auto AutoAssigned = ExpensiveTypeReference(); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoAssigned' is copy-constructed from a const reference but is only used as const reference; consider making it a const reference [performance-unnecessary-copy-initialization] + // CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference(); auto AutoCopyConstructed(ExpensiveTypeReference()); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable + // CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference()); ExpensiveToCopyType VarAssigned = ExpensiveTypeReference(); + // CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable + // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference(); ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference()); + // CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable + // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference()); +} + +void positiveNonConstVarInCodeBlock(const ExpensiveToCopyType &Obj) { + { + auto Assigned = Obj.reference(); + // CHECK-MESSAGES: [[@LINE-1]]:10: warning: the variable + // CHECK-FIXES: const auto& Assigned = Obj.reference(); + Assigned.reference(); + useAsConstReference(Assigned); + useByValue(Assigned); + } +} + +void negativeNonConstVarWithNonConstUse(const ExpensiveToCopyType &Obj) { + { + auto NonConstInvoked = Obj.reference(); + // CHECK-FIXES: auto NonConstInvoked = Obj.reference(); + NonConstInvoked.nonConstMethod(); + } + { + auto Reassigned = Obj.reference(); + // CHECK-FIXES: auto Reassigned = Obj.reference(); + Reassigned = ExpensiveToCopyType(); + } + { + auto MutatedByReference = Obj.reference(); + // CHECK-FIXES: auto MutatedByReference = Obj.reference(); + mutate(MutatedByReference); + } + { + auto MutatedByPointer = Obj.reference(); + // CHECK-FIXES: auto MutatedByPointer = Obj.reference(); + mutate(&MutatedByPointer); + } } void NegativeMethodCallNonConstRef(ExpensiveToCopyType &Obj) { @@ -146,11 +194,32 @@ void NegativeObjIsNotParam() { ExpensiveToCopyType Obj; const auto AutoAssigned = Obj.reference(); const auto AutoCopyConstructed(Obj.reference()); - const ExpensiveToCopyType VarAssigned = Obj.reference(); - const ExpensiveToCopyType VarCopyConstructed(Obj.reference()); + ExpensiveToCopyType VarAssigned = Obj.reference(); + ExpensiveToCopyType VarCopyConstructed(Obj.reference()); } struct NegativeConstructor { NegativeConstructor(const ExpensiveToCopyType &Obj) : Obj(Obj) {} ExpensiveToCopyType Obj; }; + +#define UNNECESSARY_COPY_INIT_IN_MACRO_BODY(TYPE) \ + void functionWith##TYPE(const TYPE& T) { \ + auto AssignedInMacro = T.reference(); \ + } \ +// Ensure fix is not applied. +// CHECK-FIXES: auto AssignedInMacro = T.reference(); + + +UNNECESSARY_COPY_INIT_IN_MACRO_BODY(ExpensiveToCopyType) +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the variable 'AssignedInMacro' is copy-constructed + +#define UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(ARGUMENT) \ + ARGUMENT + +void PositiveMacroArgument(const ExpensiveToCopyType &Obj) { + UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference()); + // CHECK-MESSAGES: [[@LINE-1]]:48: warning: the variable 'CopyInMacroArg' is copy-constructed + // Ensure fix is not applied. + // CHECK-FIXES: auto CopyInMacroArg = Obj.reference() +} |