namespace clang::tidy::performance {
+namespace {
+
+AST_MATCHER(VarDecl, isNRVOVariable) { return Node.isNRVOVariable(); }
+
+} // namespace
+
NoAutomaticMoveCheck::NoAutomaticMoveCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) {
- const auto ConstLocalVariable =
+ const auto NonNrvoConstLocalVariable =
varDecl(hasLocalStorage(), unless(hasType(lValueReferenceType())),
+ unless(isNRVOVariable()),
hasType(qualType(
isConstQualified(),
hasCanonicalType(matchers::isExpensiveToCopy()),
cxxConstructExpr(
hasDeclaration(LValueRefCtor),
hasArgument(0, ignoringParenImpCasts(declRefExpr(
- to(ConstLocalVariable)))))
+ to(NonNrvoConstLocalVariable)))))
.bind("ctor_call")))))),
this);
}
<clang-tidy/checks/google/readability-avoid-underscore-in-googletest-name>` when using
``DISABLED_`` in the test suite name.
+- Fixed a false positive in :doc:`performance-no-automatic-move
+ <clang-tidy/checks/performance/no-automatic-move>` when warning would be
+ emitted for a const local variable to which NRVO is applied.
+
Removed checks
^^^^^^^^^^^^^^
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj' prevents automatic move [performance-no-automatic-move]
}
-Obj PositiveSelfConstValue() {
- const Obj obj = Make<Obj>();
- return obj;
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj' prevents automatic move [performance-no-automatic-move]
+Obj PositiveCantNrvo(bool b) {
+ const Obj obj1;
+ const Obj obj2;
+ if (b) {
+ return obj1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: constness of 'obj1' prevents automatic move [performance-no-automatic-move]
+ }
+ return obj2;
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj2' prevents automatic move [performance-no-automatic-move]
}
// FIXME: Ideally we would warn here too.
// Negatives.
StatusOr<Obj> Temporary() {
- return Make<const Obj>();
+ return Make<Obj>();
}
StatusOr<Obj> ConstTemporary() {
return Make<const Obj>();
}
-StatusOr<Obj> Nrvo() {
+StatusOr<Obj> ConvertingMoveConstructor() {
Obj obj = Make<Obj>();
return obj;
}
+Obj ConstNrvo() {
+ const Obj obj = Make<Obj>();
+ return obj;
+}
+
+Obj NotNrvo(bool b) {
+ Obj obj1;
+ Obj obj2;
+ if (b) {
+ return obj1;
+ }
+ return obj2;
+}
+
StatusOr<Obj> Ref() {
Obj &obj = Make<Obj &>();
return obj;