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
This commit is contained in:
Chris Lattner 2009-05-25 17:16:10 +00:00
Родитель 442a661a2b
Коммит 3240469102
2 изменённых файлов: 39 добавлений и 24 удалений

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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