diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -2839,11 +2839,30 @@
 /// DeclStmts and initializers in them.
 CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
   assert(DS->isSingleDecl() && "Can handle single declarations only.");
+
+  if (const auto *TND = dyn_cast<TypedefNameDecl>(DS->getSingleDecl())) {
+    // If we encounter a VLA, process its size expressions.
+    const Type *T = TND->getUnderlyingType().getTypePtr();
+    if (!T->isVariablyModifiedType())
+      return Block;
+
+    autoCreateBlock();
+    appendStmt(Block, DS);
+
+    CFGBlock *LastBlock = Block;
+    for (const VariableArrayType *VA = FindVA(T); VA != nullptr;
+         VA = FindVA(VA->getElementType().getTypePtr())) {
+      if (CFGBlock *newBlock = addStmt(VA->getSizeExpr()))
+        LastBlock = newBlock;
+    }
+    return LastBlock;
+  }
+
   VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
 
   if (!VD) {
-    // Of everything that can be declared in a DeclStmt, only VarDecls impact
-    // runtime semantics.
+    // Of everything that can be declared in a DeclStmt, only VarDecls and the
+    // exceptions above impact runtime semantics.
     return Block;
   }
 
@@ -2905,6 +2924,8 @@
   }
 
   // If the type of VD is a VLA, then we must process its size expressions.
+  // FIXME: This does not find the VLA if it is embedded in other types,
+  // like here: `void (*vla)(int[x]);`
   for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr());
        VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) {
     if (CFGBlock *newBlock = addStmt(VA->getSizeExpr()))
diff --git a/clang/test/Analysis/cfg.cpp b/clang/test/Analysis/cfg.cpp
--- a/clang/test/Analysis/cfg.cpp
+++ b/clang/test/Analysis/cfg.cpp
@@ -568,6 +568,102 @@
   return 2;
 }
 
+// CHECK-LABEL: void vla_simple(int x)
+// CHECK: [B1]
+// CHECK-NEXT:   1: x
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: int vla[x];
+void vla_simple(int x) {
+  int vla[x];
+}
+
+// CHECK-LABEL: void vla_typedef(int x)
+// CHECK: [B1]
+// CHECK-NEXT:   1: x
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: typedef int VLA[x];
+void vla_typedef(int x) {
+  typedef int VLA[x];
+}
+
+// CHECK-LABEL: void vla_typealias(int x)
+// CHECK: [B1]
+// CHECK-NEXT:   1: x
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: using VLA = int [x];
+void vla_typealias(int x) {
+  using VLA = int[x];
+}
+
+// CHECK-LABEL: void vla_typedef_multi(int x, int y)
+// CHECK:  [B1]
+// CHECK-NEXT:   1: y
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: x
+// CHECK-NEXT:   4: [B1.3] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   5: typedef int VLA[x][y];
+void vla_typedef_multi(int x, int y) {
+  typedef int VLA[x][y];
+}
+
+// CHECK-LABEL: void vla_typedefname_multi(int x, int y)
+// CHECK:  [B1]
+// CHECK-NEXT:   1: x
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: typedef int VLA[x];
+// CHECK-NEXT:   4: y
+// CHECK-NEXT:   5: [B1.4] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   6: typedef VLA VLA1[y];
+// CHECK-NEXT:   7: 3
+// CHECK-NEXT:   8: using VLA2 = VLA1 [3];
+// CHECK-NEXT:   9: 4
+// CHECK-NEXT:  10: VLA2 vla[4];
+void vla_typedefname_multi(int x, int y) {
+  typedef int VLA[x];
+  typedef VLA VLA1[y];
+  using VLA2 = VLA1[3];
+  VLA2 vla[4];
+}
+
+// CHECK-LABEL: void vla_embedded(int x)
+// CHECK:  [B1]
+// CHECK-NEXT:   1: void (*vla)(int *);
+void vla_embedded(int x) {
+  // FIXME: 'x' is not generated but should be.
+  void (*vla)(int[x]);
+}
+
+// CHECK-LABEL: int vla_evaluate(int x)
+// CHECK:  [B1]
+// CHECK-NEXT:   1: x
+// CHECK-NEXT:   2: ++[B1.1]
+// CHECK-NEXT:   3: [B1.2] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   4: typedef int VLA[++x];
+// CHECK-NEXT:   5: x
+// CHECK-NEXT:   6: ++[B1.5]
+// CHECK-NEXT:   7: [B1.6] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   8: sizeof(int [++x])
+// CHECK-NEXT:   9: x
+// CHECK-NEXT:  10: ++[B1.9]
+// CHECK-NEXT:  11: [B1.10] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  12: alignof(int [++x])
+// CHECK-NEXT:  13: 0
+// CHECK-NEXT:  14: x
+// CHECK-NEXT:  15: [B1.14] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  16: return [B1.15];
+int vla_evaluate(int x) {
+  // Evaluates the ++x
+  typedef int VLA[++x];
+  sizeof(int[++x]);
+
+  // Do not evaluate the ++x
+  // FIXME: Still evaluates for _Alignof
+  _Alignof(int[++x]);
+  _Generic((int(*)[++x])0, default : 0);
+
+  return x;
+}
+
 // CHECK-LABEL: template<> int *PR18472<int>()
 // CHECK: [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1