Skip to content

Commit efa4dbc

Browse files
author
Felix Berger
committed
[clang-tidy] performance-unnecessary-copy-initialization: Look at the canonical type when checking for aliases.
This fixes a false positive case where for instance a pointer is obtained and declared using `auto`. Differential Revision: https://reviews.llvm.org/D103018 Reviewed-by: ymandel
1 parent a56bd7d commit efa4dbc

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ static bool isInitializingVariableImmutable(const VarDecl &InitializingVar,
100100
if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context))
101101
return false;
102102

103-
QualType T = InitializingVar.getType();
103+
QualType T = InitializingVar.getType().getCanonicalType();
104104
// The variable is a value type and we know it is only used as const. Safe
105105
// to reference it and avoid the copy.
106106
if (!isa<ReferenceType, PointerType>(T))

clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ struct ExpensiveToCopyType {
44
ExpensiveToCopyType();
55
virtual ~ExpensiveToCopyType();
66
const ExpensiveToCopyType &reference() const;
7+
const ExpensiveToCopyType *pointer() const;
78
void nonConstMethod();
89
bool constMethod() const;
910
};
@@ -548,6 +549,25 @@ void negativeCopiedFromGetterOfReferenceToModifiedVar() {
548549
Orig.nonConstMethod();
549550
}
550551

552+
void negativeAliasNonCanonicalPointerType() {
553+
ExpensiveToCopyType Orig;
554+
// The use of auto here hides that the type is a pointer type. The check needs
555+
// to look at the canonical type to detect the aliasing through this pointer.
556+
const auto Pointer = Orig.pointer();
557+
const auto NecessaryCopy = Pointer->reference();
558+
Orig.nonConstMethod();
559+
}
560+
561+
void negativeAliasTypedefedType() {
562+
typedef const ExpensiveToCopyType &ReferenceType;
563+
ExpensiveToCopyType Orig;
564+
// The typedef hides the fact that this is a reference type. The check needs
565+
// to look at the canonical type to detect the aliasing.
566+
ReferenceType Ref = Orig.reference();
567+
const auto NecessaryCopy = Ref.reference();
568+
Orig.nonConstMethod();
569+
}
570+
551571
void positiveCopiedFromGetterOfReferenceToConstVar() {
552572
ExpensiveToCopyType Orig;
553573
const auto &Ref = Orig.reference();

0 commit comments

Comments
 (0)