mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-13 11:15:38 +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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -2580,4 +2580,30 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
|||
public void testInstantiationOfFunctionInstance_437675() throws Exception {
|
||||
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")
|
||||
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 {
|
||||
super(linkage, parent, classType, orig);
|
||||
final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) classType;
|
||||
final long argListRec= PDOMCPPArgumentList.putArguments(this, asInstance.getTemplateArguments());
|
||||
getDB().putRecPtr(record + ARGUMENTS, argListRec);
|
||||
// Defer storing of template arguments to the post-process
|
||||
// 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) {
|
||||
|
@ -69,12 +76,29 @@ class PDOMCPPClassInstance extends PDOMCPPClassSpecialization implements ICPPTem
|
|||
|
||||
@Override
|
||||
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 {
|
||||
final long rec= getPDOM().getDB().getRecPtr(record + ARGUMENTS);
|
||||
return PDOMCPPArgumentList.getArguments(this, rec);
|
||||
// fTemplateArguments here are the temporarily stored, possibly non-PDOM
|
||||
// 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) {
|
||||
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 {
|
||||
super(linkage, parent, (ICPPSpecialization) classType, specialized);
|
||||
setFinal(classType);
|
||||
|
|
|
@ -57,7 +57,7 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization
|
|||
private volatile IType fFixedType= ProblemBinding.NOT_INITIALIZED;
|
||||
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 {
|
||||
super(linkage, parent, (ICPPSpecialization) enumeration, specialized);
|
||||
storeProperties(enumeration);
|
||||
|
|
|
@ -34,7 +34,7 @@ class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements I
|
|||
@SuppressWarnings("hiding")
|
||||
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 {
|
||||
super(linkage, parent, (ICPPSpecialization) enumerator, specialized);
|
||||
storeValue(enumerator);
|
||||
|
|
|
@ -38,7 +38,7 @@ class PDOMCPPFieldSpecialization extends PDOMCPPSpecialization implements ICPPFi
|
|||
@SuppressWarnings("hiding")
|
||||
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)
|
||||
throws CoreException {
|
||||
super(linkage, parent, (ICPPSpecialization) field, specialized);
|
||||
|
|
|
@ -324,6 +324,34 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
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.
|
||||
|
@ -336,13 +364,26 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
IBinding binding = name.resolveBinding();
|
||||
|
||||
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 (binding instanceof ICPPClassType && name.isDefinition()) {
|
||||
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();
|
||||
|
||||
return pdomBinding;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class PDOMCPPParameterSpecialization extends PDOMCPPSpecialization implements IC
|
|||
fType= t;
|
||||
}
|
||||
|
||||
public PDOMCPPParameterSpecialization(PDOMLinkage linkage, PDOMCPPFunctionSpecialization parent, ICPPParameter astParam,
|
||||
public PDOMCPPParameterSpecialization(PDOMCPPLinkage linkage, PDOMCPPFunctionSpecialization parent, ICPPParameter astParam,
|
||||
PDOMCPPParameter original, PDOMCPPParameterSpecialization next) throws CoreException {
|
||||
super(linkage, parent, (ICPPSpecialization) astParam, original);
|
||||
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 ICPPTemplateParameterMap fArgMap;
|
||||
|
||||
public PDOMCPPSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPSpecialization spec,
|
||||
public PDOMCPPSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPSpecialization spec,
|
||||
IPDOMBinding specialized) throws CoreException {
|
||||
super(linkage, parent, spec.getNameCharArray());
|
||||
getDB().putRecPtr(record + SPECIALIZED, specialized.getRecord());
|
||||
|
||||
// Specializations that are not instances have the same map as their owner.
|
||||
if (this instanceof ICPPTemplateInstance) {
|
||||
long rec= PDOMCPPTemplateParameterMap.putMap(this, spec.getTemplateParameterMap());
|
||||
getDB().putRecPtr(record + ARGMAP, rec);
|
||||
// Defer storing of template parameter map to the post-process
|
||||
// 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 {
|
||||
Integer sigHash = IndexCPPSignatureUtil.getSignatureHash(spec);
|
||||
|
@ -107,6 +112,22 @@ abstract class PDOMCPPSpecialization extends PDOMCPPBinding implements ICPPSpeci
|
|||
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
|
||||
public int getSignatureHash() throws CoreException {
|
||||
return getDB().getInt(record + SIGNATURE_HASH);
|
||||
|
|
|
@ -33,7 +33,7 @@ class PDOMCPPTypedefSpecialization extends PDOMCPPSpecialization implements ITyp
|
|||
@SuppressWarnings("hiding")
|
||||
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 {
|
||||
super(linkage, parent, (ICPPSpecialization) typedef, specialized);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ class PDOMCPPUsingDeclarationSpecialization extends PDOMCPPSpecialization implem
|
|||
|
||||
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 {
|
||||
super(linkage, parent, (ICPPSpecialization) using, specialized);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue