mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-14 03:35:37 +02:00
Bug 439923 - Avoid infinite recursion while marshalling template
definition Change-Id: Iefe78ea1dde72e745afa75b9da9d2f8ff89444ac Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/34019 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
044853140e
commit
20f192470a
11 changed files with 130 additions and 18 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007, 2013 Symbian Software Systems and others.
|
* Copyright (c) 2007, 2014 Symbian Software Systems 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
|
||||||
|
@ -2580,4 +2580,30 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
public void testInstantiationOfFunctionInstance_437675() throws Exception {
|
public void testInstantiationOfFunctionInstance_437675() throws Exception {
|
||||||
checkBindings();
|
checkBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct IID { };
|
||||||
|
//
|
||||||
|
// struct IUnknown {};
|
||||||
|
//
|
||||||
|
// template<class T>
|
||||||
|
// class IID_DUMMY : IID { };
|
||||||
|
//
|
||||||
|
// template<class T>
|
||||||
|
// const IID &__uuidof(T x) { return IID_DUMMY<T>(); }
|
||||||
|
//
|
||||||
|
// static IID IID_IUnknown = {};
|
||||||
|
//
|
||||||
|
// template<class T>
|
||||||
|
// class MYCComPtr { };
|
||||||
|
//
|
||||||
|
// template <class T, const IID* piid = &__uuidof<T> >
|
||||||
|
// class MYCComQIPtr : public MYCComPtr<T> {};
|
||||||
|
//
|
||||||
|
// template<>
|
||||||
|
// class MYCComQIPtr<IUnknown, &IID_IUnknown> : public MYCComPtr<IUnknown> {};
|
||||||
|
|
||||||
|
// // source file is deliberately empty
|
||||||
|
public void testInfiniteRecursionMarshallingTemplateDefinition_439923() throws Exception {
|
||||||
|
checkBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,19 @@ class PDOMCPPClassInstance extends PDOMCPPClassSpecialization implements ICPPTem
|
||||||
@SuppressWarnings("hiding")
|
@SuppressWarnings("hiding")
|
||||||
protected static final int RECORD_SIZE = PDOMCPPClassSpecialization.RECORD_SIZE + 4;
|
protected static final int RECORD_SIZE = PDOMCPPClassSpecialization.RECORD_SIZE + 4;
|
||||||
|
|
||||||
public PDOMCPPClassInstance(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType, PDOMBinding orig)
|
private volatile ICPPTemplateArgument[] fTemplateArguments;
|
||||||
|
|
||||||
|
public PDOMCPPClassInstance(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassType classType, PDOMBinding orig)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
super(linkage, parent, classType, orig);
|
super(linkage, parent, classType, orig);
|
||||||
final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) classType;
|
final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) classType;
|
||||||
final long argListRec= PDOMCPPArgumentList.putArguments(this, asInstance.getTemplateArguments());
|
// Defer storing of template arguments to the post-process
|
||||||
getDB().putRecPtr(record + ARGUMENTS, argListRec);
|
// to avoid infinite recursion when the evaluation of a non-type
|
||||||
|
// template argument tries to store its template definition.
|
||||||
|
// Until the post-process runs, temporarily store the input (possibly
|
||||||
|
// non-PDOM) arguments.
|
||||||
|
fTemplateArguments = asInstance.getTemplateArguments();
|
||||||
|
linkage.new ConfigureClassInstance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PDOMCPPClassInstance(PDOMLinkage linkage, long bindingRecord) {
|
public PDOMCPPClassInstance(PDOMLinkage linkage, long bindingRecord) {
|
||||||
|
@ -69,12 +76,29 @@ class PDOMCPPClassInstance extends PDOMCPPClassSpecialization implements ICPPTem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPTemplateArgument[] getTemplateArguments() {
|
public ICPPTemplateArgument[] getTemplateArguments() {
|
||||||
|
if (fTemplateArguments == null) {
|
||||||
|
try {
|
||||||
|
final long rec= getPDOM().getDB().getRecPtr(record + ARGUMENTS);
|
||||||
|
fTemplateArguments = PDOMCPPArgumentList.getArguments(this, rec);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fTemplateArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeTemplateArguments() {
|
||||||
try {
|
try {
|
||||||
final long rec= getPDOM().getDB().getRecPtr(record + ARGUMENTS);
|
// fTemplateArguments here are the temporarily stored, possibly non-PDOM
|
||||||
return PDOMCPPArgumentList.getArguments(this, rec);
|
// arguments stored by the constructor. Construct the PDOM arguments and
|
||||||
|
// store them.
|
||||||
|
final long argListRec= PDOMCPPArgumentList.putArguments(this, fTemplateArguments);
|
||||||
|
getDB().putRecPtr(record + ARGUMENTS, argListRec);
|
||||||
|
|
||||||
|
// Read the stored arguments next time getTemplateArguments() is called.
|
||||||
|
fTemplateArguments = null;
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
return ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public PDOMCPPClassSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType,
|
public PDOMCPPClassSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassType classType,
|
||||||
PDOMBinding specialized) throws CoreException {
|
PDOMBinding specialized) throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) classType, specialized);
|
super(linkage, parent, (ICPPSpecialization) classType, specialized);
|
||||||
setFinal(classType);
|
setFinal(classType);
|
||||||
|
|
|
@ -57,7 +57,7 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization
|
||||||
private volatile IType fFixedType= ProblemBinding.NOT_INITIALIZED;
|
private volatile IType fFixedType= ProblemBinding.NOT_INITIALIZED;
|
||||||
private PDOMCPPEnumScope fScope; // No need for volatile, all fields of PDOMCPPEnumScope are final.
|
private PDOMCPPEnumScope fScope; // No need for volatile, all fields of PDOMCPPEnumScope are final.
|
||||||
|
|
||||||
public PDOMCPPEnumerationSpecialization(PDOMLinkage linkage, PDOMNode parent,
|
public PDOMCPPEnumerationSpecialization(PDOMCPPLinkage linkage, PDOMNode parent,
|
||||||
ICPPEnumeration enumeration, PDOMBinding specialized) throws CoreException {
|
ICPPEnumeration enumeration, PDOMBinding specialized) throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) enumeration, specialized);
|
super(linkage, parent, (ICPPSpecialization) enumeration, specialized);
|
||||||
storeProperties(enumeration);
|
storeProperties(enumeration);
|
||||||
|
|
|
@ -34,7 +34,7 @@ class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements I
|
||||||
@SuppressWarnings("hiding")
|
@SuppressWarnings("hiding")
|
||||||
protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE;
|
protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE;
|
||||||
|
|
||||||
public PDOMCPPEnumeratorSpecialization(PDOMLinkage linkage, PDOMNode parent,
|
public PDOMCPPEnumeratorSpecialization(PDOMCPPLinkage linkage, PDOMNode parent,
|
||||||
IEnumerator enumerator, PDOMBinding specialized) throws CoreException {
|
IEnumerator enumerator, PDOMBinding specialized) throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) enumerator, specialized);
|
super(linkage, parent, (ICPPSpecialization) enumerator, specialized);
|
||||||
storeValue(enumerator);
|
storeValue(enumerator);
|
||||||
|
|
|
@ -38,7 +38,7 @@ class PDOMCPPFieldSpecialization extends PDOMCPPSpecialization implements ICPPFi
|
||||||
@SuppressWarnings("hiding")
|
@SuppressWarnings("hiding")
|
||||||
protected static final int RECORD_SIZE = VALUE_OFFSET + Database.VALUE_SIZE;
|
protected static final int RECORD_SIZE = VALUE_OFFSET + Database.VALUE_SIZE;
|
||||||
|
|
||||||
public PDOMCPPFieldSpecialization(PDOMLinkage linkage, PDOMNode parent,
|
public PDOMCPPFieldSpecialization(PDOMCPPLinkage linkage, PDOMNode parent,
|
||||||
ICPPField field, PDOMBinding specialized)
|
ICPPField field, PDOMBinding specialized)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) field, specialized);
|
super(linkage, parent, (ICPPSpecialization) field, specialized);
|
||||||
|
|
|
@ -324,6 +324,34 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
fTemplate.initData(fOriginalAliasedType);
|
fTemplate.initData(fOriginalAliasedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConfigureInstance implements Runnable {
|
||||||
|
PDOMCPPSpecialization fInstance;
|
||||||
|
|
||||||
|
public ConfigureInstance(PDOMCPPSpecialization specialization) {
|
||||||
|
fInstance = specialization;
|
||||||
|
postProcesses.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
fInstance.storeTemplateParameterMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureClassInstance implements Runnable {
|
||||||
|
PDOMCPPClassInstance fClassInstance;
|
||||||
|
|
||||||
|
public ConfigureClassInstance(PDOMCPPClassInstance classInstance) {
|
||||||
|
fClassInstance = classInstance;
|
||||||
|
postProcesses.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
fClassInstance.storeTemplateArguments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds or returns existing binding for the given name.
|
* Adds or returns existing binding for the given name.
|
||||||
|
@ -336,13 +364,26 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
IBinding binding = name.resolveBinding();
|
IBinding binding = name.resolveBinding();
|
||||||
|
|
||||||
PDOMBinding pdomBinding = addBinding(binding, name);
|
PDOMBinding pdomBinding = addBinding(binding, name);
|
||||||
|
|
||||||
|
// Some nodes schedule some of their initialization to be done
|
||||||
|
// after the binding has been added to the PDOM, to avoid
|
||||||
|
// infinite recursion. We run those post-processes now.
|
||||||
|
// Note that we need to run it before addImplicitMethods() is
|
||||||
|
// called, since addImplicitMethods() expects the binding to
|
||||||
|
// be fully initialized.
|
||||||
|
handlePostProcesses();
|
||||||
|
|
||||||
if (pdomBinding instanceof PDOMCPPClassType || pdomBinding instanceof PDOMCPPClassSpecialization) {
|
if (pdomBinding instanceof PDOMCPPClassType || pdomBinding instanceof PDOMCPPClassSpecialization) {
|
||||||
if (binding instanceof ICPPClassType && name.isDefinition()) {
|
if (binding instanceof ICPPClassType && name.isDefinition()) {
|
||||||
addImplicitMethods(pdomBinding, (ICPPClassType) binding, name);
|
addImplicitMethods(pdomBinding, (ICPPClassType) binding, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some of the nodes created during addImplicitMethods() can
|
||||||
|
// also schedule post-processes, so we need to run through
|
||||||
|
// them again.
|
||||||
handlePostProcesses();
|
handlePostProcesses();
|
||||||
|
|
||||||
return pdomBinding;
|
return pdomBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ class PDOMCPPParameterSpecialization extends PDOMCPPSpecialization implements IC
|
||||||
fType= t;
|
fType= t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PDOMCPPParameterSpecialization(PDOMLinkage linkage, PDOMCPPFunctionSpecialization parent, ICPPParameter astParam,
|
public PDOMCPPParameterSpecialization(PDOMCPPLinkage linkage, PDOMCPPFunctionSpecialization parent, ICPPParameter astParam,
|
||||||
PDOMCPPParameter original, PDOMCPPParameterSpecialization next) throws CoreException {
|
PDOMCPPParameter original, PDOMCPPParameterSpecialization next) throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) astParam, original);
|
super(linkage, parent, (ICPPSpecialization) astParam, original);
|
||||||
fType= null; // This constructor is used for adding parameters to the database, only.
|
fType= null; // This constructor is used for adding parameters to the database, only.
|
||||||
|
|
|
@ -43,15 +43,20 @@ abstract class PDOMCPPSpecialization extends PDOMCPPBinding implements ICPPSpeci
|
||||||
private volatile IBinding fSpecializedCache= null;
|
private volatile IBinding fSpecializedCache= null;
|
||||||
private volatile ICPPTemplateParameterMap fArgMap;
|
private volatile ICPPTemplateParameterMap fArgMap;
|
||||||
|
|
||||||
public PDOMCPPSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPSpecialization spec,
|
public PDOMCPPSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPSpecialization spec,
|
||||||
IPDOMBinding specialized) throws CoreException {
|
IPDOMBinding specialized) throws CoreException {
|
||||||
super(linkage, parent, spec.getNameCharArray());
|
super(linkage, parent, spec.getNameCharArray());
|
||||||
getDB().putRecPtr(record + SPECIALIZED, specialized.getRecord());
|
getDB().putRecPtr(record + SPECIALIZED, specialized.getRecord());
|
||||||
|
|
||||||
// Specializations that are not instances have the same map as their owner.
|
// Specializations that are not instances have the same map as their owner.
|
||||||
if (this instanceof ICPPTemplateInstance) {
|
if (this instanceof ICPPTemplateInstance) {
|
||||||
long rec= PDOMCPPTemplateParameterMap.putMap(this, spec.getTemplateParameterMap());
|
// Defer storing of template parameter map to the post-process
|
||||||
getDB().putRecPtr(record + ARGMAP, rec);
|
// to avoid infinite recursion when the evaluation of a non-type
|
||||||
|
// template argument tries to store its template definition.
|
||||||
|
// Until the post-process runs, temporarily store the input (possibly
|
||||||
|
// non-PDOM) map.
|
||||||
|
fArgMap = spec.getTemplateParameterMap();
|
||||||
|
linkage.new ConfigureInstance(this);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Integer sigHash = IndexCPPSignatureUtil.getSignatureHash(spec);
|
Integer sigHash = IndexCPPSignatureUtil.getSignatureHash(spec);
|
||||||
|
@ -107,6 +112,22 @@ abstract class PDOMCPPSpecialization extends PDOMCPPBinding implements ICPPSpeci
|
||||||
return fArgMap;
|
return fArgMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void storeTemplateParameterMap() {
|
||||||
|
try {
|
||||||
|
// fArgMap here is the temporarily stored, possibly non-PDOM
|
||||||
|
// map stored by the constructor. Construct the PDOM map and
|
||||||
|
// store it.
|
||||||
|
long rec= PDOMCPPTemplateParameterMap.putMap(this, fArgMap);
|
||||||
|
getDB().putRecPtr(record + ARGMAP, rec);
|
||||||
|
|
||||||
|
// Read the stored map next time getTemplateParameterMap()
|
||||||
|
// is called.
|
||||||
|
fArgMap = null;
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSignatureHash() throws CoreException {
|
public int getSignatureHash() throws CoreException {
|
||||||
return getDB().getInt(record + SIGNATURE_HASH);
|
return getDB().getInt(record + SIGNATURE_HASH);
|
||||||
|
|
|
@ -33,7 +33,7 @@ class PDOMCPPTypedefSpecialization extends PDOMCPPSpecialization implements ITyp
|
||||||
@SuppressWarnings("hiding")
|
@SuppressWarnings("hiding")
|
||||||
protected static final int RECORD_SIZE = TYPE_OFFSET + Database.TYPE_SIZE;
|
protected static final int RECORD_SIZE = TYPE_OFFSET + Database.TYPE_SIZE;
|
||||||
|
|
||||||
public PDOMCPPTypedefSpecialization(PDOMLinkage linkage, PDOMNode parent, ITypedef typedef, PDOMBinding specialized)
|
public PDOMCPPTypedefSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ITypedef typedef, PDOMBinding specialized)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) typedef, specialized);
|
super(linkage, parent, (ICPPSpecialization) typedef, specialized);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class PDOMCPPUsingDeclarationSpecialization extends PDOMCPPSpecialization implem
|
||||||
|
|
||||||
private volatile IBinding[] delegates;
|
private volatile IBinding[] delegates;
|
||||||
|
|
||||||
public PDOMCPPUsingDeclarationSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPUsingDeclaration using, PDOMBinding specialized)
|
public PDOMCPPUsingDeclarationSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPUsingDeclaration using, PDOMBinding specialized)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
super(linkage, parent, (ICPPSpecialization) using, specialized);
|
super(linkage, parent, (ICPPSpecialization) using, specialized);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue