From 20e43a27447564e83d9fd9ccbc44df1197cdd2d8 Mon Sep 17 00:00:00 2001 From: Danny Ferreira Date: Tue, 21 May 2013 21:24:48 -0400 Subject: [PATCH] Bug 402607 - [c++11] Invalid "member was not initialized warning" with delegating constructors Change-Id: I521918be7b8c1dd867b53bd22f7646e610651fb6 Reviewed-on: https://git.eclipse.org/r/13043 Reviewed-by: Nathan Ridge Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../ClassMembersInitializationChecker.java | 17 ++++++++++++++ ...ClassMembersInitializationCheckerTest.java | 22 +++++++++++++++++++ 2 files changed, 39 insertions(+) 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(); + } }