зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
442a661a2b
Коммит
3240469102
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче