diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/NonVirtualDestructorChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/NonVirtualDestructorChecker.java index bb9df540d7b..9895b75b2e4 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/NonVirtualDestructorChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/NonVirtualDestructorChecker.java @@ -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; diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java index d4001cce2b0..c24bf9f7043 100644 --- a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java @@ -248,4 +248,34 @@ public class NonVirtualDestructorCheckerTest extends CheckerTestCase { loadCodeAndRun(getAboveComment()); checkNoErrors(); } + + //template + //class Base; + //template + //class A { + // using type = Base; + //}; + //template + //class B: public A::type { + // virtual void f() {} + //}; + public void testDeferredClasses1_Bug468742() throws Exception { + loadCodeAndRun(getAboveComment()); + checkNoErrors(); + } + + //struct Root { + //}; + //template + //class A: public T { + //public: + // virtual int f() const = 0; + //}; + //typedef A B; + //class C: public A { + //}; + public void testDeferredClasses2_Bug468742() throws Exception { + loadCodeAndRun(getAboveComment()); + checkErrorLine(9); + } }