[clang-tools-extra] [clang-tidy] Unsafe CRTP check (PR #82403)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 20 14:45:58 PST 2024


================
@@ -0,0 +1,232 @@
+// RUN: %check_clang_tidy %s bugprone-unsafe-crtp %t
+
+namespace class_implicit_ctor {
+template <typename T>
+class CRTP {};
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: the implicit default constructor of the CRTP is publicly accessible [bugprone-unsafe-crtp]
+// CHECK-MESSAGES: :[[@LINE-2]]:7: note: consider making it private
+// CHECK-FIXES: CRTP() = default;
+
+class A : CRTP<A> {};
+} // namespace class_implicit_ctor
+
+namespace class_uncostructible {
+template <typename T>
+class CRTP {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: the CRTP cannot be constructed from the derived class [bugprone-unsafe-crtp]
+// CHECK-MESSAGES: :[[@LINE-2]]:7: note: consider declaring the derived class as friend
+// CHECK-FIXES: friend T;
----------------
isuckatcs wrote:

I don't see how a factory function in a CRTP context would make sense. If the only constructor is for a static factory function, which is unaccessible by the derived class, then the derived class cannot be constructed either, right? Also since the goal of the CRTP is to provide some functionality to it's template parameter, having a factory method would just result in instantiating it on it's own, which also doesn't make sense, right?

Otherwise since the goal is to prevent any kind of accidental instantiation, the check assumes that every other constructor is private, and then we need the friend, since the derived class has no way to instantiate the CRTP. If anything else other than the derived class and the CRTP itself has access to the constructors, then accidental instantiation can happen, which we want to prevent.

If the class only provides static methods, then why would any other class inherit from it, or use it as a CRTP?

https://github.com/llvm/llvm-project/pull/82403


More information about the cfe-commits mailing list