pytorch/c10/test/util/registry_test.cpp
cyy 8fa81a6066 Enable misc-use-internal-linkage check and apply fixes (#148948)
Enables clang-tidy rule [`misc-use-internal-linkage`](https://clang.llvm.org/extra/clang-tidy/checks/misc/use-internal-linkage.html). This new check was introduced in Clang-Tidy 18 and is available due to recent update of Clang-Tidy 19.

The check marks functions and variables used only in the translation unit as static. Therefore undesired symbols are not leaked into other units, more link time optimisations are possible and the resulting binaries may be smaller.

The detected violations were mostly fixed by using static. In other cases, the symbols were indeed consumed by others files, then their declaring headers were included. Still some declarations were wrong and have been fixed.

Pull Request resolved: https://github.com/pytorch/pytorch/pull/148948
Approved by: https://github.com/Skylion007
2025-03-12 14:22:56 +00:00

94 lines
2.6 KiB
C++

#include <gtest/gtest.h>
#include <iostream>
#include <memory>
#include <c10/util/Registry.h>
// Note: we use a different namespace to test if the macros defined in
// Registry.h actually works with a different namespace from c10.
namespace c10_test {
class Foo {
public:
explicit Foo(int x) {
// LOG(INFO) << "Foo " << x;
}
virtual ~Foo() = default;
};
// NOLINTNEXTLINE(misc-use-internal-linkage)
C10_DECLARE_REGISTRY(FooRegistry, Foo, int);
C10_DEFINE_REGISTRY(FooRegistry, Foo, int);
#define REGISTER_FOO(clsname) C10_REGISTER_CLASS(FooRegistry, clsname, clsname)
class Bar : public Foo {
public:
explicit Bar(int x) : Foo(x) {
// LOG(INFO) << "Bar " << x;
}
};
REGISTER_FOO(Bar);
class AnotherBar : public Foo {
public:
explicit AnotherBar(int x) : Foo(x) {
// LOG(INFO) << "AnotherBar " << x;
}
};
REGISTER_FOO(AnotherBar);
TEST(RegistryTest, CanRunCreator) {
std::unique_ptr<Foo> bar(FooRegistry()->Create("Bar", 1));
EXPECT_TRUE(bar != nullptr) << "Cannot create bar.";
std::unique_ptr<Foo> another_bar(FooRegistry()->Create("AnotherBar", 1));
EXPECT_TRUE(another_bar != nullptr);
}
TEST(RegistryTest, ReturnNullOnNonExistingCreator) {
EXPECT_EQ(FooRegistry()->Create("Non-existing bar", 1), nullptr);
}
// C10_REGISTER_CLASS_WITH_PRIORITY defines static variable
static void RegisterFooDefault() {
C10_REGISTER_CLASS_WITH_PRIORITY(
FooRegistry, FooWithPriority, c10::REGISTRY_DEFAULT, Foo);
}
static void RegisterFooDefaultAgain() {
C10_REGISTER_CLASS_WITH_PRIORITY(
FooRegistry, FooWithPriority, c10::REGISTRY_DEFAULT, Foo);
}
static void RegisterFooBarFallback() {
C10_REGISTER_CLASS_WITH_PRIORITY(
FooRegistry, FooWithPriority, c10::REGISTRY_FALLBACK, Bar);
}
static void RegisterFooBarPreferred() {
C10_REGISTER_CLASS_WITH_PRIORITY(
FooRegistry, FooWithPriority, c10::REGISTRY_PREFERRED, Bar);
}
TEST(RegistryTest, RegistryPriorities) {
FooRegistry()->SetTerminate(false);
RegisterFooDefault();
// throws because Foo is already registered with default priority
// NOLINTNEXTLINE(hicpp-avoid-goto,cppcoreguidelines-avoid-goto)
EXPECT_THROW(RegisterFooDefaultAgain(), std::runtime_error);
#ifdef __GXX_RTTI
// not going to register Bar because Foo is registered with Default priority
RegisterFooBarFallback();
std::unique_ptr<Foo> bar1(FooRegistry()->Create("FooWithPriority", 1));
EXPECT_EQ(dynamic_cast<Bar*>(bar1.get()), nullptr);
// will register Bar because of higher priority
RegisterFooBarPreferred();
std::unique_ptr<Foo> bar2(FooRegistry()->Create("FooWithPriority", 1));
EXPECT_NE(dynamic_cast<Bar*>(bar2.get()), nullptr);
#endif
}
} // namespace c10_test