Index: test/Parser/statements.c
===================================================================
--- test/Parser/statements.c	(revision 164028)
+++ test/Parser/statements.c	(working copy)
@@ -62,3 +62,18 @@
   // Should not skip '}' and produce a "expected '}'" error.
   undecl // expected-error {{use of undeclared identifier 'undecl'}}
 }
+
+int test9() {
+  int T[] = {1, 2, };
+
+  int X;
+  X = 0, // expected-error {{expected ';' after expression}}
+    {
+    }
+
+  X = 0, // expected-error {{expected ';' after expression}}
+  if (0)
+    ;
+
+  return 4, // expected-error {{expected ';' after return statement}}
+}
Index: test/Parser/cxx11-brace-initializers.cpp
===================================================================
--- test/Parser/cxx11-brace-initializers.cpp	(revision 0)
+++ test/Parser/cxx11-brace-initializers.cpp	(revision 0)
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+struct S {
+  S(int, int) {}
+};
+
+void f(int, S const&, int) {}
+
+void test1()
+{
+  S X1{1, 1,};
+  S X2 = {1, 1,};
+
+  f(0, {1, 1}, 0);
+}
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 164028)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -1221,6 +1221,9 @@
                                  bool isAddressOfOperand = false,
                                  TypeCastState isTypeCast = NotTypeCast);
 
+  /// Returns true if the next token cannot start an expression.
+  bool isNotExpressionStart();
+
   /// Returns true if the next token would start a postfix-expression
   /// suffix.
   bool isPostfixExpressionSuffixStart() {
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp	(revision 164028)
+++ lib/Parse/ParseExpr.cpp	(working copy)
@@ -265,6 +265,20 @@
   return Actions.ActOnConstantExpression(Res);
 }
 
+bool Parser::isNotExpressionStart() {
+  tok::TokenKind K = Tok.getKind();
+  if (K == tok::l_brace || K == tok::r_brace  ||
+      K == tok::kw_for  || K == tok::kw_while ||
+      K == tok::kw_if   || K == tok::kw_else  ||
+      K == tok::kw_goto || K == tok::kw_try)
+    return true;
+  // In C++, int(f()) is reported as a Declaration by isDeclarationStatement,
+  // which makes valid code misparse: 1, int(f())
+  if (getLangOpts().CPlusPlus)
+    return isCXXDeclarationSpecifier() == TPResult::True();
+  return isDeclarationStatement();
+}
+
 /// \brief Parse a binary expression that starts with \p LHS and has a
 /// precedence of at least \p MinPrec.
 ExprResult
@@ -285,6 +299,17 @@
     Token OpToken = Tok;
     ConsumeToken();
 
+    // Bail out when encountering a comma followed by a token
+    // indicating the start of a non-expression statement.
+    // e.g. f() { return 1, }
+    // We can't do this before consuming the comma, because
+    // isNotExpressionStart() looks at the token stream
+    if (OpToken.is(tok::comma) && isNotExpressionStart()) {
+      PP.EnterToken(Tok);
+      Tok = OpToken;
+      return LHS;
+    }
+
     // Special case handling for the ternary operator.
     ExprResult TernaryMiddle(true);
     if (NextTokPrec == prec::Conditional) {
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp	(revision 164028)
+++ lib/Parse/Parser.cpp	(working copy)
@@ -154,7 +154,8 @@
 
 static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) {
   switch (ExpectedTok) {
-  case tok::semi: return Tok.is(tok::colon); // : for ;
+  case tok::semi:
+    return Tok.is(tok::colon) || Tok.is(tok::comma); // : or , for ;
   default: return false;
   }
 }
