Skip to content

Commit

Permalink
[clang-tidy]performance-unnecessary-copy-initialization: fix false ne…
Browse files Browse the repository at this point in the history
…gative

We're missing all cases where the return value is a type alias.

Unfortunately, this includes things we care about, such as
`std::vector<T>::operator[]` (return value is `const_reference`,
not `const T&`).

Match the canonical type instead.

Differential Revision: https://reviews.llvm.org/D112722
  • Loading branch information
legrosbuffle committed Oct 29, 2021
1 parent a21a6ed commit fc1b24d
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, isConstRefReturningMethodCall,
// returned either points to a global static variable or to a member of the
// called object.
return cxxMemberCallExpr(
callee(cxxMethodDecl(returns(matchers::isReferenceToConst()))
callee(cxxMethodDecl(
returns(hasCanonicalType(matchers::isReferenceToConst())))
.bind(MethodDeclId)),
on(declRefExpr(to(
varDecl(
Expand All @@ -97,7 +98,8 @@ AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) {
// Only allow initialization of a const reference from a free function if it
// has no arguments. Otherwise it could return an alias to one of its
// arguments and the arguments need to be checked for const use as well.
return callExpr(callee(functionDecl(returns(matchers::isReferenceToConst()))
return callExpr(callee(functionDecl(returns(hasCanonicalType(
matchers::isReferenceToConst())))
.bind(FunctionDeclId)),
argumentCountIs(0), unless(callee(cxxMethodDecl())))
.bind(InitFunctionCallId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ struct ExpensiveToCopyType {
ExpensiveToCopyType();
virtual ~ExpensiveToCopyType();
const ExpensiveToCopyType &reference() const;
using ConstRef = const ExpensiveToCopyType &;
ConstRef referenceWithAlias() const;
const ExpensiveToCopyType *pointer() const;
Iterator<ExpensiveToCopyType> begin() const;
Iterator<ExpensiveToCopyType> end() const;
Expand Down Expand Up @@ -206,6 +208,15 @@ void positiveNonConstVarInCodeBlock(const ExpensiveToCopyType &Obj) {
}
}

void positiveNonConstVarInCodeBlockWithAlias(const ExpensiveToCopyType &Obj) {
{
const ExpensiveToCopyType Assigned = Obj.referenceWithAlias();
// CHECK-MESSAGES: [[@LINE-1]]:31: warning: the const qualified variable
// CHECK-FIXES: const ExpensiveToCopyType& Assigned = Obj.referenceWithAlias();
useAsConstReference(Assigned);
}
}

void negativeNonConstVarWithNonConstUse(const ExpensiveToCopyType &Obj) {
{
auto NonConstInvoked = Obj.reference();
Expand Down

0 comments on commit fc1b24d

Please sign in to comment.