+2020-10-22  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * expprint.c (dump_subexp_body_standard): Print RANGE_HAS_STRIDE.
+       * expression.h (enum range_type): Add RANGE_HAS_STRIDE.
+       * f-exp.y (arglist): Allow for a series of subranges.
+       (subrange): Add cases for subranges with strides.
+       * f-lang.c (value_f90_subarray): Catch use of array strides and
+       throw an error.
+       * parse.c (operator_length_standard): Handle RANGE_HAS_STRIDE.
+
 2020-10-22  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * expprint.c (print_subexp_standard): Change enum range_type to
 
        fputs_filtered ("..", stream);
        if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
          fputs_filtered ("EXP", stream);
+       if (range_flag & RANGE_HAS_STRIDE)
+         fputs_filtered (":EXP", stream);
        fputs_filtered ("'", stream);
 
        if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
          elt = dump_subexp (exp, stream, elt);
        if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
          elt = dump_subexp (exp, stream, elt);
+       if (range_flag & RANGE_HAS_STRIDE)
+         elt = dump_subexp (exp, stream, elt);
       }
       break;
 
 
 
   /* The high bound of this range is exclusive.  */
   RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
+
+  /* The range has a stride.  */
+  RANGE_HAS_STRIDE = 1 << 3,
 };
 
 DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);
 
                        { pstate->arglist_len++; }
        ;
 
+arglist        :       arglist ',' subrange   %prec ABOVE_COMMA
+                       { pstate->arglist_len++; }
+       ;
+
 /* There are four sorts of subrange types in F90.  */
 
 subrange:      exp ':' exp     %prec ABOVE_COMMA
                          write_exp_elt_opcode (pstate, OP_RANGE); }
        ;
 
+/* And each of the four subrange types can also have a stride.  */
+subrange:      exp ':' exp ':' exp     %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate, RANGE_HAS_STRIDE);
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+subrange:      exp ':' ':' exp %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate,
+                                                (RANGE_HIGH_BOUND_DEFAULT
+                                                 | RANGE_HAS_STRIDE));
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+subrange:      ':' exp ':' exp %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate,
+                                                (RANGE_LOW_BOUND_DEFAULT
+                                                 | RANGE_HAS_STRIDE));
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+subrange:      ':' ':' exp     %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate,
+                                                (RANGE_LOW_BOUND_DEFAULT
+                                                 | RANGE_HIGH_BOUND_DEFAULT
+                                                 | RANGE_HAS_STRIDE));
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
 complexnum:     exp ',' exp 
                        { }                          
         ;
 
                    struct expression *exp, int *pos, enum noside noside)
 {
   int pc = (*pos) + 1;
-  LONGEST low_bound, high_bound;
+  LONGEST low_bound, high_bound, stride;
   struct type *range = check_typedef (value_type (array)->index_type ());
   enum range_flag range_flag
     = (enum range_flag) longest_to_int (exp->elts[pc].longconst);
   else
     high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
 
+  if (range_flag & RANGE_HAS_STRIDE)
+    stride = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
+  else
+    stride = 1;
+
+  if (stride != 1)
+    error (_("Fortran array strides are not currently supported"));
+
   return value_slice (array, low_bound, high_bound - low_bound + 1);
 }
 
 
       /* Assume the range has 2 arguments (low bound and high bound), then
         reduce the argument count if any bounds are set to default.  */
       args = 2;
+      if (range_flag & RANGE_HAS_STRIDE)
+       ++args;
       if (range_flag & RANGE_LOW_BOUND_DEFAULT)
        --args;
       if (range_flag & RANGE_HIGH_BOUND_DEFAULT)
 
+2020-10-22  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * gdb.fortran/array-slices.exp: Add a new test.
+
 2020-10-21  Gary Benson <gbenson@redhat.com>
 
        * gdb.mi/mi-fullname-deleted.exp: Fix substituted
 
 }
 
 gdb_continue_to_breakpoint "continue to Final Breakpoint"
+
+# Next test that asking for an array with stride at the CLI gives an
+# error.
+clean_restart ${testfile}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+gdb_breakpoint "show"
+gdb_continue_to_breakpoint "show"
+gdb_test "up" ".*"
+gdb_test "p array (1:10:2, 1:10:2)" \
+    "Fortran array strides are not currently supported" \
+    "using array stride gives an error"