Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/VirtualMethodCallChecker.java9
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/VirtualMethodCallCheckerTest.java120
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);
+ }
}

Back to the top