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

Fix and testcase for 200553, infinite loop with recursive typedefs.

This commit is contained in:
Markus Schorn 2007-08-23 09:57:15 +00:00
parent cf73aadd70
commit 5515df94b7
3 changed files with 175 additions and 5 deletions

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBasicType;
@ -46,6 +47,7 @@ import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
@ -946,4 +948,98 @@ public class IndexBugsTests extends BaseTestCase {
}
}
// typedef bug200553_A bug200553_B;
// typedef bug200553_B bug200553_A;
public void testTypedefRecursionCpp_Bug200553() throws Exception {
StringBuffer[] contents= getContentsForTest(1);
final IIndexManager indexManager = CCorePlugin.getIndexManager();
IFile f1= TestSourceReader.createFile(fCProject.getProject(), "src.cpp", contents[0].toString());
waitForIndexer();
fIndex.acquireReadLock();
try {
IIndexBinding[] bindings= fIndex.findBindings("bug200553_A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
bindings= fIndex.findBindings("bug200553_B".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
}
finally {
fIndex.releaseReadLock();
}
indexManager.update(new ICElement[] {fCProject}, IIndexManager.UPDATE_ALL);
waitForIndexer();
fIndex.acquireReadLock();
try {
IIndexBinding[] bindings= fIndex.findBindings("bug200553_A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
bindings= fIndex.findBindings("bug200553_B".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
}
finally {
fIndex.releaseReadLock();
}
}
private void checkTypedefDepth(ITypedef td) throws DOMException {
int maxDepth= 20;
IType type= td;
while (--maxDepth > 0 && type instanceof ITypedef) {
type= ((ITypedef) type).getType();
}
assertTrue(maxDepth > 0);
}
// typedef bug200553_A bug200553_B;
// typedef bug200553_B bug200553_A;
public void testTypedefRecursionC_Bug200553() throws Exception {
StringBuffer[] contents= getContentsForTest(1);
final IIndexManager indexManager = CCorePlugin.getIndexManager();
IFile f1= TestSourceReader.createFile(fCProject.getProject(), "src.c", contents[0].toString());
waitForIndexer();
fIndex.acquireReadLock();
try {
IIndexBinding[] bindings= fIndex.findBindings("bug200553_A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
bindings= fIndex.findBindings("bug200553_B".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
}
finally {
fIndex.releaseReadLock();
}
indexManager.update(new ICElement[] {fCProject}, IIndexManager.UPDATE_ALL);
waitForIndexer();
fIndex.acquireReadLock();
try {
IIndexBinding[] bindings= fIndex.findBindings("bug200553_A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
bindings= fIndex.findBindings("bug200553_B".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertTrue(bindings[0] instanceof ITypedef);
checkTypedefDepth((ITypedef) bindings[0]);
}
finally {
fIndex.releaseReadLock();
}
}
}

View file

@ -15,8 +15,10 @@ package org.eclipse.cdt.internal.core.pdom.dom.c;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants;
@ -67,10 +69,44 @@ class PDOMCTypedef extends PDOMBinding implements ITypedef, ITypeContainer, IInd
}
}
}
private void setType(final PDOMLinkage linkage, IType newType) throws CoreException, DOMException {
PDOMNode typeNode = linkage.addType(this, newType);
pdom.getDB().putInt(record+TYPE, typeNode != null ? typeNode.getRecord() : 0);
if (introducesRecursion((IType) typeNode, getNameCharArray())) {
linkage.deleteType((IType) typeNode, record);
typeNode= null;
}
pdom.getDB().putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0);
}
private boolean introducesRecursion(IType type, char[] tdname) throws DOMException {
int maxDepth= 50;
while (--maxDepth > 0) {
if (type instanceof ITypedef && CharArrayUtils.equals(((ITypedef) type).getNameCharArray(), tdname)) {
return true;
}
if (type instanceof ITypeContainer) {
type= ((ITypeContainer) type).getType();
}
else if (type instanceof IFunctionType) {
IFunctionType ft= (IFunctionType) type;
if (introducesRecursion(ft.getReturnType(), tdname)) {
return true;
}
IType[] params= ft.getParameterTypes();
for (int i = 0; i < params.length; i++) {
IType param = params[i];
if (introducesRecursion(param, tdname)) {
return true;
}
}
return false;
}
else {
return false;
}
}
return true;
}
protected int getRecordSize() {

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -15,14 +15,17 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDelegateCreator;
import org.eclipse.cdt.internal.core.index.CPPTypedefClone;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
@ -72,15 +75,50 @@ class PDOMCPPTypedef extends PDOMCPPBinding
private void setType(final PDOMLinkage linkage, IType newType) throws CoreException, DOMException {
PDOMNode typeNode = linkage.addType(this, newType);
if (introducesRecursion((IType) typeNode, getNameCharArray())) {
linkage.deleteType((IType) typeNode, record);
typeNode= null;
}
pdom.getDB().putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0);
}
private boolean introducesRecursion(IType type, char[] tdname) throws DOMException {
int maxDepth= 50;
while (--maxDepth > 0) {
if (type instanceof ITypedef && CharArrayUtils.equals(((ITypedef) type).getNameCharArray(), tdname)) {
return true;
}
if (type instanceof ITypeContainer) {
type= ((ITypeContainer) type).getType();
}
else if (type instanceof IFunctionType) {
IFunctionType ft= (IFunctionType) type;
if (introducesRecursion(ft.getReturnType(), tdname)) {
return true;
}
IType[] params= ft.getParameterTypes();
for (int i = 0; i < params.length; i++) {
IType param = params[i];
if (introducesRecursion(param, tdname)) {
return true;
}
}
return false;
}
else {
return false;
}
}
return true;
}
protected int getRecordSize() {
return RECORD_SIZE;
}
public int getNodeType() {
return PDOMCPPLinkage.CPPTYPEDEF;
return IIndexCPPBindingConstants.CPPTYPEDEF;
}
public IType getType() {