1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 315528 - Non-virtual destructor diagnostics doesn't take superclass into account. Patch by Patrick Hofer.

This commit is contained in:
Sergey Prigogin 2011-05-19 04:20:58 +00:00
parent 63c5b6c950
commit e1157c1d05

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2010 Alena Laskavaia * Copyright (c) 2009, 2011 Alena Laskavaia
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Alena Laskavaia - initial API and implementation * Alena Laskavaia - initial API and implementation
* Patrick Hofer [bug 315528]
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers; package org.eclipse.cdt.codan.internal.checkers;
@ -20,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
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.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.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
@ -27,8 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
/** /**
* Checker to find that class has virtual method and non virtual destructor * Checker to find that class has virtual method and non virtual destructor
* *
* @author Alena * @author Alena Laskavaia
*
*/ */
public class NonVirtualDestructor extends AbstractIndexAstChecker { public class NonVirtualDestructor extends AbstractIndexAstChecker {
private static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem"; //$NON-NLS-1$ private static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem"; //$NON-NLS-1$
@ -115,14 +116,14 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
} }
} }
boolean hasVirDestructor = false; boolean hasVirDestructor = false;
// class has own virtual method and own non-virtual destructor // Class has own virtual method and own non-virtual destructor.
if (hasOwnVirtualMethod && hasOwnNonVirDestructor) { if (hasOwnVirtualMethod && hasOwnNonVirDestructor) {
return true; // Check if one of its base classes has a virtual destructor.
return !hasVirtualDtorInBaseClass(type);
} }
// class does not have virtual methods but has virtual // Class does not have virtual methods but has virtual destructor
// destructor
// - not an error // - not an error
if (hasOwnVirtualMethod == false && hasDestructor == true && hasOwnNonVirDestructor == false) { if (!hasOwnVirtualMethod && hasDestructor && !hasOwnNonVirDestructor) {
return false; return false;
} }
ICPPMethod[] allDeclaredMethods = type.getAllDeclaredMethods(); ICPPMethod[] allDeclaredMethods = type.getAllDeclaredMethods();
@ -144,15 +145,13 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
} }
} }
if (hasOwnVirtualMethod) { if (hasOwnVirtualMethod) {
// class has own virtual method and base non-virtual // Class has own virtual method and base non-virtual destructor.
// destructor if (hasDestructor && !hasVirDestructor) {
if (hasDestructor == true && hasVirDestructor == false) {
return true; return true;
} }
} else if (hasVirtualMethod) { } else if (hasVirtualMethod) {
// class has base virtual method and own non-virtual // Class has base virtual method and own non-virtual destructor.
// destructor if (hasOwnNonVirDestructor) {
if (hasOwnNonVirDestructor == true) {
return true; return true;
} }
} }
@ -160,6 +159,25 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
return false; return false;
} }
private boolean hasVirtualDtorInBaseClass(ICPPClassType classType) {
ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) {
if (!(base.getBaseClass() instanceof ICPPClassType)) {
continue;
}
ICPPClassType testedBaseClass = (ICPPClassType) base.getBaseClass();
ICPPMethod[] declaredBaseMethods = testedBaseClass.getDeclaredMethods();
for (ICPPMethod method : declaredBaseMethods) {
if (method.isDestructor() && method.isVirtual()) {
return true;
}
}
if (hasVirtualDtorInBaseClass(testedBaseClass))
return true;
}
return false;
}
/** /**
* @param decl * @param decl
* @return * @return