mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 12:55:40 +02:00
Patch for Devin Steffler.
Bug 100104 - NPE during failing KnR declarator which has consumed too much
This commit is contained in:
parent
166c0d9e22
commit
504759ff91
2 changed files with 46 additions and 50 deletions
|
@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
|
@ -25,11 +26,13 @@ import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
|
@ -264,28 +267,7 @@ public class AST2KnRTests extends AST2BaseTest {
|
||||||
buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$
|
buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$
|
||||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true, false );
|
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true, false );
|
||||||
|
|
||||||
IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[0];
|
assertTrue( tu.getDeclarations()[0] instanceof IASTProblemDeclaration );
|
||||||
assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator);
|
|
||||||
ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator();
|
|
||||||
assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$
|
|
||||||
assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$
|
|
||||||
assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTProblemDeclaration);
|
|
||||||
assertTrue(f.getBody() instanceof IASTCompoundStatement);
|
|
||||||
assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement);
|
|
||||||
assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression);
|
|
||||||
assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression);
|
|
||||||
assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$
|
|
||||||
assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression);
|
|
||||||
assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$
|
|
||||||
|
|
||||||
// TODO problem bindings, right now both bindings for x are null, similarly for the below KRCProblem tests
|
|
||||||
// f_kr.getParameterNames()[0].resolveBinding();
|
|
||||||
// ((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding();
|
|
||||||
|
|
||||||
// test tu.getDeclarations(IBinding)
|
|
||||||
IASTName[] decls = tu.getDeclarations(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding());
|
|
||||||
assertEquals( decls.length, 0 );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKRCProblem2() throws Exception {
|
public void testKRCProblem2() throws Exception {
|
||||||
|
@ -295,29 +277,8 @@ public class AST2KnRTests extends AST2BaseTest {
|
||||||
buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$
|
buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$
|
||||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true, false );
|
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true, false );
|
||||||
|
|
||||||
IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[1];
|
assertTrue( tu.getDeclarations()[1] instanceof IASTProblemDeclaration );
|
||||||
assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator);
|
assertTrue( tu.getDeclarations()[2] instanceof IASTProblemDeclaration );
|
||||||
ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator();
|
|
||||||
assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$
|
|
||||||
assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$
|
|
||||||
assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTProblemDeclaration);
|
|
||||||
assertTrue(f.getBody() instanceof IASTCompoundStatement);
|
|
||||||
assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement);
|
|
||||||
assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression);
|
|
||||||
assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression);
|
|
||||||
assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$
|
|
||||||
assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression);
|
|
||||||
assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$
|
|
||||||
|
|
||||||
// test tu.getDeclarations(IBinding)
|
|
||||||
IASTName[] decls = tu.getDeclarations(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding());
|
|
||||||
assertEquals( decls.length, 0 );
|
|
||||||
|
|
||||||
assertNotNull( ((CScope)tu.getScope()).getBinding(CScope.NAMESPACE_TYPE_OTHER, new String("i").toCharArray()) ); //$NON-NLS-1$
|
|
||||||
assertNotNull( ((CScope)tu.getScope()).getBinding(CScope.NAMESPACE_TYPE_OTHER, new String("f").toCharArray()) ); //$NON-NLS-1$
|
|
||||||
CVisitor.clearBindings(tu);
|
|
||||||
assertNull( ((CScope)tu.getScope()).getBinding(CScope.NAMESPACE_TYPE_OTHER, new String("i").toCharArray()) ); //$NON-NLS-1$
|
|
||||||
assertNull( ((CScope)tu.getScope()).getBinding(CScope.NAMESPACE_TYPE_OTHER, new String("f").toCharArray()) ); //$NON-NLS-1$
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKRCProblem3() throws Exception {
|
public void testKRCProblem3() throws Exception {
|
||||||
|
@ -653,8 +614,8 @@ public class AST2KnRTests extends AST2BaseTest {
|
||||||
|
|
||||||
public void testBug97447() throws Exception {
|
public void testBug97447() throws Exception {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
buffer.append("void f( a ) int a; {} \n");
|
buffer.append("void f( a ) int a; {} \n"); //$NON-NLS-1$
|
||||||
buffer.append("void f( int ); \n");
|
buffer.append("void f( int ); \n"); //$NON-NLS-1$
|
||||||
|
|
||||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C, true);
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C, true);
|
||||||
CNameCollector col = new CNameCollector();
|
CNameCollector col = new CNameCollector();
|
||||||
|
@ -664,4 +625,25 @@ public class AST2KnRTests extends AST2BaseTest {
|
||||||
IFunction f1 = (IFunction) col.getName(3).resolveBinding();
|
IFunction f1 = (IFunction) col.getName(3).resolveBinding();
|
||||||
IParameter a = (IParameter) col.getName(4).resolveBinding();
|
IParameter a = (IParameter) col.getName(4).resolveBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug100104() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("typedef int ush;\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("int f()\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("{\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("int a=1;\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("((ush)(a)*(ush)(a) * a);\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("{\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("};\n"); //$NON-NLS-1$
|
||||||
|
buffer.append("}\n"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C, true, true);
|
||||||
|
assertTrue( tu.getDeclarations()[0] instanceof IASTSimpleDeclaration );
|
||||||
|
assertTrue( tu.getDeclarations()[1] instanceof IASTFunctionDefinition );
|
||||||
|
IASTStatement[] stmts = ((IASTCompoundStatement)((IASTFunctionDefinition)tu.getDeclarations()[1]).getBody()).getStatements();
|
||||||
|
assertTrue( stmts[0] instanceof IASTDeclarationStatement );
|
||||||
|
assertTrue( stmts[1] instanceof IASTExpressionStatement );
|
||||||
|
assertTrue( stmts[2] instanceof IASTCompoundStatement );
|
||||||
|
assertTrue( stmts[3] instanceof IASTNullStatement );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2596,6 +2596,12 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
previousWasIdentifier = true;
|
previousWasIdentifier = true;
|
||||||
parmCount++;
|
parmCount++;
|
||||||
} else if (LT(1) == IToken.tRPAREN) {
|
} else if (LT(1) == IToken.tRPAREN) {
|
||||||
|
if (!previousWasIdentifier) {
|
||||||
|
// if the first token encountered is tRPAREN then it's not K&R C
|
||||||
|
// the first token when counting K&R C parms is always an identifier
|
||||||
|
backup(mark);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
consume();
|
consume();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2613,10 +2619,18 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
|
|
||||||
// look ahead for the start of the function body, if end of file is
|
// look ahead for the start of the function body, if end of file is
|
||||||
// found then return 0 parameters found (implies not KnR C)
|
// found then return 0 parameters found (implies not KnR C)
|
||||||
IToken previous=null;
|
int previous=-1;
|
||||||
IToken next=null;
|
int next=LA(1).hashCode();
|
||||||
while (LT(1) != IToken.tLBRACE) {
|
while (LT(1) != IToken.tLBRACE) {
|
||||||
next = consume();
|
// fix for 100104: check if the parameter declaration is a valid one
|
||||||
|
try {
|
||||||
|
simpleDeclaration();
|
||||||
|
} catch (BacktrackException e) {
|
||||||
|
backup(mark);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = LA(1).hashCode();
|
||||||
if (next == previous) { // infinite loop detected
|
if (next == previous) { // infinite loop detected
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue