[2/8] gdb/fortran: Handle internal function calls

Message ID e8ddc573732bbbde4e92beb802b7198c6583b0b7.1552913183.git.andrew.burgess@embecosm.com
State New
Headers show
Series
  • Series of Fortran type printing patches
Related show

Commit Message

Andrew Burgess March 18, 2019, 12:52 p.m.
If an convenience function is defined in python (or guile), then
currently this will not work in Fortran, instead the user is given
this message:

  (gdb) set language fortran
  (gdb) p $myfunc (3)
  Cannot perform substring on this type

Compare this to C:

  (gdb) set language c
  (gdb) p $myfunc (3)
  $1 = 1

After this patch we see the same behaviour in both C and Fortran.
I've extended the test to check that all languages can call the
convenience functions - only Fortran was broken.

When calling convenience functions in Fortran we don't need to perform
the same value preparation (passing by pointer) that we would for
calling a native function - passing the real value is fine.

gdb/ChangeLog:

	* eval.c (evaluate_subexp_standard): Handle internal functions
	during Fortran function call handling.

gdb/testsuite/ChangeLog:

	* gdb.python/py-function.exp: Check calling helper function from
	all languages.
	* lib/gdb.exp (gdb_supported_languages): New proc.
---
 gdb/ChangeLog                            |  5 +++++
 gdb/eval.c                               | 12 ++++++++----
 gdb/testsuite/ChangeLog                  |  6 ++++++
 gdb/testsuite/gdb.python/py-function.exp |  8 +++++++-
 gdb/testsuite/lib/gdb.exp                |  8 ++++++++
 5 files changed, 34 insertions(+), 5 deletions(-)

-- 
2.14.5

Comments

Tom Tromey March 19, 2019, 7:52 p.m. | #1
>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:


Andrew> If an convenience function is defined in python (or guile), then
Andrew> currently this will not work in Fortran, instead the user is given
Andrew> this message:

Thank you.  This looks good to me.  I had one nit though:

Andrew> +	      if (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC)
Andrew> +		{
Andrew> +		  bool is_artificial =
Andrew> +		    TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1);

gdb style is to line break before the "=", not after.

Tom

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 705bcaff49f..51863b21dc6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2019-03-18  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* eval.c (evaluate_subexp_standard): Handle internal functions
+	during Fortran function call handling.
+
 2019-03-18  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* NEWS: Mention new internal functions.
diff --git a/gdb/eval.c b/gdb/eval.c
index 0c0cf7f6ac7..085c00a7d65 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1979,6 +1979,7 @@  evaluate_subexp_standard (struct type *expect_type,
 
 	case TYPE_CODE_PTR:
 	case TYPE_CODE_FUNC:
+	case TYPE_CODE_INTERNAL_FUNCTION:
 	  /* It's a function call.  */
 	  /* Allocate arg vector, including space for the function to be
 	     called in argvec[0] and a terminating NULL.  */
@@ -1996,10 +1997,13 @@  evaluate_subexp_standard (struct type *expect_type,
 		 results in malloc being called with a pointer to an integer
 		 followed by an attempt to malloc the arguments to malloc in
 		 target memory.  Infinite recursion ensues.  */
-	      bool is_artificial =
-		TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1);
-	      argvec[tem] = fortran_argument_convert (argvec[tem],
-						      is_artificial);
+	      if (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC)
+		{
+		  bool is_artificial =
+		    TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1);
+		  argvec[tem] = fortran_argument_convert (argvec[tem],
+							  is_artificial);
+		}
 	    }
 	  argvec[tem] = 0;	/* signal end of arglist */
 	  if (noside == EVAL_SKIP)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index b471f374271..6094d773163 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@ 
+2019-03-18  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gdb.python/py-function.exp: Check calling helper function from
+	all languages.
+	* lib/gdb.exp (gdb_supported_languages): New proc.
+
 2019-03-18  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.base/complex-parts.c: New file.
diff --git a/gdb/testsuite/gdb.python/py-function.exp b/gdb/testsuite/gdb.python/py-function.exp
index 76cc57d81c9..01c326b5d0b 100644
--- a/gdb/testsuite/gdb.python/py-function.exp
+++ b/gdb/testsuite/gdb.python/py-function.exp
@@ -51,7 +51,13 @@  gdb_py_test_multiple "input value-returning convenience function" \
   "Double ()" "" \
   "end" ""
 
-gdb_test "print \$double (1)" "= 2" "call value-returning function"
+# Different languages can have different parsers, so lets check that
+# internal functions are understood by every language.  Place auto
+# last in the list so we end up back in 'auto' language mode.
+foreach lang [concat [gdb_supported_languages] auto] {
+    gdb_test_no_output "set language $lang"
+    gdb_test "print \$double (1)" "= 2" "call value-returning function, language = $lang"
+}
 
 gdb_py_test_multiple "input int-returning function" \
   "python" "" \
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index f13f909c344..ad5f1857e1c 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -6308,5 +6308,13 @@  proc cd { dir } {
     builtin_cd $dir
 }
 
+# Return a list of all languages supported by GDB, suitable for use in
+# 'set language NAME'.  This doesn't include either the 'local' or
+# 'auto' keywords.
+proc gdb_supported_languages {} {
+    return [list c objective-c c++ d go fortran modula-2 asm pascal \
+		opencl rust minimal ada]
+}
+
 # Always load compatibility stuff.
 load_lib future.exp