On 07/02/14 00:02, Harald van Dijk wrote:
> On 06/02/14 00:48, Harald van Dijk wrote:
>> On 06/02/14 00:13, Richard Smith wrote:
>>> On Wed, Feb 5, 2014 at 2:36 PM, Harald van Dijk <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>     On 04/02/14 22:24, Richard Smith wrote:
>>>     > On Tue, Feb 4, 2014 at 1:13 PM, Harald van Dijk
>>>     <[email protected] <mailto:[email protected]>
>>>     > <mailto:[email protected] <mailto:[email protected]>>> wrote:
>>>     >
>>>     >     On 04/02/14 20:25, Justin Bogner wrote:
>>>     >     > Harald van Dijk <[email protected]
>>>     <mailto:[email protected]> <mailto:[email protected]
>>>     <mailto:[email protected]>>>
>>>     >     writes:
>>>     >     >> Attached are my updated patches intended to fix various
>>>     whitespace
>>>     >     >> issues in clang, modified to take Justin Bogner's comments into
>>>     >     account.
>>>     >     >> They are intended to ensure that whitespace is not
>>>     inappropriately
>>>     >     >> removed just because a macro or macro argument expansion is
>>>     >     empty, and
>>>     >     >> does get removed during token pasting.
>>>     >     >
>>>     >     > I've committed the first four patches for you: r200785 through
>>>     >     r200788.
>>>     >
>>>     >     Thanks!
>>>     >
>>>     >     >> I have moved the handling of invalid token pastes from
>>>     >     >> TokenLexer::ExpandFunctionArguments to TokenLexer::Lex, so that
>>>     >     it works
>>>     >     >> for both object- and function-like macros, and both when ##'s
>>>     >     operands
>>>     >     >> use macro parameters and when they don't.
>>>     >     >
>>>     >     > Given that the tests needed to be changed and the behaviour
>>>     clearly
>>>     >     > hasn't followed the comment in a while, I'm not entirely
>>>     convinced
>>>     >     this
>>>     >     > is the right thing to do. Could the comment simply be wrong? Are
>>>     >     people
>>>     >     > relying on one behaviour or the other for invalid token
>>>     pastes in
>>>     >     > assembler-with-cpp?
>>>     >     >
>>>     >     > Basically, is there a way to objectively say one of these
>>>     >     behaviours is
>>>     >     > better than the other?
>>>     >
>>>     >     Having looked closer, the current behaviour is inconsistent in
>>>     a way
>>>     >     that cannot really be explained to someone not familiar with a few
>>>     >     implementation details. Given
>>>     >
>>>     >     #define foo(x) (. ## x . ## y)
>>>     >
>>>     >     foo(y) actually expands to (.y . y) in assembler-with-cpp
>>>     mode, with or
>>>     >     without my first four patches. That first result is what the
>>>     comment
>>>     >     refers to; could the fact that the second result is different
>>>     be an
>>>     >     oversight? There does not seem to be a reason for this
>>>     difference, at
>>>     >     least. Surprisingly though, this is exactly what GCC does too.
>>>     >
>>>     >     My last patch would have turned this into (.y .y), removing
>>>     the second
>>>     >     space. That makes sense to me. (. y . y) could also be a perfectly
>>>     >     sensible result.
>>>     >
>>>     >
>>>     > I think (.y .y) is probably the best answer here (consistently remove
>>>     > whitespace on both sides of ## wherever it appears) -- this also
>>>     > probably better matches what MSVC does (where token-paste can
>>>     result in
>>>     > multiple tokens, and seems to act as if the tokens were merely abutted
>>>     > with no adjacent whitespace). This would also behave more consistently
>>>     > when processing languages with a different lexical structure from C --
>>>     > in a language where an identifier can start with a period, (.y .y)
>>>     seems
>>>     > to unambiguously be the right answer.
>>>
>>>     That is a good point about MSVC. There is actually one test case
>>>     affected by this change, using -fms-extensions, where the behaviour did
>>>     not match that of MSVC, and does now, at least for the compiler that
>>>     comes with Visual Studio 2013.
>>>
>>>     >     I suspect, but do not actually know, that nobody really uses .
>>>     ## foo
>>>     >     unless foo is a macro argument, because when foo is not a macro
>>>     >     argument, there is no point in using ## in the first place. It
>>>     would
>>>     >     explain why this went unnoticed for so long. And I can imagine
>>>     a few
>>>     >     cases where this would be useful: assembler directives that
>>>     have subtly
>>>     >     different syntax, depending on the assembler used. x y would be
>>>     >     insufficient if x is ., if y is size, and if .size is a
>>>     directive, but .
>>>     >     size is a syntax error. ## would work here.
>>>     >
>>>     >     Even if clang's behaviour should change, though, my patch does
>>>     not have
>>>     >     adequate testing for these special cases, so shouldn't be
>>>     applied as is.
>>>     >     Should I work on better tests, or do you think it is more
>>>     likely that
>>>     >     the behaviour should remain unchanged and get decent testing?
>>>     >
>>>     >
>>>     > There's a risk of breaking someone's assumption by making a change
>>>     here
>>>     > (especially since we'd be introducing a difference from GCC) but I
>>>     think
>>>     > the new behavior is much more defensible, and there's probably no
>>>     way to
>>>     > find out without trying it.
>>>
>>>     All right. I have now taken a closer look at the test cases where the
>>>     behaviour changes, and noticed that for blargh ## $foo -> blargh $foo it
>>>     would not be right to simply change the test case to blargh$foo, as that
>>>     misses the point of the test.
>>>
>>>
>>> Right, I see, it's just making sure that -fdollars-in-identifiers allows
>>> the paste to work. I like your fix to the test here.
>>
>> Thanks :)
>>
>>>     There was also already a test for . ## foo, but it only tested the case
>>>     where foo is a macro argument. I have extended that test to also check
>>>     what happens when foo is not a macro argument.
>>>
>>>
>>> Can you also add a test for the case where the . comes from a macro
>>> argument? May as well be thorough =)
>>
>> In both tests, the . comes from a macro argument, so I think you mean
>> add cases where it doesn't come from a macro argument? Sure.
>>
>>>     How does the attached patch look? I've re-tested it on sources of today,
>>>     but on top of my patch in the "r200787 - Fix whitespace handling in
>>>     empty macro expansions" thread (after your okay for that).
>>>
>>>
>>> Checking whether the previous token was a ## worries me a little. What
>>> about cases like this:
>>>
>>> #define foo(x, y) x####y
>>> foo(, z)
>>>
>>> This expands to "## z" under our current left-to-right pasting strategy,
>>> but I think your patch drops the space.
>>
>> In that test, I think dropping the space is correct. Leading and
>> trailing white space in a macro argument is insignificant, which is why
>>
>> #define ID(x) x
>> #define FOO(x,y) ID(x)ID(y)
>> FOO(  [  ,  ]  )
>>
>> should (and does) expand to
>>
>> []
>>
>> Since there is no space between the second ## and the y, there should be
>> no space in the output. That said, I do see your point. If I change your
>> test to
>>
>> #define foo(x) x#### y
>> foo()
>>
>> then (still assuming left-to-right, otherwise the test won't work at
>> all) the output should be
>>
>> ## y
>>
>> and I am now getting
>>
>> ##y
>>
>>> Amusingly, "##z" appears to be
>>> the right answer under a right-to-left pasting strategy, so maybe that's
>>> OK? Both GCC and EDG expand this to just "z"; the standard is not
>>> spectacularly clear here, but I think we're right, because a ## produced
>>> by pasting a placemarker token onto a ## is not a token in the
>>> replacement list (that token is already gone).
>>>
>>> If you want to say that we don't care about this case, I could live with
>>> that =)
>>
>> The preprocessor is supposed to change ## from tok::hashhash to
>> tok::unknown in those cases during macro expansion where it is not a
>> paste, to avoid this and similar problems. For example, this altered
>> test does behave as desired:
>>
>> #define hash #
>> #define concat_(x, y) x ## y
>> #define concat(x, y) concat_(x, y)
>> #define bar() concat(hash, hash) y
>> bar()
>>
>> The preprocessor output with my patch is ## y, even though the y follows ##.
>>
>> This test also works:
>>
>> #define foo(x) x y
>> foo(##)
> 
> Ensuring that any remaining ## token is always tok::unknown turned out
> to be hugely impractical, in light of the fact that invalid token pastes
> may also occur in object-like macro expansions, where the RHS can
> equally be a ## token, and there is no ExpandFunctionArgs() or
> equivalent where the tokens can be checked before the actual expansion.
> Without an additional pass before expansion, checking whether a token is
> the RHS of an invalid paste becomes too complicated to be worth the
> effort, and remembering invalid pastes instead is easily done.
> 
> That said...
> 
>> I think the reason it does not happen for x#### y is because when the
>> LHS of a token paste is an empty macro argument, the RHS is copied
>> without actually performing any paste, and in that case, the change to
>> tok::unknown is skipped. It's tempting to say that we don't care, but I
>> think this affects more than a single space. I will look into this.
> 
> ...it does affect more than a single space, and it exposes some
> interesting corner cases.
> 
> #define foo(x,y) x ## ## y y
> foo(,)
> 
> No matter which ## is interpreted first, the result should be ##. For
> purposes of special handling of empty argument pastes, the first
> appearance of y should not be treated as following a paste operator.
> 
> At the same time, though, for purposes of pre-expansion of macro
> arguments, it should be: in
> 
> foo(,foo(,))
> 
> (where it now matters that the scan for ## searches from left to right)
> the first y follows a ## token, so should not be pre-expanded. The
> second y does not, so should be. Normally, this would not matter, except
> when the later expansion would give different results, as it does here:
> later expansion occurs in the context of the expansion of foo, so the
> first nested foo is not expanded. The second is, because the argument
> was pre-expanded, so the result should be
> 
> ## foo(,) ##
> 
> I've only been able to get this result by tracking HashHashBefore and
> PasteBefore independently, where HashHashBefore indicates whether the
> token follows a ## token, and PasteBefore indicates whether that ##
> token was interpreted as an operator.
> 
> Note that if clang actually used placemarker tokens, this would already
> be the natural result without special effort, but I understand that that
> may be impractical for other reasons.
> 
> If I then take an extra look at my attempt to get whitespace handled
> consistently in invalid token pastes, I end up with a similar extra
> variable to track whether an attempted token paste has taken place,
> instead of checking tok::hashhash, just like you suggested.
> 
> However, another problem is that when slightly modifying the example, to
> 
> #define foo(x,y) w x ## ## y z
> foo(,)
> 
> argument substitution should give w ## z, but the actual expansion
> should then not see the ## as a token paste operation. So even though
> TokenLexer::Lex should not check for tok::hashhash, the fact that ## is
> not changed to tok::unknown here is still a problem.
> 
> I have almost-working patches that I hope to finish over the weekend.

And here they are. Especially the first of these patches seems at first
glance overly complicated, but as stated, the simpler approaches I was
able to come up with get corner cases wrong.

Note: I tested these on top of my patches in the <r200787 - Fix
whitespace handling in empty macro expansions> thread.

Cheers,
Harald van Dijk
Ensure ## does not get misinterpreted

When one ## token is an operand of another ## token, both tokens would
be interpreted as an operator in the expansion of a function-like macro.
Instead of detecting whether a token follows a token paste operator,
remember it.
---
 lib/Lex/TokenLexer.cpp                   | 48 +++++++++++++++++++++-----------
 test/Preprocessor/macro_paste_hashhash.c | 12 ++++++++
 2 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 543ca92..3c66c68 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -178,14 +178,29 @@ void TokenLexer::ExpandFunctionArguments() {
   // we install the newly expanded sequence as the new 'Tokens' list.
   bool MadeChange = false;
 
+  bool HashHash = false;
+  bool Paste = false;
+  bool NonEmptyPaste = false;
+
   for (unsigned i = 0, e = NumTokens; i != e; ++i) {
-    // If we found the stringify operator, get the argument stringified.  The
-    // preprocessor already verified that the following token is a macro name
-    // when the #define was parsed.
+    // Find out if there is a paste (##) operator before or after the token.
+    bool HashHashBefore = HashHash;
+    bool PasteBefore = Paste;
+    assert(!PasteBefore || HashHashBefore);
+    bool NonEmptyPasteBefore = NonEmptyPaste;
+    assert(!NonEmptyPasteBefore || PasteBefore);
+    bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
+    HashHash = false;
+    Paste = false;
+    NonEmptyPaste = false;
+
     const Token &CurTok = Tokens[i];
-    if (i != 0 && !Tokens[i-1].is(tok::hashhash) && CurTok.hasLeadingSpace())
+    if (i != 0 && !PasteBefore && CurTok.hasLeadingSpace())
       NextTokGetsSpace = true;
 
+    // If we found the stringify operator, get the argument stringified.  The
+    // preprocessor already verified that the following token is a macro name
+    // when the #define was parsed.
     if (CurTok.is(tok::hash) || CurTok.is(tok::hashat)) {
       int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
       assert(ArgNo != -1 && "Token following # is not an argument?");
@@ -220,13 +235,6 @@ void TokenLexer::ExpandFunctionArguments() {
       continue;
     }
 
-    // Find out if there is a paste (##) operator before or after the token.
-    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);
-
     // Otherwise, if this is not an argument token, just add the token to the
     // output buffer.
     IdentifierInfo *II = CurTok.getIdentifierInfo();
@@ -235,12 +243,17 @@ void TokenLexer::ExpandFunctionArguments() {
       // This isn't an argument, just add it.
       ResultToks.push_back(CurTok);
 
+      Token& ResultTok = ResultToks.back();
       if (NextTokGetsSpace) {
-        ResultToks.back().setFlag(Token::LeadingSpace);
+        ResultTok.setFlag(Token::LeadingSpace);
         NextTokGetsSpace = false;
       } else if (PasteBefore && !NonEmptyPasteBefore)
-        ResultToks.back().clearFlag(Token::LeadingSpace);
+        ResultTok.clearFlag(Token::LeadingSpace);
 
+      HashHash = ResultTok.is(tok::hashhash);
+      Paste = NonEmptyPaste = !PasteBefore && HashHash;
+      if (HashHash && !Paste)
+        ResultTok.setKind(tok::unknown);
       continue;
     }
 
@@ -252,7 +265,7 @@ void TokenLexer::ExpandFunctionArguments() {
 
     // In Microsoft mode, remove the comma before __VA_ARGS__ to ensure there
     // are no trailing commas if __VA_ARGS__ is empty.
-    if (!PasteBefore && ActualArgs->isVarargsElidedUse() &&
+    if (!HashHashBefore && ActualArgs->isVarargsElidedUse() &&
         MaybeRemoveCommaBeforeVaArgs(ResultToks,
                                      /*HasPasteOperator=*/false,
                                      Macro, ArgNo, PP))
@@ -261,7 +274,7 @@ void TokenLexer::ExpandFunctionArguments() {
     // If it is not the LHS/RHS of a ## operator, we must pre-expand the
     // argument and substitute the expanded tokens into the result.  This is
     // C99 6.10.3.1p1.
-    if (!PasteBefore && !PasteAfter) {
+    if (!HashHashBefore && !PasteAfter) {
       const Token *ResultArgToks;
 
       // Only preexpand the argument if it could possibly need it.  This
@@ -368,13 +381,14 @@ void TokenLexer::ExpandFunctionArguments() {
       // Discard the argument token and skip (don't copy to the expansion
       // buffer) the paste operator after it.
       ++i;
+      HashHash = Paste = true;
+      NonEmptyPaste = NonEmptyPasteBefore;
       continue;
     }
 
     // If this is on the RHS of a paste operator, we've already copied the
     // paste operator to the ResultToks list, unless the LHS was empty too.
     // Remove it.
-    assert(PasteBefore);
     if (NonEmptyPasteBefore) {
       assert(ResultToks.back().is(tok::hashhash));
       ResultToks.pop_back();
@@ -384,7 +398,7 @@ void TokenLexer::ExpandFunctionArguments() {
     // and if the macro had at least one real argument, and if the token before
     // the ## was a comma, remove the comma.  This is a GCC extension which is
     // disabled when using -std=c99.
-    if (ActualArgs->isVarargsElidedUse())
+    if (PasteBefore && ActualArgs->isVarargsElidedUse())
       MaybeRemoveCommaBeforeVaArgs(ResultToks,
                                    /*HasPasteOperator=*/true,
                                    Macro, ArgNo, PP);
diff --git a/test/Preprocessor/macro_paste_hashhash.c b/test/Preprocessor/macro_paste_hashhash.c
index f4b03be..61b1c41 100644
--- a/test/Preprocessor/macro_paste_hashhash.c
+++ b/test/Preprocessor/macro_paste_hashhash.c
@@ -9,3 +9,15 @@ join(x, y);
 #define FOO(x) A x B
 // CHECK: A ## B;
 FOO(##);
+
+#define BAR(x, y) x ## ## y
+// CHECK: ## ;
+BAR(,);
+
+#define BAZ(x, y) x ## ## y y
+// CHECK: ## BAZ(,) ##
+BAZ(,BAZ(,))
+
+#define QUX(x, y) w x ## ## y z
+// CHECK: w ## z
+QUX(,)
Fix handling of whitespace in invalid token pastes

A comment in TokenLexer shows that the intent is that x ## y is always
permitted in assembler-with-cpp mode, even if the paste does not result
in a valid token, and that any whitespace before ## or before y is
ignored in that case.

The first two existing tweaked tests in assembler-with-cpp.c do not care
about whitespace, and are updated to reflect the new behaviour. The
third does: it checks that blargh$foo is not an identifier by
concatenating blargh and $foo, and checking whether a space is present
in the output. Since this no longer works, an alternative means of
checking this is required: if blargh$foo is an identifier, and blargh is
a macro, then it does not get expanded. The fourth test is exactly what
this change is about, and gets an extra test for what used to fail.

Another test that verify that ## in object-like macros does not get
treated differently from ## in function-like macros, is useful because
an earlier, simpler, attempt that avoids the extra InvalidTokenPaste
variable would get this wrong, and it would be easy to overlook if
someone else wants to simplify this.

The preprocessed output for macro_paste_identifier_error.c, which
specifically tests -fms-extensions, now matches that of MSVC.
---
 include/clang/Lex/TokenLexer.h                   |  5 +++++
 lib/Lex/TokenLexer.cpp                           | 20 +++++++++++++-------
 test/Preprocessor/assembler-with-cpp.c           | 16 +++++++++++-----
 test/Preprocessor/macro_paste_identifier_error.c |  2 +-
 4 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 659643d..e6035a6 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -99,6 +99,11 @@ class TokenLexer {
   /// should not be subject to further macro expansion.
   bool DisableMacroExpansion : 1;
 
+  /// InvalidTokenPaste - This is true when the token paste (##) operator did
+  /// not produce a valid token.  It is used to handle white space properties
+  /// of the next token.
+  bool InvalidTokenPaste : 1;
+
   TokenLexer(const TokenLexer &) LLVM_DELETED_FUNCTION;
   void operator=(const TokenLexer &) LLVM_DELETED_FUNCTION;
 public:
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 3c66c68..99aa213 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -41,6 +41,7 @@ void TokenLexer::Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI,
   Tokens = &*Macro->tokens_begin();
   OwnsTokens = false;
   DisableMacroExpansion = false;
+  InvalidTokenPaste = false;
   NumTokens = Macro->tokens_end()-Macro->tokens_begin();
   MacroExpansionStart = SourceLocation();
 
@@ -97,6 +98,7 @@ void TokenLexer::Init(const Token *TokArray, unsigned NumToks,
   AtStartOfLine = false;
   HasLeadingSpace = false;
   NextTokGetsSpace = false;
+  InvalidTokenPaste = false;
   MacroExpansionStart = SourceLocation();
 
   // Set HasLeadingSpace/AtStartOfLine so that the first token will be
@@ -359,13 +361,6 @@ void TokenLexer::ExpandFunctionArguments() {
       // If this token (the macro argument) was supposed to get leading
       // whitespace, transfer this information onto the first token of the
       // expansion.
-      //
-      // Do not do this if the paste operator occurs before the macro argument,
-      // as in "A ## MACROARG".  In valid code, the first token will get
-      // smooshed onto the preceding one anyway (forming AMACROARG).  In
-      // assembler-with-cpp mode, invalid pastes are allowed through: in this
-      // case, we do not want the extra whitespace to be added.  For example,
-      // we want ". ## foo" -> ".foo" not ". foo".
       if (NextTokGetsSpace)
         ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace);
 
@@ -423,6 +418,9 @@ void TokenLexer::ExpandFunctionArguments() {
 /// Lex - Lex and return a token from this macro stream.
 ///
 bool TokenLexer::Lex(Token &Tok) {
+  bool InvalidPasteBefore = InvalidTokenPaste;
+  InvalidTokenPaste = false;
+
   // Lexing off the end of the macro, pop this macro off the expansion stack.
   if (isAtEnd()) {
     // If this is a macro (not a token stream), mark the macro enabled now
@@ -448,6 +446,12 @@ bool TokenLexer::Lex(Token &Tok) {
 
   bool TokenIsFromPaste = false;
 
+  // In assembler-with-cpp mode, invalid pastes are allowed through: in this
+  // case, we do not want the extra whitespace to be added.  For example, we
+  // want ". ## foo" -> ".foo" not ". foo".
+  if (InvalidPasteBefore)
+    Tok.clearFlag(Token::LeadingSpace);
+
   // If this token is followed by a token paste (##) operator, paste the tokens!
   // Note that ## is a normal token when not expanding a macro.
   if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash) && Macro) {
@@ -623,6 +627,8 @@ bool TokenLexer::PasteTokens(Token &Tok) {
           return true;
         }
 
+        InvalidTokenPaste = true;
+
         // Do not emit the error when preprocessing assembler code.
         if (!PP.getLangOpts().AsmPreprocessor) {
           // Explicitly convert the token location to have proper expansion
diff --git a/test/Preprocessor/assembler-with-cpp.c b/test/Preprocessor/assembler-with-cpp.c
index f03cb06..c89bb7a 100644
--- a/test/Preprocessor/assembler-with-cpp.c
+++ b/test/Preprocessor/assembler-with-cpp.c
@@ -8,7 +8,7 @@
 // Invalid token pasting is ok. 
 #define A X ## .
 1: A
-// CHECK-Identifiers-False: 1: X .
+// CHECK-Identifiers-False: 1: X.
 
 // Line markers are not linemarkers in .S files, they are passed through.
 # 321
@@ -42,15 +42,17 @@
 #define M5() M4 ## (
 
 5: M5()
-// CHECK-Identifiers-False: 5: expanded (
+// CHECK-Identifiers-False: 5: expanded(
 
 // rdar://6804322
 #define FOO(name)  name ## $foo
+#define blarg
 6: FOO(blarg)
-// CHECK-Identifiers-False: 6: blarg $foo
+// CHECK-Identifiers-False: 6: $foo
 
 // RUN: %clang_cc1 -x assembler-with-cpp -fdollars-in-identifiers -E %s -o - | FileCheck -check-prefix=CHECK-Identifiers-True -strict-whitespace %s
 #define FOO(name)  name ## $foo
+#define blarg
 7: FOO(blarg)
 // CHECK-Identifiers-True: 7: blarg$foo
 
@@ -63,9 +65,9 @@
 // CHECK-Identifiers-True: 9: T7 "foo"
 
 // Concatenation with period doesn't leave a space
-#define T8(A,B) A ## B
+#define T8(A,B) A ## B A ## T8 . ## B . ## T8
 10: T8(.,T8)
-// CHECK-Identifiers-True: 10: .T8
+// CHECK-Identifiers-True: 10: .T8 .T8 .T8 .T8
 
 // This should not crash.
 #define T11(a) #0
@@ -76,6 +78,10 @@
 12: \u0020\u0030\u0080\u0000
 // CHECK-Identifiers-False: 12: \u0020\u0030\u0080\u0000
 
+#define T13 x ## ## y
+// CHECK: 13: x## y
+13: T13
+
 // This should not crash
 // rdar://8823139
 # ##
diff --git a/test/Preprocessor/macro_paste_identifier_error.c b/test/Preprocessor/macro_paste_identifier_error.c
index bba3172..038b054 100644
--- a/test/Preprocessor/macro_paste_identifier_error.c
+++ b/test/Preprocessor/macro_paste_identifier_error.c
@@ -5,4 +5,4 @@
 
 #define foo a ## b ## = 0
 int foo;
-// CHECK: int ab = 0;
+// CHECK: int ab= 0;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to