mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Bug 552076 - Fix false positive virtual method with qualified name
Change-Id: Iaf82368fce793f9c23d6e8a13d88bf57282f9ae9 Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
This commit is contained in:
parent
7a2ff27b91
commit
42daf203a6
2 changed files with 97 additions and 32 deletions
|
@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
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.ICPPASTFunctionDefinition;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
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.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
|
@ -104,18 +105,22 @@ public class VirtualMethodCallChecker extends AbstractIndexAstChecker {
|
||||||
IASTExpression fNameExp = fCall.getFunctionNameExpression();
|
IASTExpression fNameExp = fCall.getFunctionNameExpression();
|
||||||
IBinding fBinding = null;
|
IBinding fBinding = null;
|
||||||
IASTNode problemNode = expression;
|
IASTNode problemNode = expression;
|
||||||
|
boolean isQualified = false;
|
||||||
if (fNameExp instanceof IASTIdExpression) {
|
if (fNameExp instanceof IASTIdExpression) {
|
||||||
IASTIdExpression fName = (IASTIdExpression) fNameExp;
|
IASTIdExpression fName = (IASTIdExpression) fNameExp;
|
||||||
|
isQualified = fName.getName() instanceof ICPPASTQualifiedName;
|
||||||
fBinding = fName.getName().resolveBinding();
|
fBinding = fName.getName().resolveBinding();
|
||||||
} else if (fNameExp instanceof IASTFieldReference) {
|
} else if (fNameExp instanceof IASTFieldReference) {
|
||||||
IASTFieldReference fName = (IASTFieldReference) fNameExp;
|
IASTFieldReference fName = (IASTFieldReference) fNameExp;
|
||||||
problemNode = fName.getFieldName();
|
problemNode = fName.getFieldName();
|
||||||
if (referencesThis(fName.getFieldOwner()))
|
if (referencesThis(fName.getFieldOwner())) {
|
||||||
|
isQualified = fName.getFieldName() instanceof ICPPASTQualifiedName;
|
||||||
fBinding = fName.getFieldName().resolveBinding();
|
fBinding = fName.getFieldName().resolveBinding();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (fBinding instanceof ICPPMethod) {
|
if (fBinding instanceof ICPPMethod) {
|
||||||
ICPPMethod method = (ICPPMethod) fBinding;
|
ICPPMethod method = (ICPPMethod) fBinding;
|
||||||
if (method.isPureVirtual() || ClassTypeHelper.isVirtual(method)) {
|
if (method.isPureVirtual() || (!isQualified && ClassTypeHelper.isVirtual(method))) {
|
||||||
reportProblem(VIRTUAL_CALL_ID, problemNode);
|
reportProblem(VIRTUAL_CALL_ID, problemNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class Foo {
|
//class Foo {
|
||||||
//public:
|
//public:
|
||||||
//Foo();
|
// Foo();
|
||||||
//~Foo();
|
// ~Foo();
|
||||||
//virtual void bar();
|
// virtual void bar();
|
||||||
//virtual void pure() = 0;
|
// virtual void pure() = 0;
|
||||||
//virtual void notpure();
|
// virtual void notpure();
|
||||||
//};
|
//};
|
||||||
//Foo::Foo() {
|
//Foo::Foo() {
|
||||||
// pure();
|
// pure();
|
||||||
|
@ -53,11 +53,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class Foo {
|
//class Foo {
|
||||||
//public:
|
//public:
|
||||||
//Foo();
|
// Foo();
|
||||||
//~Foo();
|
// ~Foo();
|
||||||
//virtual void bar();
|
// virtual void bar();
|
||||||
//virtual void pure() = 0;
|
// virtual void pure() = 0;
|
||||||
//virtual void notpure();
|
// virtual void notpure();
|
||||||
//};
|
//};
|
||||||
//Foo::Foo() {
|
//Foo::Foo() {
|
||||||
// notpure();
|
// notpure();
|
||||||
|
@ -73,11 +73,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class Foo {
|
//class Foo {
|
||||||
//public:
|
//public:
|
||||||
//Foo();
|
// Foo();
|
||||||
//~Foo();
|
// ~Foo();
|
||||||
//virtual void bar();
|
// virtual void bar();
|
||||||
//virtual void pure() = 0;
|
// virtual void pure() = 0;
|
||||||
//virtual void notpure();
|
// virtual void notpure();
|
||||||
//};
|
//};
|
||||||
//Foo::Foo() {
|
//Foo::Foo() {
|
||||||
//}
|
//}
|
||||||
|
@ -93,11 +93,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class Foo {
|
//class Foo {
|
||||||
//public:
|
//public:
|
||||||
//Foo();
|
// Foo();
|
||||||
//~Foo();
|
// ~Foo();
|
||||||
//virtual void bar();
|
// virtual void bar();
|
||||||
//virtual void pure() = 0;
|
// virtual void pure() = 0;
|
||||||
//virtual void notpure();
|
// virtual void notpure();
|
||||||
//};
|
//};
|
||||||
//Foo::Foo() {
|
//Foo::Foo() {
|
||||||
//}
|
//}
|
||||||
|
@ -113,11 +113,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class Foo {
|
//class Foo {
|
||||||
//public:
|
//public:
|
||||||
//Foo();
|
// Foo();
|
||||||
//~Foo();
|
// ~Foo();
|
||||||
//virtual void bar();
|
// virtual void bar();
|
||||||
//virtual void pure() = 0;
|
// virtual void pure() = 0;
|
||||||
//virtual void notpure();
|
// virtual void notpure();
|
||||||
//};
|
//};
|
||||||
//Foo::Foo() {
|
//Foo::Foo() {
|
||||||
//}
|
//}
|
||||||
|
@ -138,7 +138,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
//};
|
//};
|
||||||
//class B {
|
//class B {
|
||||||
//private:
|
//private:
|
||||||
//A a;
|
// A a;
|
||||||
//public:
|
//public:
|
||||||
// B() { a.v(); }
|
// B() { a.v(); }
|
||||||
//};
|
//};
|
||||||
|
@ -149,7 +149,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class B {
|
//class B {
|
||||||
//private:
|
//private:
|
||||||
//A a;
|
// A a;
|
||||||
//public:
|
//public:
|
||||||
// B() { this->v(); }
|
// B() { this->v(); }
|
||||||
// virtual void v() {}
|
// virtual void v() {}
|
||||||
|
@ -161,7 +161,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
|
|
||||||
//class B {
|
//class B {
|
||||||
//private:
|
//private:
|
||||||
//A a;
|
// A a;
|
||||||
//public:
|
//public:
|
||||||
// B() { (*this).v(); }
|
// B() { (*this).v(); }
|
||||||
// virtual void v() {}
|
// virtual void v() {}
|
||||||
|
@ -181,7 +181,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
//};
|
//};
|
||||||
public void testVirtualMethodChildClass() throws Exception {
|
public void testVirtualMethodChildClass() throws Exception {
|
||||||
loadCodeAndRun(getAboveComment());
|
loadCodeAndRun(getAboveComment());
|
||||||
checkErrorLine(7, ERR_VIRTUAL_ID);
|
checkNoErrorsOfKind(ERR_VIRTUAL_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
//class Foo {
|
//class Foo {
|
||||||
|
@ -245,4 +245,64 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
|
||||||
loadCodeAndRun(getAboveComment());
|
loadCodeAndRun(getAboveComment());
|
||||||
checkErrorLines(4, 9);
|
checkErrorLines(4, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//class Foo {
|
||||||
|
//public:
|
||||||
|
// Foo();
|
||||||
|
// ~Foo();
|
||||||
|
// virtual void bar();
|
||||||
|
// virtual void pure() = 0;
|
||||||
|
// virtual void notpure();
|
||||||
|
//};
|
||||||
|
//Foo::Foo() {
|
||||||
|
// Foo::pure();
|
||||||
|
//}
|
||||||
|
//Foo::~Foo() {
|
||||||
|
//}
|
||||||
|
//Foo::bar() {
|
||||||
|
//}
|
||||||
|
public void testWithQualifiedPureInCtor_Bug552076() throws Exception {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(10, ERR_VIRTUAL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//class Foo {
|
||||||
|
//public:
|
||||||
|
// Foo();
|
||||||
|
// ~Foo();
|
||||||
|
// virtual void bar();
|
||||||
|
// virtual void pure() = 0;
|
||||||
|
// virtual void notpure();
|
||||||
|
//};
|
||||||
|
//Foo::Foo() {
|
||||||
|
// Foo::notpure();
|
||||||
|
//}
|
||||||
|
//Foo::~Foo() {
|
||||||
|
//}
|
||||||
|
//Foo::bar() {
|
||||||
|
//}
|
||||||
|
public void testWithQualifiedNotPureInCtor_Bug552076() throws Exception {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrorsOfKind(ERR_VIRTUAL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//class Foo {
|
||||||
|
//public:
|
||||||
|
// Foo();
|
||||||
|
// ~Foo();
|
||||||
|
// virtual void bar();
|
||||||
|
// virtual void pure() = 0;
|
||||||
|
// virtual void notpure();
|
||||||
|
//};
|
||||||
|
//Foo::Foo() {
|
||||||
|
// this->Foo::notpure();
|
||||||
|
//}
|
||||||
|
//Foo::~Foo() {
|
||||||
|
//}
|
||||||
|
//Foo::bar() {
|
||||||
|
//}
|
||||||
|
public void testWithQualifiedNotPureInCtorField_Bug552076() throws Exception {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrorsOfKind(ERR_VIRTUAL_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue