1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-03 22:35:43 +02:00

Bug 468742 - Fix false positive no-virtual destructor

Change-Id: Id8d2efaf3f7a5ca74d160e4a726c08a71c6d7067
Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
This commit is contained in:
Marco Stornelli 2019-05-12 12:20:34 +02:00
parent ec6f9d204d
commit 6452688c18
2 changed files with 39 additions and 0 deletions

View file

@ -30,10 +30,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/**
* Checker to find that class has virtual method and non virtual destructor
@ -73,6 +75,10 @@ public class NonVirtualDestructorChecker extends AbstractIndexAstChecker {
if (destructor != null && destructor.isVirtual()) {
return true;
}
//We can't say anything in this case, so return true to avoid false positive
if (destructor == null && CPPTemplates.isDependentType(classType)) {
return true;
}
ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass();
@ -81,6 +87,9 @@ public class NonVirtualDestructorChecker extends AbstractIndexAstChecker {
if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType)) {
return true;
}
} else if (baseClass instanceof ICPPTemplateTypeParameter) {
//We can't say anything in this case, so return true to avoid false positive
return true;
}
}
return false;

View file

@ -248,4 +248,34 @@ public class NonVirtualDestructorCheckerTest extends CheckerTestCase {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
//template<typename T>
//class Base;
//template <typename T>
//class A {
// using type = Base<T>;
//};
//template<typename T>
//class B: public A<T>::type {
// virtual void f() {}
//};
public void testDeferredClasses1_Bug468742() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
//struct Root {
//};
//template<typename T>
//class A: public T {
//public:
// virtual int f() const = 0;
//};
//typedef A<Root> B;
//class C: public A<Root> {
//};
public void testDeferredClasses2_Bug468742() throws Exception {
loadCodeAndRun(getAboveComment());
checkErrorLine(9);
}
}