Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2007-08-23 09:57:15 +0000
committerMarkus Schorn2007-08-23 09:57:15 +0000
commit5515df94b7cec9f34b3a7cc1370f017b4766996c (patch)
treef87ca2150bbe0639b86ca86a4c165c11871ef407
parentcf73aadd70aac02ffa5cd4fd087e13b719cecc93 (diff)
downloadorg.eclipse.cdt-5515df94b7cec9f34b3a7cc1370f017b4766996c.tar.gz
org.eclipse.cdt-5515df94b7cec9f34b3a7cc1370f017b4766996c.tar.xz
org.eclipse.cdt-5515df94b7cec9f34b3a7cc1370f017b4766996c.zip
Fix and testcase for 200553, infinite loop with recursive typedefs.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java96
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java40
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java44
3 files changed, 175 insertions, 5 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
index 27eb4e0f8ff..948c371ecaf 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
@@ -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();
+ }
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java
index c0fc61ae150..231a5739cb4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java
@@ -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() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java
index 04e5563fb3c..dd9db020887 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java
@@ -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() {

Back to the top