1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 23:05:47 +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.ICPPBase;
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.ICPPMethod; 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.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; 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.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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 * 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()) { if (destructor != null && destructor.isVirtual()) {
return true; 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(); ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass(); IBinding baseClass = base.getBaseClass();
@ -81,6 +87,9 @@ public class NonVirtualDestructorChecker extends AbstractIndexAstChecker {
if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType)) { if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType)) {
return true; 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; return false;

View file

@ -248,4 +248,34 @@ public class NonVirtualDestructorCheckerTest extends CheckerTestCase {
loadCodeAndRun(getAboveComment()); loadCodeAndRun(getAboveComment());
checkNoErrors(); 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);
}
} }