1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 14:15:23 +02:00
Fixed Bug 45476 : preprocessor macro "defined" not handled correctly 
	Fixed Bug 45477 : macro redefines prevent further parsing 

TESTS
	Added testBug45476() to ScannerTestCase.  
	Added testBug45477() to ScannerTestCase.
This commit is contained in:
John Camelon 2003-10-24 21:34:15 +00:00
parent 5be9f16c62
commit a95faa4dbe
8 changed files with 223 additions and 29 deletions

View file

@ -1,3 +1,7 @@
2003-10-24 John Camelon
Added testBug45476() to ScannerTestCase.
Added testBug45477() to ScannerTestCase.
2003-10-24 John Camelon
Moved testBug39542() from ASTFailedTests to QuickParseASTTests.
Moved testBug39549() from ASTFailedTests to QuickParseASTTests.

View file

@ -1411,5 +1411,88 @@ public class ScannerTestCase extends BaseScannerTest
validateWideChar( "hijklmnop");
validateEOF();
}
public void testBug45476() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append( "#define X 5\n");
buffer.append( "#if defined X\n");
buffer.append( "#define Y 10\n");
buffer.append( "#endif");
initializeScanner( buffer.toString() );
validateEOF();
validateDefinition( "Y", "10");
}
public void testBug45477() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append( "#define D\n" );
buffer.append( "#define D\n" );
buffer.append( "#define sum(x,y) x+y\n" );
buffer.append( "#define E 3\n" );
buffer.append( "#define E 3\n" );
buffer.append( "#define sum(x,y) x+y\n");
buffer.append( "#if defined(D)\n" );
buffer.append( "printf\n" );
buffer.append( "#endif\n" );
buffer.append( "#if defined(sum)\n" );
buffer.append( "scanf\n" );
buffer.append( "#endif\n" );
buffer.append( "#if defined(E)\n" );
buffer.append( "sprintf\n" );
buffer.append( "#endif\n" );
initializeScanner( buffer.toString() );
validateIdentifier( "printf" );
validateIdentifier( "scanf");
validateIdentifier( "sprintf" );
validateEOF();
for( int i = 0; i < 5; ++i)
{
buffer = new StringBuffer();
buffer.append( "#define D blah\n" );
switch( i )
{
case 0:
buffer.append( "#define D\n");
break;
case 1:
buffer.append( "#define D( x ) echo\n");
break;
case 2:
buffer.append( "#define D ACDC\n");
break;
case 3:
buffer.append( "#define D defined( D )\n");
break;
case 4:
buffer.append( "#define D blahh\n");
break;
}
initializeScanner( buffer.toString() );
try
{
validateEOF();
fail( "Should not reach here");
}
catch( ScannerException se )
{
assertEquals( se.getErrorCode(), ScannerException.ErrorCode.ATTEMPTED_REDEFINITION );
}
}
buffer = new StringBuffer();
buffer.append( "#define X 5\n");
buffer.append( "#define Y 7\n");
buffer.append( "#define SUMXY X _+ Y");
buffer.append( "#define SUMXY X + Y");
initializeScanner(buffer.toString());
validateEOF();
}
}

View file

@ -1,4 +1,8 @@
2003-10-22 John Camelon
2003-10-24 John Camelon
Fixed Bug 45476 : preprocessor macro "defined" not handled correctly
Fixed Bug 45477 : macro redefines prevent further parsing
2003-10-24 John Camelon
Fixed Bug 39542 : Parser fails on 'struct' parameter types
Fixed Bug 39549 : Designated initializers are not supported (ANSI C99)
Fixed Bug 39551 : Complex and imaginary numbers are not supported (ANSI C99)

View file

@ -15,4 +15,5 @@ public interface IMacroDescriptor {
List getTokenizedExpansion();
String getName();
String getSignature();
boolean compatible(IMacroDescriptor descriptor);
}

View file

@ -78,14 +78,12 @@ public class ScannerException extends Exception {
return true;
if( mode == ParserMode.COMPLETE_PARSE )
if( this == ErrorCode.POUND_ERROR ||
this == ErrorCode.DEFINITION_NOT_FOUND ||
this == ErrorCode.UNBALANCED_CONDITIONALS ||
this == ErrorCode.MALFORMED_MACRO_DEFN ||
this == ErrorCode.UNEXPECTED_EOF ||
this == ErrorCode.MACRO_USAGE_ERROR ||
this == ErrorCode.MACRO_PASTING_ERROR ||
this == ErrorCode.EXPRESSION_EVALUATION_ERROR ||
this == ErrorCode.ATTEMPTED_REDEFINITION )
this == ErrorCode.EXPRESSION_EVALUATION_ERROR )
return true;
return false;
}

View file

@ -107,4 +107,20 @@ public class MacroDescriptor implements IMacroDescriptor {
return signature;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IMacroDescriptor#compatible(org.eclipse.cdt.core.parser.IMacroDescriptor)
*/
public boolean compatible(IMacroDescriptor descriptor) {
if( descriptor.getName() == null ) return false;
if( descriptor.getTokenizedExpansion() == null ) return false;
if( descriptor.getParameters() == null ) return false;
if( ! name.equals( descriptor.getName() )) return false;
if( descriptor.getParameters().size() != identifierParameters.size() ) return false;
if( descriptor.getTokenizedExpansion().size() != tokenizedExpansion.size() ) return false;
if( ! (descriptor.getParameters().containsAll( identifierParameters ) )) return false;
if( ! (descriptor.getTokenizedExpansion().containsAll( tokenizedExpansion ))) return false;
return true;
}
}

View file

@ -2119,12 +2119,8 @@ public class Scanner implements IScanner {
String key = getNextIdentifier();
int offset = contextStack.getCurrentContext().getOffset() - key.length() - contextStack.getCurrentContext().undoStackSize();
if (mode == ParserMode.COMPLETE_PARSE) {
String checkForRedefinition = (String) definitions.get(key);
if (checkForRedefinition != null) {
throw new ScannerException( ScannerException.ErrorCode.ATTEMPTED_REDEFINITION, key, getCurrentFile(), getCurrentOffset());
}
}
// store the previous definition to check against later
Object previousDefinition = definitions.get( key );
// get the next character
// the C++ standard says that macros must not put
@ -2217,12 +2213,15 @@ public class Scanner implements IScanner {
parameterIdentifiers,
macroReplacementTokens,
key + "(" + parameters + ")");
checkValidMacroRedefinition(key, previousDefinition, descriptor);
addDefinition(key, descriptor);
}
else if ((c == '\n') || (c == '\r'))
{
addDefinition( key, "" );
checkValidMacroRedefinition(key, previousDefinition, "");
addDefinition( key, "" );
}
else if ((c == ' ') || (c == '\t') ) {
// this is a simple definition
@ -2230,7 +2229,9 @@ public class Scanner implements IScanner {
// get what we are to map the name to and add it to the definitions list
String value = getRestOfPreprocessorLine();
addDefinition( key, value );
checkValidMacroRedefinition(key, previousDefinition, value);
addDefinition( key, value );
} else if (c == '/') {
// this could be a comment
@ -2238,27 +2239,31 @@ public class Scanner implements IScanner {
if (c == '/') // one line comment
{
skipOverSinglelineComment();
checkValidMacroRedefinition(key, previousDefinition, "");
addDefinition(key, "");
} else if (c == '*') // multi-line comment
{
if (skipOverMultilineComment()) {
// we have gone over a newline
// therefore, this symbol was defined to an empty string
checkValidMacroRedefinition(key, previousDefinition, "");
addDefinition(key, "");
} else {
String value = getRestOfPreprocessorLine();
checkValidMacroRedefinition(key, previousDefinition, "");
addDefinition(key, value);
}
} else {
// this is not a comment
// it is a bad statement
if (throwExceptionOnBadPreprocessorSyntax)
throw new ScannerException( ScannerException.ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE, getCurrentFile(), getCurrentOffset() );
throw new ScannerException( ScannerException.ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE, getCurrentFile(), getCurrentOffset() );
}
} else {
Util.debugLog("Scanner : Encountered unexpected character " + ((char) c), IDebugLogConstants.PARSER);
if (throwExceptionOnBadPreprocessorSyntax)
throw new ScannerException( ScannerException.ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE, getCurrentFile(), getCurrentOffset() );
throw new ScannerException( ScannerException.ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE, getCurrentFile(), getCurrentOffset() );
}
try
@ -2270,6 +2275,75 @@ public class Scanner implements IScanner {
/* do nothing */
}
}
protected void checkValidMacroRedefinition(
String key,
Object previousDefinition,
Object newDefinition )
throws ScannerException
{
if( mode == ParserMode.COMPLETE_PARSE && previousDefinition != null )
{
if( newDefinition instanceof IMacroDescriptor )
{
if( previousDefinition instanceof IMacroDescriptor )
{
if( ((IMacroDescriptor)previousDefinition).compatible( (IMacroDescriptor) newDefinition ) )
return;
}
}
else if( newDefinition instanceof String )
{
if( previousDefinition instanceof String )
{
Scanner previous = new Scanner( new StringReader( (String)previousDefinition ), "redef-test", new ScannerInfo(), null, null, new NullSourceElementRequestor(),
mode, language );
Scanner current = new Scanner( new StringReader( (String)newDefinition ), "redef-test", new ScannerInfo(), null, null, new NullSourceElementRequestor(),
mode, language );
for ( ; ; )
{
IToken p = null;
IToken c = null;
try
{
p = previous.nextToken();
c = current.nextToken();
if ( c.equals( p ) ) continue;
break;
}
catch( EndOfFile eof )
{
if( ( p != null ) && ( c == null ) )
break;
if( p == null )
{
try
{
c = current.nextToken();
break;
}
catch( EndOfFile eof2 )
{
return;
}
}
}
}
}
}
throw new ScannerException(
ScannerException.ErrorCode.ATTEMPTED_REDEFINITION,
key,
getCurrentFile(),
getCurrentOffset());
}
}
protected Vector getMacroParameters (String params, boolean forStringizing) throws ScannerException {
@ -2464,24 +2538,22 @@ public class Scanner implements IScanner {
skipOverWhitespace();
int c = getChar();
String definitionIdentifier = null;
if (c == '(') {
if (c != '(') {
if (throwExceptionOnBadMacroExpansion)
throw new ScannerException( ScannerException.ErrorCode.MACRO_USAGE_ERROR, "defined()", getCurrentFile(), getCurrentOffset() );
}
StringBuffer buffer = new StringBuffer();
c = getChar();
while ((c != NOCHAR) && (c != ')')) {
buffer.append((char) c);
definitionIdentifier = getNextIdentifier();
skipOverWhitespace();
c = getChar();
if (c != ')')
if (throwExceptionOnBadMacroExpansion)
throw new ScannerException( ScannerException.ErrorCode.MACRO_USAGE_ERROR, "defined()", getCurrentFile(), getCurrentOffset() );
}
if (c == NOCHAR) {
if (throwExceptionOnBadMacroExpansion)
throw new ScannerException( ScannerException.ErrorCode.MACRO_USAGE_ERROR, "defined()", getCurrentFile(), getCurrentOffset() );
}
String definitionIdentifier = buffer.toString().trim();
else
{
ungetChar(c);
definitionIdentifier = getNextIdentifier();
}
if (definitions.get(definitionIdentifier) != null)
return "1";

View file

@ -151,5 +151,21 @@ public class Token implements IToken {
public void setImage( String i ) {
image = i;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object other) {
if( other == null ) return false;
if( !( other instanceof IToken ) )
return false;
if( !(((IToken)other).getImage().equals( image )))
return false;
if( ((IToken)other).getType() != type )
return false;
return true;
}
}