From 6db088cd45cc2b8b12b419cf1928c370a4c0d7aa Mon Sep 17 00:00:00 2001 From: Marco Stornelli Date: Tue, 15 Oct 2019 18:40:04 +0200 Subject: Bug 552076 - Fix false positive virtual method with qualified name Change-Id: Iaf82368fce793f9c23d6e8a13d88bf57282f9ae9 Signed-off-by: Marco Stornelli --- .../checkers/VirtualMethodCallChecker.java | 9 +- .../checkers/VirtualMethodCallCheckerTest.java | 120 +++++++++++++++------ 2 files changed, 97 insertions(+), 32 deletions(-) diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/VirtualMethodCallChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/VirtualMethodCallChecker.java index dd971602833..c35e70a40ae 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/VirtualMethodCallChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/VirtualMethodCallChecker.java @@ -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); } } diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/VirtualMethodCallCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/VirtualMethodCallCheckerTest.java index fa054060294..848e074c9f2 100644 --- a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/VirtualMethodCallCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/VirtualMethodCallCheckerTest.java @@ -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); + } } -- cgit v1.2.3