diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -147,6 +147,7 @@ return compoundStmt( forEachDescendant( declStmt( + unless(has(decompositionDecl())), has(varDecl(hasLocalStorage(), hasType(qualType( hasCanonicalType(allOf( diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s performance-unnecessary-copy-initialization %t +// RUN: %check_clang_tidy -std=c++17 %s performance-unnecessary-copy-initialization %t template struct Iterator { @@ -637,3 +637,18 @@ } }; } + +void negativeStructuredBinding() { + // Structured bindings are not yet supported but can trigger false positives + // since the DecompositionDecl itself is unused and the check doesn't traverse + // VarDecls of the BindingDecls. + struct Pair { + ExpensiveToCopyType first; + ExpensiveToCopyType second; + }; + + Pair P; + const auto [C, D] = P; + C.constMethod(); + D.constMethod(); +}