================ @@ -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:
Since checking if a public or protected function can construct the class would require path sensitive analysis I'd add this example as a limitation to the docs. E.g.: ```c++ template <class T> class CRTP { CRTP(int I) {} public: static void hardToDetect(CRTP* Escape, int X) { if(X > 2) { Escape = new CRTP{1}; } } }; ``` Another solution would be to walk the callgraph, but that would just pollute the user with non-meaningful warnings. E.g.: ```c++ template <class T> class CRTP { CRTP(int I) {} public: void hardToDetect(CRTP* Escape, int X) { if(CRTP && X > 2) { Escape = new CRTP{1}; } } void warning1() { hardToDetect(nullptr, 3); } void warning2() { warning1(); } void warning3() { warning2(); } }; ``` In the above `CRTP` we could report a warning for every function, right? https://github.com/llvm/llvm-project/pull/82403 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits