1 // RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-incorrect-enable-shared-from-this %t
2 
3 // NOLINTBEGIN
4 namespace std {
5     template <typename T> class enable_shared_from_this {};
6 } //namespace std
7 // NOLINTEND
8 
9 class BadClassExample : std::enable_shared_from_this<BadClassExample> {};
10 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadClassExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
11 // CHECK-FIXES: public std::enable_shared_from_this<BadClassExample>
12 
13 class BadClass2Example : private std::enable_shared_from_this<BadClass2Example> {};
14 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadClass2Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
15 // CHECK-FIXES: public std::enable_shared_from_this<BadClass2Example>
16 
17 struct BadStructExample : private std::enable_shared_from_this<BadStructExample> {};
18 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'BadStructExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
19 // CHECK-FIXES: public std::enable_shared_from_this<BadStructExample>
20 
21 class GoodClassExample : public std::enable_shared_from_this<GoodClassExample> {};
22 
23 struct GoodStructExample : public std::enable_shared_from_this<GoodStructExample> {};
24 
25 struct GoodStruct2Example : std::enable_shared_from_this<GoodStruct2Example> {};
26 
27 class dummy_class1 {};
28 class dummy_class2 {};
29 
30 class BadMultiClassExample : std::enable_shared_from_this<BadMultiClassExample>, dummy_class1 {};
31 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClassExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
32 // CHECK-FIXES: public std::enable_shared_from_this<BadMultiClassExample>, dummy_class1
33 
34 class BadMultiClass2Example : dummy_class1, std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2 {};
35 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClass2Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
36 // CHECK-FIXES: dummy_class1, public std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2
37 
38 class BadMultiClass3Example : dummy_class1, dummy_class2, std::enable_shared_from_this<BadMultiClass3Example> {};
39 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClass3Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
40 // CHECK-FIXES: dummy_class1, dummy_class2, public std::enable_shared_from_this<BadMultiClass3Example>
41 
42 class ClassBase : public std::enable_shared_from_this<ClassBase> {};
43 class PrivateInheritClassBase : private ClassBase {};
44 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'PrivateInheritClassBase' is not publicly inheriting from 'ClassBase' which inherits from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
45 
46 class DefaultInheritClassBase : ClassBase {};
47 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'DefaultInheritClassBase' is not publicly inheriting from 'ClassBase' which inherits from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
48 
49 class PublicInheritClassBase : public ClassBase {};
50 
51 struct StructBase : public std::enable_shared_from_this<StructBase> {};
52 struct PrivateInheritStructBase : private StructBase {};
53 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'PrivateInheritStructBase' is not publicly inheriting from 'StructBase' which inherits from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
54 
55 struct DefaultInheritStructBase : StructBase {};
56 
57 struct PublicInheritStructBase : StructBase {};
58 
59 //alias the template itself
60 template <typename T> using esft_template = std::enable_shared_from_this<T>;
61 
62 class PrivateAliasTemplateClassBase : private esft_template<PrivateAliasTemplateClassBase> {};
63 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'PrivateAliasTemplateClassBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
64 // CHECK-FIXES: class PrivateAliasTemplateClassBase : public esft_template<PrivateAliasTemplateClassBase> {};
65 
66 class DefaultAliasTemplateClassBase : esft_template<DefaultAliasTemplateClassBase> {};
67 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'DefaultAliasTemplateClassBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
68 // CHECK-FIXES: class DefaultAliasTemplateClassBase : public esft_template<DefaultAliasTemplateClassBase> {};
69 
70 class PublicAliasTemplateClassBase : public esft_template<PublicAliasTemplateClassBase> {};
71 
72 struct PrivateAliasTemplateStructBase : private esft_template<PrivateAliasTemplateStructBase> {};
73 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'PrivateAliasTemplateStructBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
74 // CHECK-FIXES: struct PrivateAliasTemplateStructBase : public esft_template<PrivateAliasTemplateStructBase> {};
75 
76 struct DefaultAliasTemplateStructBase : esft_template<DefaultAliasTemplateStructBase> {};
77 
78 struct PublicAliasTemplateStructBase : public esft_template<PublicAliasTemplateStructBase> {};
79 
80 //alias with specific instance
81 using esft = std::enable_shared_from_this<ClassBase>;
82 class PrivateAliasClassBase : private esft {};
83 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'PrivateAliasClassBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
84 // CHECK-FIXES: class PrivateAliasClassBase : public esft {};
85 
86 class DefaultAliasClassBase : esft {};
87 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'DefaultAliasClassBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
88 // CHECK-FIXES: class DefaultAliasClassBase : public esft {};
89 
90 class PublicAliasClassBase : public esft {};
91 
92 struct PrivateAliasStructBase : private esft {};
93 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'PrivateAliasStructBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
94 // CHECK-FIXES: struct PrivateAliasStructBase : public esft {};
95 
96 struct DefaultAliasStructBase : esft {};
97 
98 struct PublicAliasStructBase : public esft {};
99 
100 //we can only typedef a specific instance of the template
101 typedef std::enable_shared_from_this<ClassBase> EnableSharedFromThis;
102 class PrivateTypedefClassBase : private EnableSharedFromThis {};
103 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'PrivateTypedefClassBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
104 // CHECK-FIXES: class PrivateTypedefClassBase : public EnableSharedFromThis {};
105 
106 class DefaultTypedefClassBase : EnableSharedFromThis {};
107 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'DefaultTypedefClassBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
108 // CHECK-FIXES: class DefaultTypedefClassBase : public EnableSharedFromThis {};
109 
110 class PublicTypedefClassBase : public EnableSharedFromThis {};
111 
112 struct PrivateTypedefStructBase : private EnableSharedFromThis {};
113 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'PrivateTypedefStructBase' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
114 // CHECK-FIXES: struct PrivateTypedefStructBase : public EnableSharedFromThis {};
115 
116 struct DefaultTypedefStructBase : EnableSharedFromThis {};
117 
118 struct PublicTypedefStructBase : public EnableSharedFromThis {};
119 
120 #define PRIVATE_ESFT_CLASS(ClassName) \
121    class ClassName: private std::enable_shared_from_this<ClassName> { \
122    };
123 
124 PRIVATE_ESFT_CLASS(PrivateEsftClass);
125 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'PrivateEsftClass' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
126 
127 #define DEFAULT_ESFT_CLASS(ClassName) \
128    class ClassName: std::enable_shared_from_this<ClassName> { \
129    };
130 
131 DEFAULT_ESFT_CLASS(DefaultEsftClass);
132 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'DefaultEsftClass' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
133 
134 #define PUBLIC_ESFT_CLASS(ClassName) \
135    class ClassName: public std::enable_shared_from_this<ClassName> { \
136    };
137 
138 PUBLIC_ESFT_CLASS(PublicEsftClass);
139 
140 #define PRIVATE_ESFT_STRUCT(StructName) \
141    struct StructName: private std::enable_shared_from_this<StructName> { \
142    };
143 
144 PRIVATE_ESFT_STRUCT(PrivateEsftStruct);
145 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'PrivateEsftStruct' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
146 
147 #define DEFAULT_ESFT_STRUCT(StructName) \
148    struct StructName: std::enable_shared_from_this<StructName> { \
149    };
150 
151 DEFAULT_ESFT_STRUCT(DefaultEsftStruct);
152 
153 #define PUBLIC_ESFT_STRUCT(StructName) \
154    struct StructName: std::enable_shared_from_this<StructName> { \
155    };
156 
157 PUBLIC_ESFT_STRUCT(PublicEsftStruct);
158 
159 struct A : std::enable_shared_from_this<A> {};
160 #define MACRO_A A
161 
162 class B : MACRO_A {};
163 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'B' is not publicly inheriting from 'A' which inherits from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
164 
165 class C : private MACRO_A {};
166 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'C' is not publicly inheriting from 'A' which inherits from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
167 
168 class D : public MACRO_A {};
169 
170 #define MACRO_PARAM(CLASS) std::enable_shared_from_this<CLASS>
171 
172 class E : MACRO_PARAM(E) {};
173 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'E' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
174 // CHECK-FIXES: class E : public MACRO_PARAM(E) {};
175 
176 class F : private MACRO_PARAM(F) {};
177 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'F' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
178 // CHECK-FIXES: class F : public MACRO_PARAM(F) {};
179 
180 class G : public MACRO_PARAM(G) {};
181