1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 368420 - FP in members not initialized in in copy constructor

This commit is contained in:
Marc-Andre Laperle 2012-03-07 20:36:34 -05:00
parent ef1a32b6df
commit 53bc0f10e6
2 changed files with 64 additions and 6 deletions

View file

@ -18,6 +18,7 @@ import java.util.Stack;
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@ -67,11 +68,12 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
// NOTE: Classes can be nested and even can be declared in constructors of the other classes
private final Stack< Set<IField> > constructorsStack = new Stack< Set<IField> >();
private boolean skipConstructorsWithFCalls = skipConstructorsWithFCalls();
OnEachClass() {
shouldVisitDeclarations = true;
shouldVisitNames = true;
shouldVisitExpressions = skipConstructorsWithFCalls();
shouldVisitExpressions = true;
}
@Override
@ -102,10 +104,11 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
@Override
public int visit(IASTExpression expression) {
if (!constructorsStack.empty() && expression instanceof IASTFunctionCallExpression) {
boolean skipCurrentConstructor = false;
if (skipConstructorsWithFCalls && !constructorsStack.empty() && expression instanceof IASTFunctionCallExpression) {
Set<IField> actualConstructorFields = constructorsStack.peek();
if (!actualConstructorFields.isEmpty()) {
boolean skipCurrentConstructor = false;
IASTFunctionCallExpression fCall = (IASTFunctionCallExpression)expression;
IASTExpression fNameExp = fCall.getFunctionNameExpression();
if (fNameExp instanceof IASTIdExpression) {
@ -126,11 +129,20 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
}
}
}
}
}
// Bug 368420 - Skip constructor if pattern is *this = toBeCopied;
if(expression instanceof IASTBinaryExpression) {
IASTBinaryExpression binaryExpression = (IASTBinaryExpression) expression;
if(referencesThis(binaryExpression.getOperand1()) && binaryExpression.getOperand1().isLValue()) {
skipCurrentConstructor = true;
}
}
if (skipCurrentConstructor) {
constructorsStack.peek().clear();
}
}
}
return PROCESS_CONTINUE;
}

View file

@ -497,4 +497,50 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
runOnProject();
checkNoErrors();
}
//class D {
// int field;
// D(const D& toBeCopied) {
// *this = toBeCopied;
// };
//};
public void testBug368420_assignThis() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
//class D {
// int field;
// D(const D& toBeCopied) {
// *(&(*this)) = toBeCopied;
// };
//};
public void testBug368420_assignThisUnaryExpressions() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
//class D {
// int field;
// D(const D& toBeCopied) {
// this = toBeCopied;
// };
//};
public void testBug368420_assignThisNonLValue() throws Exception {
loadCodeAndRun(getAboveComment());
checkErrorLines(3);
}
//class D {
// int field;
// D();
// D(const D& toBeCopied) {
// D temp;
// temp = *(&(*this)) = toBeCopied;
// };
//};
public void testBug368420_assignThisMultiBinaryExpressions() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
}