[clang-tools-extra] r256632 - [clang-tidy] Add UnnecessaryCopyInitialization check to new "performance" module in ClangTidy

Alexander Kornienko via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 30 02:24:41 PST 2015


Author: alexfh
Date: Wed Dec 30 04:24:40 2015
New Revision: 256632

URL: http://llvm.org/viewvc/llvm-project?rev=256632&view=rev
Log:
[clang-tidy] Add UnnecessaryCopyInitialization check to new "performance" module in ClangTidy

Summary:
The patch adds a new ClangTidy check that detects when expensive-to-copy types are unnecessarily copy initialized from a const reference that has the same or are larger scope than the copy.

It currently only detects this when the copied variable is const qualified. But this will be extended to non const variables if they are only used in a const fashion.

Reviewers: alexfh

Subscribers: cfe-commits

Patch by Felix Berger!

Differential Revision: http://reviews.llvm.org/D15623

Added:
    clang-tools-extra/trunk/clang-tidy/performance/
    clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/performance/PerformanceTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
    clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.h
    clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.cpp
    clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.h
    clang-tools-extra/trunk/test/clang-tidy/performance-unnecessary-copy-initialization.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/Makefile
    clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
    clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/CMakeLists.txt?rev=256632&r1=256631&r2=256632&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/CMakeLists.txt Wed Dec 30 04:24:40 2015
@@ -32,5 +32,6 @@ add_subdirectory(cppcoreguidelines)
 add_subdirectory(google)
 add_subdirectory(misc)
 add_subdirectory(modernize)
+add_subdirectory(performance)
 add_subdirectory(readability)
 add_subdirectory(utils)

Modified: clang-tools-extra/trunk/clang-tidy/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/Makefile?rev=256632&r1=256631&r2=256632&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/Makefile (original)
+++ clang-tools-extra/trunk/clang-tidy/Makefile Wed Dec 30 04:24:40 2015
@@ -11,6 +11,6 @@ CLANG_LEVEL := ../../..
 LIBRARYNAME := clangTidy
 include $(CLANG_LEVEL)/../../Makefile.config
 
-DIRS = utils cert cppcoreguidelines readability llvm google misc modernize tool
+DIRS = utils cert cppcoreguidelines readability llvm google misc modernize performance tool
 
 include $(CLANG_LEVEL)/Makefile

Added: clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt (added)
+++ clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt Wed Dec 30 04:24:40 2015
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyPerformanceModule
+  PerformanceTidyModule.cpp
+  UnnecessaryCopyInitialization.cpp
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangLex
+  clangTidy
+  clangTidyUtils
+  )

Added: clang-tools-extra/trunk/clang-tidy/performance/PerformanceTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/PerformanceTidyModule.cpp?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/performance/PerformanceTidyModule.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/performance/PerformanceTidyModule.cpp Wed Dec 30 04:24:40 2015
@@ -0,0 +1,39 @@
+//===--- PeformanceTidyModule.cpp - clang-tidy ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../ClangTidy.h"
+#include "../ClangTidyModule.h"
+#include "../ClangTidyModuleRegistry.h"
+
+#include "UnnecessaryCopyInitialization.h"
+
+namespace clang {
+namespace tidy {
+namespace performance {
+
+class PerformanceModule : public ClangTidyModule {
+public:
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<UnnecessaryCopyInitialization>(
+        "performance-unnecessary-copy-initialization");
+  }
+};
+
+// Register the PerformanceModule using this statically initialized variable.
+static ClangTidyModuleRegistry::Add<PerformanceModule>
+    X("performance-module", "Adds performance checks.");
+
+} // namespace performance
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the PerformanceModule.
+volatile int PerformanceModuleAnchorSource = 0;
+
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.cpp?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.cpp Wed Dec 30 04:24:40 2015
@@ -0,0 +1,73 @@
+//===--- UnnecessaryCopyInitialization.cpp - clang-tidy--------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UnnecessaryCopyInitialization.h"
+
+#include "../utils/LexerUtils.h"
+#include "../utils/Matchers.h"
+
+namespace clang {
+namespace tidy {
+namespace performance {
+
+using namespace ::clang::ast_matchers;
+
+namespace {
+AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); }
+AST_MATCHER(QualType, isPointerType) { return Node->isPointerType(); }
+} // namespace
+
+void UnnecessaryCopyInitialization::registerMatchers(
+    ast_matchers::MatchFinder *Finder) {
+  auto ConstReference = referenceType(pointee(qualType(isConstQualified())));
+  auto ConstOrConstReference =
+      allOf(anyOf(ConstReference, isConstQualified()),
+            unless(allOf(isPointerType(), unless(pointerType(pointee(qualType(
+                                              isConstQualified())))))));
+  // Match method call expressions where the this argument is a const
+  // type or const reference. This returned const reference is highly likely to
+  // outlive the local const reference of the variable being declared.
+  // The assumption is that the const reference being returned either points
+  // to a global static variable or to a member of the called object.
+  auto ConstRefReturningMethodCallOfConstParam = cxxMemberCallExpr(
+      callee(cxxMethodDecl(returns(ConstReference))),
+      on(declRefExpr(to(varDecl(hasType(qualType(ConstOrConstReference)))))));
+  auto ConstRefReturningFunctionCall =
+      callExpr(callee(functionDecl(returns(ConstReference))),
+               unless(callee(cxxMethodDecl())));
+  Finder->addMatcher(
+      varDecl(
+          isLocalVarDecl(), hasType(isConstQualified()),
+          hasType(matchers::isExpensiveToCopy()),
+          hasInitializer(cxxConstructExpr(
+              hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
+              hasArgument(0, anyOf(ConstRefReturningFunctionCall,
+                                   ConstRefReturningMethodCallOfConstParam)))))
+          .bind("varDecl"),
+      this);
+}
+
+void UnnecessaryCopyInitialization::check(
+    const ast_matchers::MatchFinder::MatchResult &Result) {
+  const auto *Var = Result.Nodes.getNodeAs<VarDecl>("varDecl");
+  SourceLocation AmpLocation = Var->getLocation();
+  auto Token = lexer_utils::getPreviousNonCommentToken(*Result.Context,
+                                                       Var->getLocation());
+  if (!Token.is(tok::unknown)) {
+    AmpLocation = Token.getLocation().getLocWithOffset(Token.getLength());
+  }
+  diag(Var->getLocation(),
+       "the const qualified variable '%0' is copy-constructed from a "
+       "const reference; consider making it a const reference")
+      << Var->getName() << FixItHint::CreateInsertion(AmpLocation, "&");
+}
+
+} // namespace performance
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.h?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.h (added)
+++ clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.h Wed Dec 30 04:24:40 2015
@@ -0,0 +1,38 @@
+//===--- UnnecessaryCopyInitialization.h - clang-tidy------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_COPY_INITIALIZATION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_COPY_INITIALIZATION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace performance {
+
+// A check that detects const local variable declarations that are copy
+// initialized with the const reference of a function call or the const
+// reference of a method call whose object is guaranteed to outlive the
+// variable's scope and suggests to use a const reference.
+//
+// The check currently only understands a subset of variables that are
+// guaranteed to outlive the const reference returned, namely: const variables,
+// const references, and const pointers to const.
+class UnnecessaryCopyInitialization : public ClangTidyCheck {
+public:
+  using ClangTidyCheck::ClangTidyCheck;
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace performance
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_COPY_INITIALIZATION_H

Modified: clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt?rev=256632&r1=256631&r2=256632&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt Wed Dec 30 04:24:40 2015
@@ -16,6 +16,7 @@ target_link_libraries(clang-tidy
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
+  clangTidyPerformanceModule
   clangTidyReadabilityModule
   clangTooling
   )

Modified: clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp?rev=256632&r1=256631&r2=256632&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp Wed Dec 30 04:24:40 2015
@@ -377,6 +377,11 @@ extern volatile int ModernizeModuleAncho
 static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination =
     ModernizeModuleAnchorSource;
 
+// This anchor is used to force the linker to link the PerformanceModule.
+extern volatile int PerformanceModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED PerformanceModuleAnchorDestination =
+    PerformanceModuleAnchorSource;
+
 // This anchor is used to force the linker to link the ReadabilityModule.
 extern volatile int ReadabilityModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED ReadabilityModuleAnchorDestination =

Modified: clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt?rev=256632&r1=256631&r2=256632&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt Wed Dec 30 04:24:40 2015
@@ -4,6 +4,7 @@ add_clang_library(clangTidyUtils
   HeaderGuard.cpp
   IncludeInserter.cpp
   IncludeSorter.cpp
+  LexerUtils.cpp
   TypeTraits.cpp
 
   LINK_LIBS

Added: clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.cpp?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.cpp Wed Dec 30 04:24:40 2015
@@ -0,0 +1,39 @@
+//===--- LexerUtils.cpp - clang-tidy---------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LexerUtils.h"
+
+namespace clang {
+namespace tidy {
+namespace lexer_utils {
+
+Token getPreviousNonCommentToken(const ASTContext &Context,
+                                 SourceLocation Location) {
+  const auto &SourceManager = Context.getSourceManager();
+  Token Token;
+  Token.setKind(tok::unknown);
+  Location = Location.getLocWithOffset(-1);
+  auto StartOfFile =
+      SourceManager.getLocForStartOfFile(SourceManager.getFileID(Location));
+  while (Location != StartOfFile) {
+    Location = Lexer::GetBeginningOfToken(Location, SourceManager,
+                                          Context.getLangOpts());
+    if (!Lexer::getRawToken(Location, Token, SourceManager,
+                            Context.getLangOpts()) &&
+        !Token.is(tok::comment)) {
+      break;
+    }
+    Location = Location.getLocWithOffset(-1);
+  }
+  return Token;
+}
+
+} // namespace lexer_utils
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.h?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.h (added)
+++ clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.h Wed Dec 30 04:24:40 2015
@@ -0,0 +1,29 @@
+//===--- LexerUtils.h - clang-tidy-------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+namespace tidy {
+namespace lexer_utils {
+
+// Returns previous non-comment token skipping over any comment text or
+// tok::unknown if not found.
+Token getPreviousNonCommentToken(const ASTContext &Context,
+                                 SourceLocation Location);
+
+} // namespace lexer_utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H

Added: clang-tools-extra/trunk/test/clang-tidy/performance-unnecessary-copy-initialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/performance-unnecessary-copy-initialization.cpp?rev=256632&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/performance-unnecessary-copy-initialization.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/performance-unnecessary-copy-initialization.cpp Wed Dec 30 04:24:40 2015
@@ -0,0 +1,152 @@
+// RUN: %check_clang_tidy %s performance-unnecessary-copy-initialization %t
+
+struct ExpensiveToCopyType {
+  ExpensiveToCopyType() {}
+  virtual ~ExpensiveToCopyType() {}
+  const ExpensiveToCopyType &reference() const { return *this; }
+};
+
+struct TrivialToCopyType {
+  const TrivialToCopyType &reference() const { return *this; }
+};
+
+const ExpensiveToCopyType &ExpensiveTypeReference() {
+  static const ExpensiveToCopyType *Type = new ExpensiveToCopyType();
+  return *Type;
+}
+
+const TrivialToCopyType &TrivialTypeReference() {
+  static const TrivialToCopyType *Type = new TrivialToCopyType();
+  return *Type;
+}
+
+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]
+  // CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
+  const auto AutoCopyConstructed(ExpensiveTypeReference());
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
+  const ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES:   const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
+  const ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
+}
+
+void PositiveMethodCallConstReferenceParam(const ExpensiveToCopyType &Obj) {
+  const auto AutoAssigned = Obj.reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+  const auto AutoCopyConstructed(Obj.reference());
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
+  const ExpensiveToCopyType VarAssigned = Obj.reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
+}
+
+void PositiveMethodCallConstParam(const ExpensiveToCopyType Obj) {
+  const auto AutoAssigned = Obj.reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
+  const auto AutoCopyConstructed(Obj.reference());
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
+  const ExpensiveToCopyType VarAssigned = Obj.reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
+}
+
+void PositiveMethodCallConstPointerParam(const ExpensiveToCopyType *const Obj) {
+  const auto AutoAssigned = Obj->reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
+  const auto AutoCopyConstructed(Obj->reference());
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& AutoCopyConstructed(Obj->reference());
+  const ExpensiveToCopyType VarAssigned = Obj->reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj->reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable
+  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj->reference());
+}
+
+void PositiveLocalConstValue() {
+  const ExpensiveToCopyType Obj;
+  const auto UnnecessaryCopy = Obj.reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& UnnecessaryCopy = Obj.reference();
+}
+
+void PositiveLocalConstRef() {
+  const ExpensiveToCopyType Obj;
+  const ExpensiveToCopyType &ConstReference = Obj.reference();
+  const auto UnnecessaryCopy = ConstReference.reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& UnnecessaryCopy = ConstReference.reference();
+}
+
+void PositiveLocalConstPointer() {
+  const ExpensiveToCopyType Obj;
+  const ExpensiveToCopyType *const ConstPointer = &Obj;
+  const auto UnnecessaryCopy = ConstPointer->reference();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable
+  // CHECK-FIXES: const auto& UnnecessaryCopy = ConstPointer->reference();
+}
+
+void NegativeFunctionCallTrivialType() {
+  const auto AutoAssigned = TrivialTypeReference();
+  const auto AutoCopyConstructed(TrivialTypeReference());
+  const TrivialToCopyType VarAssigned = TrivialTypeReference();
+  const TrivialToCopyType VarCopyConstructed(TrivialTypeReference());
+}
+
+void NegativeFunctionCallExpensiveTypeNonConstVariable() {
+  auto AutoAssigned = ExpensiveTypeReference();
+  auto AutoCopyConstructed(ExpensiveTypeReference());
+  ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
+  ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
+}
+
+void NegativeMethodCallNonConstRef(ExpensiveToCopyType &Obj) {
+  const auto AutoAssigned = Obj.reference();
+  const auto AutoCopyConstructed(Obj.reference());
+  const ExpensiveToCopyType VarAssigned = Obj.reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+}
+
+void NegativeMethodCallNonConst(ExpensiveToCopyType Obj) {
+  const auto AutoAssigned = Obj.reference();
+  const auto AutoCopyConstructed(Obj.reference());
+  const ExpensiveToCopyType VarAssigned = Obj.reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+}
+
+void NegativeMethodCallNonConstPointer(ExpensiveToCopyType *const Obj) {
+  const auto AutoAssigned = Obj->reference();
+  const auto AutoCopyConstructed(Obj->reference());
+  const ExpensiveToCopyType VarAssigned = Obj->reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
+}
+
+void NegativeObjIsNotParam() {
+  ExpensiveToCopyType Obj;
+  const auto AutoAssigned = Obj.reference();
+  const auto AutoCopyConstructed(Obj.reference());
+  const ExpensiveToCopyType VarAssigned = Obj.reference();
+  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
+}
+
+struct NegativeConstructor {
+  NegativeConstructor(const ExpensiveToCopyType &Obj) : Obj(Obj) {}
+  ExpensiveToCopyType Obj;
+};




More information about the cfe-commits mailing list