mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-20 23:45:23 +02:00
Bug 368420 - FP in members not initialized in in copy constructor
This commit is contained in:
parent
ef1a32b6df
commit
53bc0f10e6
2 changed files with 64 additions and 6 deletions
|
@ -18,6 +18,7 @@ import java.util.Stack;
|
||||||
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
||||||
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
|
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
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.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
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
|
// 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 final Stack< Set<IField> > constructorsStack = new Stack< Set<IField> >();
|
||||||
|
private boolean skipConstructorsWithFCalls = skipConstructorsWithFCalls();
|
||||||
|
|
||||||
OnEachClass() {
|
OnEachClass() {
|
||||||
shouldVisitDeclarations = true;
|
shouldVisitDeclarations = true;
|
||||||
shouldVisitNames = true;
|
shouldVisitNames = true;
|
||||||
shouldVisitExpressions = skipConstructorsWithFCalls();
|
shouldVisitExpressions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,10 +104,11 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTExpression expression) {
|
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();
|
Set<IField> actualConstructorFields = constructorsStack.peek();
|
||||||
if (!actualConstructorFields.isEmpty()) {
|
if (!actualConstructorFields.isEmpty()) {
|
||||||
boolean skipCurrentConstructor = false;
|
|
||||||
IASTFunctionCallExpression fCall = (IASTFunctionCallExpression)expression;
|
IASTFunctionCallExpression fCall = (IASTFunctionCallExpression)expression;
|
||||||
IASTExpression fNameExp = fCall.getFunctionNameExpression();
|
IASTExpression fNameExp = fCall.getFunctionNameExpression();
|
||||||
if (fNameExp instanceof IASTIdExpression) {
|
if (fNameExp instanceof IASTIdExpression) {
|
||||||
|
@ -126,11 +129,20 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skipCurrentConstructor) {
|
|
||||||
constructorsStack.peek().clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,4 +497,50 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
|
||||||
runOnProject();
|
runOnProject();
|
||||||
checkNoErrors();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue