================
@@ -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

Reply via email to