PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 1ms

/test/testclass.cpp

https://github.com/toralf/cppcheck
C++ | 6139 lines | 5314 code | 632 blank | 193 comment | 7 complexity | 9088e92ec4301a522b70a4bef6cb00a0 MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Cppcheck - A tool for static C/C++ code analysis
  3. * Copyright (C) 2007-2014 Daniel Marjamäki and Cppcheck team.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "tokenize.h"
  19. #include "checkclass.h"
  20. #include "testsuite.h"
  21. #include <sstream>
  22. extern std::ostringstream errout;
  23. class TestClass : public TestFixture {
  24. public:
  25. TestClass() : TestFixture("TestClass") {
  26. }
  27. private:
  28. void run() {
  29. TEST_CASE(virtualDestructor1); // Base class not found => no error
  30. TEST_CASE(virtualDestructor2); // Base class doesn't have a destructor
  31. TEST_CASE(virtualDestructor3); // Base class has a destructor, but it's not virtual
  32. TEST_CASE(virtualDestructor4); // Derived class doesn't have a destructor => no error
  33. TEST_CASE(virtualDestructor5); // Derived class has empty destructor => no error
  34. TEST_CASE(virtualDestructor6); // only report error if base class pointer that points at derived class is deleted
  35. TEST_CASE(virtualDestructorProtected);
  36. TEST_CASE(virtualDestructorInherited);
  37. TEST_CASE(virtualDestructorTemplate);
  38. TEST_CASE(virtualDestructorInconclusive); // ticket # 5807
  39. TEST_CASE(copyConstructor1);
  40. TEST_CASE(copyConstructor2); // ticket #4458
  41. TEST_CASE(operatorEq1);
  42. TEST_CASE(operatorEq2);
  43. TEST_CASE(operatorEq3); // ticket #3051
  44. TEST_CASE(operatorEq4); // ticket #3114
  45. TEST_CASE(operatorEq5); // ticket #3296
  46. TEST_CASE(operatorEqRetRefThis1);
  47. TEST_CASE(operatorEqRetRefThis2); // ticket #1323
  48. TEST_CASE(operatorEqRetRefThis3); // ticket #1405
  49. TEST_CASE(operatorEqRetRefThis4); // ticket #1451
  50. TEST_CASE(operatorEqRetRefThis5); // ticket #1550
  51. TEST_CASE(operatorEqRetRefThis6); // ticket #2479
  52. TEST_CASE(operatorEqRetRefThis7); // ticket #5782 endless recursion
  53. TEST_CASE(operatorEqToSelf1); // single class
  54. TEST_CASE(operatorEqToSelf2); // nested class
  55. TEST_CASE(operatorEqToSelf3); // multiple inheritance
  56. TEST_CASE(operatorEqToSelf4); // nested class with multiple inheritance
  57. TEST_CASE(operatorEqToSelf5); // ticket # 1233
  58. TEST_CASE(operatorEqToSelf6); // ticket # 1550
  59. TEST_CASE(operatorEqToSelf7);
  60. TEST_CASE(operatorEqToSelf8); // ticket #2179
  61. TEST_CASE(operatorEqToSelf9); // ticket #2592
  62. TEST_CASE(memsetOnStruct);
  63. TEST_CASE(memsetVector);
  64. TEST_CASE(memsetOnClass);
  65. TEST_CASE(memsetOnInvalid); // Ticket #5425: Crash upon invalid
  66. TEST_CASE(memsetOnStdPodType); // Ticket #5901 - std::uint8_t
  67. TEST_CASE(memsetOnFloat); // Ticket #5421
  68. TEST_CASE(mallocOnClass);
  69. TEST_CASE(this_subtraction); // warn about "this-x"
  70. // can member function be made const
  71. TEST_CASE(const1);
  72. TEST_CASE(const2);
  73. TEST_CASE(const3);
  74. TEST_CASE(const4);
  75. TEST_CASE(const5); // ticket #1482
  76. TEST_CASE(const6); // ticket #1491
  77. TEST_CASE(const7);
  78. TEST_CASE(const8); // ticket #1517
  79. TEST_CASE(const9); // ticket #1515
  80. TEST_CASE(const10); // ticket #1522
  81. TEST_CASE(const11); // ticket #1529
  82. TEST_CASE(const12); // ticket #1552
  83. TEST_CASE(const13); // ticket #1519
  84. TEST_CASE(const14);
  85. TEST_CASE(const15);
  86. TEST_CASE(const16); // ticket #1551
  87. TEST_CASE(const17); // ticket #1552
  88. TEST_CASE(const18);
  89. TEST_CASE(const19); // ticket #1612
  90. TEST_CASE(const20); // ticket #1602
  91. TEST_CASE(const21); // ticket #1683
  92. TEST_CASE(const22);
  93. TEST_CASE(const23); // ticket #1699
  94. TEST_CASE(const24); // ticket #1708
  95. TEST_CASE(const25); // ticket #1724
  96. TEST_CASE(const26); // ticket #1847
  97. TEST_CASE(const27); // ticket #1882
  98. TEST_CASE(const28); // ticket #1883
  99. TEST_CASE(const29); // ticket #1922
  100. TEST_CASE(const30);
  101. TEST_CASE(const31);
  102. TEST_CASE(const32); // ticket #1905 - member array is assigned
  103. TEST_CASE(const33);
  104. TEST_CASE(const34); // ticket #1964
  105. TEST_CASE(const35); // ticket #2001
  106. TEST_CASE(const36); // ticket #2003
  107. TEST_CASE(const37); // ticket #2081 and #2085
  108. TEST_CASE(const38); // ticket #2135
  109. TEST_CASE(const39);
  110. TEST_CASE(const40); // ticket #2228
  111. TEST_CASE(const41); // ticket #2255
  112. TEST_CASE(const42); // ticket #2282
  113. TEST_CASE(const43); // ticket #2377
  114. TEST_CASE(const44); // ticket #2595
  115. TEST_CASE(const45); // ticket #2664
  116. TEST_CASE(const46); // ticket #2636
  117. TEST_CASE(const47); // ticket #2670
  118. TEST_CASE(const48); // ticket #2672
  119. TEST_CASE(const49); // ticket #2795
  120. TEST_CASE(const50); // ticket #2943
  121. TEST_CASE(const51); // ticket #3040
  122. TEST_CASE(const52); // ticket #3048
  123. TEST_CASE(const53); // ticket #3049
  124. TEST_CASE(const54); // ticket #3052
  125. TEST_CASE(const55);
  126. TEST_CASE(const56); // ticket #3149
  127. TEST_CASE(const57); // tickets #2669 and #2477
  128. TEST_CASE(const58); // ticket #2698
  129. TEST_CASE(const59); // ticket #4646
  130. TEST_CASE(const60); // ticket #3322
  131. TEST_CASE(const61); // ticket #5606
  132. TEST_CASE(const62); // ticket #5701
  133. TEST_CASE(const63); // ticket #5983
  134. TEST_CASE(const64); // ticket #6268
  135. TEST_CASE(const_handleDefaultParameters);
  136. TEST_CASE(const_passThisToMemberOfOtherClass);
  137. TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
  138. TEST_CASE(assigningArrayElementIsNotAConstOperation);
  139. TEST_CASE(constoperator1); // operator< can often be const
  140. TEST_CASE(constoperator2); // operator<<
  141. TEST_CASE(constoperator3);
  142. TEST_CASE(constoperator4);
  143. TEST_CASE(constoperator5); // ticket #3252
  144. TEST_CASE(constincdec); // increment/decrement => non-const
  145. TEST_CASE(constassign1);
  146. TEST_CASE(constassign2);
  147. TEST_CASE(constincdecarray); // increment/decrement array element => non-const
  148. TEST_CASE(constassignarray);
  149. TEST_CASE(constReturnReference);
  150. TEST_CASE(constDelete); // delete member variable => not const
  151. TEST_CASE(constLPVOID); // a function that returns LPVOID can't be const
  152. TEST_CASE(constFunc); // a function that calls const functions can be const
  153. TEST_CASE(constVirtualFunc);
  154. TEST_CASE(constIfCfg); // ticket #1881 - fp when there are #if
  155. TEST_CASE(constFriend); // ticket #1921 - fp for friend function
  156. TEST_CASE(constUnion); // ticket #2111 - fp when there is a union
  157. TEST_CASE(constArrayOperator); // #4406
  158. TEST_CASE(initializerListOrder);
  159. TEST_CASE(initializerListUsage);
  160. TEST_CASE(selfInitialization);
  161. TEST_CASE(pureVirtualFunctionCall);
  162. TEST_CASE(pureVirtualFunctionCallOtherClass);
  163. TEST_CASE(pureVirtualFunctionCallWithBody);
  164. TEST_CASE(pureVirtualFunctionCallPrevented);
  165. TEST_CASE(duplInheritedMembers);
  166. }
  167. void checkDuplInheritedMembers(const char code[]) {
  168. // Clear the error log
  169. errout.str("");
  170. Settings settings;
  171. settings.addEnabled("warning");
  172. // Tokenize..
  173. Tokenizer tokenizer(&settings, this);
  174. std::istringstream istr(code);
  175. tokenizer.tokenize(istr, "test.cpp");
  176. tokenizer.simplifyTokenList2();
  177. // Check..
  178. CheckClass checkClass(&tokenizer, &settings, this);
  179. checkClass.checkDuplInheritedMembers();
  180. }
  181. void duplInheritedMembers() {
  182. checkDuplInheritedMembers("class Base {\n"
  183. " int x;\n"
  184. "};\n"
  185. "struct Derived : Base {\n"
  186. " int x;\n"
  187. "};");
  188. ASSERT_EQUALS("", errout.str());
  189. checkDuplInheritedMembers("class Base {\n"
  190. " protected:\n"
  191. " int x;\n"
  192. "};\n"
  193. "struct Derived : Base {\n"
  194. " int x;\n"
  195. "};");
  196. ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:3]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base'.\n", errout.str());
  197. checkDuplInheritedMembers("class Base {\n"
  198. " protected:\n"
  199. " int x;\n"
  200. "};\n"
  201. "struct Derived : public Base {\n"
  202. " int x;\n"
  203. "};");
  204. ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:3]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base'.\n", errout.str());
  205. checkDuplInheritedMembers("class Base0 {\n"
  206. " int x;\n"
  207. "};\n"
  208. "class Base1 {\n"
  209. " int x;\n"
  210. "};\n"
  211. "struct Derived : Base0, Base1 {\n"
  212. " int x;\n"
  213. "};");
  214. ASSERT_EQUALS("", errout.str());
  215. checkDuplInheritedMembers("class Base0 {\n"
  216. " protected:\n"
  217. " int x;\n"
  218. "};\n"
  219. "class Base1 {\n"
  220. " int x;\n"
  221. "};\n"
  222. "struct Derived : Base0, Base1 {\n"
  223. " int x;\n"
  224. "};");
  225. ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base0'.\n", errout.str());
  226. checkDuplInheritedMembers("class Base0 {\n"
  227. " protected:\n"
  228. " int x;\n"
  229. "};\n"
  230. "class Base1 {\n"
  231. " public:\n"
  232. " int x;\n"
  233. "};\n"
  234. "struct Derived : Base0, Base1 {\n"
  235. " int x;\n"
  236. "};");
  237. ASSERT_EQUALS("[test.cpp:10] -> [test.cpp:3]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base0'.\n"
  238. "[test.cpp:10] -> [test.cpp:7]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base1'.\n", errout.str());
  239. checkDuplInheritedMembers("class Base {\n"
  240. " int x;\n"
  241. "};\n"
  242. "struct Derived : Base {\n"
  243. " int y;\n"
  244. "};");
  245. ASSERT_EQUALS("", errout.str());
  246. checkDuplInheritedMembers("class A {\n"
  247. " int x;\n"
  248. "};\n"
  249. "struct B {\n"
  250. " int x;\n"
  251. "};");
  252. ASSERT_EQUALS("", errout.str());
  253. // Unknown 'Base' class
  254. checkDuplInheritedMembers("class Derived : public UnknownBase {\n"
  255. " int x;\n"
  256. "};");
  257. ASSERT_EQUALS("", errout.str());
  258. checkDuplInheritedMembers("class Base {\n"
  259. " int x;\n"
  260. "};\n"
  261. "class Derived : public Base {\n"
  262. "};");
  263. ASSERT_EQUALS("", errout.str());
  264. }
  265. void checkCopyConstructor(const char code[]) {
  266. // Clear the error log
  267. errout.str("");
  268. Settings settings;
  269. settings.addEnabled("style");
  270. // Tokenize..
  271. Tokenizer tokenizer(&settings, this);
  272. std::istringstream istr(code);
  273. tokenizer.tokenize(istr, "test.cpp");
  274. tokenizer.simplifyTokenList2();
  275. // Check..
  276. CheckClass checkClass(&tokenizer, &settings, this);
  277. checkClass.copyconstructors();
  278. }
  279. void copyConstructor1() {
  280. checkCopyConstructor("class F\n"
  281. "{\n"
  282. " public:\n"
  283. " char *c,*p,*d;\n"
  284. " F(const F &f) : p(f.p), c(f.c)\n"
  285. " {\n"
  286. " p=(char *)malloc(strlen(f.p)+1);\n"
  287. " strcpy(p,f.p);\n"
  288. " }\n"
  289. " F(char *str)\n"
  290. " {\n"
  291. " p=(char *)malloc(strlen(str)+1);\n"
  292. " strcpy(p,str);\n"
  293. " }\n"
  294. "};");
  295. ASSERT_EQUALS("[test.cpp:5]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n", errout.str());
  296. checkCopyConstructor("class F {\n"
  297. " char *p;\n"
  298. " F(const F &f) {\n"
  299. " p = f.p;\n"
  300. " }\n"
  301. " F(char *str) {\n"
  302. " p = malloc(strlen(str)+1);\n"
  303. " }\n"
  304. "};");
  305. TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n"
  306. "[test.cpp:3] -> [test.cpp:7]: (warning) Copy constructor does not allocate memory for member 'p' although memory has been allocated in other constructors.\n",
  307. "[test.cpp:4]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n"
  308. , errout.str());
  309. checkCopyConstructor("class F\n"
  310. "{\n"
  311. " public:\n"
  312. " char *c,*p,*d;\n"
  313. " F(const F &f) :p(f.p)\n"
  314. " {\n"
  315. " }\n"
  316. " F(char *str)\n"
  317. " {\n"
  318. " p=(char *)malloc(strlen(str)+1);\n"
  319. " strcpy(p,str);\n"
  320. " }\n"
  321. "};");
  322. TODO_ASSERT_EQUALS("[test.cpp:5]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n"
  323. "[test.cpp:5] -> [test.cpp:10]: (warning) Copy constructor does not allocate memory for member 'p' although memory has been allocated in other constructors.\n",
  324. "[test.cpp:5]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n"
  325. , errout.str());
  326. checkCopyConstructor("class kalci\n"
  327. "{\n"
  328. " public:\n"
  329. " char *c,*p,*d;\n"
  330. " kalci()\n"
  331. " {\n"
  332. " p=(char *)malloc(100);\n"
  333. " strcpy(p,\"hello\");\n"
  334. " c=(char *)malloc(100);\n"
  335. " strcpy(p,\"hello\");\n"
  336. " d=(char *)malloc(100);\n"
  337. " strcpy(p,\"hello\");\n"
  338. " }\n"
  339. " kalci(const kalci &f)\n"
  340. " {\n"
  341. " p=(char *)malloc(strlen(str)+1);\n"
  342. " strcpy(p,f.p);\n"
  343. " c=(char *)malloc(strlen(str)+1);\n"
  344. " strcpy(p,f.p);\n"
  345. " d=(char *)malloc(strlen(str)+1);\n"
  346. " strcpy(p,f.p);\n"
  347. " }\n"
  348. "};");
  349. ASSERT_EQUALS("", errout.str());
  350. checkCopyConstructor("class F\n"
  351. "{\n"
  352. " public:\n"
  353. " char *c,*p,*d;\n"
  354. " F(char *str,char *st,char *string)\n"
  355. " {\n"
  356. " p=(char *)malloc(100);\n"
  357. " strcpy(p,str);\n"
  358. " c=(char *)malloc(100);\n"
  359. " strcpy(p,st);\n"
  360. " d=(char *)malloc(100);\n"
  361. " strcpy(p,string);\n"
  362. " }\n"
  363. " F(const F &f)\n"
  364. " {\n"
  365. " p=(char *)malloc(strlen(str)+1);\n"
  366. " strcpy(p,f.p);\n"
  367. " c=(char *)malloc(strlen(str)+1);\n"
  368. " strcpy(p,f.p);\n"
  369. " }\n"
  370. "};");
  371. TODO_ASSERT_EQUALS("[test.cpp:14] -> [test.cpp:11]: (warning) Copy constructor does not allocate memory for member 'd' although memory has been allocated in other constructors.\n", "", errout.str());
  372. checkCopyConstructor("class F {\n"
  373. " char *c;\n"
  374. " F(char *str,char *st,char *string) {\n"
  375. " p=(char *)malloc(100);\n"
  376. " }\n"
  377. " F(const F &f)\n"
  378. " : p(malloc(size))\n"
  379. " {\n"
  380. " }\n"
  381. "};");
  382. ASSERT_EQUALS("", errout.str());
  383. checkCopyConstructor("class F {\n"
  384. " char *c;\n"
  385. " F(char *str,char *st,char *string)\n"
  386. " : p(malloc(size))\n"
  387. " {\n"
  388. " }\n"
  389. " F(const F &f)\n"
  390. " {\n"
  391. " }\n"
  392. "};");
  393. TODO_ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:4]: (warning) Copy constructor does not allocate memory for member 'd' although memory has been allocated in other constructors.\n", "", errout.str());
  394. checkCopyConstructor("class F\n"
  395. "{\n"
  396. " public:\n"
  397. " char *c,*p,*d;\n"
  398. " F()\n"
  399. " {\n"
  400. " p=(char *)malloc(100);\n"
  401. " c=(char *)malloc(100);\n"
  402. " d=(char*)malloc(100);\n"
  403. " }\n"
  404. "};");
  405. ASSERT_EQUALS("[test.cpp:1]: (style) 'class F' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.\n", errout.str());
  406. checkCopyConstructor("class F\n"
  407. "{\n"
  408. " public:\n"
  409. " char *c;\n"
  410. " const char *p,*d;\n"
  411. " F(char *str,char *st,char *string)\n"
  412. " {\n"
  413. " p=str;\n"
  414. " d=st;\n"
  415. " c=(char *)malloc(strlen(string)+1);\n"
  416. " strcpy(d,string);\n"
  417. " }\n"
  418. " F(const F &f)\n"
  419. " {\n"
  420. " p=f.p;\n"
  421. " d=f.d;\n"
  422. " c=(char *)malloc(strlen(str)+1);\n"
  423. " strcpy(d,f.p);\n"
  424. " }\n"
  425. "};");
  426. ASSERT_EQUALS("", errout.str());
  427. checkCopyConstructor("class F : E\n"
  428. "{\n"
  429. " char *p;\n"
  430. " F() {\n"
  431. " p = malloc(100);\n"
  432. " }\n"
  433. "};");
  434. ASSERT_EQUALS("", errout.str());
  435. checkCopyConstructor("class E { E(E&); };\n" // non-copyable
  436. "class F : E\n"
  437. "{\n"
  438. " char *p;\n"
  439. " F() {\n"
  440. " p = malloc(100);\n"
  441. " }\n"
  442. "};");
  443. ASSERT_EQUALS("", errout.str());
  444. checkCopyConstructor("class E {};\n"
  445. "class F : E {\n"
  446. " char *p;\n"
  447. " F() {\n"
  448. " p = malloc(100);\n"
  449. " }\n"
  450. "};");
  451. TODO_ASSERT_EQUALS("[test.cpp:2]: (style) 'class F' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.\n", "", errout.str());
  452. checkCopyConstructor("class F {\n"
  453. " char *p;\n"
  454. " F() {\n"
  455. " p = malloc(100);\n"
  456. " }\n"
  457. " F(F& f);\n" // non-copyable
  458. "};");
  459. ASSERT_EQUALS("", errout.str());
  460. checkCopyConstructor("class F {\n"
  461. " char *p;\n"
  462. " F() : p(malloc(100)) {}\n"
  463. "};");
  464. ASSERT_EQUALS("[test.cpp:1]: (style) 'class F' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.\n", errout.str());
  465. }
  466. void copyConstructor2() { // ticket #4458
  467. checkCopyConstructor("template <class _Tp>\n"
  468. "class Vector\n"
  469. "{\n"
  470. "public:\n"
  471. " Vector() {\n"
  472. " _M_finish = new _Tp[ 42 ];\n"
  473. " }\n"
  474. " Vector( const Vector<_Tp>& v ) {\n"
  475. " }\n"
  476. " _Tp* _M_finish;\n"
  477. "};");
  478. ASSERT_EQUALS("", errout.str());
  479. }
  480. // Check the operator Equal
  481. void checkOpertorEq(const char code[]) {
  482. // Clear the error log
  483. errout.str("");
  484. Settings settings;
  485. settings.addEnabled("style");
  486. settings.inconclusive = true;
  487. // Tokenize..
  488. Tokenizer tokenizer(&settings, this);
  489. std::istringstream istr(code);
  490. tokenizer.tokenize(istr, "test.cpp");
  491. tokenizer.simplifyTokenList2();
  492. // Check..
  493. CheckClass checkClass(&tokenizer, &settings, this);
  494. checkClass.operatorEq();
  495. }
  496. void operatorEq1() {
  497. checkOpertorEq("class A\n"
  498. "{\n"
  499. "public:\n"
  500. " void goo() {}"
  501. " void operator=(const A&);\n"
  502. "};");
  503. ASSERT_EQUALS("[test.cpp:4]: (style) 'A::operator=' should return 'A &'.\n", errout.str());
  504. checkOpertorEq("class A\n"
  505. "{\n"
  506. "public:\n"
  507. " void goo() {}"
  508. " void operator=(const A&)=delete;\n"
  509. "};");
  510. ASSERT_EQUALS("", errout.str());
  511. checkOpertorEq("class A\n"
  512. "{\n"
  513. "private:\n"
  514. " void operator=(const A&);\n"
  515. "};");
  516. ASSERT_EQUALS("", errout.str());
  517. checkOpertorEq("class A\n"
  518. "{\n"
  519. "private:\n"
  520. " void operator=(const A&)=delete;\n"
  521. "};");
  522. ASSERT_EQUALS("", errout.str());
  523. checkOpertorEq("class A\n"
  524. "{\n"
  525. " void operator=(const A&);\n"
  526. "};");
  527. ASSERT_EQUALS("", errout.str());
  528. checkOpertorEq("class A\n"
  529. "{\n"
  530. "public:\n"
  531. " void goo() {}\n"
  532. "private:\n"
  533. " void operator=(const A&);\n"
  534. "};");
  535. ASSERT_EQUALS("", errout.str());
  536. checkOpertorEq("class A\n"
  537. "{\n"
  538. "public:\n"
  539. " void operator=(const A&);\n"
  540. "};\n"
  541. "class B\n"
  542. "{\n"
  543. "public:\n"
  544. " void operator=(const B&);\n"
  545. "};");
  546. ASSERT_EQUALS("[test.cpp:4]: (style) 'A::operator=' should return 'A &'.\n"
  547. "[test.cpp:9]: (style) 'B::operator=' should return 'B &'.\n", errout.str());
  548. checkOpertorEq("struct A\n"
  549. "{\n"
  550. " void operator=(const A&);\n"
  551. "};");
  552. ASSERT_EQUALS("[test.cpp:3]: (style) 'A::operator=' should return 'A &'.\n", errout.str());
  553. checkOpertorEq("struct A\n"
  554. "{\n"
  555. " void operator=(const A&)=delete;\n"
  556. "};");
  557. ASSERT_EQUALS("", errout.str());
  558. }
  559. void operatorEq2() {
  560. checkOpertorEq("class A\n"
  561. "{\n"
  562. "public:\n"
  563. " void * operator=(const A&);\n"
  564. "};");
  565. ASSERT_EQUALS("[test.cpp:4]: (style) 'A::operator=' should return 'A &'.\n", errout.str());
  566. checkOpertorEq("class A\n"
  567. "{\n"
  568. "public:\n"
  569. " A * operator=(const A&);\n"
  570. "};");
  571. ASSERT_EQUALS("[test.cpp:4]: (style) 'A::operator=' should return 'A &'.\n", errout.str());
  572. checkOpertorEq("class A\n"
  573. "{\n"
  574. "public:\n"
  575. " const A & operator=(const A&);\n"
  576. "};");
  577. ASSERT_EQUALS("[test.cpp:4]: (style) 'A::operator=' should return 'A &'.\n", errout.str());
  578. checkOpertorEq("class A\n"
  579. "{\n"
  580. "public:\n"
  581. " B & operator=(const A&);\n"
  582. "};");
  583. ASSERT_EQUALS("[test.cpp:4]: (style) 'A::operator=' should return 'A &'.\n", errout.str());
  584. }
  585. void operatorEq3() { // ticket #3051
  586. checkOpertorEq("class A\n"
  587. "{\n"
  588. "public:\n"
  589. " A * operator=(const A*);\n"
  590. "};");
  591. ASSERT_EQUALS("", errout.str());
  592. }
  593. void operatorEq4() { // ticket #3114 (infinite loop)
  594. checkOpertorEq("struct A {\n"
  595. " A& operator=(A const& a) { return operator=(&a); }\n"
  596. " A& operator=(const A*) { return *this; }\n"
  597. "};");
  598. ASSERT_EQUALS("", errout.str());
  599. }
  600. void operatorEq5() { // ticket #3296 (virtual operator)
  601. checkOpertorEq(
  602. "class A {\n"
  603. " virtual A& operator=(const A &a) {return *this};\n"
  604. "};");
  605. ASSERT_EQUALS("", errout.str());
  606. }
  607. // Check that operator Equal returns reference to this
  608. void checkOpertorEqRetRefThis(const char code[]) {
  609. // Clear the error log
  610. errout.str("");
  611. Settings settings;
  612. settings.addEnabled("style");
  613. // Tokenize..
  614. Tokenizer tokenizer(&settings, this);
  615. std::istringstream istr(code);
  616. tokenizer.tokenize(istr, "test.cpp");
  617. tokenizer.simplifyTokenList2();
  618. // Check..
  619. CheckClass checkClass(&tokenizer, &settings, this);
  620. checkClass.operatorEqRetRefThis();
  621. }
  622. void operatorEqRetRefThis1() {
  623. checkOpertorEqRetRefThis(
  624. "class A\n"
  625. "{\n"
  626. "public:\n"
  627. " A & operator=(const A &a) { return *this; }\n"
  628. "};");
  629. ASSERT_EQUALS("", errout.str());
  630. checkOpertorEqRetRefThis(
  631. "class A\n"
  632. "{\n"
  633. "public:\n"
  634. " A & operator=(const A &a) { return a; }\n"
  635. "};");
  636. ASSERT_EQUALS("[test.cpp:4]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  637. checkOpertorEqRetRefThis(
  638. "class A\n"
  639. "{\n"
  640. "public:\n"
  641. " A & operator=(const A &);\n"
  642. "};\n"
  643. "A & A::operator=(const A &a) { return *this; }");
  644. ASSERT_EQUALS("", errout.str());
  645. checkOpertorEqRetRefThis(
  646. "class A\n"
  647. "{\n"
  648. "public:\n"
  649. " A & operator=(const A &a);\n"
  650. "};\n"
  651. "A & A::operator=(const A &a) { return *this; }");
  652. ASSERT_EQUALS("", errout.str());
  653. checkOpertorEqRetRefThis(
  654. "class A\n"
  655. "{\n"
  656. "public:\n"
  657. " A & operator=(const A &);\n"
  658. "};\n"
  659. "A & A::operator=(const A &a) { return a; }");
  660. ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  661. checkOpertorEqRetRefThis(
  662. "class A\n"
  663. "{\n"
  664. "public:\n"
  665. " A & operator=(const A &a);\n"
  666. "};\n"
  667. "A & A::operator=(const A &a) { return a; }");
  668. ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  669. checkOpertorEqRetRefThis(
  670. "class A\n"
  671. "{\n"
  672. "public:\n"
  673. " class B\n"
  674. " {\n"
  675. " public:\n"
  676. " B & operator=(const B &b) { return *this; }\n"
  677. " };\n"
  678. "};");
  679. ASSERT_EQUALS("", errout.str());
  680. checkOpertorEqRetRefThis(
  681. "class A\n"
  682. "{\n"
  683. "public:\n"
  684. " class B\n"
  685. " {\n"
  686. " public:\n"
  687. " B & operator=(const B &b) { return b; }\n"
  688. " };\n"
  689. "};");
  690. ASSERT_EQUALS("[test.cpp:7]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  691. checkOpertorEqRetRefThis(
  692. "class A\n"
  693. "{\n"
  694. "public:\n"
  695. " class B\n"
  696. " {\n"
  697. " public:\n"
  698. " B & operator=(const B &);\n"
  699. " };\n"
  700. "};\n"
  701. "A::B & A::B::operator=(const A::B &b) { return *this; }");
  702. ASSERT_EQUALS("", errout.str());
  703. checkOpertorEqRetRefThis(
  704. "class A\n"
  705. "{\n"
  706. "public:\n"
  707. " class B\n"
  708. " {\n"
  709. " public:\n"
  710. " B & operator=(const B &);\n"
  711. " };\n"
  712. "};\n"
  713. "A::B & A::B::operator=(const A::B &b) { return b; }");
  714. ASSERT_EQUALS("[test.cpp:10]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  715. }
  716. void operatorEqRetRefThis2() {
  717. // ticket # 1323
  718. checkOpertorEqRetRefThis(
  719. "class szp\n"
  720. "{\n"
  721. " szp &operator =(int *other) {};\n"
  722. "};");
  723. ASSERT_EQUALS("[test.cpp:3]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  724. checkOpertorEqRetRefThis(
  725. "class szp\n"
  726. "{\n"
  727. " szp &operator =(int *other);\n"
  728. "};\n"
  729. "szp &szp::operator =(int *other) {}");
  730. ASSERT_EQUALS("[test.cpp:5]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  731. }
  732. void operatorEqRetRefThis3() {
  733. // ticket # 1405
  734. checkOpertorEqRetRefThis(
  735. "class A {\n"
  736. "public:\n"
  737. " inline A &operator =(int *other) { return (*this); };\n"
  738. " inline A &operator =(long *other) { return (*this = 0); };\n"
  739. "};");
  740. ASSERT_EQUALS("", errout.str());
  741. checkOpertorEqRetRefThis(
  742. "class A {\n"
  743. "public:\n"
  744. " A &operator =(int *other);\n"
  745. " A &operator =(long *other);\n"
  746. "};\n"
  747. "A &A::operator =(int *other) { return (*this); };\n"
  748. "A &A::operator =(long *other) { return (*this = 0); };");
  749. ASSERT_EQUALS("", errout.str());
  750. checkOpertorEqRetRefThis(
  751. "class A {\n"
  752. "public:\n"
  753. " inline A &operator =(int *other) { return (*this); };\n"
  754. " inline A &operator =(long *other) { return operator = (*(int *)other); };\n"
  755. "};");
  756. ASSERT_EQUALS("", errout.str());
  757. checkOpertorEqRetRefThis(
  758. "class A {\n"
  759. "public:\n"
  760. " A &operator =(int *other);\n"
  761. " A &operator =(long *other);\n"
  762. "};\n"
  763. "A &A::operator =(int *other) { return (*this); };\n"
  764. "A &A::operator =(long *other) { return operator = (*(int *)other); };");
  765. ASSERT_EQUALS("", errout.str());
  766. checkOpertorEqRetRefThis(
  767. "class A {\n"
  768. "public:\n"
  769. " A &operator =(int *other);\n"
  770. " A &operator =(long *other);\n"
  771. "};\n"
  772. "A &A::operator =(int *other) { return (*this); };\n"
  773. "A &A::operator =(long *other) { return this->operator = (*(int *)other); };");
  774. ASSERT_EQUALS("", errout.str());
  775. }
  776. void operatorEqRetRefThis4() {
  777. // ticket # 1451
  778. checkOpertorEqRetRefThis(
  779. "P& P::operator = (const P& pc)\n"
  780. "{\n"
  781. " return (P&)(*this += pc);\n"
  782. "}");
  783. ASSERT_EQUALS("", errout.str());
  784. }
  785. void operatorEqRetRefThis5() {
  786. // ticket # 1550
  787. checkOpertorEqRetRefThis(
  788. "class A {\n"
  789. "public:\n"
  790. " A & operator=(const A &a) { }\n"
  791. "};");
  792. ASSERT_EQUALS("[test.cpp:3]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  793. checkOpertorEqRetRefThis(
  794. "class A {\n"
  795. "public:\n"
  796. " A & operator=(const A &a);\n"
  797. "};\n"
  798. "A & A :: operator=(const A &a) { }");
  799. ASSERT_EQUALS("[test.cpp:5]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
  800. }
  801. void operatorEqRetRefThis6() { // ticket #2478 (segmentation fault)
  802. checkOpertorEqRetRefThis(
  803. "class UString {\n"
  804. "public:\n"
  805. " UString& assign( const char* c_str );\n"
  806. " UString& operator=( const UString& s );\n"
  807. "};\n"
  808. "UString& UString::assign( const char* c_str ) {\n"
  809. " std::string tmp( c_str );\n"
  810. " return assign( tmp );\n"
  811. "}\n"
  812. "UString& UString::operator=( const UString& s ) {\n"
  813. " return assign( s );\n"
  814. "}");
  815. }
  816. void operatorEqRetRefThis7() { // ticket #5782 Endless recursion in CheckClass::checkReturnPtrThis()
  817. checkOpertorEqRetRefThis(
  818. "class basic_fbstring {\n"
  819. " basic_fbstring& operator=(int il) {\n"
  820. " return assign();\n"
  821. " }\n"
  822. " basic_fbstring& assign() {\n"
  823. " return replace();\n"
  824. " }\n"
  825. " basic_fbstring& replaceImplDiscr() {\n"
  826. " return replace();\n"
  827. " }\n"
  828. " basic_fbstring& replace() {\n"
  829. " return replaceImplDiscr();\n"
  830. " }\n"
  831. "};\n");
  832. ASSERT_EQUALS("", errout.str());
  833. }
  834. // Check that operator Equal checks for assignment to self
  835. void checkOpertorEqToSelf(const char code[]) {
  836. // Clear the error log
  837. errout.str("");
  838. Settings settings;
  839. settings.addEnabled("warning");
  840. // Tokenize..
  841. Tokenizer tokenizer(&settings, this);
  842. std::istringstream istr(code);
  843. tokenizer.tokenize(istr, "test.cpp");
  844. tokenizer.simplifyTokenList2();
  845. // Check..
  846. CheckClass checkClass(&tokenizer, &settings, this);
  847. checkClass.operatorEqToSelf();
  848. }
  849. void operatorEqToSelf1() {
  850. // this test has an assignment test but it is not needed
  851. checkOpertorEqToSelf(
  852. "class A\n"
  853. "{\n"
  854. "public:\n"
  855. " A & operator=(const A &a) { if (&a != this) { } return *this; }\n"
  856. "};");
  857. ASSERT_EQUALS("", errout.str());
  858. // this test doesn't have an assignment test but it is not needed
  859. checkOpertorEqToSelf(
  860. "class A\n"
  861. "{\n"
  862. "public:\n"
  863. " A & operator=(const A &a) { return *this; }\n"
  864. "};");
  865. ASSERT_EQUALS("", errout.str());
  866. // this test needs an assignment test and has it
  867. checkOpertorEqToSelf(
  868. "class A\n"
  869. "{\n"
  870. "public:\n"
  871. " char *s;\n"
  872. " A & operator=(const A &a)\n"
  873. " {\n"
  874. " if (&a != this)\n"
  875. " {\n"
  876. " free(s);\n"
  877. " s = strdup(a.s);\n"
  878. " }\n"
  879. " return *this;\n"
  880. " }\n"
  881. "};");
  882. ASSERT_EQUALS("", errout.str());
  883. // this class needs an assignment test but doesn't have it
  884. checkOpertorEqToSelf(
  885. "class A\n"
  886. "{\n"
  887. "public:\n"
  888. " char *s;\n"
  889. " A & operator=(const A &a)\n"
  890. " {\n"
  891. " free(s);\n"
  892. " s = strdup(a.s);\n"
  893. " return *this;\n"
  894. " }\n"
  895. "};");
  896. ASSERT_EQUALS("[test.cpp:5]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory.\n", errout.str());
  897. // this test has an assignment test but doesn't need it
  898. checkOpertorEqToSelf(
  899. "class A\n"
  900. "{\n"
  901. "public:\n"
  902. " A & operator=(const A &);\n"
  903. "};\n"
  904. "A & A::operator=(const A &a) { if (&a != this) { } return *this; }");
  905. ASSERT_EQUALS("", errout.str());
  906. // this test doesn't have an assignment test but doesn't need it
  907. checkOpertorEqToSelf(
  908. "class A\n"
  909. "{\n"
  910. "public:\n"
  911. " A & operator=(const A &);\n"
  912. "};\n"
  913. "A & A::operator=(const A &a) { return *this; }");
  914. ASSERT_EQUALS("", errout.str());
  915. // this test needs an assignment test and has it
  916. checkOpertorEqToSelf(
  917. "class A\n"
  918. "{\n"
  919. "public:\n"
  920. " char *s;\n"
  921. " A & operator=(const A &);\n"
  922. "};\n"
  923. "A & A::operator=(const A &a)\n"
  924. "{\n"
  925. " if (&a != this)\n"
  926. " {\n"
  927. " free(s);\n"
  928. " s = strdup(a.s);\n"
  929. " }\n"
  930. " return *this;\n"
  931. "}");
  932. ASSERT_EQUALS("", errout.str());
  933. // this test needs an assignment test but doesn’t have it
  934. checkOpertorEqToSelf(
  935. "class A\n"
  936. "{\n"
  937. "public:\n"
  938. " char *s;\n"
  939. " A & operator=(const A &);\n"
  940. "};\n"
  941. "A & A::operator=(const A &a)\n"
  942. "{\n"
  943. " free(s);\n"
  944. " s = strdup(a.s);\n"
  945. " return *this;\n"
  946. "}");
  947. ASSERT_EQUALS("[test.cpp:7]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory.\n", errout.str());
  948. // ticket #1224
  949. checkOpertorEqToSelf(
  950. "const SubTree &SubTree::operator= (const SubTree &b)\n"
  951. "{\n"
  952. " CodeTree *oldtree = tree;\n"
  953. " tree = new CodeTree(*b.tree);\n"
  954. " delete oldtree;\n"
  955. " return *this;\n"
  956. "}\n"
  957. "const SubTree &SubTree::operator= (const CodeTree &b)\n"
  958. "{\n"
  959. " CodeTree *oldtree = tree;\n"
  960. " tree = new CodeTree(b);\n"
  961. " delete oldtree;\n"
  962. " return *this;\n"
  963. "}");
  964. ASSERT_EQUALS("", errout.str());
  965. }
  966. void operatorEqToSelf2() {
  967. // this test has an assignment test but doesn't need it
  968. checkOpertorEqToSelf(
  969. "class A\n"
  970. "{\n"
  971. "public:\n"
  972. " class B\n"
  973. " {\n"
  974. " public:\n"
  975. " B & operator=(const B &b) { if (&b != this) { } return *this; }\n"
  976. " };\n"
  977. "};");
  978. ASSERT_EQUALS("", errout.str());
  979. // this test doesn't have an assignment test but doesn't need it
  980. checkOpertorEqToSelf(
  981. "class A\n"
  982. "{\n"
  983. "public:\n"
  984. " class B\n"
  985. " {\n"
  986. " public:\n"
  987. " B & operator=(const B &b) { return *this; }\n"
  988. " };\n"
  989. "};");
  990. ASSERT_EQUALS("", errout.str());
  991. // this test needs an assignment test but has it
  992. checkOpertorEqToSelf(
  993. "class A\n"
  994. "{\n"
  995. "public:\n"
  996. " class B\n"
  997. " {\n"
  998. " public:\n"
  999. " char *s;\n"
  1000. " B & operator=(const B &b)\n"
  1001. " {\n"
  1002. " if (&b != this)\n"
  1003. " {\n"
  1004. " }\n"
  1005. " return *this;\n"
  1006. " }\n"
  1007. " };\n"
  1008. "};");
  1009. ASSERT_EQUALS("", errout.str());
  1010. // this test needs an assignment test but doesn't have it
  1011. checkOpertorEqToSelf(
  1012. "class A\n"
  1013. "{\n"
  1014. "public:\n"
  1015. " class B\n"
  1016. " {\n"
  1017. " public:\n"
  1018. " char *s;\n"
  1019. " B & operator=(const B &b)\n"
  1020. " {\n"
  1021. " free(s);\n"
  1022. " s = strdup(b.s);\n"
  1023. " return *this;\n"
  1024. " }\n"
  1025. " };\n"
  1026. "};");
  1027. ASSERT_EQUALS("[test.cpp:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory.\n", errout.str());
  1028. // this test has an assignment test but doesn't need it
  1029. checkOpertorEqToSelf(
  1030. "class A\n"
  1031. "{\n"
  1032. "public:\n"
  1033. " class B\n"
  1034. " {\n"
  1035. " public:\n"
  1036. " B & operator=(const B &);\n"
  1037. " };\n"
  1038. "};\n"
  1039. "A::B & A::B::operator=(const A::B &b) { if (&b != this) { } return *this; }");
  1040. ASSERT_EQUALS("", errout.str());
  1041. // this test doesn't have an assignment test but doesn't need it
  1042. checkOpertorEqToSelf(
  1043. "class A\n"
  1044. "{\n"
  1045. "public:\n"
  1046. " class B\n"
  1047. " {\n"
  1048. " public:\n"
  1049. " B & operator=(const B &);\n"
  1050. " };\n"
  1051. "};\n"
  1052. "A::B & A::B::operator=(const A::B &b) { return *this; }");
  1053. ASSERT_EQUALS("", errout.str());
  1054. // this test needs an assignment test and has it
  1055. checkOpertorEqToSelf(
  1056. "class A\n"
  1057. "{\n"
  1058. "public:\n"
  1059. " class B\n"
  1060. " {\n"
  1061. " public:\n"
  1062. " char * s;\n"
  1063. " B & operator=(const B &);\n"
  1064. " };\n"
  1065. "};\n"
  1066. "A::B & A::B::operator=(const A::B &b)\n"
  1067. "{\n"
  1068. " if (&b != this)\n"
  1069. " {\n"
  1070. " free(s);\n"
  1071. " s = strdup(b.s);\n"
  1072. " }\n"
  1073. " return *this;\n"
  1074. " }");
  1075. ASSERT_EQUALS("", errout.str());
  1076. // this test needs an assignment test but doesn't have it
  1077. checkOpertorEqToSelf(
  1078. "class A\n"
  1079. "{\n"
  1080. "public:\n"
  1081. " class B\n"
  1082. " {\n"
  1083. " public:\n"
  1084. " char * s;\n"
  1085. " B & operator=(const B &);\n"
  1086. " };\n"
  1087. "};\n"
  1088. "A::B & A::B::operator=(const A::B &b)\n"
  1089. "{\n"
  1090. " free(s);\n"
  1091. " s = strdup(b.s);\n"
  1092. " return *this;\n"
  1093. " }");
  1094. ASSERT_EQUALS("[test.cpp:11]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory.\n", errout.str());
  1095. }
  1096. void operatorEqToSelf3() {
  1097. // this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
  1098. checkOpertorEqToSelf(
  1099. "class A : public B, public C\n"
  1100. "{\n"
  1101. "public:\n"
  1102. " A & operator=(const A &a) { return *this; }\n"
  1103. "};");
  1104. ASSERT_EQUALS("", errout.str());
  1105. // this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it
  1106. checkOpertorEqToSelf(
  1107. "class A : public B, public C\n"
  1108. "{\n"
  1109. "public:\n"
  1110. " char *s;\n"
  1111. " A & operator=(const A &a)\n"
  1112. " {\n"
  1113. " free(s);\n"
  1114. " s = strdup(a.s);\n"
  1115. " return *this;\n"
  1116. " }\n"
  1117. "};");
  1118. ASSERT_EQUALS("", errout.str());
  1119. // this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
  1120. checkOpertorEqToSelf(
  1121. "class A : public B, public C\n"
  1122. "{\n"
  1123. "public:\n"
  1124. " A & operator=(const A &);\n"
  1125. "};\n"
  1126. "A & A::operator=(const A &a) { return *this; }");
  1127. ASSERT_EQUALS("", errout.str());
  1128. // this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it
  1129. checkOpertorEqToSelf(
  1130. "class A : public B, public C\n"
  1131. "{\n"
  1132. "public:\n"
  1133. " char *s;\n"
  1134. " A & operator=(const A &);\n"
  1135. "};\n"
  1136. "A & A::operator=(const A &a)\n"
  1137. "{\n"
  1138. " free(s);\n"
  1139. " s = strdup(a.s);\n"
  1140. " return *this;\n"
  1141. "}");
  1142. ASSERT_EQUALS("", errout.str());
  1143. }
  1144. void operatorEqToSelf4() {
  1145. // this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
  1146. checkOpertorEqToSelf(
  1147. "class A\n"
  1148. "{\n"
  1149. "public:\n"
  1150. " class B : public C, public D\n"
  1151. " {\n"
  1152. " public:\n"
  1153. " B & operator=(const B &b) { return *this; }\n"

Large files files are truncated, but you can click here to view the full file