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

Bug 368446 - NonVirtualDestructor checker: stack overflow when class

inherits itself
This commit is contained in:
Marc-Andre Laperle 2012-01-14 16:25:19 -05:00
parent 59c4d10629
commit d98768295b
2 changed files with 27 additions and 4 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2011 Alena Laskavaia
* Copyright (c) 2009, 2012 Alena Laskavaia
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -12,6 +12,8 @@
*******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers;
import java.util.HashSet;
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@ -33,6 +35,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
*/
public class NonVirtualDestructor extends AbstractIndexAstChecker {
public static final String PROBLEM_ID = "org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem"; //$NON-NLS-1$
// Prevent stack overflow in case: class A: public A {};
private static HashSet<ICPPClassType> checkedClassTypes = new HashSet<ICPPClassType>();
@Override
public void processAst(IASTTranslationUnit ast) {
@ -50,6 +55,7 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
}
private static boolean hasVirtualDestructor(ICPPClassType classType) {
checkedClassTypes.add(classType);
ICPPMethod destructor = getDestructor(classType);
if (destructor != null && destructor.isVirtual()) {
return true;
@ -58,7 +64,8 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass();
if (baseClass instanceof ICPPClassType) {
if (hasVirtualDestructor((ICPPClassType) baseClass)) {
ICPPClassType cppClassType = (ICPPClassType) baseClass;
if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType)) {
return true;
}
}
@ -81,7 +88,9 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
return PROCESS_SKIP;
}
ICPPClassType classType = (ICPPClassType) binding;
if (hasVirtualDestructor(classType)) {
boolean hasVirtualDestructor = hasVirtualDestructor(classType);
checkedClassTypes.clear();
if (hasVirtualDestructor) {
return PROCESS_SKIP;
}
ICPPMethod virtualMethod = null;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011 Patrick Hofer and others.
* Copyright (c) 2011, 2012 Patrick Hofer and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -181,4 +181,18 @@ public class NonVirtualDestructorCheckerTest extends CheckerTestCase {
loadCodeAndRun(getAboveComment());
checkErrorLines(4);
}
// class C : public C {};
public void testBug368446_stackOverflow() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// class B;
// class A : public B {};
// class B : public A {};
public void testBug368446_stackOverflow_indirect() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
}