mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 08:46:02 +02:00
Bug 368446 - NonVirtualDestructor checker: stack overflow when class
inherits itself
This commit is contained in:
parent
59c4d10629
commit
d98768295b
2 changed files with 27 additions and 4 deletions
|
@ -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
|
* 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
|
||||||
|
@ -12,6 +12,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.codan.internal.checkers;
|
package org.eclipse.cdt.codan.internal.checkers;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
@ -34,6 +36,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
||||||
public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
||||||
public static final String PROBLEM_ID = "org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem"; //$NON-NLS-1$
|
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
|
@Override
|
||||||
public void processAst(IASTTranslationUnit ast) {
|
public void processAst(IASTTranslationUnit ast) {
|
||||||
// Traverse the AST using the visitor pattern.
|
// Traverse the AST using the visitor pattern.
|
||||||
|
@ -50,6 +55,7 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasVirtualDestructor(ICPPClassType classType) {
|
private static boolean hasVirtualDestructor(ICPPClassType classType) {
|
||||||
|
checkedClassTypes.add(classType);
|
||||||
ICPPMethod destructor = getDestructor(classType);
|
ICPPMethod destructor = getDestructor(classType);
|
||||||
if (destructor != null && destructor.isVirtual()) {
|
if (destructor != null && destructor.isVirtual()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -58,7 +64,8 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
||||||
for (ICPPBase base : bases) {
|
for (ICPPBase base : bases) {
|
||||||
IBinding baseClass = base.getBaseClass();
|
IBinding baseClass = base.getBaseClass();
|
||||||
if (baseClass instanceof ICPPClassType) {
|
if (baseClass instanceof ICPPClassType) {
|
||||||
if (hasVirtualDestructor((ICPPClassType) baseClass)) {
|
ICPPClassType cppClassType = (ICPPClassType) baseClass;
|
||||||
|
if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +88,9 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
ICPPClassType classType = (ICPPClassType) binding;
|
ICPPClassType classType = (ICPPClassType) binding;
|
||||||
if (hasVirtualDestructor(classType)) {
|
boolean hasVirtualDestructor = hasVirtualDestructor(classType);
|
||||||
|
checkedClassTypes.clear();
|
||||||
|
if (hasVirtualDestructor) {
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
ICPPMethod virtualMethod = null;
|
ICPPMethod virtualMethod = null;
|
||||||
|
|
|
@ -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
|
* 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
|
||||||
|
@ -181,4 +181,18 @@ public class NonVirtualDestructorCheckerTest extends CheckerTestCase {
|
||||||
loadCodeAndRun(getAboveComment());
|
loadCodeAndRun(getAboveComment());
|
||||||
checkErrorLines(4);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue