aboutsummaryrefslogtreecommitdiff
path: root/gdb/eval.c
diff options
context:
space:
mode:
authorRichard Bunt <richard.bunt@arm.com>2018-09-19 10:43:56 +0100
committerRichard Bunt <richard.bunt@arm.com>2018-09-19 10:43:56 +0100
commit23be8da7396ffc4d5492d976e244daaa543eaac9 (patch)
tree937a4d2e683bceb377afdbf8f97eb525651c380a /gdb/eval.c
parent7307a73aed246eaccec9277b11e045f974322796 (diff)
downloadgdb-23be8da7396ffc4d5492d976e244daaa543eaac9.zip
gdb-23be8da7396ffc4d5492d976e244daaa543eaac9.tar.gz
gdb-23be8da7396ffc4d5492d976e244daaa543eaac9.tar.bz2
Logical short circuiting with argument lists
When evaluating Fortran expressions such as the following: print truth_table(1,1) .OR. truth_table(2,1) where truth_table(1,1) evaluates to true, the debugger would report that it could not perform substring operations on this type. This patch addresses this issue. Investigation revealed that EVAL_SKIP was not being handled correctly for all types serviced by the OP_F77_UNDETERMINED_ARGLIST case in evaluate_subexp_standard. While skipping an undetermined argument list the type is resolved to be an integer (as this is what evaluate_subexp returns when skipping) and so it was not possible to delegate to the appropriate case (e.g. array, function call). The solution implemented here updates OP_VAR_VALUE to return correct type information when skipping. This way OP_F77_UNDETERMINED_ARGLIST can delegate the skipping to the appropriate case or routine, which should know how to skip/evaluate the type in question. koenig.exp was updated to include a testcase which exercises the modified skip logic in OP_VAR_VALUE, as it falls through from OP_ADL_FUNC. This patch has been tested for regressions with GCC 7.3 on aarch64, ppc64le and x86_64. gdb/ChangeLog: * eval.c (skip_undetermined_arglist): Skip argument list helper. (evaluate_subexp_standard): Return a dummy type when honoring EVAL_SKIP in OP_VAR_VALUE and handle skipping in the OP_F77_UNDETERMINED_ARGLIST case. * expression.h (enum noside): Update comment. gdb/testsuite/ChangeLog: * gdb.cp/koenig.exp: Extend to test logical short circuiting. * gdb.fortran/short-circuit-argument-list.exp: New file. * gdb.fortran/short-circuit-argument-list.f90: New test.
Diffstat (limited to 'gdb/eval.c')
-rw-r--r--gdb/eval.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/gdb/eval.c b/gdb/eval.c
index f9349e6..2144b1d 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1238,6 +1238,19 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
return eval_call (exp, noside, nargs, argvec, var_func_name, expect_type);
}
+/* Helper for skipping all the arguments in an undetermined argument list.
+ This function was designed for use in the OP_F77_UNDETERMINED_ARGLIST
+ case of evaluate_subexp_standard as multiple, but not all, code paths
+ require a generic skip. */
+
+static void
+skip_undetermined_arglist (int nargs, struct expression *exp, int *pos,
+ enum noside noside)
+{
+ for (int i = 0; i < nargs; ++i)
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
+}
+
struct value *
evaluate_subexp_standard (struct type *expect_type,
struct expression *exp, int *pos,
@@ -1286,16 +1299,19 @@ evaluate_subexp_standard (struct type *expect_type,
case OP_ADL_FUNC:
case OP_VAR_VALUE:
- (*pos) += 3;
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
-
{
+ (*pos) += 3;
symbol *var = exp->elts[pc + 2].symbol;
if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ERROR)
error_unknown_type (SYMBOL_PRINT_NAME (var));
-
- return evaluate_var_value (noside, exp->elts[pc + 1].block, var);
+ if (noside != EVAL_SKIP)
+ return evaluate_var_value (noside, exp->elts[pc + 1].block, var);
+ else
+ {
+ /* Return a dummy value of the correct type when skipping, so
+ that parent functions know what is to be skipped. */
+ return allocate_value (SYMBOL_TYPE (var));
+ }
}
case OP_VAR_MSYM_VALUE:
@@ -1933,13 +1949,27 @@ evaluate_subexp_standard (struct type *expect_type,
if (exp->elts[*pos].opcode == OP_RANGE)
return value_f90_subarray (arg1, exp, pos, noside);
else
- goto multi_f77_subscript;
+ {
+ if (noside == EVAL_SKIP)
+ {
+ skip_undetermined_arglist (nargs, exp, pos, noside);
+ /* Return the dummy value with the correct type. */
+ return arg1;
+ }
+ goto multi_f77_subscript;
+ }
case TYPE_CODE_STRING:
if (exp->elts[*pos].opcode == OP_RANGE)
return value_f90_subarray (arg1, exp, pos, noside);
else
{
+ if (noside == EVAL_SKIP)
+ {
+ skip_undetermined_arglist (nargs, exp, pos, noside);
+ /* Return the dummy value with the correct type. */
+ return arg1;
+ }
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
return value_subscript (arg1, value_as_long (arg2));
}