mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
fix bug 64939 - recursive loop
This commit is contained in:
parent
c3338eda94
commit
b6aed83db2
8 changed files with 55 additions and 15 deletions
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
|
|||
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTVariable;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserException;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableError;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -967,4 +968,13 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
|
|||
parent = (IASTBaseSpecifier) A3.getBaseClauses().next();
|
||||
assertEquals( parent.getParentClassSpecifier(), A2 );
|
||||
}
|
||||
|
||||
public void testBug64939() throws Exception
|
||||
{
|
||||
try{
|
||||
parse( "template < class T > class A : public A< T * > {}; A<int> a;" ).getDeclarations(); //NON-NLS-1$
|
||||
assertTrue( false );
|
||||
} catch ( ParserSymbolTableError e ){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,4 +429,6 @@ public interface IProblem
|
|||
public static final int SEMANTIC_MALFORMED_EXPRESSION = SEMANTICS_RELATED | 0x010;
|
||||
|
||||
public static final int SEMANTIC_ILLFORMED_FRIEND = SEMANTICS_RELATED | 0x011;
|
||||
|
||||
public static final int SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION = SEMANTICS_RELATED | 0x012;
|
||||
}
|
||||
|
|
|
@ -63,3 +63,4 @@ ASTProblemFactory.error.semantic.pst.unableToResolveFunction=Unable to resolve f
|
|||
ASTProblemFactory.error.semantic.pst.invalidTemplateArgument=Invalid template argument: {0}
|
||||
ASTProblemFactory.error.semantic.pst.invalidTemplateParameter=Invalid template parameter: {0}
|
||||
ASTProblemFactory.error.semantic.pst.redeclaredTemplateParameter=Redeclaration of template parameter: {0}
|
||||
ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation=Possible infinite recursive loop encountered while instantiating {0}
|
||||
|
|
|
@ -145,6 +145,9 @@ public class Problem implements IProblem {
|
|||
errorMessages.put(
|
||||
new Integer( IProblem.SEMANTIC_REDECLARED_TEMPLATE_PARAMETER ),
|
||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.redeclaredTemplateParameter")); //$NON-NLS-1$
|
||||
errorMessages.put(
|
||||
new Integer( IProblem.SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION ),
|
||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation")); //$NON-NLS-1$
|
||||
errorMessages.put(
|
||||
new Integer(IProblem.PREPROCESSOR_POUND_ERROR),
|
||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
|
||||
|
|
|
@ -67,6 +67,7 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
|
|||
* @param kind
|
||||
*/
|
||||
public void registerDeferredInstatiation( Object obj0, Object obj1, DeferredKind kind, Map argMap );
|
||||
public int getNumberDeferredInstantiations();
|
||||
|
||||
public static class DeferredKind{
|
||||
private DeferredKind( int v ){
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
|
|||
public class ParserSymbolTable {
|
||||
|
||||
public static final int TYPE_LOOP_THRESHOLD = 50;
|
||||
public static final int TEMPLATE_LOOP_THRESHOLD = 10;
|
||||
public static final String EMPTY_NAME = ""; //$NON-NLS-1$
|
||||
public static final String THIS = "this"; //$NON-NLS-1$
|
||||
|
||||
|
|
|
@ -45,7 +45,9 @@ public class ParserSymbolTableException extends Exception {
|
|||
public static final int r_BadTemplateArgument = 8;
|
||||
public static final int r_BadTemplateParameter = 9;
|
||||
public static final int r_RedeclaredTemplateParam = 10;
|
||||
public static final int r_RecursiveTemplate = 11;
|
||||
public int reason = -1;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
@ -74,6 +76,8 @@ public class ParserSymbolTableException extends Exception {
|
|||
return IProblem.SEMANTIC_INVALID_TEMPLATE_PARAMETER;
|
||||
case r_RedeclaredTemplateParam:
|
||||
return IProblem.SEMANTIC_REDECLARED_TEMPLATE_PARAMETER;
|
||||
case r_RecursiveTemplate:
|
||||
return IProblem.SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION;
|
||||
default:
|
||||
// assert false : this;
|
||||
return -1;
|
||||
|
|
|
@ -421,27 +421,44 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
|||
_deferredInstantiations.add( new Object [] { obj0, obj1, kind, argMap } );
|
||||
}
|
||||
|
||||
public int getNumberDeferredInstantiations(){
|
||||
return _deferredInstantiations.size();
|
||||
}
|
||||
|
||||
protected void processDeferredInstantiations() throws ParserSymbolTableException{
|
||||
if( _deferredInstantiations == Collections.EMPTY_LIST )
|
||||
return;
|
||||
|
||||
int size = _deferredInstantiations.size();
|
||||
for( int i = 0; i < size; i++ ){
|
||||
Object [] objs = (Object [])_deferredInstantiations.get(i);
|
||||
|
||||
DeferredKind kind = (DeferredKind) objs[2];
|
||||
|
||||
if( kind == DeferredKind.PARENT ){
|
||||
DerivableContainerSymbol d = (DerivableContainerSymbol) objs[0];
|
||||
d.instantiateDeferredParent( (ISymbol) objs[ 1 ], this, (Map) objs[3] );
|
||||
} else if( kind == DeferredKind.RETURN_TYPE ){
|
||||
ParameterizedSymbol p = (ParameterizedSymbol) objs[0];
|
||||
p.instantiateDeferredReturnType( (ISymbol) objs[1], this, (Map) objs[3] );
|
||||
} else if( kind == DeferredKind.TYPE_SYMBOL ){
|
||||
TemplateEngine.instantiateDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
|
||||
}
|
||||
if( _processingDeferred ){
|
||||
return;
|
||||
}
|
||||
_processingDeferred = true;
|
||||
int numDeferred = _deferredInstantiations.size();
|
||||
int loopCount = 0;
|
||||
while( numDeferred > 0 ){
|
||||
while( numDeferred > 0 ) {
|
||||
Object [] objs = (Object [])_deferredInstantiations.get(0);
|
||||
|
||||
DeferredKind kind = (DeferredKind) objs[2];
|
||||
|
||||
if( kind == DeferredKind.PARENT ){
|
||||
DerivableContainerSymbol d = (DerivableContainerSymbol) objs[0];
|
||||
d.instantiateDeferredParent( (ISymbol) objs[ 1 ], this, (Map) objs[3] );
|
||||
} else if( kind == DeferredKind.RETURN_TYPE ){
|
||||
ParameterizedSymbol p = (ParameterizedSymbol) objs[0];
|
||||
p.instantiateDeferredReturnType( (ISymbol) objs[1], this, (Map) objs[3] );
|
||||
} else if( kind == DeferredKind.TYPE_SYMBOL ){
|
||||
TemplateEngine.instantiateDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
|
||||
}
|
||||
|
||||
_deferredInstantiations.remove( 0 );
|
||||
numDeferred--;
|
||||
}
|
||||
numDeferred = _deferredInstantiations.size();
|
||||
if( ++loopCount > ParserSymbolTable.TEMPLATE_LOOP_THRESHOLD )
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_RecursiveTemplate );
|
||||
}
|
||||
_processingDeferred = false;
|
||||
}
|
||||
|
||||
private List _specializations = Collections.EMPTY_LIST; //template specializations
|
||||
|
@ -449,6 +466,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
|||
private Map _defnParameterMap = Collections.EMPTY_MAP; //members could be defined with different template parameter names
|
||||
private Map _instantiations = Collections.EMPTY_MAP;
|
||||
private List _deferredInstantiations = Collections.EMPTY_LIST; //used to avoid recursive loop
|
||||
private boolean _processingDeferred = false;
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue