Fix crash in is_nocall_function

Message ID 20221211195331.252485-1-tom@tromey.com
State Committed
Headers
Series Fix crash in is_nocall_function |

Commit Message

Tom Tromey Dec. 11, 2022, 7:53 p.m. UTC
  is_nocall_function anticipates only being called for a function or a
method.  However, PR gdb/29871 points out a situation where an unusual
expression -- but one that parses to a valid, if extremely weird,
function call -- breaks this assumption.

This patch changes is_nocall_function to remove this assert and
instead simply return 'false' in this case.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29871
---
 gdb/gdbtypes.c                   | 4 ++--
 gdb/gdbtypes.h                   | 4 +---
 gdb/testsuite/gdb.base/exprs.exp | 4 ++++
 3 files changed, 7 insertions(+), 5 deletions(-)
  

Comments

Simon Marchi Dec. 12, 2022, 2:45 a.m. UTC | #1
> diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp
> index 5bf03bf1320..b8698880339 100644
> --- a/gdb/testsuite/gdb.base/exprs.exp
> +++ b/gdb/testsuite/gdb.base/exprs.exp
> @@ -271,3 +271,7 @@ gdb_test "print & (void) v_char" "value not located in memory."
>  # Regression test for "&&".
>  gdb_test "print null_t_struct && null_t_struct->v_int_member == 0" \
>      " = 0"
> +
> +# Regression test for unusual function-call parse that caused a crash.
> +gdb_test "print v_short++ (97)" \
> +    "cast the call to its declared return type"
To avoid the trailing parenthesis to be considered not in the test name,
either remove the space, or give an explicit name to the test.

Otherwise, LGTM:

Approved-By: Simon Marchi <simon.marchi@efficios.com>

Simon
  

Patch

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 2166257f71e..30dd7744553 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -4037,8 +4037,8 @@  type_byte_order (const struct type *type)
 bool
 is_nocall_function (const struct type *type)
 {
-  gdb_assert (type->code () == TYPE_CODE_FUNC
-	      || type->code () == TYPE_CODE_METHOD);
+  if (type->code () != TYPE_CODE_FUNC && type->code () != TYPE_CODE_METHOD)
+    return false;
 
   return TYPE_CALLING_CONVENTION (type) == DW_CC_nocall;
 }
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index d7189ff9813..8fc5c97c95a 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -2845,9 +2845,7 @@  extern unsigned int overload_debug;
    to call by the debugger.
 
    This usually indicates that the function does not follow the target's
-   standard calling convention.
-
-   The TYPE argument must be of code TYPE_CODE_FUNC or TYPE_CODE_METHOD.  */
+   standard calling convention.  */
 
 extern bool is_nocall_function (const struct type *type);
 
diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp
index 5bf03bf1320..b8698880339 100644
--- a/gdb/testsuite/gdb.base/exprs.exp
+++ b/gdb/testsuite/gdb.base/exprs.exp
@@ -271,3 +271,7 @@  gdb_test "print & (void) v_char" "value not located in memory."
 # Regression test for "&&".
 gdb_test "print null_t_struct && null_t_struct->v_int_member == 0" \
     " = 0"
+
+# Regression test for unusual function-call parse that caused a crash.
+gdb_test "print v_short++ (97)" \
+    "cast the call to its declared return type"