diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp index 0dc47d5db93d..e277ad3419f7 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -79,6 +79,10 @@ UnnecessaryValueParamCheck::UnnecessaryValueParamCheck( Options.getLocalOrGlobal("IncludeStyle", "llvm"))) {} void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) { + // This check is specific to C++ and doesn't apply to languages like + // Objective-C. + if (!getLangOpts().CPlusPlus) + return; const auto ExpensiveValueParamDecl = parmVarDecl(hasType(hasCanonicalType(allOf( unless(referenceType()), matchers::isExpensiveToCopy()))), diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp index 6dd4141ba70c..2cdc506476b1 100644 --- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp +++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp @@ -45,7 +45,8 @@ llvm::Optional isExpensiveToCopy(QualType Type, return llvm::None; return !Type.isTriviallyCopyableType(Context) && !classHasTrivialCopyAndDestroy(Type) && - !hasDeletedCopyConstructor(Type); + !hasDeletedCopyConstructor(Type) && + !Type->isObjCLifetimeType(); } bool recordIsTriviallyDefaultConstructible(const RecordDecl &RecordDecl, diff --git a/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.m b/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.m new file mode 100644 index 000000000000..0a9ea0639ecd --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.m @@ -0,0 +1,16 @@ +// RUN: clang-tidy %s -checks=-*,performance-unnecessary-value-param -- \ +// RUN: -xobjective-c -fobjc-abi-version=2 -fobjc-arc | count 0 + +#if !__has_feature(objc_arc) +#error Objective-C ARC not enabled as expected +#endif + +// Passing an Objective-C ARC-managed object to a C function should +// not raise performance-unnecessary-value-param. +void foo(id object) { } + +// Same for explcitly non-ARC-managed Objective-C objects. +void bar(__unsafe_unretained id object) { } + +// Same for Objective-c classes. +void baz(Class c) { } diff --git a/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.mm b/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.mm new file mode 100644 index 000000000000..4ed05069a4b5 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param-arc.mm @@ -0,0 +1,16 @@ +// RUN: clang-tidy %s -checks=-*,performance-unnecessary-value-param -- \ +// RUN: -xobjective-c++ -fobjc-abi-version=2 -fobjc-arc | count 0 + +#if !__has_feature(objc_arc) +#error Objective-C ARC not enabled as expected +#endif + +// Passing an Objective-C ARC-managed object to a C function should +// not raise performance-unnecessary-value-param. +void foo(id object) { } + +// Same for explcitly non-ARC-managed Objective-C objects. +void bar(__unsafe_unretained id object) { } + +// Same for Objective-c classes. +void baz(Class c) { }