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.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);
} }
} }

View file

@ -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);
}
} }