/******************************************************************************* * Copyright (c) 2011, 2013 Anton Gorenkov and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Anton Gorenkov - initial implementation * Marc-Andre Laperle * Nathan Ridge * Danny Ferreira *******************************************************************************/ package org.eclipse.cdt.codan.core.internal.checkers; import org.eclipse.cdt.codan.core.test.CheckerTestCase; import org.eclipse.cdt.codan.internal.checkers.ClassMembersInitializationChecker; /** * Test for {@see ClassMembersInitializationChecker} class */ public class ClassMembersInitializationCheckerTest extends CheckerTestCase { @Override public boolean isCpp() { return true; } @Override public void setUp() throws Exception { super.setUp(); enableProblems(ClassMembersInitializationChecker.ER_ID); } private void disableSkipConstructorsWithFCalls() { setPreferenceValue(ClassMembersInitializationChecker.ER_ID, ClassMembersInitializationChecker.PARAM_SKIP, false); } public void checkMultiErrorsOnLine(int line, int count) { for (int i = 0; i < count; ++i) { checkErrorLine(line); } assertEquals(count, markers.length); } // class C { // int m; // C() : m(0) {} // No warnings. // }; public void testInitializationListShouldBeChecked() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // int m; // C() { m = 0; } // No warnings. // }; public void testAssignmentsInConstructorShouldBeChecked() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // int m; // unsigned int ui; // float f; // double d; // bool b; // char c; // long l; // C() {} // 7 warnings for: m, ui, f, d, b, c, l. // }; public void testBasicTypesShouldBeInitialized() throws Exception { loadCodeAndRun(getAboveComment()); checkMultiErrorsOnLine(9, 7); } // class Value {}; // class C { // int* i; // Value* v; // C() {} // 2 warnings for: i, v. // } public void testPointersShouldBeInitialized() throws Exception { loadCodeAndRun(getAboveComment()); checkMultiErrorsOnLine(5, 2); } // class Value {}; // class C { // int& i; // Value& v; // C() {} // 2 warnings for: i, v. // } public void testReferencesShouldBeInitialized() throws Exception { loadCodeAndRun(getAboveComment()); checkMultiErrorsOnLine(5, 2); } // enum Enum { v1, v2 }; // class C { // Enum e; // C() {} // 1 warning for: e. // } public void testEnumsShouldBeInitialized() throws Exception { loadCodeAndRun(getAboveComment()); checkMultiErrorsOnLine(4, 1); } // enum Enum { v1, v2 }; // class Value {}; // typedef int IntTypedef; // typedef int* IntPtrTypedef; // typedef int& IntRefTypedef; // typedef Enum EnumTypedef; // typedef Value ValueTypedef; // class C { // IntTypedef i; // IntPtrTypedef ip; // IntRefTypedef ir; // EnumTypedef e; // ValueTypedef v; // C() {} // 5 warnings for: i, ip, ir, e. // } public void testTypedefsShouldBeInitialized() throws Exception { loadCodeAndRun(getAboveComment()); checkMultiErrorsOnLine(14, 4); } // class C { // C() : i1(0) {} // 1 warning for: i2. // C(int) : i2(0) {} // 1 warning for: i1. // int i1, i2; // }; public void testAFewConstructorsHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(2, 3); } // template <typename T1, typename T2> // class C { // C() : i1(0), t1(T1()) {} // 1 warning for: i2. // int i1, i2; // T1 t1; // T2 t2; // }; public void testTemplateClassHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(3); } // class C { // template <typename T> // C() : i1(0) {} // 1 warning for: i2. // int i1, i2; // }; public void testTemplateConstructorHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(3); } // class C { // C(); // No warnings. // int i; // }; public void testTemplateConstructorDeclarationOnlyHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // C(); // int i1, i2; // }; // C::C() : i1(0) {} // 1 warning for: i2. public void testExternalConstructorHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(5); } // template <typename T1, typename T2> // class C { // C(); // int i1, i2; // T1 t1; // T2 t2; // }; // template <typename T1, typename T2> // C<T1,T2>::C() : i1(0), t1(T1()) {} // 1 warning for: i2. public void testExternalConstructorOfTemplateClassHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(9); } // class C { // template <typename T> // C(); // int i1, i2; // }; // template <typename T> // C::C() : i1(0) {} // 1 warning for: i2. public void testExternalTemplateConstructorHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(7); } // template <typename T1, typename T2> // class C { // template <typename T> // C(); // int i1, i2; // T1 t1; // T2 t2; // }; // template <typename T1, typename T2> // template <typename T> // C<T1,T2>::C() : i1(0), t1(T1()) {} // 1 warning for: i2. public void testExternalTemplateConstructorOfTemplateClassHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(11); } // class C { // class NestedC { // NestedC() : i(0) {} // No warnings. // int i; // }; // C() {} // 1 warning for: i. // int i; // }; public void testNestedClassesHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(6); } // class C { // C() // 1 warning for: i. // { // class NestedC { // NestedC() { i = 0; } // No warnings. // int i; // }; // } // int i; // }; public void testNestedClassInConstructorHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(2); } // class C { // C(); // int i; // }; // // C::C() // 1 warning for: i. // { // class NestedC { // No warnings. // NestedC() { i = 0; } // int i; // }; // } public void testNestedClassInExternalConstructorHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(6); } // class C { // C() // 1 warning for: i. // { // class NestedC { // NestedC() { i = 0; } // No warnings. // void C() { i = 0; } // No warnings. // int i; // }; // } // int i; // }; public void testNestedClassWithMethodNamedAsAnotherClassHandling() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(2); } // class C { // C() {} // 1 warning for: i. // int someFunction() { i = 0; } // No warnings. // int i; // }; public void testAssignmentIsNotInConstructor() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(2); } // class CBase { // CBase() : i1(0) {} // No warnings. // int i1; // }; // class CDerived : public CBase { // CDerived() : i2(0) {} // No warnings. // int i2; // }; public void testBaseClassMemberShouldNotBeTakenIntoAccount() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // C() {} // No warnings. // static int i1, i2; // }; // int C::i1 = 0; // // NOTE: Static members are always initialized with 0, so there should not be warning on C::i2 // int C::i2; public void testNoErrorsOnStaticMembers() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // public: // C(const C& c) = delete; // int i1, i2; // }; public void testNoErrorsOnDeletedConstructor() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // void func(int & a) { a = 0; } // class C { // C() { func(i); } // No warnings. // int i; // }; public void testNoErrorsOnFunctionCallInitialization() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // void func(const int & a) {} // class C { // C() { func(i); } // 1 warning for: i. // int i; // }; public void testNoErrorsOnReadingFunctionCall() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(3); } // class C { // C() { (i1) = 0; *&i2 = 0; } // No warnings. // int i1, i2; // }; public void testNoErrorsOnComplexAssignment() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // C() : i1(0) { // No warnings. // i2 = i1; // int someVar = 0; // i3 = someVar; // } // int i1, i2, i3; // }; public void testNoErrorsOnChainInitialization() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class A { protected: A(){} public: int a; }; // 1 warning for: a. // class C: public A { // C() { // a = 1; // } // }; public void testErrorOnProtectedConstructor() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(1); } // struct S { // int i; // S() {} // 1 warning for: i. // }; public void testCheckStructs() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(3); } // union U { // int a; // char b; // U() { // No warnings. // a=0; // } // }; public void testSkipUnions() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // int c; // }; public void testNoErrorsIfThereIsNoConstructorsDefined() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class C { // int i; // C(bool b) { // No warnings. // if (b) // i = 0; // // else - 'i' will be not initialized // } // }; public void testNoErrorsIfMemberWasInitializedInOneOfTheIfBranch() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class A { // int a; // A(int a) { setA(a); } // No warnings. // A() { getA(); } // 1 warning for: a. // void setA(int a) { // this->a = a; // } // int getA() const { // return a; // } // }; public void testUsingMethodsInConstructorWithPreference() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(4); } // class A; // void initializeA1(A*); // void initializeA2(A**); // void initializeA3(A&); // // class A { // int a; // A() { initializeA1(this); } // No warnings. // A(int a) { initializeA2(&this); } // No warnings. // A(float a) { initializeA3(*this); } // No warnings. // A(double a) { initializeA3(*(this)); } // No warnings. // }; public void testUsingConstMethodsInConstructorWithPreference() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // class A { // int a; // A(int a) { setA(a); } // 1 warning for: a. // A() { getA(); } // 1 warning for: a. // void setA(int a) { // this->a = a; // } // int getA() const { // return a; // } // }; public void testUsingMethodsInConstructorWithoutPreference() throws Exception { disableSkipConstructorsWithFCalls(); loadCodeAndRun(getAboveComment()); checkErrorLines(3,4); } // class A; // void initializeA1(A*); // void initializeA2(A**); // void initializeA3(A&); // // class A { // int a; // A() { initializeA1(this); } // 1 warning for: a. // A(int a) { initializeA2(&this); } // 1 warning for: a. // A(float a) { initializeA3(*this); } // 1 warning for: a. // A(double a) { initializeA3(*(this)); } // 1 warning for: a. // }; public void testUsingConstMethodsInConstructorWithoutPreference() throws Exception { disableSkipConstructorsWithFCalls(); loadCodeAndRun(getAboveComment()); checkErrorLines(8,9,10,11); } // @file:test.h // class C { // int field; // C(); // void initObject(); //}; // @file:test.cpp // #include "test.h" // C::C() { // initObject(); // } public void testMethodDeclarationInOtherFile_368419() throws Exception { CharSequence[] code = getContents(2); loadcode(code[0].toString()); loadcode(code[1].toString()); runOnProject(); checkNoErrors(); } //class D { // int field; // D(const D& toBeCopied) { // *this = toBeCopied; // }; //}; public void testAssignThis_368420() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } //class D { // int field; // D(const D& toBeCopied) { // *(&(*this)) = toBeCopied; // }; //}; public void testAssignThisUnaryExpressions_368420() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } //class D { // int field; // D(const D& toBeCopied) { // this = toBeCopied; // }; //}; public void testAssignThisNonLValue_368420() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLines(3); } //class D { // int field; // D(); // D(const D& toBeCopied) { // D temp; // temp = *(&(*this)) = toBeCopied; // }; //}; public void testAssignThisMultiBinaryExpressions_368420() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } //@file:test.h //template <typename> //struct B; //@file:test.cpp //#include "test.h" // //template <typename> //struct A { //}; // //template <typename valueT> //struct B<A<valueT> > { // const A<valueT>& obj; // B(const A<valueT>& o) : obj(o) {} //}; public void testTemplatePartialSpecialization_368611() throws Exception { CharSequence[] code = getContents(2); loadcode(code[0].toString()); loadcode(code[1].toString()); runOnProject(); checkNoErrors(); } // struct S { // int i; // S() = default; // }; public void testDefaultConstructor_365498() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLine(3); } // struct S { // int i; // // S(S&) = default; // S(const S&) = default; // S(volatile S&) = default; // S(const volatile S&) = default; // S(S&&) = default; // S(const S&&) = default; // S(volatile S&&) = default; // S(const volatile S&&) = default; // }; public void testDefaultCopyOrMoveConstructor_395018() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // template <typename T> // struct S { // int i; // // S(const S&) = default; // S(S&&) = default; // }; public void testDefaultCopyOrMoveConstructorInTemplate_408303() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // struct A { // A(int n) : waldo(n) {} // A() : A(42) {} // int waldo; // }; public void testDelegatingConstructor_402607() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // struct A { // typedef A B; // A(int n) : waldo(n) {} // A() : B(42) {} // int waldo; // }; public void testDelegatingConstructorTypedef_402607() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // struct A { // A() {}; // int x = 0; // }; public void testNonstaticDataMemberInitializer_400673() throws Exception { loadCodeAndRun(getAboveComment()); checkNoErrors(); } }