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

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 20 13:07: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:

If you want to use `boost::noncopyable` as a CRPT, then it is an interesting question.

The idea that the checker is built around is that we want to help the user ensuring, that their CRTP class won't be instantiated accidentally. This could be achieved by making the constructor accessible only to the derived class.

`boost::noncopyable` uses a protected constructor and makes the copy-constructor private, which if used as a CRTP would automatically trigger the other issue, when a protected constructor allows any template parameter to be passed. E.g.: `class Derived : Noncopyable<Foo> {};`

As a result I think a functionality such as `boost::noncopyable` is not suitable for a CRTP, but if the user insists on creating it `// NOLINT(bugprone-unsafe-crtp)` could be applied.

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


More information about the cfe-commits mailing list