Author: akirtzidis Date: Fri May 24 20:35:18 2013 New Revision: 182699 URL: http://llvm.org/viewvc/llvm-project?rev=182699&view=rev Log: [Preprocessor] Prevent expansion of y in x ## y when x is empty
When x is empty, x ## is suppressed, and when y gets expanded, the fact that it follows ## is not available in the macro expansion result. The macro definition can be checked instead, the ## will be available there regardless of what x expands to. Fixes http://llvm.org/PR12767 Patch by Harald van Dijk! Modified: cfe/trunk/lib/Lex/TokenLexer.cpp cfe/trunk/test/Preprocessor/macro_paste_empty.c Modified: cfe/trunk/lib/Lex/TokenLexer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=182699&r1=182698&r2=182699&view=diff ============================================================================== --- cfe/trunk/lib/Lex/TokenLexer.cpp (original) +++ cfe/trunk/lib/Lex/TokenLexer.cpp Fri May 24 20:35:18 2013 @@ -244,9 +244,11 @@ void TokenLexer::ExpandFunctionArguments // Otherwise, this is a use of the argument. Find out if there is a paste // (##) operator before or after the argument. - bool PasteBefore = + bool NonEmptyPasteBefore = !ResultToks.empty() && ResultToks.back().is(tok::hashhash); + bool PasteBefore = i != 0 && Tokens[i-1].is(tok::hashhash); bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash); + assert(!NonEmptyPasteBefore || PasteBefore); // In Microsoft mode, remove the comma before __VA_ARGS__ to ensure there // are no trailing commas if __VA_ARGS__ is empty. @@ -314,7 +316,7 @@ void TokenLexer::ExpandFunctionArguments // that __VA_ARGS__ expands to multiple tokens, avoid a pasting error when // the expander trys to paste ',' with the first token of the __VA_ARGS__ // expansion. - if (PasteBefore && ResultToks.size() >= 2 && + if (NonEmptyPasteBefore && ResultToks.size() >= 2 && ResultToks[ResultToks.size()-2].is(tok::comma) && (unsigned)ArgNo == Macro->getNumArgs()-1 && Macro->isVariadic()) { @@ -350,7 +352,7 @@ void TokenLexer::ExpandFunctionArguments // case, we do not want the extra whitespace to be added. For example, // we want ". ## foo" -> ".foo" not ". foo". if ((CurTok.hasLeadingSpace() || NextTokGetsSpace) && - !PasteBefore) + !NonEmptyPasteBefore) ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace); NextTokGetsSpace = false; @@ -371,10 +373,14 @@ void TokenLexer::ExpandFunctionArguments } // If this is on the RHS of a paste operator, we've already copied the - // paste operator to the ResultToks list. Remove it. - assert(PasteBefore && ResultToks.back().is(tok::hashhash)); - NextTokGetsSpace |= ResultToks.back().hasLeadingSpace(); - ResultToks.pop_back(); + // paste operator to the ResultToks list, unless the LHS was empty too. + // Remove it. + assert(PasteBefore); + if (NonEmptyPasteBefore) { + assert(ResultToks.back().is(tok::hashhash)); + NextTokGetsSpace |= ResultToks.back().hasLeadingSpace(); + ResultToks.pop_back(); + } // If this is the __VA_ARGS__ token, and if the argument wasn't provided, // and if the macro had at least one real argument, and if the token before Modified: cfe/trunk/test/Preprocessor/macro_paste_empty.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/macro_paste_empty.c?rev=182699&r1=182698&r2=182699&view=diff ============================================================================== --- cfe/trunk/test/Preprocessor/macro_paste_empty.c (original) +++ cfe/trunk/test/Preprocessor/macro_paste_empty.c Fri May 24 20:35:18 2013 @@ -1,13 +1,17 @@ -// RUN: %clang_cc1 -E %s | grep 'a:Y' -// RUN: %clang_cc1 -E %s | grep 'b:Y' -// RUN: %clang_cc1 -E %s | grep 'c:YY' +// RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s #define FOO(X) X ## Y a:FOO() +// CHECK: a:Y #define FOO2(X) Y ## X b:FOO2() +// CHECK: b:Y #define FOO3(X) X ## Y ## X ## Y ## X ## X c:FOO3() +// CHECK: c:YY +#define FOO4(X, Y) X ## Y +d:FOO4(,FOO4(,)) +// CHECK: d:FOO4 _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
