Index: lib/Lex/TokenLexer.cpp
==================================================================
--- lib/Lex/TokenLexer.cpp
+++ lib/Lex/TokenLexer.cpp
@@ -116,10 +116,38 @@
   }
 
   // TokenLexer owns its formal arguments.
   if (ActualArgs) ActualArgs->destroy(PP);
 }
+
+/// Remove comma ahead of __VA_ARGS__, if present.  Returns true if the comma
+/// is removed.
+static bool MaybeRemoveCommaBeforeVaArgs(SmallVector<Token, 128> &ResultToks,
+                                         bool &NextTokGetsSpace,
+                                         bool HasExtensionDiagnostic,
+                                         Preprocessor &PP) {
+  // Is a comma available to be removed?
+  if (ResultToks.empty() || !ResultToks.back().is(tok::comma))
+    return false;
+
+  if (HasExtensionDiagnostic)
+    PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
+
+  // Remove the comma.
+  ResultToks.pop_back();
+
+  // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"),
+  // then removal of the comma should produce a placemarker token (in C99
+  // terms) which we model by popping off the previous ##, giving us a plain
+  // "X" when __VA_ARGS__ is empty.
+  if (!ResultToks.empty() && ResultToks.back().is(tok::hashhash))
+    ResultToks.pop_back();
+
+  // Never add a space, even if the comma, ##, or arg had a space.
+  NextTokGetsSpace = false;
+  return true;
+}
 
 /// Expand the arguments of a function-like macro so that we can quickly
 /// return preexpanded tokens from Tokens.
 void TokenLexer::ExpandFunctionArguments() {
 
@@ -196,10 +224,19 @@
     // Otherwise, this is a use of the argument.  Find out if there is a paste
     // (##) operator before or after the argument.
     bool PasteBefore =
       !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
     bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
+
+    // In Microsoft mode, remove the comma before __VA_ARGS__ to ensure there
+    // are no trailing commas if __VA_ARGS__ is empty.
+    if (!PasteBefore && PP.getLangOpts().MicrosoftMode &&
+        (unsigned)ArgNo == Macro->getNumArgs()-1 && // Is __VA_ARGS__.
+        ActualArgs->isVarargsElidedUse() &&         // Argument elided.
+        MaybeRemoveCommaBeforeVaArgs(ResultToks, NextTokGetsSpace,
+                                     /*HasExtensionDiagnostic=*/false, PP))
+      continue;
 
     // 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) {
@@ -319,27 +356,18 @@
     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
-    // the ## was a comma, remove the comma.
-    if ((unsigned)ArgNo == Macro->getNumArgs()-1 && // is __VA_ARGS__
-        ActualArgs->isVarargsElidedUse() &&       // Argument elided.
-        !ResultToks.empty() && ResultToks.back().is(tok::comma)) {
-      // Never add a space, even if the comma, ##, or arg had a space.
-      NextTokGetsSpace = false;
-      // Remove the paste operator, report use of the extension.
-      PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
-      ResultToks.pop_back();
-      
-      // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"),
-      // then removal of the comma should produce a placemarker token (in C99
-      // terms) which we model by popping off the previous ##, giving us a plain
-      // "X" when __VA_ARGS__ is empty.
-      if (!ResultToks.empty() && ResultToks.back().is(tok::hashhash))
-        ResultToks.pop_back();
-    }
+    // the ## was a comma, remove the comma.  This is a GCC extension which is
+    // disabled when using -std=c99.
+    if ((unsigned)ArgNo == Macro->getNumArgs()-1 && // Is __VA_ARGS__.
+        ActualArgs->isVarargsElidedUse() &&         // Argument elided.
+        (!PP.getLangOpts().C99 || PP.getLangOpts().GNUMode))
+      MaybeRemoveCommaBeforeVaArgs(ResultToks, NextTokGetsSpace,
+                                   /*HasExtensionDiagnostic=*/true, PP);
+
     continue;
   }
 
   // If anything changed, install this as the new Tokens list.
   if (MadeChange) {

ADDED   test/Preprocessor/macro_fn_comma_swallow2.c
Index: test/Preprocessor/macro_fn_comma_swallow2.c
==================================================================
--- test/Preprocessor/macro_fn_comma_swallow2.c
+++ test/Preprocessor/macro_fn_comma_swallow2.c
@@ -0,0 +1,42 @@
+// Test the __VA_ARGS__ comma swallowing extensions of various compiler dialects.
+
+// RUN: %clang_cc1 -E %s | FileCheck -check-prefix=GCC -strict-whitespace %s
+// RUN: %clang_cc1 -E -std=c99 %s | FileCheck -check-prefix=C99 -strict-whitespace %s
+// RUN: %clang_cc1 -E -std=c11 %s | FileCheck -check-prefix=C99 -strict-whitespace %s
+// RUN: %clang_cc1 -E -x c++ %s | FileCheck -check-prefix=GCC -strict-whitespace %s
+// RUN: %clang_cc1 -E -std=gnu99 %s | FileCheck -check-prefix=GCC -strict-whitespace %s
+// RUN: %clang_cc1 -E -fms-compatibility %s | FileCheck -check-prefix=MS -strict-whitespace %s
+
+#define A(...) [ __VA_ARGS__ ]
+#define B(...) [ , __VA_ARGS__ ]
+#define C(...) [ , ## __VA_ARGS__ ]
+
+1: A() B() C()
+2: A(a) B(a) C(a)
+3: A(,) B(,) C(,)
+4: A(a,b,c) B(a,b,c) C(a,b,c)
+
+// The GCC ", ## __VA_ARGS__" extension swallows the comma when followed by
+// empty __VA_ARGS__.  This extension does not apply in -std=c99 mode, but
+// does apply in C++.
+//
+// GCC: 1: [ ] [ , ] [ ]
+// GCC: 2: [ a ] [ , a ] [ ,a ]
+// GCC: 3: [ , ] [ , , ] [ ,, ]
+// GCC: 4: [ a,b,c ] [ , a,b,c ] [ ,a,b,c ]
+
+// Under C99 standard mode, the GCC ", ## __VA_ARGS__" extension *does not*
+// swallow the comma when followed by empty __VA_ARGS__.
+//
+// C99: 1: [ ] [ , ] [ , ]
+// C99: 2: [ a ] [ , a ] [ ,a ]
+// C99: 3: [ , ] [ , , ] [ ,, ]
+// C99: 4: [ a,b,c ] [ , a,b,c ] [ ,a,b,c ]
+
+// Microsoft's extension is on ", __VA_ARGS__" (without explicit ##) where
+// the comma is swallowed when followed by empty __VA_ARGS__.
+
+// MS: 1: [ ] [ ] [ ]
+// MS: 2: [ a ] [ , a ] [ ,a ]
+// MS: 3: [ , ] [ , , ] [ ,, ]
+// MS: 4: [ a,b,c ] [ , a,b,c ] [ ,a,b,c ]

