https://github.com/goldvitaly created 
https://github.com/llvm/llvm-project/pull/97766

Clang-Tidy unnecessary-value-param value param will be triggered for
templated functions if at least one instantiontion with expensive to
copy type is present in translation unit.

It is relatively common mistake to write lambda functions with auto
arguments for expensive to copy types.

Example:
Copy of the vectors will happen on every comparison.

void SortBySize(std::vector<std::vector<int>>& a) {
  std::sort(
      a.begin(), a.end(),
      [](auto x, auto y) { return a.size() < b.size()});
}


>From 1cf4340d7302e075a8785f23fd383db29cedd590 Mon Sep 17 00:00:00 2001
From: %username% <%userna...@google.com>
Date: Thu, 4 Jul 2024 22:32:19 +0200
Subject: [PATCH] Allow unnecessary-value-param to match templated functions
 including lambdas with auto.

Clang-Tidy unnecessary-value-param value param will be triggered for
templated functions if at least one instantiontion with expensive to
copy type is present in translation unit.

It is relatively common mistake to write lambda functions with auto
arguments for expensive to copy types.

Example:
Copy of the vectors will happen on every comparison.

void SortBySize(std::vector<std::vector<int>>& a) {
  std::sort(
      a.begin(), a.end(),
      [](auto x, auto y) { return a.size() < b.size()});
}
---
 .../unnecessary-value-param-templates.cpp     | 92 +++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp

diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp
new file mode 100644
index 0000000000000..4e6ec401f17c8
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy  -std=c++14-or-later %s 
performance-unnecessary-value-param %t
+
+struct ExpensiveToCopyType {
+  virtual ~ExpensiveToCopyType();
+};
+
+template <typename T> void templateWithNonTemplatizedParameter(const 
ExpensiveToCopyType S, T V) {
+  // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'S'
+  // CHECK-MESSAGES: [[@LINE-2]]:95: warning: the parameter 'V'
+  // CHECK-FIXES: template <typename T> void 
templateWithNonTemplatizedParameter(const ExpensiveToCopyType& S, const T& V) {
+}
+
+void instantiatedWithExpensiveValue() {
+  templateWithNonTemplatizedParameter(
+      ExpensiveToCopyType(), ExpensiveToCopyType());
+  templateWithNonTemplatizedParameter(ExpensiveToCopyType(), 5);
+}
+
+template <typename T> void 
templateWithNonTemplatizedParameterCheapTemplate(const ExpensiveToCopyType S, T 
V) {
+  // CHECK-MESSAGES: [[@LINE-1]]:103: warning: the const qualified parameter 
'S'
+  // CHECK-FIXES: template <typename T> void 
templateWithNonTemplatizedParameterCheapTemplate(const ExpensiveToCopyType& S, 
T V) {
+}
+
+void instantiatedWithCheapValue() {
+  templateWithNonTemplatizedParameterCheapTemplate(ExpensiveToCopyType(), 5);
+}
+
+template <typename T> void nonInstantiatedTemplateWithConstValue(const T S) {}
+template <typename T> void nonInstantiatedTemplateWithNonConstValue(T S) {}
+
+template <typename T> void instantiatedTemplateSpecialization(T NoSpecS) {}
+template <>
+void instantiatedTemplateSpecialization<ExpensiveToCopyType>(
+    ExpensiveToCopyType SpecS) {
+  // CHECK-MESSAGES: [[@LINE-1]]:25: warning: the parameter 'SpecS'
+  // CHECK-FIXES: const T& NoSpecS
+  // CHECK-FIXES: const ExpensiveToCopyType& SpecS
+}
+
+void instantiatedTemplateSpecialization() {
+  instantiatedTemplateSpecialization(ExpensiveToCopyType());
+}
+
+template <typename T> void instantiatedTemplateWithConstValue(const T S) {
+  // CHECK-MESSAGES: [[@LINE-1]]:71: warning: the const qualified parameter 'S'
+  // CHECK-FIXES: template <typename T> void 
instantiatedTemplateWithConstValue(const T& S) {
+}
+
+void instantiatedConstValue() {
+  instantiatedTemplateWithConstValue(ExpensiveToCopyType());
+}
+
+template <typename T> void instantiatedTemplateWithNonConstValue(T S) {
+  // CHECK-MESSAGES: [[@LINE-1]]:68: warning: the parameter 'S'
+  // CHECK-FIXES: template <typename T> void 
instantiatedTemplateWithNonConstValue(const T& S) {
+}
+
+void instantiatedNonConstValue() {
+  instantiatedTemplateWithNonConstValue(ExpensiveToCopyType());
+}
+
+void lambdaConstValue() {
+  auto fn = [](const ExpensiveToCopyType S) {
+    // CHECK-MESSAGES: [[@LINE-1]]:42: warning: the const qualified parameter 
'S'
+    // CHECK-FIXES: auto fn = [](const ExpensiveToCopyType& S) {
+  };
+  fn(ExpensiveToCopyType());
+}
+
+void lambdaNonConstValue() {
+  auto fn = [](ExpensiveToCopyType S) {
+    // CHECK-MESSAGES: [[@LINE-1]]:36: warning: the parameter 'S'
+    // CHECK-FIXES: auto fn = [](const ExpensiveToCopyType& S) {
+  };
+  fn(ExpensiveToCopyType());
+}
+
+void lambdaConstAutoValue() {
+  auto fn = [](const auto S) {
+    // CHECK-MESSAGES: [[@LINE-1]]:27: warning: the const qualified parameter 
'S'
+    // CHECK-FIXES: auto fn = [](const auto& S) {
+  };
+  fn(ExpensiveToCopyType());
+}
+
+void lambdaNonConstAutoValue() {
+  auto fn = [](auto S) {
+    // CHECK-MESSAGES: [[@LINE-1]]:21: warning: the parameter 'S'
+    // CHECK-FIXES: auto fn = [](const auto& S) {
+  };
+  fn(ExpensiveToCopyType());
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to