mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 14:48:27 +08:00
[clang-tidy] support return c ? a : b; in bugprone-return-const-ref-from-parameter (#107657)
A `const &` parameter can also be returned via a conditional operator: `c ? a : b`. This change adds support for diagnosing returning these parameters with conditional operators.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ReturnConstRefFromParameterCheck.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
|
||||
@@ -15,19 +16,24 @@ using namespace clang::ast_matchers;
|
||||
namespace clang::tidy::bugprone {
|
||||
|
||||
void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) {
|
||||
const auto DRef = ignoringParens(
|
||||
declRefExpr(
|
||||
to(parmVarDecl(hasType(hasCanonicalType(
|
||||
qualType(lValueReferenceType(pointee(
|
||||
qualType(isConstQualified()))))
|
||||
.bind("type"))))
|
||||
.bind("param")))
|
||||
.bind("dref"));
|
||||
const auto Func =
|
||||
functionDecl(hasReturnTypeLoc(loc(
|
||||
qualType(hasCanonicalType(equalsBoundNode("type"))))))
|
||||
.bind("func");
|
||||
|
||||
Finder->addMatcher(returnStmt(hasReturnValue(DRef), hasAncestor(Func)), this);
|
||||
Finder->addMatcher(
|
||||
returnStmt(
|
||||
hasReturnValue(declRefExpr(
|
||||
to(parmVarDecl(hasType(hasCanonicalType(
|
||||
qualType(lValueReferenceType(pointee(
|
||||
qualType(isConstQualified()))))
|
||||
.bind("type"))))
|
||||
.bind("param")))),
|
||||
hasAncestor(
|
||||
functionDecl(hasReturnTypeLoc(loc(qualType(
|
||||
hasCanonicalType(equalsBoundNode("type"))))))
|
||||
.bind("func")))
|
||||
.bind("ret"),
|
||||
returnStmt(hasReturnValue(ignoringParens(conditionalOperator(
|
||||
eachOf(hasTrueExpression(DRef), hasFalseExpression(DRef)),
|
||||
hasAncestor(Func))))),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -85,8 +91,8 @@ void ReturnConstRefFromParameterCheck::check(
|
||||
const MatchFinder::MatchResult &Result) {
|
||||
const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("func");
|
||||
const auto *PD = Result.Nodes.getNodeAs<ParmVarDecl>("param");
|
||||
const auto *R = Result.Nodes.getNodeAs<ReturnStmt>("ret");
|
||||
const SourceRange Range = R->getRetValue()->getSourceRange();
|
||||
const auto *DRef = Result.Nodes.getNodeAs<DeclRefExpr>("dref");
|
||||
const SourceRange Range = DRef->getSourceRange();
|
||||
if (Range.isInvalid())
|
||||
return;
|
||||
|
||||
|
||||
@@ -163,6 +163,11 @@ Changes in existing checks
|
||||
<clang-tidy/checks/bugprone/posix-return>` check to support integer literals
|
||||
as LHS and posix call as RHS of comparison.
|
||||
|
||||
- Improved :doc:`bugprone-return-const-ref-from-parameter
|
||||
<clang-tidy/checks/bugprone/return-const-ref-from-parameter>` check to
|
||||
diagnose potential dangling references when returning a ``const &`` parameter
|
||||
by using the conditional operator ``cond ? var1 : var2``.
|
||||
|
||||
- Improved :doc:`bugprone-sizeof-expression
|
||||
<clang-tidy/checks/bugprone/sizeof-expression>` check to find suspicious
|
||||
usages of ``sizeof()``, ``alignof()``, and ``offsetof()`` when adding or
|
||||
|
||||
@@ -27,6 +27,10 @@ int const &f3(TConstRef a) { return a; }
|
||||
int const &f4(TConst &a) { return a; }
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter
|
||||
|
||||
int const &f5(TConst &a) { return true ? a : a; }
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: returning a constant reference parameter
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: returning a constant reference parameter
|
||||
|
||||
template <typename T>
|
||||
const T& tf1(const T &a) { return a; }
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter
|
||||
@@ -47,6 +51,11 @@ template <typename T>
|
||||
const T& itf4(typename ConstRef<T>::type a) { return a; }
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter
|
||||
|
||||
template <typename T>
|
||||
const T& itf5(const T &a) { return true ? a : a; }
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: returning a constant reference parameter
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:47: warning: returning a constant reference parameter
|
||||
|
||||
void instantiate(const int ¶m, const float ¶mf, int &mut_param, float &mut_paramf) {
|
||||
itf1(0);
|
||||
itf1(param);
|
||||
|
||||
Reference in New Issue
Block a user