Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 190426)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -3896,6 +3896,9 @@
   "field %0 with variable sized type %1 not at the end of a struct or class is"
   " a GNU extension">, InGroup<GNU>;
 
+def warn_flexible_array_assignment : ExtWarn<
+  "assignment of flexible arrays does not copy the array members">,
+  InGroup<FlexibleArrayExtensions>;
 def err_flexible_array_empty_struct : Error<
   "flexible array %0 not allowed in otherwise empty struct">;
 def err_flexible_array_has_nonpod_type : Error<
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 190426)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -10442,10 +10442,20 @@
   bool IsNSString = false;
 
   switch (ConvTy) {
-  case Compatible:
-      DiagnoseAssignmentEnum(DstType, SrcType, SrcExpr);
-      return false;
+  case Compatible: {
+    DiagnoseAssignmentEnum(DstType, SrcType, SrcExpr);
 
+    // If the source is a structure that contains a flexible array member, the
+    // assignment is compatible, but should be diagnosed since the array
+    // members will not be copied.
+    const RecordType *RT = SrcType->getAs<RecordType>();
+    if (RT) {
+      const RecordDecl *S = RT->getDecl();
+      if (S->hasFlexibleArrayMember())
+        Diag(Loc, diag::warn_flexible_array_assignment);
+    }
+    return false;
+  }
   case PointerToInt:
     DiagKind = diag::ext_typecheck_convert_pointer_int;
     ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this);
Index: test/Sema/flexible-array.c
===================================================================
--- test/Sema/flexible-array.c	(revision 0)
+++ test/Sema/flexible-array.c	(working copy)
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+extern void *malloc(unsigned);
+
+struct arr {
+  int n;
+  int d[];
+};
+
+void foo(struct arr s) {}
+void baz(struct arr *s) {}
+
+void bar(void) {
+  struct arr *s = (struct arr *)malloc(sizeof(struct arr) + (10 * sizeof(int)));
+  struct arr s2 = *s;  // expected-warning {{assignment of flexible arrays does not copy the array members}}
+
+  foo(*s);  // expected-warning {{assignment of flexible arrays does not copy the array members}}
+
+  baz(s);
+  baz(&s2);
+}
