1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 354553: Handling of invalid token paste

This commit is contained in:
Markus Schorn 2011-08-17 11:54:39 +02:00
parent b099aac333
commit c17176f43c
4 changed files with 64 additions and 46 deletions

View file

@ -327,4 +327,18 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
validateProblemCount(0); validateProblemCount(0);
} }
// #define foo(x) (## x)
// void test foo(void); // Valid for Microsoft's compiler, expands to (void)
public void testInvalidTokenPasting_Bug354553() throws Exception {
initializeScanner();
validateToken(IToken.t_void);
validateIdentifier("test");
validateToken(IToken.tLPAREN);
validateToken(IToken.t_void);
validateToken(IToken.tRPAREN);
validateToken(IToken.tSEMI);
validateEOF();
validateProblem(0, IProblem.PREPROCESSOR_MACRO_PASTING_ERROR, "foo");
validateProblemCount(1);
}
} }

View file

@ -227,6 +227,8 @@ public class PreprocessorTests extends PreprocessorTestsBase {
validateString("a"); validateString("a");
validateToken(IToken.tSEMI); validateToken(IToken.tSEMI);
validateString("a");
validateIdentifier("b");
validateToken(IToken.tSEMI); validateToken(IToken.tSEMI);
validateEOF(); validateEOF();
validateProblemCount(1); validateProblemCount(1);

View file

@ -65,8 +65,7 @@ public class MacroExpander {
public void execute(IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) { public void execute(IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
if (fIsStart) { if (fIsStart) {
forbidden.put(fMacro, fMacro); forbidden.put(fMacro, fMacro);
} } else {
else {
forbidden.remove(fMacro); forbidden.remove(fMacro);
} }
} }
@ -303,18 +302,15 @@ public class MacroExpander {
} }
tracker.endFunctionStyleMacro(); tracker.endFunctionStyleMacro();
} }
} } else {
else {
if (tracker == null) { if (tracker == null) {
objStyleTokenPaste(macro, result); objStyleTokenPaste(macro, result);
} } else {
else {
if (tracker.isRequestedStep()) { if (tracker.isRequestedStep()) {
TokenList replacement= new TokenList(); TokenList replacement= new TokenList();
objStyleTokenPaste(macro, replacement); objStyleTokenPaste(macro, replacement);
tracker.storeObjectStyleMacroReplacement(macro, lastConsumed, replacement, result); tracker.storeObjectStyleMacroReplacement(macro, lastConsumed, replacement, result);
} } else {
else {
objStyleTokenPaste(macro, result); objStyleTokenPaste(macro, result);
} }
tracker.endObjectStyleMacro(); tracker.endObjectStyleMacro();
@ -349,21 +345,17 @@ public class MacroExpander {
PreprocessorMacro macro= fDictionary.get(image); PreprocessorMacro macro= fDictionary.get(image);
if (protect || (tracker != null && tracker.isDone())) { if (protect || (tracker != null && tracker.isDone())) {
result.append(t); result.append(t);
} } else if (protectDefinedConstructs && Arrays.equals(image, Keywords.cDEFINED)) {
else if (protectDefinedConstructs && Arrays.equals(image, Keywords.cDEFINED)) {
t.setType(CPreprocessor.tDEFINED); t.setType(CPreprocessor.tDEFINED);
result.append(t); result.append(t);
protect= true; protect= true;
} } else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) {
// tricky: don't mark function-style macros if you don't find the left parenthesis // Tricky: Don't mark function-style macros if you don't find the left parenthesis
else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) {
result.append(t); result.append(t);
} } else if (forbidden.containsKey(macro)) {
else if (forbidden.containsKey(macro)) {
t.setType(CPreprocessor.tEXPANDED_IDENTIFIER); // prevent any further expansion t.setType(CPreprocessor.tEXPANDED_IDENTIFIER); // prevent any further expansion
result.append(t); result.append(t);
} } else {
else {
if (fLocationMap != null) { if (fLocationMap != null) {
ImageLocationInfo info= null; ImageLocationInfo info= null;
if (fLexOptions.fCreateImageLocations) { if (fLexOptions.fCreateImageLocations) {
@ -403,8 +395,7 @@ public class MacroExpander {
final Object s= t.fSource; final Object s= t.fSource;
if (s instanceof ObjectStyleMacro) { if (s instanceof ObjectStyleMacro) {
return new MacroImageLocationInfo((ObjectStyleMacro) s, t.getOffset(), t.getEndOffset()); return new MacroImageLocationInfo((ObjectStyleMacro) s, t.getOffset(), t.getEndOffset());
} } else if (s instanceof CPreprocessor) {
else if (s instanceof CPreprocessor) {
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(t.getOffset()); int sequenceNumber= fLocationMap.getSequenceNumberForOffset(t.getOffset());
int sequenceEndNumber= fLocationMap.getSequenceNumberForOffset(t.getEndOffset()); int sequenceEndNumber= fLocationMap.getSequenceNumberForOffset(t.getEndOffset());
return new ParameterImageLocationInfo(sequenceNumber, sequenceEndNumber); return new ParameterImageLocationInfo(sequenceNumber, sequenceEndNumber);
@ -514,8 +505,7 @@ public class MacroExpander {
spaceMarkers.clear(); spaceMarkers.clear();
idx++; idx++;
continue loop; continue loop;
} } else if (!hasVarargs) {
else if (!hasVarargs) {
tooManyArgs= true; tooManyArgs= true;
break loop; break loop;
} }
@ -525,8 +515,7 @@ public class MacroExpander {
case CPreprocessor.tSCOPE_MARKER: case CPreprocessor.tSCOPE_MARKER:
if (argCount == 0) { if (argCount == 0) {
((ExpansionBoundary) t).execute(forbidden); ((ExpansionBoundary) t).execute(forbidden);
} } else {
else {
result[idx].append(t); result[idx].append(t);
} }
continue loop; continue loop;
@ -556,9 +545,9 @@ public class MacroExpander {
throw new AbortMacroExpansionException(); throw new AbortMacroExpansionException();
} }
if (tooManyArgs) if (tooManyArgs) {
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray()); handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
else if (idx+1 < requiredArgs) { } else if (idx+1 < requiredArgs) {
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray()); handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
} }
return lastToken; return lastToken;
@ -589,8 +578,7 @@ public class MacroExpander {
result.appendAllButLast(arg); result.appendAllButLast(arg);
addSpacemarker(result.last(), pasteArg1, result); // start token paste addSpacemarker(result.last(), pasteArg1, result); // start token paste
} }
} } else {
else {
TokenList arg= clone(expandedArgs[idx]); TokenList arg= clone(expandedArgs[idx]);
result.appendAll(arg); result.appendAll(arg);
addSpacemarker(t, n, result); // end argument replacement addSpacemarker(t, n, result); // end argument replacement
@ -618,8 +606,7 @@ public class MacroExpander {
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image); Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
pasteArg1= generated; pasteArg1= generated;
} } else {
else {
result.append(generated); result.append(generated);
addSpacemarker(t, n, result); // end stringify addSpacemarker(t, n, result); // end stringify
} }
@ -654,13 +641,23 @@ public class MacroExpander {
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND); final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
generated= tokenpaste(pasteArg1, pasteArg2, macro); generated= tokenpaste(pasteArg1, pasteArg2, macro);
if (generated == null) {
// Cannot perform token paste.
// Use the two tokens instead, see bug 354553.
generated= pasteArg1;
if (rest == null)
rest= new TokenList();
rest.prepend(pasteArg2);
spaceDef0= generated;
spaceDef1= pasteArg2;
}
pasteArg1= null; pasteArg1= null;
if (generated != null) { if (generated != null) {
if (pasteNext && rest == null) { if (pasteNext && rest == null) {
pasteArg1= generated; // no need to mark spaces, done ahead pasteArg1= generated; // no need to mark spaces, done ahead
} } else {
else {
result.append(generated); result.append(generated);
addSpacemarker(spaceDef0, spaceDef1, result); // end token paste addSpacemarker(spaceDef0, spaceDef1, result); // end token paste
} }
@ -672,8 +669,7 @@ public class MacroExpander {
result.appendAllButLast(rest); result.appendAllButLast(rest);
addSpacemarker(result.last(), pasteArg1, result); // start token paste addSpacemarker(result.last(), pasteArg1, result); // start token paste
} }
} } else {
else {
result.appendAll(rest); result.appendAll(rest);
if (idx >= 0) { if (idx >= 0) {
addSpacemarker(t, n, result); // end argument replacement addSpacemarker(t, n, result); // end argument replacement
@ -697,8 +693,7 @@ public class MacroExpander {
if (arg.isEmpty()) { if (arg.isEmpty()) {
addSpacemarker(l, t, result); addSpacemarker(l, t, result);
addSpacemarker(nn, nnn, result); addSpacemarker(nn, nnn, result);
} } else {
else {
result.append(t); result.append(t);
addSpacemarker(t, n, result); addSpacemarker(t, n, result);
result.appendAll(arg); result.appendAll(arg);
@ -712,8 +707,7 @@ public class MacroExpander {
addSpacemarker(l, t, result); addSpacemarker(l, t, result);
pasteArg1= t; pasteArg1= t;
} } else {
else {
result.append(t); result.append(t);
} }
break; break;
@ -722,8 +716,7 @@ public class MacroExpander {
if (isKind(n, IToken.tPOUNDPOUND)) { if (isKind(n, IToken.tPOUNDPOUND)) {
addSpacemarker(l, t, result); // start token paste addSpacemarker(l, t, result); // start token paste
pasteArg1= t; pasteArg1= t;
} } else {
else {
result.append(t); result.append(t);
} }
break; break;
@ -767,8 +760,7 @@ public class MacroExpander {
if (isKind(l, IToken.tCOMMA) && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS && if (isKind(l, IToken.tCOMMA) && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
idx == macro.getParameterPlaceholderList().length-1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) { idx == macro.getParameterPlaceholderList().length-1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
result.set(2*idx+1); result.set(2*idx+1);
} } else {
else {
result.set(2*idx); result.set(2*idx);
} }
t= n; n= (Token) n.getNext(); t= n; n= (Token) n.getNext();
@ -801,8 +793,7 @@ public class MacroExpander {
if (t != null) { if (t != null) {
if (isKind(n, IToken.tPOUNDPOUND)) { if (isKind(n, IToken.tPOUNDPOUND)) {
pasteArg1= t; pasteArg1= t;
} } else {
else {
result.append(t); result.append(t);
addSpacemarker(pasteArg2, n, result); // end token paste addSpacemarker(pasteArg2, n, result); // end token paste
} }
@ -814,8 +805,7 @@ public class MacroExpander {
if (isKind(n, IToken.tPOUNDPOUND)) { if (isKind(n, IToken.tPOUNDPOUND)) {
addSpacemarker(l, t, result); // start token paste addSpacemarker(l, t, result); // start token paste
pasteArg1= t; pasteArg1= t;
} } else {
else {
result.append(t); result.append(t);
} }
break; break;

View file

@ -58,6 +58,18 @@ class TokenList {
} }
} }
public final void prepend(Token t) {
final Token first= t;
if (first != null) {
final Token last= t;
last.setNext(fFirst);
fFirst= first;
if (fLast == null) {
fLast= last;
}
}
}
public final void prepend(TokenList prepend) { public final void prepend(TokenList prepend) {
final Token first= prepend.fFirst; final Token first= prepend.fFirst;
if (first != null) { if (first != null) {