1
0
Fork 0
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:
Nathan Ridge 2014-09-29 01:07:53 -04:00 committed by Sergey Prigogin
parent 044853140e
commit 20f192470a
11 changed files with 130 additions and 18 deletions

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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.

View file

@ -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);

View file

@ -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);

View file

@ -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);