+2021-03-08  Tom Tromey  <tom@tromey.com>
+
+       * f-lang.c (fortran_bound_1arg::evaluate)
+       (fortran_bound_2arg::evaluate): New methods.
+       * f-exp.h (class fortran_bound_1arg, class fortran_bound_2arg):
+       New.
+
 2021-03-08  Tom Tromey  <tom@tromey.com>
 
        * expop.h (class unop_addr_operation) <get_expression>: New
 
                         enum noside noside);
 };
 
+/* Single-argument form of Fortran ubound/lbound intrinsics.  */
+class fortran_bound_1arg
+  : public tuple_holding_operation<exp_opcode, operation_up>
+{
+public:
+
+  using tuple_holding_operation::tuple_holding_operation;
+
+  value *evaluate (struct type *expect_type,
+                  struct expression *exp,
+                  enum noside noside) override;
+
+  enum exp_opcode opcode () const override
+  { return std::get<0> (m_storage); }
+};
+
+/* Two-argument form of Fortran ubound/lbound intrinsics.  */
+class fortran_bound_2arg
+  : public tuple_holding_operation<exp_opcode, operation_up, operation_up>
+{
+public:
+
+  using tuple_holding_operation::tuple_holding_operation;
+
+  value *evaluate (struct type *expect_type,
+                  struct expression *exp,
+                  enum noside noside) override;
+
+  enum exp_opcode opcode () const override
+  { return std::get<0> (m_storage); }
+};
+
 } /* namespace expr */
 
 #endif /* FORTRAN_EXP_H */
 
     }
 }
 
+value *
+fortran_bound_1arg::evaluate (struct type *expect_type,
+                             struct expression *exp,
+                             enum noside noside)
+{
+  bool lbound_p = std::get<0> (m_storage) == FORTRAN_LBOUND;
+  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+  fortran_require_array (value_type (arg1), lbound_p);
+  return fortran_bounds_all_dims (lbound_p, exp->gdbarch, arg1);
+}
+
+value *
+fortran_bound_2arg::evaluate (struct type *expect_type,
+                             struct expression *exp,
+                             enum noside noside)
+{
+  bool lbound_p = std::get<0> (m_storage) == FORTRAN_LBOUND;
+  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+  fortran_require_array (value_type (arg1), lbound_p);
+
+  /* User asked for the bounds of a specific dimension of the array.  */
+  value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
+  struct type *type = check_typedef (value_type (arg2));
+  if (type->code () != TYPE_CODE_INT)
+    {
+      if (lbound_p)
+       error (_("LBOUND second argument should be an integer"));
+      else
+       error (_("UBOUND second argument should be an integer"));
+    }
+
+  return fortran_bounds_for_dimension (lbound_p, exp->gdbarch, arg1, arg2);
+}
+
 } /* namespace expr */
 
 /* Special expression lengths for Fortran.  */