diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 315c9574e95b02281d7d2a18481a797e3da685b0..e889085b829e30b09afdc3f7092644c69629bc30 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2106,6 +2106,17 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
     if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
       Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
     } else {
+      // Find the nearest non-record decl context. Variables declared in a
+      // statement expression behave as if they were declared in the enclosing
+      // function, block, or other code construct.
+      DeclContext *CodeDC = Actions.CurContext;
+      while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) {
+        CodeDC = CodeDC->getParent();
+        assert(CodeDC && !CodeDC->isFileContext() &&
+               "statement expr not in code context");
+      }
+      Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false);
+
       Actions.ActOnStartStmtExpr();
 
       StmtResult Stmt(ParseCompoundStatement(true));
diff --git a/test/Sema/statements.c b/test/Sema/statements.c
index 9ab571521a3af80a49ca950ec8005c5685e5444e..dbb4d56ee1d17aed11ba083e0f20b20cff1c4248 100644
--- a/test/Sema/statements.c
+++ b/test/Sema/statements.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify  -triple x86_64-pc-linux-gnu
+// RUN: %clang_cc1 %s -fsyntax-only -verify  -triple x86_64-pc-linux-gnu -Wno-unevaluated-expression
 
 typedef unsigned __uint32_t;
 
@@ -97,3 +97,16 @@ int test_pr8880() {
   return 1;
 }
 
+// In PR22849, we considered __ptr to be a static data member of the anonymous
+// union. Now we declare it in the parent DeclContext.
+void test_pr22849() {
+  struct Bug {
+    typeof(({ unsigned long __ptr; (int *)(0); })) __val;
+    union Nested {
+      typeof(({ unsigned long __ptr; (int *)(0); })) __val;
+    } n;
+  };
+  enum E {
+    SIZE = sizeof(({unsigned long __ptr; __ptr;}))
+  };
+}