diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index fc214e7dfe1..dc2c25410fe 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -353,6 +353,16 @@ gen_extend (struct agent_expr *ax, struct type *type)
   ((type->is_unsigned () ? ax_zero_ext : ax_ext) (ax, bits));
 }
 
+/* A helper that returns the target type if TYPE is a range type, or
+   otherwise just returns TYPE.  */
+
+static struct type *
+strip_range_type (struct type *type)
+{
+  if (type->code () == TYPE_CODE_RANGE)
+    return type->target_type ();
+  return type;
+}
 
 /* Assume that the top of the stack contains a value of type "pointer
    to TYPE"; generate code to fetch its value.  Note that TYPE is the
@@ -366,8 +376,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
       ax_trace_quick (ax, type->length ());
     }
 
-  if (type->code () == TYPE_CODE_RANGE)
-    type = type->target_type ();
+  type = strip_range_type (type);
 
   switch (type->code ())
     {
@@ -832,9 +841,12 @@ static void
 gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
 		      struct axs_value *value2)
 {
+  struct type *type1 = strip_range_type (value1->type);
+  struct type *type2 = strip_range_type (value2->type);
+
   /* Do the usual binary conversions.  */
-  if (value1->type->code () == TYPE_CODE_INT
-      && value2->type->code () == TYPE_CODE_INT)
+  if (type1->code () == TYPE_CODE_INT
+      && type2->code () == TYPE_CODE_INT)
     {
       /* The ANSI integral promotions seem to work this way: Order the
 	 integer types by size, and then by signedness: an n-bit
@@ -842,18 +854,18 @@ gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
 	 type.  Promote to the "wider" of the two types, and always
 	 promote at least to int.  */
       struct type *target = max_type (builtin_type (ax->gdbarch)->builtin_int,
-				      max_type (value1->type, value2->type));
+				      max_type (type1, type2));
 
       /* Deal with value2, on the top of the stack.  */
-      gen_conversion (ax, value2->type, target);
+      gen_conversion (ax, type2, target);
 
       /* Deal with value1, not on the top of the stack.  Don't
 	 generate the `swap' instructions if we're not actually going
 	 to do anything.  */
-      if (is_nontrivial_conversion (value1->type, target))
+      if (is_nontrivial_conversion (type1, target))
 	{
 	  ax_simple (ax, aop_swap);
-	  gen_conversion (ax, value1->type, target);
+	  gen_conversion (ax, type1, target);
 	  ax_simple (ax, aop_swap);
 	}
 
@@ -892,6 +904,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
   require_rvalue (ax, value);
   /* Dereference typedefs.  */
   type = check_typedef (type);
+  type = strip_range_type (type);
 
   switch (type->code ())
     {
@@ -960,7 +973,7 @@ gen_ptradd (struct agent_expr *ax, struct axs_value *value,
 	    struct axs_value *value1, struct axs_value *value2)
 {
   gdb_assert (value1->type->is_pointer_or_reference ());
-  gdb_assert (value2->type->code () == TYPE_CODE_INT);
+  gdb_assert (strip_range_type (value2->type)->code () == TYPE_CODE_INT);
 
   gen_scale (ax, aop_mul, value1->type);
   ax_simple (ax, aop_add);
@@ -976,7 +989,7 @@ gen_ptrsub (struct agent_expr *ax, struct axs_value *value,
 	    struct axs_value *value1, struct axs_value *value2)
 {
   gdb_assert (value1->type->is_pointer_or_reference ());
-  gdb_assert (value2->type->code () == TYPE_CODE_INT);
+  gdb_assert (strip_range_type (value2->type)->code () == TYPE_CODE_INT);
 
   gen_scale (ax, aop_mul, value1->type);
   ax_simple (ax, aop_sub);
@@ -1048,14 +1061,15 @@ gen_binop (struct agent_expr *ax, struct axs_value *value,
 	   int may_carry, const char *name)
 {
   /* We only handle INT op INT.  */
-  if ((value1->type->code () != TYPE_CODE_INT)
-      || (value2->type->code () != TYPE_CODE_INT))
+  struct type *type1 = strip_range_type (value1->type);
+  if ((type1->code () != TYPE_CODE_INT)
+      || (strip_range_type (value2->type)->code () != TYPE_CODE_INT))
     error (_("Invalid combination of types in %s."), name);
 
-  ax_simple (ax, value1->type->is_unsigned () ? op_unsigned : op);
+  ax_simple (ax, type1->is_unsigned () ? op_unsigned : op);
   if (may_carry)
-    gen_extend (ax, value1->type);	/* catch overflow */
-  value->type = value1->type;
+    gen_extend (ax, type1);	/* catch overflow */
+  value->type = type1;
   value->kind = axs_rvalue;
 }
 
@@ -1064,8 +1078,9 @@ static void
 gen_logical_not (struct agent_expr *ax, struct axs_value *value,
 		 struct type *result_type)
 {
-  if (value->type->code () != TYPE_CODE_INT
-      && value->type->code () != TYPE_CODE_PTR)
+  struct type *type = strip_range_type (value->type);
+  if (type->code () != TYPE_CODE_INT
+      && type->code () != TYPE_CODE_PTR)
     error (_("Invalid type of operand to `!'."));
 
   ax_simple (ax, aop_log_not);
@@ -1076,11 +1091,12 @@ gen_logical_not (struct agent_expr *ax, struct axs_value *value,
 static void
 gen_complement (struct agent_expr *ax, struct axs_value *value)
 {
-  if (value->type->code () != TYPE_CODE_INT)
+  struct type *type = strip_range_type (value->type);
+  if (type->code () != TYPE_CODE_INT)
     error (_("Invalid type of operand to `~'."));
 
   ax_simple (ax, aop_bit_not);
-  gen_extend (ax, value->type);
+  gen_extend (ax, type);
 }
 
 
@@ -2078,7 +2094,7 @@ gen_expr_binop_rest (struct expression *exp,
   switch (op)
     {
     case BINOP_ADD:
-      if (value1->type->code () == TYPE_CODE_INT
+      if (strip_range_type (value1->type)->code () == TYPE_CODE_INT
 	  && value2->type->is_pointer_or_reference ())
 	{
 	  /* Swap the values and proceed normally.  */
@@ -2086,7 +2102,7 @@ gen_expr_binop_rest (struct expression *exp,
 	  gen_ptradd (ax, value, value2, value1);
 	}
       else if (value1->type->is_pointer_or_reference ()
-	       && value2->type->code () == TYPE_CODE_INT)
+	       && strip_range_type (value2->type)->code () == TYPE_CODE_INT)
 	gen_ptradd (ax, value, value1, value2);
       else
 	gen_binop (ax, value, value1, value2,
@@ -2094,7 +2110,7 @@ gen_expr_binop_rest (struct expression *exp,
       break;
     case BINOP_SUB:
       if (value1->type->is_pointer_or_reference ()
-	  && value2->type->code () == TYPE_CODE_INT)
+	  && strip_range_type (value2->type)->code () == TYPE_CODE_INT)
 	gen_ptrsub (ax,value, value1, value2);
       else if (value1->type->is_pointer_or_reference ()
 	       && value2->type->is_pointer_or_reference ())
diff --git a/gdb/testsuite/gdb.ada/ax-ada.exp b/gdb/testsuite/gdb.ada/ax-ada.exp
index b08f7c4362c..d0464b7a5b8 100644
--- a/gdb/testsuite/gdb.ada/ax-ada.exp
+++ b/gdb/testsuite/gdb.ada/ax-ada.exp
@@ -29,3 +29,4 @@ set bp_location [gdb_get_line_number "START" ${testdir}/prog.adb]
 runto "prog.adb:$bp_location"
 
 gdb_test "maint agent-eval variable = 23" ".*end"
+gdb_test "maint agent-eval range_variable = 23" ".*end"
diff --git a/gdb/testsuite/gdb.ada/ax-ada/prog.adb b/gdb/testsuite/gdb.ada/ax-ada/prog.adb
index 3852711e88c..85148d0c9c5 100644
--- a/gdb/testsuite/gdb.ada/ax-ada/prog.adb
+++ b/gdb/testsuite/gdb.ada/ax-ada/prog.adb
@@ -14,7 +14,10 @@
 --  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 procedure Prog is
+   type Range_Type is range -15 .. 73;
+
    Variable : Integer := 23;
+   Range_Variable : Range_Type := 23;
 begin
    null; -- START
 end Prog;
