From: Chris Lattner Date: Mon, 25 May 2009 17:16:10 +0000 (+0000) Subject: Fix a couple of bugs: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3240469102eca90fa5123ec9636fa0364df3034c;p=clang 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 --- 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