diff options
author | Chris Lattner <sabre@nondot.org> | 2009-05-25 17:16:10 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-05-25 17:16:10 +0000 |
commit | 3240469102eca90fa5123ec9636fa0364df3034c (patch) | |
tree | ad2600bcac2f7d2cb04a9299c03d9d47605793b7 | |
parent | 442a661a2b44e78e3c66e35bf842c3dc119dfe92 (diff) |
Fix a couple of bugs:
1. When we accept "#garbage" in asm-with-cpp mode, change the token kind
of the # to unknown so that the preprocessor won't try to process it as
a real #. This fixes a crash on the attached example
2. Fix macro definition extents processing to handle #foo at the end of a
macro to say the definition ends with the foo, not the #.
This is a follow-on fix to r72283, and rdar://6916026
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72388 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 45 | ||||
-rw-r--r-- | test/Preprocessor/assembler-with-cpp.c | 18 |
2 files changed, 39 insertions, 24 deletions
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index d7b8fc7fd8..af59ded275 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -1359,15 +1359,15 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { } } else { - // Otherwise, read the body of a function-like macro. This has to validate - // the # (stringize) operator. + // Otherwise, read the body of a function-like macro. While we are at it, + // check C99 6.10.3.2p1: ensure that # operators are followed by macro + // parameters in function-like macro expansions. while (Tok.isNot(tok::eom)) { LastTok = Tok; - MI->AddTokenToBody(Tok); - // Check C99 6.10.3.2p1: ensure that # operators are followed by macro - // parameters in function-like macro expansions. if (Tok.isNot(tok::hash)) { + MI->AddTokenToBody(Tok); + // Get the next token of the macro. LexUnexpandedToken(Tok); continue; @@ -1376,22 +1376,31 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { // Get the next token of the macro. LexUnexpandedToken(Tok); - // Check for a valid macro arg identifier, unless this is a .S file in - // which case it is still added to the body. - if ((!Tok.getIdentifierInfo() || - MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) && - !getLangOptions().AsmPreprocessor) { - Diag(Tok, diag::err_pp_stringize_not_parameter); - ReleaseMacroInfo(MI); - - // Disable __VA_ARGS__ again. - Ident__VA_ARGS__->setIsPoisoned(true); - return; + // Check for a valid macro arg identifier. + if (Tok.getIdentifierInfo() == 0 || + MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) { + + // If this is assembler-with-cpp mode, we accept random gibberish after + // the '#' because '#' is often a comment character. However, change + // the kind of the token to tok::unknown so that the preprocessor isn't + // confused. + if (getLangOptions().AsmPreprocessor && Tok.isNot(tok::eom)) { + LastTok.setKind(tok::unknown); + } else { + Diag(Tok, diag::err_pp_stringize_not_parameter); + ReleaseMacroInfo(MI); + + // Disable __VA_ARGS__ again. + Ident__VA_ARGS__->setIsPoisoned(true); + return; + } } - // Things look ok, add the param name token to the macro. + // Things look ok, add the '#' and param name tokens to the macro. + MI->AddTokenToBody(LastTok); MI->AddTokenToBody(Tok); - + LastTok = Tok; + // Get the next token of the macro. LexUnexpandedToken(Tok); } diff --git a/test/Preprocessor/assembler-with-cpp.c b/test/Preprocessor/assembler-with-cpp.c index 00080cce9b..2e84ed1a6b 100644 --- a/test/Preprocessor/assembler-with-cpp.c +++ b/test/Preprocessor/assembler-with-cpp.c @@ -58,14 +58,20 @@ // #define T6() T6 #nostring #define T7(x) T7 #x -T6() -T7(foo) -// RUN: grep 'T6 #nostring' %t && -// RUN: grep 'T7 "foo"' %t && +8: T6() +9: T7(foo) +// RUN: grep '8: T6 #nostring' %t && +// RUN: grep '9: T7 "foo"' %t && // Concatenation with period doesn't leave a space -// RUN: grep -F '.T8' %t && +// RUN: grep -F '10: .T8' %t && #define T8(A,B) A ## B -T8(.,T8) +10: T8(.,T8) + + +// This should not crash. +// RUN: grep '11: #0' %t && +#define T11(a) #0 +11: T11(b) // RUN: true |