1
0
Fork 0
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:
Marco Stornelli 2019-10-15 18:40:04 +02:00
parent 7a2ff27b91
commit 42daf203a6
2 changed files with 97 additions and 32 deletions

View file

@ -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.ICPPASTConstructorChainInitializer;
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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
@ -104,18 +105,22 @@ public class VirtualMethodCallChecker extends AbstractIndexAstChecker {
IASTExpression fNameExp = fCall.getFunctionNameExpression();
IBinding fBinding = null;
IASTNode problemNode = expression;
boolean isQualified = false;
if (fNameExp instanceof IASTIdExpression) {
IASTIdExpression fName = (IASTIdExpression) fNameExp;
isQualified = fName.getName() instanceof ICPPASTQualifiedName;
fBinding = fName.getName().resolveBinding();
} else if (fNameExp instanceof IASTFieldReference) {
IASTFieldReference fName = (IASTFieldReference) fNameExp;
problemNode = fName.getFieldName();
if (referencesThis(fName.getFieldOwner()))
if (referencesThis(fName.getFieldOwner())) {
isQualified = fName.getFieldName() instanceof ICPPASTQualifiedName;
fBinding = fName.getFieldName().resolveBinding();
}
}
if (fBinding instanceof ICPPMethod) {
ICPPMethod method = (ICPPMethod) fBinding;
if (method.isPureVirtual() || ClassTypeHelper.isVirtual(method)) {
if (method.isPureVirtual() || (!isQualified && ClassTypeHelper.isVirtual(method))) {
reportProblem(VIRTUAL_CALL_ID, problemNode);
}
}

View file

@ -33,11 +33,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class Foo {
//public:
//Foo();
//~Foo();
//virtual void bar();
//virtual void pure() = 0;
//virtual void notpure();
// Foo();
// ~Foo();
// virtual void bar();
// virtual void pure() = 0;
// virtual void notpure();
//};
//Foo::Foo() {
// pure();
@ -53,11 +53,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class Foo {
//public:
//Foo();
//~Foo();
//virtual void bar();
//virtual void pure() = 0;
//virtual void notpure();
// Foo();
// ~Foo();
// virtual void bar();
// virtual void pure() = 0;
// virtual void notpure();
//};
//Foo::Foo() {
// notpure();
@ -73,11 +73,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class Foo {
//public:
//Foo();
//~Foo();
//virtual void bar();
//virtual void pure() = 0;
//virtual void notpure();
// Foo();
// ~Foo();
// virtual void bar();
// virtual void pure() = 0;
// virtual void notpure();
//};
//Foo::Foo() {
//}
@ -93,11 +93,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class Foo {
//public:
//Foo();
//~Foo();
//virtual void bar();
//virtual void pure() = 0;
//virtual void notpure();
// Foo();
// ~Foo();
// virtual void bar();
// virtual void pure() = 0;
// virtual void notpure();
//};
//Foo::Foo() {
//}
@ -113,11 +113,11 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class Foo {
//public:
//Foo();
//~Foo();
//virtual void bar();
//virtual void pure() = 0;
//virtual void notpure();
// Foo();
// ~Foo();
// virtual void bar();
// virtual void pure() = 0;
// virtual void notpure();
//};
//Foo::Foo() {
//}
@ -138,7 +138,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//};
//class B {
//private:
//A a;
// A a;
//public:
// B() { a.v(); }
//};
@ -149,7 +149,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class B {
//private:
//A a;
// A a;
//public:
// B() { this->v(); }
// virtual void v() {}
@ -161,7 +161,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//class B {
//private:
//A a;
// A a;
//public:
// B() { (*this).v(); }
// virtual void v() {}
@ -181,7 +181,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
//};
public void testVirtualMethodChildClass() throws Exception {
loadCodeAndRun(getAboveComment());
checkErrorLine(7, ERR_VIRTUAL_ID);
checkNoErrorsOfKind(ERR_VIRTUAL_ID);
}
//class Foo {
@ -209,7 +209,7 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
// A(int a) : a(a) { }
// virtual void foo();
//private:
// int a;
// int a;
//};
public void testVirtualMethodDelCtor() throws Exception {
loadCodeAndRun(getAboveComment());
@ -245,4 +245,64 @@ public class VirtualMethodCallCheckerTest extends CheckerTestCase {
loadCodeAndRun(getAboveComment());
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);
}
}