From: Richard Bunt <richard.bunt@arm.com>
To: gdb-patches@sourceware.org
Cc: nd@arm.com
Subject: [PATCH] Logical short circuiting with Fortran argument lists
Date: Fri, 03 Aug 2018 09:32:00 -0000 [thread overview]
Message-ID: <20f669fe-9f31-fd39-9c3e-f2e1835576c6@arm.com> (raw)
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 proposed here is to hoist the skip from the function call
case to apply to all types of argument list.
While this patch allows a wider range of expressions to be evaluated, it
should be noted that this patch does not allow the skipping of arrays
which use Fortran array slicing, due to the inability of the debugger
to skip OP_RANGE.
This patch has been tested with GCC 7.3 on x86_64, aarch64 and ppc64le.
2018-06-06 Richard Bunt <richard.bunt@arm.com>
Chris January <chris.january@arm.com>
* eval.c (evaluate_subexp_standard): Skip evaluation of Fortran
argument lists when requested.
gdb/testsuite/ChangeLog:
2018-06-06 Richard Bunt <richard.bunt@arm.com>
Chris January <chris.january@arm.com>
* gdb.fortran/short-circuit-argument-list.exp: New file.
* gdb.fortran/short-circuit-argument-list.f90: New test.
---
gdb/eval.c | 13 +++-
.../gdb.fortran/short-circuit-argument-list.exp | 80
++++++++++++++++++++++
.../gdb.fortran/short-circuit-argument-list.f90 | 66 ++++++++++++++++++
3 files changed, 157 insertions(+), 2 deletions(-)
create mode 100644
gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp
create mode 100644
gdb/testsuite/gdb.fortran/short-circuit-argument-list.f90
diff --git a/gdb/eval.c b/gdb/eval.c
index
9db6e7c69dad9e674f66991e2aee7dd8d66d80c7..2350c7faaf6221a5990cf5264fe7fe93b4f4be4c
100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1902,6 +1902,17 @@ evaluate_subexp_standard (struct type *expect_type,
/* First determine the type code we are dealing with. */
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* Allow the short-circuiting of array accesses, function calls
+ and substring operations in logical expressions. */
+ if (noside == EVAL_SKIP)
+ {
+ /* Skip all the array subscripts. */
+ for (int i = 0; i < nargs; ++i)
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ return eval_skip_value (exp);
+ }
+
type = check_typedef (value_type (arg1));
code = TYPE_CODE (type);
@@ -1952,8 +1963,6 @@ evaluate_subexp_standard (struct type *expect_type,
for (; tem <= nargs; tem++)
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
argvec[tem] = 0; /* signal end of arglist */
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
return eval_call (exp, noside, nargs, argvec, NULL, expect_type);
default:
diff --git a/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp
b/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp
new file mode 100644
index
0000000000000000000000000000000000000000..294d808d99e6debfde5b802dd34aa17e3a136cd0
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp
@@ -0,0 +1,80 @@
+# Copyright 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/> .
+
+# Test evaluating logical expressions that contain array references,
function
+# calls and substring operations that are to be skipped due to short
+# circuiting.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile ".f90"
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
+ {debug f90}] } {
+ return -1
+}
+
+if ![runto [gdb_get_line_number "post_truth_table_init"] ] then {
+ perror "couldn't run to breakpoint post_truth_table_init"
+ continue
+}
+
+# Vary conditional and input over the standard truth table.
+# Test that the debugger can evaluate expressions of the form
+# a(x,y) .OR./.AND. a(a,b) correctly.
+foreach_with_prefix truth_table_index {1 2 3 4} {
+ gdb_test "p truth_table($truth_table_index, 1) \
+ .OR. truth_table($truth_table_index, 2)" \
+ "[expr $truth_table_index > 1 ? \".TRUE.\" : \".FALSE.\"]"
+}
+
+foreach_with_prefix truth_table_index {1 2 3 4} {
+ gdb_test "p truth_table($truth_table_index, 1) \
+ .AND. truth_table($truth_table_index, 2)" \
+ "[expr $truth_table_index > 3 ? \".TRUE.\" : \".FALSE.\"]"
+}
+
+# Vary number of function arguments to skip.
+set argument_list ""
+foreach_with_prefix arg {"No" "One" "Two"} {
+ set trimmed_args [string trimright $argument_list ,]
+ set arg_lower [string tolower $arg]
+ gdb_test "p function_no_arg_false() .OR.
function_${arg_lower}_arg($trimmed_args)" \
+ " $arg, return true.\r\n\\\$$decimal = .TRUE."
+ gdb_test "p .TRUE. .OR. function_${arg_lower}_arg($trimmed_args)" \
+ "\\\$$decimal = .TRUE."
+ set argument_list "$argument_list .TRUE.,"
+}
+
+# Vary number of components in the expression to skip.
+set expression "p .TRUE."
+foreach_with_prefix expression_components {1 2 3 4} {
+ set expression "$expression .OR. function_one_arg(.TRUE.)"
+ gdb_test "$expression" \
+ "\\\$$decimal = .TRUE."
+}
+
+# Check parsing skipped substring operations.
+gdb_test "p .TRUE. .OR. binary_string(1)" "\\\$$decimal = .TRUE."
+
+# Check evaluation of substring operations in logical expressions.
+gdb_test "p .FALSE. .OR. binary_string(1)" "\\\$$decimal = .FALSE."
+
+# Check nested calls
+gdb_test "p function_one_arg(.FALSE. .OR. function_no_arg())" \
+ " No, return true.\r\n One, return true.\r\n\\\$$decimal = .TRUE."
+
+gdb_test "p function_one_arg(.TRUE. .OR. function_no_arg())" \
+ " One, return true.\r\n\\\$$decimal = .TRUE."
diff --git a/gdb/testsuite/gdb.fortran/short-circuit-argument-list.f90
b/gdb/testsuite/gdb.fortran/short-circuit-argument-list.f90
new file mode 100644
index
0000000000000000000000000000000000000000..28386d029c1db0afa503d77804fc2c4bb6881dad
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/short-circuit-argument-list.f90
@@ -0,0 +1,66 @@
+! Copyright 2018 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/> .
+
+! Source code for short-circuit-argument-list.exp.
+
+logical function function_no_arg()
+ print *, "No, return true."
+ function_no_arg = .TRUE.
+end function function_no_arg
+
+logical function function_no_arg_false()
+ function_no_arg_false = .FALSE.
+end function function_no_arg_false
+
+logical function function_one_arg(x)
+ logical, intent(in) :: x
+ print *, "One, return true."
+ function_one_arg = .TRUE.
+end function function_one_arg
+
+logical function function_two_arg(x, y)
+ logical, intent(in) :: x, y
+ print *, "Two, return true."
+ function_two_arg = .TRUE.
+end function function_two_arg
+
+program generate_truth_table
+ implicit none
+ interface
+ logical function function_no_arg()
+ end function function_no_arg
+ logical function function_no_arg_false()
+ end function
+ logical function function_one_arg(x)
+ logical, intent(in) :: x
+ end function
+ logical function function_two_arg(x, y)
+ logical, intent(in) :: x, y
+ end function
+ end interface
+ logical, dimension (4,2) :: truth_table
+ logical :: a, b, c, d
+ character(2) :: binary_string
+ binary_string = char(0) // char(1)
+ truth_table = .FALSE.
+ truth_table(3:4,1) = .TRUE.
+ truth_table(2::2,2) = .TRUE.
+ a = function_no_arg() ! post_truth_table_init
+ b = function_no_arg_false()
+ c = function_one_arg(b)
+ d = function_two_arg(a, b)
+ print *, truth_table(:, 1), a, b
+ print *, truth_table(:, 2), c, d
+end program generate_truth_table
--
2.7.4
next reply other threads:[~2018-08-03 9:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-03 9:32 Richard Bunt [this message]
2018-08-03 19:24 ` Simon Marchi
2018-08-06 16:35 ` Richard Bunt
2018-08-06 18:34 ` Simon Marchi
2018-08-06 19:07 ` Tom Tromey
2018-08-07 16:26 ` Richard Bunt
2018-08-07 17:40 ` Tom Tromey
2018-08-08 16:59 ` Richard Bunt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20f669fe-9f31-fd39-9c3e-f2e1835576c6@arm.com \
--to=richard.bunt@arm.com \
--cc=gdb-patches@sourceware.org \
--cc=nd@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox