diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 0d0ad0a6374..33edeefd285 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -976,6 +976,11 @@ Wstringop-truncation
 C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall)
 Warn about truncation in string manipulation functions like strncat and strncpy.
 
+Wstrict-flex-arrays
+C C++ Var(warn_strict_flex_arrays) Warning
+Warn about inproper usages of flexible array members
+according to the level of -fstrict-flex-arrays.
+
 Wsuggest-attribute=format
 C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
 Warn about functions which might be candidates for format attributes.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 726392409b6..4402b0427ef 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wstrict-aliasing=n  -Wstrict-overflow  -Wstrict-overflow=@var{n} @gol
 -Wstring-compare @gol
 -Wno-stringop-overflow -Wno-stringop-overread @gol
--Wno-stringop-truncation @gol
+-Wno-stringop-truncation -Wstrict-flex-arrays @gol
 -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol
 -Wswitch  -Wno-switch-bool  -Wswitch-default  -Wswitch-enum @gol
 -Wno-switch-outside-range  -Wno-switch-unreachable  -Wsync-nand @gol
@@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect
 such arrays GCC issues warnings unless it can prove that the use is
 safe.  @xref{Common Variable Attributes}.
 
+@item -Wstrict-flex-arrays
+@opindex Wstrict-flex-arrays
+@opindex Wno-strict-flex-arrays
+Warn about inproper usages of flexible array members
+according to the @var{level} of the @code{strict_flex_array (@var{level})}
+attribute attached to the trailing array field of a structure if it's
+available, otherwise according to the @var{level} of the option
+@option{-fstrict-flex-arrays=@var{level}}.
+
+This option is effective only when @var{level} is bigger than 0.  Otherwise,
+it will be ignored with a warning.
+
+when @var{level}=1, warnings will be issued for a trailing array reference
+of a structure that have 2 or more elements if the trailing array is referenced
+as a flexible array member.
+
+when @var{level}=2, in addition to @var{level}=1, additional warnings will be
+issued for a trailing one-element array reference of a structure
+if the array is referenced as a flexible array member.
+
+when @var{level}=3, in addition to @var{level}=2, additional warnings will be
+issued for a trailing zero-length array reference of a structure
+if the array is referenced as a flexible array member.
+
+
 @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]}
 @opindex Wsuggest-attribute=
 @opindex Wno-suggest-attribute=
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index db3459af325..825f11331b5 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl,
 
 /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND
    and UP_BOUND_P1, check whether the array reference REF is out of bound.
-   Issue warnings if out of bound, return TRUE if warnings are issued.  */ 
+   When out of bounds, set OUT_OF_BOUND to true.
+   Issue warnings if FOR_ARRAY_BOUND is true.
+   return TRUE if warnings are issued.  */
+
 
 static bool
 check_out_of_bounds_and_warn (location_t location, tree ref,
 			      tree low_sub_org, tree low_sub, tree up_sub,
 			      tree up_bound, tree up_bound_p1,
 			      const value_range *vr,
-			      bool ignore_off_by_one)
+			      bool ignore_off_by_one, bool for_array_bound,
+			      bool *out_of_bound)
 {
   tree low_bound = array_ref_low_bound (ref);
   tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
 
   bool warned = false;
+  *out_of_bound = false;
 
   /* Empty array.  */
   if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
-    warned = warning_at (location, OPT_Warray_bounds_,
-			 "array subscript %E is outside array bounds of %qT",
-			 low_sub_org, artype);
+    {
+      *out_of_bound = true;
+      if (for_array_bound)
+	warned = warning_at (location, OPT_Warray_bounds_,
+			     "array subscript %E is outside array"
+			     " bounds of %qT", low_sub_org, artype);
+    }
 
   if (warned)
     ; /* Do nothing.  */
@@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref,
 	      : tree_int_cst_le (up_bound, up_sub))
 	  && TREE_CODE (low_sub) == INTEGER_CST
 	  && tree_int_cst_le (low_sub, low_bound))
-	warned = warning_at (location, OPT_Warray_bounds_,
-			     "array subscript [%E, %E] is outside "
-			     "array bounds of %qT",
-			     low_sub, up_sub, artype);
+	{
+	  *out_of_bound = true;
+	  warned = warning_at (location, OPT_Warray_bounds_,
+			       "array subscript [%E, %E] is outside "
+			       "array bounds of %qT",
+			       low_sub, up_sub, artype);
+	}
     }
   else if (up_bound
 	   && TREE_CODE (up_sub) == INTEGER_CST
 	   && (ignore_off_by_one
 	       ? !tree_int_cst_le (up_sub, up_bound_p1)
 	       : !tree_int_cst_le (up_sub, up_bound)))
-    warned = warning_at (location, OPT_Warray_bounds_,
-			 "array subscript %E is above array bounds of %qT",
-			 up_sub, artype);
+    {
+      *out_of_bound = true;
+      warned = warning_at (location, OPT_Warray_bounds_,
+			   "array subscript %E is above array bounds of %qT",
+			   up_sub, artype);
+    }
   else if (TREE_CODE (low_sub) == INTEGER_CST
 	   && tree_int_cst_lt (low_sub, low_bound))
-    warned = warning_at (location, OPT_Warray_bounds_,
-			 "array subscript %E is below array bounds of %qT",
-			 low_sub, artype);
+    {
+      *out_of_bound = true;
+      warned = warning_at (location, OPT_Warray_bounds_,
+			   "array subscript %E is below array bounds of %qT",
+			   low_sub, artype);
+    }
   return warned;
 }
 
@@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 
   tree arg = TREE_OPERAND (ref, 0);
   const bool compref = TREE_CODE (arg) == COMPONENT_REF;
+  unsigned int strict_flex_array_level = flag_strict_flex_arrays;
 
   if (compref)
-    /* Try to determine special array member type for this COMPONENT_REF.  */
-    sam = component_ref_sam_type (arg);
+    {
+      /* Try to determine special array member type for this COMPONENT_REF.  */
+      sam = component_ref_sam_type (arg);
+      /* Get the level of strict_flex_array for this array field.  */
+      tree afield_decl = TREE_OPERAND (arg, 1);
+      strict_flex_array_level = strict_flex_array_level_of (afield_decl);
+    }
 
   get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1);
 
   bool warned = false;
+  bool out_of_bound = false;
 
   tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
   tree low_sub_org = TREE_OPERAND (ref, 1);
@@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
   warned = check_out_of_bounds_and_warn (location, ref,
 					 low_sub_org, low_sub, up_sub,
 					 up_bound, up_bound_p1, vr,
-					 ignore_off_by_one);
+					 ignore_off_by_one, warn_array_bounds,
+					 &out_of_bound);
 
 
   if (!warned && sam == special_array_member::int_0)
@@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
 			       "of an interior zero-length array %qT")),
 			 low_sub, artype);
 
-  if (warned)
+  if (warned || out_of_bound)
     {
-      if (dump_file && (dump_flags & TDF_DETAILS))
+      if (warned && dump_file && (dump_flags & TDF_DETAILS))
 	{
 	  fprintf (dump_file, "Array bound warning for ");
 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
 	  fprintf (dump_file, "\n");
 	}
 
+      /* issue warnings for -Wstrict-flex-arrays according to the level of
+	 flag_strict_flex_arrays.  */
+      if (out_of_bound && warn_strict_flex_arrays)
+      switch (strict_flex_array_level)
+	{
+	  case 3:
+	    /* Issue additional warnings for trailing arrays [0].  */
+	    if (sam == special_array_member::trail_0)
+	      warned = warning_at (location, OPT_Wstrict_flex_arrays,
+				   "trailing array %qT should not be used as "
+				   "a flexible array member for level 3",
+				   artype);
+	    /* FALLTHROUGH.  */
+	  case 2:
+	    /* Issue additional warnings for trailing arrays [1].  */
+	    if (sam == special_array_member::trail_1)
+	      warned = warning_at (location, OPT_Wstrict_flex_arrays,
+				   "trailing array %qT should not be used as "
+				   "a flexible array member for level 2 and "
+				   "above", artype);
+	    /* FALLTHROUGH.  */
+	  case 1:
+	    /* Issue warnings for trailing arrays [n].  */
+	    if (sam == special_array_member::trail_n)
+	      warned = warning_at (location, OPT_Wstrict_flex_arrays,
+				   "trailing array %qT should not be used as "
+				   "a flexible array member for level 1 and "
+				   "above", artype);
+	    break;
+	  case 0:
+	    /* Do nothing.  */
+	    break;
+	  default:
+	    gcc_unreachable ();
+	}
+
       /* Avoid more warnings when checking more significant subscripts
 	 of the same expression.  */
       ref = TREE_OPERAND (ref, 0);
       suppress_warning (ref, OPT_Warray_bounds_);
+      suppress_warning (ref, OPT_Wstrict_flex_arrays);
 
       if (decl)
 	ref = decl;
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 73fc97756e4..8db53ad6c77 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
       opts->x_profile_flag = 0;
     }
 
+  if (opts->x_warn_strict_flex_arrays)
+    if (opts->x_flag_strict_flex_arrays == 0)
+      {
+	opts->x_warn_strict_flex_arrays = 0;
+	warning_at (UNKNOWN_LOCATION, 0,
+		    "%<-Wstrict-flex-arrays%> is ignored when"
+		    " %<-fstrict-flex-arrays%> does not present");
+      }
 
   diagnose_options (opts, opts_set, loc);
 }
diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c
new file mode 100644
index 00000000000..72b4b7c6406
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c
@@ -0,0 +1,9 @@
+/* Test the usage of option -Wstrict-flex-arrays.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstrict-flex-arrays" } */
+
+int main(int argc, char *argv[])
+{
+    return 0;
+}
+/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
index d36ba4d86cb..65c9fec43af 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
@@ -1,6 +1,6 @@
-/* Test -fstrict-flex-arrays + -Warray-bounds.  */
+/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays.  */
 /* { dg-do compile} */
-/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */
 
 struct trailing_array_1 {
     int a;
@@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff(
     struct trailing_array_4 *trailing_flex)
 {
     normal->c[5] = 5; 	/*{ dg-warning "array subscript 5 is above array bounds of" } */
+    			/*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */
     trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */
     trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
     trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
index f63206e1948..2b5a895c598 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
@@ -1,6 +1,6 @@
-/* Test -fstrict-flex-arrays + -Warray-bounds.  */
+/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */
 
 struct trailing_array_1 {
     int a;
@@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff(
     struct trailing_array_4 *trailing_flex)
 {
     normal->c[5] = 5; 	/*{ dg-warning "array subscript 5 is above array bounds of" } */
+    			/*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */
     trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of"  } */
+    			  /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */
     trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
     trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
 
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
index e3273714e8b..25b903f2615 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
@@ -1,6 +1,6 @@
-/* Test -fstrict-flex-arrays + -Warray-bounds.  */
+/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */
 
 struct trailing_array_1 {
     int a;
@@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff(
     struct trailing_array_4 *trailing_flex)
 {
     normal->c[5] = 5; 	/*{ dg-warning "array subscript 5 is above array bounds of" } */ 
+    			/*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */
     trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ 
+    			  /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */
     trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ 
+    			  /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */
     trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */
 
 }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
index cabaea77dc2..5fc500a19ca 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
@@ -1,6 +1,6 @@
-/* Test -fstrict-flex-arrays + -Warray-bounds=2.  */
+/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */
 
 struct trailing_array_1 {
     int a;
@@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff(
     struct trailing_array_4 *trailing_flex)
 {
     normal->c[5] = 5; 	/*{ dg-warning "array subscript 5 is above array bounds of" } */
+    			/*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */
     trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */
     trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
     trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
index 8b7db6e4f39..30bb4ca8832 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
@@ -1,6 +1,6 @@
-/* Test -fstrict-flex-arrays + -Warray-bounds=2.  */
+/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */
 
 struct trailing_array_1 {
     int a;
@@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff(
     struct trailing_array_4 *trailing_flex)
 {
     normal->c[5] = 5;   /*{ dg-warning "array subscript 5 is above array bounds of" } */
+    			/*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */
     trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */
+    			  /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */
     trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
     trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
 
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
index 035bf481396..e847a44516e 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
@@ -1,6 +1,6 @@
-/* Test -fstrict-flex-arrays + -Warray-bounds=2.  */
+/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */
 
 struct trailing_array_1 {
     int a;
@@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff(
     struct trailing_array_4 *trailing_flex)
 {
     normal->c[5] = 5; 	/*{ dg-warning "array subscript 5 is above array bounds of" } */ 
+    			/*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */
     trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */
+    			  /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */
     trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */
+    			  /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */
     trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
 
 }
diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c
new file mode 100644
index 00000000000..2e241f96208
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c
@@ -0,0 +1,39 @@
+/* Test -Wstrict-flex-arrays.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */
+
+struct trailing_array_1 {
+    int a;
+    int b;
+    int c[4]; 
+};
+
+struct trailing_array_2 {
+    int a;
+    int b;
+    int c[1]; 
+};
+
+struct trailing_array_3 {
+    int a;
+    int b;
+    int c[0];
+};
+struct trailing_array_4 {
+    int a;
+    int b;
+    int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+    struct trailing_array_1 *normal,
+    struct trailing_array_2 *trailing_1,
+    struct trailing_array_3 *trailing_0,
+    struct trailing_array_4 *trailing_flex)
+{
+    normal->c[5] = 5; 	/*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */
+    trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */
+    trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */
+    trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c
new file mode 100644
index 00000000000..97eb65ba0a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c
@@ -0,0 +1,39 @@
+/* Test -Wstrict-flex-arrays.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */
+
+struct trailing_array_1 {
+    int a;
+    int b;
+    int c[4]; 
+};
+
+struct trailing_array_2 {
+    int a;
+    int b;
+    int c[1]; 
+};
+
+struct trailing_array_3 {
+    int a;
+    int b;
+    int c[0];
+};
+struct trailing_array_4 {
+    int a;
+    int b;
+    int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+    struct trailing_array_1 *normal,
+    struct trailing_array_2 *trailing_1,
+    struct trailing_array_3 *trailing_0,
+    struct trailing_array_4 *trailing_flex)
+{
+    normal->c[5] = 5; 	/*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */
+    trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */
+    trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */
+    trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c
new file mode 100644
index 00000000000..110fdc72778
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c
@@ -0,0 +1,39 @@
+/* Test -Wstrict-flex-arrays.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */
+
+struct trailing_array_1 {
+    int a;
+    int b;
+    int c[4]; 
+};
+
+struct trailing_array_2 {
+    int a;
+    int b;
+    int c[1]; 
+};
+
+struct trailing_array_3 {
+    int a;
+    int b;
+    int c[0];
+};
+struct trailing_array_4 {
+    int a;
+    int b;
+    int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+    struct trailing_array_1 *normal,
+    struct trailing_array_2 *trailing_1,
+    struct trailing_array_3 *trailing_0,
+    struct trailing_array_4 *trailing_flex)
+{
+    normal->c[5] = 5; 	/*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */
+    trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */
+    trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */
+    trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */
+
+}
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 3846dc1d849..e6c6c5a301d 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p,
   if (dump_file && (dump_flags & TDF_DETAILS))
     ranger->dump (dump_file);
 
-  if (warn_array_bounds && warn_array_bounds_p)
+  if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p)
     {
       // Set all edges as executable, except those ranger says aren't.
       int non_exec_flag = ranger->non_executable_edge_flag;
