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

Fixed another case of an infinite loop. This time accompanied by a memory leak.

This commit is contained in:
Sergey Prigogin 2008-05-27 05:40:34 +00:00
parent 973c77a635
commit 12cc9fcc6a
8 changed files with 144 additions and 67 deletions

View file

@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright (c) 2008 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.parser.util.IObjectComparator;
public class ASTTypeComparator implements IObjectComparator {
/**
* Returns <code>true</code> if the two objects are equal or represent the same type.
*/
public boolean isSame(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 instanceof IType && o2 instanceof IType) {
return ((IType) o1).isSameType((IType) o2);
}
return o1.equals(o2);
}
}

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
@ -15,6 +16,8 @@ package org.eclipse.cdt.core.dom.ast;
*/ */
public interface IType extends Cloneable { public interface IType extends Cloneable {
public static final IType[] EMPTY_TYPE_ARRAY = new IType[0]; public static final IType[] EMPTY_TYPE_ARRAY = new IType[0];
public static final ASTTypeComparator TYPE_COMPARATOR = new ASTTypeComparator();
public Object clone(); public Object clone();
/** /**

View file

@ -0,0 +1,15 @@
/*******************************************************************************
* Copyright (c) 2008 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.util;
public interface IObjectComparator {
boolean isSame(Object o1, Object o2);
}

View file

@ -145,6 +145,20 @@ public class ObjectMap extends ObjectTable<Object> {
return vals; return vals;
} }
public boolean isSame(ObjectMap other, IObjectComparator comparator) {
if (!super.isSame(other, comparator)) {
return false;
}
for (int i = 0; i < keyTable.length; i++) {
Object val1 = valueTable[i];
Object val2 = other.valueTable[i];
if (val1 != val2 && !comparator.isSame(val1, val2)) {
return false;
}
}
return true;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("{"); //$NON-NLS-1$ StringBuilder sb = new StringBuilder("{"); //$NON-NLS-1$

View file

@ -153,4 +153,19 @@ public abstract class ObjectTable<T> extends HashTable {
System.arraycopy(keyTable, 0, keys, 0, keys.length); System.arraycopy(keyTable, 0, keys, 0, keys.length);
return keys; return keys;
} }
public boolean isSame(ObjectTable<T> other, IObjectComparator comparator) {
if (size() != other.size()) {
return false;
}
for (int i = 0; i < keyTable.length; i++) {
T key1 = keyTable[i];
T key2 = other.keyTable[i];
if (key1 != key2 && !comparator.isSame(key1, key2)) {
return false;
}
}
return true;
}
} }

View file

@ -27,7 +27,6 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
* @author jcamelon * @author jcamelon
*/ */
public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator { public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator {
private IASTParameterDeclaration[] parameters = null; private IASTParameterDeclaration[] parameters = null;
private int parametersPos = -1; private int parametersPos = -1;
private ICPPFunctionScope scope = null; private ICPPFunctionScope scope = null;
@ -35,7 +34,10 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
private boolean pureVirtual; private boolean pureVirtual;
private boolean isVolatile; private boolean isVolatile;
private boolean isConst; private boolean isConst;
private IASTTypeId[] typeIds = null;
private int typeIdsPos = -1;
private ICPPASTConstructorChainInitializer[] constructorChain = null;
private int constructorChainPos = -1;
public CPPASTFunctionDeclarator() { public CPPASTFunctionDeclarator() {
} }
@ -66,12 +68,10 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
varArgs = value; varArgs = value;
} }
public boolean isConst() { public boolean isConst() {
return isConst; return isConst;
} }
public void setConst(boolean value) { public void setConst(boolean value) {
this.isConst = value; this.isConst = value;
} }
@ -84,16 +84,12 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
this.isVolatile = value; this.isVolatile = value;
} }
private IASTTypeId [] typeIds = null;
private int typeIdsPos=-1;
public IASTTypeId[] getExceptionSpecification() { public IASTTypeId[] getExceptionSpecification() {
if (typeIds == null) return IASTTypeId.EMPTY_TYPEID_ARRAY; if (typeIds == null) return IASTTypeId.EMPTY_TYPEID_ARRAY;
typeIds = (IASTTypeId[]) ArrayUtil.removeNullsAfter(IASTTypeId.class, typeIds, typeIdsPos); typeIds = (IASTTypeId[]) ArrayUtil.removeNullsAfter(IASTTypeId.class, typeIds, typeIdsPos);
return typeIds; return typeIds;
} }
public void addExceptionSpecificationTypeId(IASTTypeId typeId) { public void addExceptionSpecificationTypeId(IASTTypeId typeId) {
if (typeId != null) { if (typeId != null) {
typeIds = (IASTTypeId[]) ArrayUtil.append(IASTTypeId.class, typeIds, ++typeIdsPos, typeId); typeIds = (IASTTypeId[]) ArrayUtil.append(IASTTypeId.class, typeIds, ++typeIdsPos, typeId);
@ -102,31 +98,25 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
} }
} }
public boolean isPureVirtual() { public boolean isPureVirtual() {
return pureVirtual; return pureVirtual;
} }
public void setPureVirtual(boolean isPureVirtual) { public void setPureVirtual(boolean isPureVirtual) {
this.pureVirtual = isPureVirtual; this.pureVirtual = isPureVirtual;
} }
private ICPPASTConstructorChainInitializer [] constructorChain = null;
private int constructorChainPos=-1;
public ICPPASTConstructorChainInitializer[] getConstructorChain() { public ICPPASTConstructorChainInitializer[] getConstructorChain() {
if (constructorChain == null) return ICPPASTConstructorChainInitializer.EMPTY_CONSTRUCTORCHAININITIALIZER_ARRAY; if (constructorChain == null) return ICPPASTConstructorChainInitializer.EMPTY_CONSTRUCTORCHAININITIALIZER_ARRAY;
constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.removeNullsAfter( ICPPASTConstructorChainInitializer.class, constructorChain, constructorChainPos ); constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.removeNullsAfter(
ICPPASTConstructorChainInitializer.class, constructorChain, constructorChainPos);
return constructorChain; return constructorChain;
} }
public void addConstructorToChain(ICPPASTConstructorChainInitializer initializer) { public void addConstructorToChain(ICPPASTConstructorChainInitializer initializer) {
if (initializer != null) { if (initializer != null) {
constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.append(ICPPASTConstructorChainInitializer.class, constructorChain, ++constructorChainPos, initializer ); constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.append(
ICPPASTConstructorChainInitializer.class, constructorChain, ++constructorChainPos, initializer);
initializer.setParent(this); initializer.setParent(this);
initializer.setPropertyInParent(CONSTRUCTOR_CHAIN_MEMBER); initializer.setPropertyInParent(CONSTRUCTOR_CHAIN_MEMBER);
} }
@ -137,8 +127,9 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
return scope; return scope;
ASTNodeProperty prop = getPropertyInParent(); ASTNodeProperty prop = getPropertyInParent();
if( prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR ) if (prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR) {
scope = new CPPFunctionScope(this); scope = new CPPFunctionScope(this);
}
return scope; return scope;
} }
@ -155,7 +146,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
} }
IASTInitializer initializer = getInitializer(); IASTInitializer initializer = getInitializer();
if( initializer != null ) if( !initializer.accept( action ) ) return false; if (initializer != null && !initializer.accept(action)) return false;
IASTTypeId[] ids = getExceptionSpecification(); IASTTypeId[] ids = getExceptionSpecification();
for (int i = 0; i < ids.length; i++) { for (int i = 0; i < ids.length; i++) {

View file

@ -48,8 +48,11 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
public IType getType() throws DOMException { public IType getType() throws DOMException {
if (type == null) { if (type == null) {
type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope()); type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope());
if (type == this) { // A typedef pointing to itself is a sure recipe for an infinite loop -- replace with
// A typedef pointing to itself is a sure recipe for an infinite loop. // a problem binding.
if (type instanceof CPPTypedefSpecialization &&
((CPPTypedefSpecialization) type).getSpecializedBinding().equals(getSpecializedBinding()) &&
((CPPTypedefSpecialization) type).getArgumentMap().isSame(argumentMap, IType.TYPE_COMPARATOR)) {
type = new ProblemBinding(getDefinition(), IProblemBinding.SEMANTIC_INVALID_TYPE, type = new ProblemBinding(getDefinition(), IProblemBinding.SEMANTIC_INVALID_TYPE,
getNameCharArray()); getNameCharArray());
} }

View file

@ -67,6 +67,8 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPClassType.RECORD_SIZE + 16; protected static final int RECORD_SIZE = PDOMCPPClassType.RECORD_SIZE + 16;
private ICPPTemplateParameter[] params; // Cached template parameters.
public PDOMCPPClassTemplate(PDOM pdom, PDOMNode parent, ICPPClassTemplate template) throws CoreException { public PDOMCPPClassTemplate(PDOM pdom, PDOMNode parent, ICPPClassTemplate template) throws CoreException {
super(pdom, parent, template); super(pdom, parent, template);
} }
@ -100,17 +102,22 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
} }
public ICPPTemplateParameter[] getTemplateParameters() { public ICPPTemplateParameter[] getTemplateParameters() {
if (params == null) {
try { try {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl()); PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl());
TemplateParameterCollector visitor = new TemplateParameterCollector(); TemplateParameterCollector visitor = new TemplateParameterCollector();
list.accept(visitor); list.accept(visitor);
params = visitor.getTemplateParameters();
return visitor.getTemplateParameters();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
return new ICPPTemplateParameter[0]; params = ICPPTemplateParameter.EMPTY_TEMPLATE_PARAMETER_ARRAY;
} }
} }
// Copy to a new array for safety.
ICPPTemplateParameter[] result = new ICPPTemplateParameter[params.length];
System.arraycopy(params, 0, result, 0, params.length);
return result;
}
private PDOMCPPClassTemplatePartialSpecialization getFirstPartial() throws CoreException { private PDOMCPPClassTemplatePartialSpecialization getFirstPartial() throws CoreException {
int value = pdom.getDB().getInt(record + FIRST_PARTIAL); int value = pdom.getDB().getInt(record + FIRST_PARTIAL);