diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index ea60df2..77c5866 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10807,13 +10807,11 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
         case TYPE_CODE_FUNC:
           if (noside == EVAL_AVOID_SIDE_EFFECTS)
 	    {
-	      struct type *rtype = TYPE_TARGET_TYPE (type);
-
-	      if (TYPE_GNU_IFUNC (type))
-		return allocate_value (TYPE_TARGET_TYPE (rtype));
-	      return allocate_value (rtype);
+	      if (TYPE_TARGET_TYPE (type) == NULL)
+		error_call_unknown_return_type (NULL);
+	      return allocate_value (TYPE_TARGET_TYPE (type));
 	    }
-          return call_function_by_hand (argvec[0], nargs, argvec + 1);
+	  return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1);
 	case TYPE_CODE_INTERNAL_FUNCTION:
 	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
 	    /* We don't know anything about what the internal
diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c
index 3c33bdc..65b8084 100644
--- a/gdb/ada-typeprint.c
+++ b/gdb/ada-typeprint.c
@@ -775,7 +775,8 @@ print_func_type (struct type *type, struct ui_file *stream, const char *name,
 {
   int i, len = TYPE_NFIELDS (type);
 
-  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
+  if (TYPE_TARGET_TYPE (type) != NULL
+      && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
     fprintf_filtered (stream, "procedure");
   else
     fprintf_filtered (stream, "function");
@@ -800,7 +801,9 @@ print_func_type (struct type *type, struct ui_file *stream, const char *name,
       fprintf_filtered (stream, ")");
     }
 
-  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+  if (TYPE_TARGET_TYPE (type) == NULL)
+    fprintf_filtered (stream, " return <unknown return type>");
+  else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
     {
       fprintf_filtered (stream, " return ");
       ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 9e197f5..64bb51c 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -893,13 +893,19 @@ c_type_print_base (struct type *type, struct ui_file *stream,
       fprintf_filtered (stream, _("<unnamed typedef>"));
       break;
 
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_METHOD:
+      if (TYPE_TARGET_TYPE (type) == NULL)
+	type_print_unknown_return_type (stream);
+      else
+	c_type_print_base (TYPE_TARGET_TYPE (type),
+			   stream, show, level, flags);
+      break;
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBERPTR:
     case TYPE_CODE_REF:
     case TYPE_CODE_RVALUE_REF:
-    case TYPE_CODE_FUNC:
-    case TYPE_CODE_METHOD:
     case TYPE_CODE_METHODPTR:
       c_type_print_base (TYPE_TARGET_TYPE (type),
 			 stream, show, level, flags);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index 15e1d6d..c5ec941 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -379,9 +379,7 @@ convert_symbol_bmsym (struct compile_c_instance *context,
       break;
 
     case mst_text_gnu_ifunc:
-      /* nodebug_text_gnu_ifunc_symbol would cause:
-	 function return type cannot be function  */
-      type = objfile_type (objfile)->nodebug_text_symbol;
+      type = objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
       kind = GCC_C_SYMBOL_FUNCTION;
       addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
       break;
diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c
index 22aee78..7fbab13 100644
--- a/gdb/compile/compile-c-types.c
+++ b/gdb/compile/compile-c-types.c
@@ -21,6 +21,8 @@
 #include "defs.h"
 #include "gdbtypes.h"
 #include "compile-internal.h"
+#include "objfiles.h"
+
 /* An object that maps a gdb type to a gcc type.  */
 
 struct type_map_instance
@@ -234,9 +236,25 @@ convert_func (struct compile_c_instance *context, struct type *type)
   struct gcc_type_array array;
   int is_varargs = TYPE_VARARGS (type) || !TYPE_PROTOTYPED (type);
 
+  struct type *target_type = TYPE_TARGET_TYPE (type);
+
+  /* Functions with no debug info have no return type.  Ideally we'd
+     want to fallback to the type of the cast just before the
+     function, like GDB's built-in expression parser, but we don't
+     have access to that type here.  For now, fallback to int, like
+     GDB's parser used to do.  */
+  if (target_type == NULL)
+    {
+      if (TYPE_OBJFILE_OWNED (type))
+	target_type = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
+      else
+	target_type = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
+      warning (_("function has unknown return type; assuming int"));
+    }
+
   /* This approach means we can't make self-referential function
      types.  Those are impossible in C, though.  */
-  return_type = convert_type (context, TYPE_TARGET_TYPE (type));
+  return_type = convert_type (context, target_type);
 
   array.n_elements = TYPE_NFIELDS (type);
   array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type));
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index de5fa16..43da59f 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -172,7 +172,8 @@ compile_object_run (struct compile_module *module)
 	  ++current_arg;
 	}
       gdb_assert (current_arg == TYPE_NFIELDS (func_type));
-      call_function_by_hand_dummy (func_val, TYPE_NFIELDS (func_type), vargs,
+      call_function_by_hand_dummy (func_val,
+				   NULL, TYPE_NFIELDS (func_type), vargs,
 				   do_module_cleanup, data);
     }
   CATCH (ex, RETURN_MASK_ERROR)
diff --git a/gdb/elfread.c b/gdb/elfread.c
index fba2026..b34cdd5 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -889,7 +889,7 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
   target_auxv_search (&current_target, AT_HWCAP, &hwcap);
   hwcap_val = value_from_longest (builtin_type (gdbarch)
 				  ->builtin_unsigned_long, hwcap);
-  address_val = call_function_by_hand (function, 1, &hwcap_val);
+  address_val = call_function_by_hand (function, NULL, 1, &hwcap_val);
   address = value_as_address (address_val);
   address = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
 						&current_target);
diff --git a/gdb/eval.c b/gdb/eval.c
index 80dfb2e..1ec6751 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1147,12 +1147,12 @@ evaluate_subexp_standard (struct type *expect_type,
 	argvec[3] = value_from_longest (long_type, selector);
 	argvec[4] = 0;
 
-	ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+	ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
 	if (gnu_runtime)
 	  {
 	    /* Function objc_msg_lookup returns a pointer.  */
 	    argvec[0] = ret;
-	    ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+	    ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
 	  }
 	if (value_as_long (ret) == 0)
 	  error (_("Target does not respond to this message selector."));
@@ -1169,11 +1169,11 @@ evaluate_subexp_standard (struct type *expect_type,
 	argvec[3] = value_from_longest (long_type, selector);
 	argvec[4] = 0;
 
-	ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+	ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
 	if (gnu_runtime)
 	  {
 	    argvec[0] = ret;
-	    ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+	    ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
 	  }
 
 	/* ret should now be the selector.  */
@@ -1315,10 +1315,10 @@ evaluate_subexp_standard (struct type *expect_type,
 	    deprecated_set_value_type (argvec[0],
 				       lookup_pointer_type (lookup_function_type (value_type (argvec[0]))));
 	    argvec[0]
-	      = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
+	      = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1);
 	  }
 
-	ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
+	ret = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1);
 	return ret;
       }
       break;
@@ -1705,12 +1705,9 @@ evaluate_subexp_standard (struct type *expect_type,
 	error (_("Cannot evaluate function -- may be inlined"));
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
 	{
-	  /* If the return type doesn't look like a function type, call an
-	     error.  This can happen if somebody tries to turn a variable into
-	     a function call.  This is here because people often want to
-	     call, eg, strcmp, which gdb doesn't know is a function.  If
-	     gdb isn't asked for it's opinion (ie. through "whatis"),
-	     it won't offer it.  */
+	  /* If the return type doesn't look like a function type,
+	     call an error.  This can happen if somebody tries to turn
+	     a variable into a function call.  */
 
 	  struct type *ftype = value_type (argvec[0]);
 
@@ -1731,10 +1728,19 @@ evaluate_subexp_standard (struct type *expect_type,
 		error (_("Xmethod is missing return type."));
 	      return value_zero (return_type, not_lval);
 	    }
-	  else if (TYPE_GNU_IFUNC (ftype))
-	    return allocate_value (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)));
-	  else if (TYPE_TARGET_TYPE (ftype))
-	    return allocate_value (TYPE_TARGET_TYPE (ftype));
+	  else if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
+		   || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+	    {
+	      struct type *return_type = TYPE_TARGET_TYPE (ftype);
+
+	      if (return_type == NULL)
+		return_type = expect_type;
+
+	      if (return_type == NULL)
+		error_call_unknown_return_type (NULL);
+
+	      return allocate_value (return_type);
+	    }
 	  else
 	    error (_("Expression of type other than "
 		     "\"Function returning ...\" used as function"));
@@ -1747,7 +1753,8 @@ evaluate_subexp_standard (struct type *expect_type,
 	case TYPE_CODE_XMETHOD:
 	  return call_xmethod (argvec[0], nargs, argvec + 1);
 	default:
-	  return call_function_by_hand (argvec[0], nargs, argvec + 1);
+	  return call_function_by_hand (argvec[0],
+					expect_type, nargs, argvec + 1);
 	}
       /* pai: FIXME save value from call_function_by_hand, then adjust
 	 pc by adjust_fn_pc if +ve.  */
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 7dbe093..2a858aa 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -304,9 +304,14 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show,
       break;
 
     case TYPE_CODE_ARRAY:
-    case TYPE_CODE_FUNC:
       f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
       break;
+    case TYPE_CODE_FUNC:
+      if (TYPE_TARGET_TYPE (type) == NULL)
+	type_print_unknown_return_type (stream);
+      else
+	f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+      break;
 
     case TYPE_CODE_PTR:
       fprintf_filtered (stream, "PTR TO -> ( ");
diff --git a/gdb/gcore.c b/gdb/gcore.c
index c32d2ff..687ad8c 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -302,7 +302,7 @@ call_target_sbrk (int sbrk_arg)
   target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, 
 					sbrk_arg);
   gdb_assert (target_sbrk_arg);
-  ret = call_function_by_hand (sbrk_fn, 1, &target_sbrk_arg);
+  ret = call_function_by_hand (sbrk_fn, NULL, 1, &target_sbrk_arg);
   if (ret == NULL)
     return (bfd_vma) 0;
 
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ceb4f0c..a22f0ca 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -5312,13 +5312,13 @@ objfile_type (struct objfile *objfile)
   objfile_type->nodebug_text_symbol
     = init_type (objfile, TYPE_CODE_FUNC, 1,
 		 "<text variable, no debug info>");
-  TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol)
-    = objfile_type->builtin_int;
   objfile_type->nodebug_text_gnu_ifunc_symbol
     = init_type (objfile, TYPE_CODE_FUNC, 1,
 		 "<text gnu-indirect-function variable, no debug info>");
+  /* Ifunc resolvers return a function address.  */
   TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
-    = objfile_type->nodebug_text_symbol;
+    = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1,
+			 "__IFUNC_RESOLVER_RET");
   TYPE_GNU_IFUNC (objfile_type->nodebug_text_gnu_ifunc_symbol) = 1;
   objfile_type->nodebug_got_plt_symbol
     = init_pointer_type (objfile, gdbarch_addr_bit (gdbarch),
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index f631032..0dc6630 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -864,7 +864,7 @@ gdbscm_value_call (SCM self, SCM args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark);
       struct value *return_value;
 
-      return_value = call_function_by_hand (function, args_count, vargs);
+      return_value = call_function_by_hand (function, NULL, args_count, vargs);
       result = vlscm_scm_from_value (return_value);
       do_cleanups (cleanup);
     }
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 38335a7..b09dc8f 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -340,6 +340,20 @@ push_dummy_code (struct gdbarch *gdbarch,
 				  regcache);
 }
 
+/* See infcall.h.  */
+
+void
+error_call_unknown_return_type (const char *func_name)
+{
+  if (func_name != NULL)
+    error (_("'%s' has unknown return type; "
+	     "cast the call to its declared return type"),
+	   func_name);
+  else
+    error (_("function has unknown return type; "
+	     "cast the call to its declared return type"));
+}
+
 /* Fetch the name of the function at FUNADDR.
    This is used in printing an error message for call_function_by_hand.
    BUF is used to print FUNADDR in hex if the function name cannot be
@@ -673,9 +687,12 @@ cleanup_delete_std_terminate_breakpoint (void *ignore)
 /* See infcall.h.  */
 
 struct value *
-call_function_by_hand (struct value *function, int nargs, struct value **args)
+call_function_by_hand (struct value *function,
+		       type *default_return_type,
+		       int nargs, struct value **args)
 {
-  return call_function_by_hand_dummy (function, nargs, args, NULL, NULL);
+  return call_function_by_hand_dummy (function, default_return_type,
+				      nargs, args, NULL, NULL);
 }
 
 /* All this stuff with a dummy frame may seem unnecessarily complicated
@@ -698,6 +715,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
 
 struct value *
 call_function_by_hand_dummy (struct value *function,
+			     type *default_return_type,
 			     int nargs, struct value **args,
 			     dummy_frame_dtor_ftype *dummy_dtor,
 			     void *dummy_dtor_data)
@@ -850,8 +868,16 @@ call_function_by_hand_dummy (struct value *function,
   }
 
   funaddr = find_function_addr (function, &values_type);
-  if (!values_type)
-    values_type = builtin_type (gdbarch)->builtin_int;
+  if (values_type == NULL)
+    values_type = default_return_type;
+  if (values_type == NULL)
+    {
+      const char *name = get_function_name (funaddr,
+					    name_buf, sizeof (name_buf));
+      error (_("'%s' has unknown return type; "
+	       "cast the call to its declared return type"),
+	     name);
+    }
 
   values_type = check_typedef (values_type);
 
@@ -955,6 +981,21 @@ call_function_by_hand_dummy (struct value *function,
 	   prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */
 	if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
 	  prototyped = 1;
+	if (TYPE_TARGET_TYPE (ftype) == NULL && TYPE_NFIELDS (ftype) == 0
+	    && default_return_type != NULL)
+	  {
+	    /* Calling a no-debug function with the return type
+	       explicitly cast.  Assume the function is prototyped,
+	       with a prototype matching the types of the arguments.
+	       E.g., with:
+		 float mult (float v1, float v2) { return v1 * v2; }
+	       This:
+		 (gdb) p (float) mult (2.0f, 3.0f)
+	       Is a simpler alternative to:
+		 (gdb) p ((float (*) (float, float)) mult) (2.0f, 3.0f)
+	     */
+	    prototyped = 1;
+	  }
 	else if (i < TYPE_NFIELDS (ftype))
 	  prototyped = TYPE_PROTOTYPED (ftype);
 	else
diff --git a/gdb/infcall.h b/gdb/infcall.h
index cbaa943..a456d92 100644
--- a/gdb/infcall.h
+++ b/gdb/infcall.h
@@ -35,9 +35,15 @@ extern CORE_ADDR find_function_addr (struct value *function,
    representing what the function returned.  May fail to return, if a
    breakpoint or signal is hit during the execution of the function.
 
+   DFEAULT_RETURN_TYPE is used as function return type if the return
+   type is unknown.  This is used when calling functions with no debug
+   info.
+
    ARGS is modified to contain coerced values.  */
 
-extern struct value *call_function_by_hand (struct value *function, int nargs,
+extern struct value *call_function_by_hand (struct value *function,
+					    type *default_return_type,
+					    int nargs,
 					    struct value **args);
 
 /* Similar to call_function_by_hand and additional call
@@ -45,9 +51,18 @@ extern struct value *call_function_by_hand (struct value *function, int nargs,
    created inferior call dummy frame.  */
 
 extern struct value *
-  call_function_by_hand_dummy (struct value *function, int nargs,
+  call_function_by_hand_dummy (struct value *function,
+			       type *default_return_type,
+			       int nargs,
 			       struct value **args,
 			       dummy_frame_dtor_ftype *dummy_dtor,
 			       void *dummy_dtor_data);
 
+/* Throw an error indicating that the user tried to call a function
+   that has unknown return type.  FUNC_NAME is the name of the
+   function to be included in the error message; may be NULL, in which
+   case the error message doesn't include a function name.  */
+
+extern void error_call_unknown_return_type (const char *func_name);
+
 #endif
diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c
index 573a3e9..16403c9 100644
--- a/gdb/linux-fork.c
+++ b/gdb/linux-fork.c
@@ -248,7 +248,7 @@ call_lseek (int fd, off_t offset, int whence)
 {
   char exp[80];
 
-  snprintf (&exp[0], sizeof (exp), "lseek (%d, %ld, %d)",
+  snprintf (&exp[0], sizeof (exp), "(long) lseek (%d, %ld, %d)",
 	    fd, (long) offset, whence);
   return (off_t) parse_and_eval_long (&exp[0]);
 }
@@ -492,7 +492,7 @@ inferior_call_waitpid (ptid_t pptid, int pid)
   argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
   argv[3] = 0;
 
-  retv = call_function_by_hand (waitpid_fn, 3, argv);
+  retv = call_function_by_hand (waitpid_fn, NULL, 3, argv);
   if (value_as_long (retv) < 0)
     goto out;
 
@@ -707,7 +707,7 @@ checkpoint_command (char *args, int from_tty)
     scoped_restore save_pid
       = make_scoped_restore (&checkpointing_pid, ptid_get_pid (inferior_ptid));
 
-    ret = call_function_by_hand (fork_fn, 0, &ret);
+    ret = call_function_by_hand (fork_fn, NULL, 0, &ret);
   }
 
   if (!ret)	/* Probably can't happen.  */
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 2792cbd..37dd95e 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -2427,7 +2427,7 @@ linux_infcall_mmap (CORE_ADDR size, unsigned prot)
   arg[ARG_FD] = value_from_longest (builtin_type (gdbarch)->builtin_int, -1);
   arg[ARG_OFFSET] = value_from_longest (builtin_type (gdbarch)->builtin_int64,
 					0);
-  addr_val = call_function_by_hand (mmap_val, ARG_LAST, arg);
+  addr_val = call_function_by_hand (mmap_val, NULL, ARG_LAST, arg);
   retval = value_as_address (addr_val);
   if (retval == (CORE_ADDR) -1)
     error (_("Failed inferior mmap call for %s bytes, errno is changed."),
@@ -2456,7 +2456,7 @@ linux_infcall_munmap (CORE_ADDR addr, CORE_ADDR size)
   /* Assuming sizeof (unsigned long) == sizeof (size_t).  */
   arg[ARG_LENGTH] = value_from_ulongest
 		    (builtin_type (gdbarch)->builtin_unsigned_long, size);
-  retval_val = call_function_by_hand (munmap_val, ARG_LAST, arg);
+  retval_val = call_function_by_hand (munmap_val, NULL, ARG_LAST, arg);
   retval = value_as_long (retval_val);
   if (retval != 0)
     warning (_("Failed inferior munmap call at %s for %s bytes, "
diff --git a/gdb/m2-typeprint.c b/gdb/m2-typeprint.c
index 4cf1569..0dd6f19 100644
--- a/gdb/m2-typeprint.c
+++ b/gdb/m2-typeprint.c
@@ -280,7 +280,8 @@ m2_procedure (struct type *type, struct ui_file *stream,
 {
   fprintf_filtered (stream, "PROCEDURE ");
   m2_type_name (type, stream);
-  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+  if (TYPE_TARGET_TYPE (type) == NULL
+      || TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
     {
       int i, len = TYPE_NFIELDS (type);
 
@@ -294,11 +295,11 @@ m2_procedure (struct type *type, struct ui_file *stream,
 	    }
 	  m2_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0, flags);
 	}
+      fprintf_filtered (stream, ") : ");
       if (TYPE_TARGET_TYPE (type) != NULL)
-	{
-	  fprintf_filtered (stream, " : ");
-	  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
-	}
+	m2_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
+      else
+	type_print_unknown_return_type (stream);
     }
 }
 
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 934d9c6..fbdd69f 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -130,7 +130,8 @@ lookup_objc_class (struct gdbarch *gdbarch, const char *classname)
 
   classval = value_string (classname, strlen (classname) + 1, char_type);
   classval = value_coerce_array (classval);
-  return (CORE_ADDR) value_as_long (call_function_by_hand (function, 
+  return (CORE_ADDR) value_as_long (call_function_by_hand (function,
+							   NULL,
 							   1, &classval));
 }
 
@@ -160,7 +161,7 @@ lookup_child_selector (struct gdbarch *gdbarch, const char *selname)
   selstring = value_coerce_array (value_string (selname, 
 						strlen (selname) + 1,
 						char_type));
-  return value_as_long (call_function_by_hand (function, 1, &selstring));
+  return value_as_long (call_function_by_hand (function, NULL, 1, &selstring));
 }
 
 struct value * 
@@ -181,12 +182,13 @@ value_nsstring (struct gdbarch *gdbarch, char *ptr, int len)
   if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym)
     {
       function = find_function_in_inferior("_NSNewStringFromCString", NULL);
-      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
+      nsstringValue = call_function_by_hand(function,
+					    NULL, 1, &stringValue[2]);
     }
   else if (lookup_minimal_symbol("istr", 0, 0).minsym)
     {
       function = find_function_in_inferior("istr", NULL);
-      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
+      nsstringValue = call_function_by_hand(function, NULL, 1, &stringValue[2]);
     }
   else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym)
     {
@@ -198,7 +200,7 @@ value_nsstring (struct gdbarch *gdbarch, char *ptr, int len)
 	(type, lookup_objc_class (gdbarch, "NSString"));
       stringValue[1] = value_from_longest 
 	(type, lookup_child_selector (gdbarch, "stringWithCString:"));
-      nsstringValue = call_function_by_hand(function, 3, &stringValue[0]);
+      nsstringValue = call_function_by_hand(function, NULL, 3, &stringValue[0]);
     }
   else
     error (_("NSString: internal error -- no way to create new NSString"));
@@ -1209,7 +1211,7 @@ print_object_command (char *args, int from_tty)
   if (function == NULL)
     error (_("Unable to locate _NSPrintForDebugger in child process"));
 
-  description = call_function_by_hand (function, 1, &object);
+  description = call_function_by_hand (function, NULL, 1, &object);
 
   string_addr = value_as_long (description);
   if (string_addr == 0)
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
index d08f6f7..33b4992 100644
--- a/gdb/p-typeprint.c
+++ b/gdb/p-typeprint.c
@@ -227,7 +227,8 @@ pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
     case TYPE_CODE_METHOD:
       if (passed_a_ptr)
 	fprintf_filtered (stream, "(");
-      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+      if (TYPE_TARGET_TYPE (type) != NULL
+	  && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
 	{
 	  fprintf_filtered (stream, "function  ");
 	}
@@ -255,7 +256,8 @@ pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
       if (passed_a_ptr)
 	fprintf_filtered (stream, "(");
 
-      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+      if (TYPE_TARGET_TYPE (type) != NULL
+	  && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
 	{
 	  fprintf_filtered (stream, "function  ");
 	}
@@ -334,6 +336,33 @@ pascal_print_func_args (struct type *type, struct ui_file *stream,
     }
 }
 
+/* Helper for pascal_type_print_varspec_suffix to print the suffix of
+   a function or method.  */
+
+static void
+pascal_type_print_func_varspec_suffix  (struct type *type, struct ui_file *stream,
+					int show, int passed_a_ptr,
+					int demangled_args,
+					const struct type_print_options *flags)
+{
+  if (TYPE_TARGET_TYPE (type) == NULL
+      || TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+    {
+      fprintf_filtered (stream, " : ");
+      pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+					stream, 0, 0, flags);
+
+      if (TYPE_TARGET_TYPE (type) == NULL)
+	type_print_unknown_return_type (stream);
+      else
+	pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0,
+				flags);
+
+      pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+					passed_a_ptr, 0, flags);
+    }
+}
+
 /* Print any array sizes, function arguments or close parentheses
    needed after the variable name (to describe its type).
    Args work like pascal_type_print_varspec_prefix.  */
@@ -365,16 +394,8 @@ pascal_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
       pascal_type_print_method_args ("",
 				     "",
 				     stream);
-      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
-	{
-	  fprintf_filtered (stream, " : ");
-	  pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
-					    stream, 0, 0, flags);
-	  pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0,
-				  flags);
-	  pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
-					    passed_a_ptr, 0, flags);
-	}
+      pascal_type_print_func_varspec_suffix (type, stream, show,
+					     passed_a_ptr, 0, flags);
       break;
 
     case TYPE_CODE_PTR:
@@ -388,16 +409,8 @@ pascal_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
 	fprintf_filtered (stream, ")");
       if (!demangled_args)
 	pascal_print_func_args (type, stream, flags);
-      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
-	{
-	  fprintf_filtered (stream, " : ");
-	  pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
-					    stream, 0, 0, flags);
-	  pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0,
-				  flags);
-	  pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
-					    passed_a_ptr, 0, flags);
-	}
+      pascal_type_print_func_varspec_suffix (type, stream, show,
+					     passed_a_ptr, 0, flags);
       break;
 
     case TYPE_CODE_UNDEF:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index b5a0ef8..cbbb936 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -925,7 +925,8 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
       scoped_value_mark free_values;
       struct value *return_value;
 
-      return_value = call_function_by_hand (function, args_count, vargs);
+      return_value = call_function_by_hand (function, NULL,
+					    args_count, vargs);
       result = value_to_value_object (return_value);
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index d4cda1f..14e7f9b 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -1292,7 +1292,7 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval);
   else
-    result = call_function_by_hand (function, num_args + 1, args.data ());
+    result = call_function_by_hand (function, NULL, num_args + 1, args.data ());
   return result;
 }
 
diff --git a/gdb/testsuite/gdb.base/break-main-file-remove-fail.exp b/gdb/testsuite/gdb.base/break-main-file-remove-fail.exp
index eba72bc..080d193 100644
--- a/gdb/testsuite/gdb.base/break-main-file-remove-fail.exp
+++ b/gdb/testsuite/gdb.base/break-main-file-remove-fail.exp
@@ -88,7 +88,7 @@ proc test_remove_bp { initial_load } {
 	# should warn the user about it.
 	set pagesize [get_integer_valueof "pg_size" 0]
 	set align_addr [expr $bp_addr - $bp_addr % $pagesize]
-	set munmap [get_integer_valueof "munmap ($align_addr, $pagesize)" -1]
+	set munmap [get_integer_valueof "(int) munmap ($align_addr, $pagesize)" -1]
 
 	if {$munmap != 0} {
 	    unsupported "can't munmap foo's page"
diff --git a/gdb/testsuite/gdb.base/break-probes.exp b/gdb/testsuite/gdb.base/break-probes.exp
index 929509a..318a219 100644
--- a/gdb/testsuite/gdb.base/break-probes.exp
+++ b/gdb/testsuite/gdb.base/break-probes.exp
@@ -86,5 +86,5 @@ if { $using_probes } {
     }
 
     # Call something to ensure that relocation occurred
-    gdb_test "call foo(23)" "\\\$.* = 31.*\\\M.*"
+    gdb_test "call (int) foo(23)" "\\\$.* = 31.*\\\M.*"
 }
diff --git a/gdb/testsuite/gdb.base/checkpoint.exp b/gdb/testsuite/gdb.base/checkpoint.exp
index 12c1d8a..677c389 100644
--- a/gdb/testsuite/gdb.base/checkpoint.exp
+++ b/gdb/testsuite/gdb.base/checkpoint.exp
@@ -224,45 +224,11 @@ gdb_test "shell diff $pi_txt $copy1_txt" \
 delete_breakpoints
 gdb_breakpoint $break2_loc
 
-gdb_test "restart 1" "if .c == EOF.*" "restart 1 three"
-gdb_test "continue" "breakpoint 2.*" "break2 1 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 1"
-
-gdb_test "restart 2" "if .c == EOF.*" "restart 2 three"
-gdb_test "continue" "breakpoint 2.*" "break2 2 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 2"
-
-gdb_test "restart 3" "if .c == EOF.*" "restart 3 three"
-gdb_test "continue" "breakpoint 2.*" "break2 3 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 3"
-
-gdb_test "restart 4" "if .c == EOF.*" "restart 4 three"
-gdb_test "continue" "breakpoint 2.*" "break2 4 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 4"
-
-gdb_test "restart 5" "if .c == EOF.*" "restart 5 three"
-gdb_test "continue" "breakpoint 2.*" "break2 5 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 5"
-
-gdb_test "restart 6" "if .c == EOF.*" "restart 6 three"
-gdb_test "continue" "breakpoint 2.*" "break2 6 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 6"
-
-gdb_test "restart 7" "if .c == EOF.*" "restart 7 three"
-gdb_test "continue" "breakpoint 2.*" "break2 7 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 7"
-
-gdb_test "restart 8" "if .c == EOF.*" "restart 8 three"
-gdb_test "continue" "breakpoint 2.*" "break2 8 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 8"
-
-gdb_test "restart 9" "if .c == EOF.*" "restart 9 three"
-gdb_test "continue" "breakpoint 2.*" "break2 9 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 9"
-
-gdb_test "restart 10" "if .c == EOF.*" "restart 10 three"
-gdb_test "continue" "breakpoint 2.*" "break2 10 one"
-gdb_test "print ftell (out) > 100000" " = 1.*" "outfile still open 10"
+for {set num 1} {$num <= 10} {incr num} {
+    gdb_test "restart $num" "if .c == EOF.*" "restart $num three"
+    gdb_test "continue" "breakpoint 2.*" "break2 $num one"
+    gdb_test "print (long) ftell (out) > 100000" " = 1.*" "outfile still open $num"
+}
 
 #
 # Now confirm that if one fork exits, we automatically switch to another one.
diff --git a/gdb/testsuite/gdb.base/dprintf-detach.exp b/gdb/testsuite/gdb.base/dprintf-detach.exp
index 4c6ef1c..940a9ef 100644
--- a/gdb/testsuite/gdb.base/dprintf-detach.exp
+++ b/gdb/testsuite/gdb.base/dprintf-detach.exp
@@ -53,7 +53,7 @@ proc dprintf_detach_test { breakpoint_always_inserted dprintf_style disconnected
 	# Get PID of test program.
 	set inferior_pid -1
 	set test "get inferior process ID"
-	gdb_test_multiple "call getpid ()" $test {
+	gdb_test_multiple "call (int) getpid ()" $test {
 	    -re ".* = ($decimal).*$gdb_prompt $" {
 		set inferior_pid $expect_out(1,string)
 		pass $test
diff --git a/gdb/testsuite/gdb.base/infcall-exec.exp b/gdb/testsuite/gdb.base/infcall-exec.exp
index 3984076..8419905 100644
--- a/gdb/testsuite/gdb.base/infcall-exec.exp
+++ b/gdb/testsuite/gdb.base/infcall-exec.exp
@@ -44,5 +44,5 @@ append expected_result "\[\r\n\]+.*"
 append expected_result "Breakpoint 1, main .*at .*$srcfile2:$decimal"
 append expected_result ".*"
 
-gdb_test "call execlp \(\"$binfile2\", \"$binfile2\", \(char \*\)0\)" \
+gdb_test "call (int) execlp \(\"$binfile2\", \"$binfile2\", \(char \*\)0\)" \
     $expected_result "call execlp"
diff --git a/gdb/testsuite/gdb.base/info-os.exp b/gdb/testsuite/gdb.base/info-os.exp
index 0168ccb..574da26 100644
--- a/gdb/testsuite/gdb.base/info-os.exp
+++ b/gdb/testsuite/gdb.base/info-os.exp
@@ -39,14 +39,18 @@ if ![runto_main] then {
 }
 
 # Get PID of test program.
-set inferior_pid -1
+set inferior_pid ""
 set test "get inferior process ID"
-gdb_test_multiple "call getpid()" $test {
+gdb_test_multiple "call (int) getpid()" $test {
     -re ".* = ($decimal).*$gdb_prompt $" {
 	set inferior_pid $expect_out(1,string)
 	pass $test
     }
 }
+if {$inferior_pid == ""} {
+    untested "failed to get pid"
+    return
+}
 
 gdb_breakpoint ${srcfile}:[gdb_get_line_number "Set breakpoint here"]
 gdb_continue_to_breakpoint "Set breakpoint here"
diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
index eb5d661..99641e8 100644
--- a/gdb/testsuite/gdb.base/nodebug.c
+++ b/gdb/testsuite/gdb.base/nodebug.c
@@ -1,4 +1,6 @@
 #include <stdlib.h>
+#include <stdint.h>
+
 /* Test that things still (sort of) work when compiled without -g.  */
 
 int dataglobal = 3;			/* Should go in global data */
@@ -43,3 +45,42 @@ int array_index (char *arr, int i)
   free (x);
   return retval;
 }
+
+float
+multf (float v1, float v2)
+{
+  return v1 * v2;
+}
+
+float
+multf_noproto (v1, v2)
+  float v1, v2;
+{
+  return v1 * v2;
+}
+
+double
+mult (double v1, double v2)
+{
+  return v1 * v2;
+}
+
+double
+mult_noproto (v1, v2)
+  double v1, v2;
+{
+  return v1 * v2;
+}
+
+uint8_t
+add8 (uint8_t v1, uint8_t v2)
+{
+  return v1 + v2;
+}
+
+uint8_t
+add8_noproto (v1, v2)
+  uint8_t v1, v2;
+{
+  return v1 + v2;
+}
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
index a54e5bb..7bdf9ad 100644
--- a/gdb/testsuite/gdb.base/nodebug.exp
+++ b/gdb/testsuite/gdb.base/nodebug.exp
@@ -39,6 +39,40 @@ if  { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "
 
 clean_restart $binfile
 
+# Test calling no-debug functions involving argument types that may
+# require coercion/promotion, both prototyped and unprototyped, both
+# return-type-cast style, and function-pointer-cast styles.
+proc test_call_promotion {} {
+    if [target_info exists gdb,cannot_call_functions] {
+	return
+    }
+
+    # Call prototyped function with float parameters via both
+    # return-type cast and function-pointer cast.  This checks that
+    # GDB doesn't do float->double coercion.
+    gdb_test "p (float) multf(2.0f, 3.0f)" " = 6"
+    gdb_test "p ((float (*) (float, float)) multf)(2, 3)" " = 6"
+    gdb_test "p ((float (*) (float, float)) multf)(2.0f, 3.0f)" " = 6"
+
+    # Call unprototyped function with float parameters via
+    # function-pointer cast, only.  return-type cast assumes
+    # protototyped.  Check that GDB does float->double coercion.
+    gdb_test "p ((float (*) ()) multf_noproto)(2.0f, 3.0f)" " = 6"
+    gdb_test "p ((float (*) ()) multf_noproto)(2.0, 3.0)" " = 6"
+
+    # Same, but for double.
+    gdb_test "p (double) mult (2.0, 3.0)" " = 6"
+    gdb_test "p ((double (*) (double, double)) mult)(2.0f, 3.0f)" " = 6"
+    gdb_test "p ((double (*) (double, double)) mult)(2, 3)" " = 6"
+    gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
+    gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
+
+    # Check that GDB promotes char->int correctly.
+    gdb_test "p /d (uint8) add8((uint8) 2, (uint8) 3)" " = 5"
+    gdb_test "p /d ((uint8 (*) (uint8, uint8)) add8)((uint8) 2, (uint8) 3)" " = 5"
+    gdb_test "p /d ((uint8 (*) ()) add8_noproto)((uint8) 2, (uint8) 3)" " = 5"
+}
+
 if [runto inner] then {
     
     # Expect to find global/local symbols in each of text/data/bss.
@@ -59,18 +93,66 @@ if [runto inner] then {
     # out debugging info for non-aggregate return values of functions
     # even without -g, which should be accepted.
 
-    gdb_test "p top" \
-	"\{(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))\} \[0-9a-fx]* <\\.?top(\\(int\\)|)>"
-    gdb_test "whatis top" \
-	"(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))"
-    gdb_test "ptype top" "(short|int) \\((|void|int|<non-float parameter>|<non-float parameter>, <non-float parameter>)\\)"
-    
-    gdb_test "p middle" \
-	"\{(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))\} \[0-9a-fx]* <\\.?middle(\\(int\\)|)>"
-    gdb_test "whatis middle" \
-	"(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))"
-    gdb_test "ptype middle" "(short|int) \\((|void|int|<non-float parameter>|<non-float parameter>, <non-float parameter>)\\)"
-    
+    with_test_prefix "func" {
+	# Most languages default to printing like C.
+	set c_print_re " = \\{<text variable, no debug info>\\} $hex <top>"
+	set c_whatis_re " = <text variable, no debug info>"
+	set c_ptype_re "= <unknown return type> \\(\\)"
+
+	set cxx_ptype_re "= <unknown return type> \\(void\\)"
+
+	set ada_ptype_re " = function return <unknown return type>"
+
+	set m2_print_re " = \\{PROCEDURE <text variable, no debug info> \\(\\) : <unknown return type>\\} $hex <top>"
+	set m2_whatis_re "PROCEDURE <text variable, no debug info> \\(\\) : <unknown return type>"
+	set m2_ptype_re $m2_whatis_re
+
+	# Rust can't access minsyms?
+	set rust_nosym "No symbol 'top' in current context"
+
+	set pascal_ptype_re "type = procedure  : <unknown return type>"
+
+	#LANG		#PRINT		#WHATIS		#PTYPE
+	foreach lang_line {
+	    {"ada"		$c_print_re	$c_whatis_re	$ada_ptype_re}
+	    {"asm"		$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"c"		$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"c++"		$c_print_re	$c_whatis_re	$cxx_ptype_re}
+	    {"d"		$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"fortran"	$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"go"		$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"minimal"	$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"modula-2"	$m2_print_re	$m2_whatis_re	$m2_ptype_re}
+	    {"objective-c"	$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"opencl"	$c_print_re	$c_whatis_re	$c_ptype_re}
+	    {"pascal"	$c_print_re	$c_whatis_re	$pascal_ptype_re}
+	    {"rust"		$rust_nosym	$rust_nosym	$rust_nosym}
+	} {
+	    set lang [lindex $lang_line 0]
+	    set print_re [lindex $lang_line 1]
+	    set whatis_re [lindex $lang_line 2]
+	    set ptype_re [lindex $lang_line 3]
+
+	    set print_re [subst "$print_re"]
+	    set whatis_re [subst "$whatis_re"]
+	    set ptype_re [subst "$ptype_re"]
+
+	    with_test_prefix "$lang" {
+		gdb_test_no_output "set language $lang"
+		gdb_test "p top" $print_re
+		gdb_test "whatis top" $whatis_re
+		gdb_test "ptype top" $ptype_re
+	    }
+	}
+    }
+
+    gdb_test_no_output "set language auto"
+
+    # We can't rely on uintXX_t being available/known to GDB because
+    # we may or may not have debug info for those (depending on
+    # whether we have debug info for the C runtime, for example).
+    gdb_test_no_output "macro define uint8 unsigned char"
+
     gdb_test "p dataglobal" "= 3"
     gdb_test "whatis dataglobal" \
 	"<(data variable|variable), no debug info>|int"
@@ -122,17 +204,27 @@ if [runto inner] then {
     
     # This test is not as obscure as it might look.  `p getenv ("TERM")'
     # is a real-world example, at least on many systems.
+
+    gdb_test {p/c array_index("abcdef",2)} \
+	"'array_index' has unknown return type; cast the call to its declared return type"
+    gdb_test {ptype array_index("abcdef",2)} \
+	"function has unknown return type; cast the call to its declared return type"
+    gdb_test {whatis array_index("abcdef",2)} \
+	"function has unknown return type; cast the call to its declared return type"
+
     if [target_info exists gdb,cannot_call_functions] {
-	unsupported "p/c array_index(\"abcdef\",2)"
+	unsupported "p/c (int) array_index(\"abcdef\",2)"
     } else {
 	# We need to up this because this can be really slow on some boards.
 	# (malloc() is called as part of the test).
 	set prev_timeout $timeout
 	set timeout 60
-	gdb_test {p/c array_index("abcdef",2)} " = 99 'c'"
+	gdb_test {p/c (int) array_index("abcdef",2)} " = 99 'c'"
 	set timeout $prev_timeout
     }
-    
+
+    test_call_promotion
+
     # Now, try that we can give names of file-local symbols which happen
     # to be unique, and have it still work
     if [runto middle] then {
diff --git a/gdb/testsuite/gdb.compile/compile.exp b/gdb/testsuite/gdb.compile/compile.exp
index b221870..c23ff6a 100644
--- a/gdb/testsuite/gdb.compile/compile.exp
+++ b/gdb/testsuite/gdb.compile/compile.exp
@@ -296,12 +296,14 @@ gdb_test "p globalvar" " = 77" "expect 77"
 
 # Test reference to minimal_symbol, not (full) symbol.
 
-gdb_test_no_output "compile code globalvar = func_nodebug (75);" \
+gdb_test "compile code globalvar = func_nodebug (75);" \
+    "warning: function has unknown return type; assuming int" \
     "call func_nodebug"
 gdb_test "p globalvar" " = -75" "expect -75"
-gdb_test_no_output \
-  "compile code int (*funcp) (int) = func_nodebug; globalvar = funcp (76);" \
-  "call func_nodebug indirectly"
+gdb_test \
+    "compile code int (*funcp) (int) = func_nodebug; globalvar = funcp (76);" \
+    "warning: function has unknown return type; assuming int" \
+    "call func_nodebug indirectly"
 gdb_test "p globalvar" " = -76" "expect -76"
 
 
diff --git a/gdb/testsuite/gdb.threads/siginfo-threads.exp b/gdb/testsuite/gdb.threads/siginfo-threads.exp
index 328168c..8ee4c36 100644
--- a/gdb/testsuite/gdb.threads/siginfo-threads.exp
+++ b/gdb/testsuite/gdb.threads/siginfo-threads.exp
@@ -40,12 +40,17 @@ gdb_test "handle SIGUSR2 stop print pass" \
 gdb_breakpoint [gdb_get_line_number "break-at-exit"]
 
 set test "get pid"
-gdb_test_multiple "p getpid ()" $test {
+set pid ""
+gdb_test_multiple "p (int) getpid ()" $test {
     -re " = (\[0-9\]+)\r\n$gdb_prompt $" {
 	set pid $expect_out(1,string)
 	pass $test
     }
 }
+if {$pid == ""} {
+    untested "failed to get pid"
+    return
+}
 
 for {set sigcount 0} {$sigcount < 4} {incr sigcount} {
     set test "catch signal $sigcount"
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 045271a..8e58bf9 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -386,6 +386,14 @@ type_to_string (struct type *type)
   return {};
 }
 
+/* See typeprint.h.  */
+
+void
+type_print_unknown_return_type (struct ui_file *stream)
+{
+  fprintf_filtered (stream, _("<unknown return type>"));
+}
+
 /* Print type of EXP, or last thing in value history if EXP == NULL.
    show is passed to type_print.  */
 
@@ -757,4 +765,3 @@ val_print_not_associated (struct ui_file *stream)
 {
   fprintf_filtered (stream, _("<not associated>"));
 }
-
diff --git a/gdb/typeprint.h b/gdb/typeprint.h
index 72da7f4..d4e19e5b 100644
--- a/gdb/typeprint.h
+++ b/gdb/typeprint.h
@@ -74,6 +74,10 @@ void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
 void c_type_print_args (struct type *, struct ui_file *, int, enum language,
 			const struct type_print_options *);
 
+/* Print <unknown return type> to stream STREAM.  */
+
+void type_print_unknown_return_type (struct ui_file *stream);
+
 extern void val_print_not_allocated (struct ui_file *stream);
 
 extern void val_print_not_associated (struct ui_file *stream);
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 985233c..6c765df 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -505,7 +505,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
 	    = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
 	  return value_zero (return_type, VALUE_LVAL (arg1));
 	}
-      return call_function_by_hand (argvec[0], 2 - static_memfuncp,
+      return call_function_by_hand (argvec[0], NULL, 2 - static_memfuncp,
 				    argvec + 1);
     }
   throw_error (NOT_FOUND_ERROR,
@@ -624,7 +624,7 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
 	    = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
 	  return value_zero (return_type, VALUE_LVAL (arg1));
 	}
-      return call_function_by_hand (argvec[0], nargs, argvec + 1);
+      return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1);
     }
   throw_error (NOT_FOUND_ERROR,
                _("member function %s not found"), tstr);
diff --git a/gdb/valops.c b/gdb/valops.c
index f3f5308..66678e5 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -191,7 +191,7 @@ value_allocate_space_in_inferior (int len)
   struct value *blocklen;
 
   blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len);
-  val = call_function_by_hand (val, 1, &blocklen);
+  val = call_function_by_hand (val, NULL, 1, &blocklen);
   if (value_logical_not (val))
     {
       if (!target_has_execution)
