diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java index 17c48840337..b7d2f619873 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java @@ -9,6 +9,7 @@ * Anton Gorenkov - initial implementation * Marc-Andre Laperle * Nathan Ridge + * Danny Ferreira *******************************************************************************/ package org.eclipse.cdt.codan.internal.checkers; @@ -39,8 +40,10 @@ import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; @@ -261,6 +264,20 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker { return null; if (constructor.getClassOwner().getKey() == ICompositeType.k_union) return null; + // Skip delegating constructors. + for (ICPPASTConstructorChainInitializer memberInitializer : functionDefinition.getMemberInitializers()) { + IASTName memberName = memberInitializer.getMemberInitializerId(); + if (memberName != null) { + IBinding memberBinding = memberName.resolveBinding(); + ICPPClassType classType = null; + if (memberBinding instanceof ICPPClassType) + classType = (ICPPClassType) memberBinding; + else if (memberBinding instanceof ICPPConstructor) + classType = ((ICPPConstructor) memberBinding).getClassOwner(); + if (classType != null && classType.isSameType(constructor.getClassOwner())) + return null; + } + } return constructor; } } diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java index e318918b84c..3277f796bf4 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java @@ -9,6 +9,7 @@ * Anton Gorenkov - initial implementation * Marc-Andre Laperle * Nathan Ridge + * Danny Ferreira *******************************************************************************/ package org.eclipse.cdt.codan.core.internal.checkers; @@ -602,4 +603,25 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase { loadCodeAndRun(getAboveComment()); checkNoErrors(); } + + // struct A { + // A(int n) : waldo(n) {} + // A() : A(42) {} // warning: "Member 'waldo' was not initialized in this constructor" + // int waldo; + // }; + public void testBug402607_delegatingConstructor() throws Exception { + loadCodeAndRun(getAboveComment()); + checkNoErrors(); + } + + // struct A { + // typedef A B; + // A(int n) : waldo(n) {} + // A() : B(42) {} // warning: "Member 'waldo' was not initialized in this constructor" + // int waldo; + // }; + public void testBug402607_delegatingConstructorTypedef() throws Exception { + loadCodeAndRun(getAboveComment()); + checkNoErrors(); + } }