1/ According to ":help functions", function cursor() is meant
to return a value of type 'Number'.  But function cursor()
(f_cursor() in eval.c) does not return anything.  So doing
":echo cursor(1,1)" prints an uninitialized value and valgrind
reports the following error:

==20458== Use of uninitialised value of size 4
==20458==    at 0x4F9A7F6: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==20458==    by 0x4F9E398: vfprintf (in /lib/tls/i686/cmov/libc-2.8.90.so)
==20458==    by 0x4FBE02B: vsprintf (in /lib/tls/i686/cmov/libc-2.8.90.so)
==20458==    by 0x4FA5D3A: sprintf (in /lib/tls/i686/cmov/libc-2.8.90.so)
==20458==    by 0x80932DE: get_tv_string_buf_chk (stdio2.h:34)
==20458==    by 0x809334A: get_tv_string_buf (eval.c:18752)
==20458==    by 0x8094A71: echo_string (eval.c:7290)
==20458==    by 0x80AD37E: ex_echo (eval.c:19507)
==20458==    by 0x80CCA86: do_one_cmd (ex_docmd.c:2622)
==20458==    by 0x80CAD92: do_cmdline (ex_docmd.c:1096)
==20458==    by 0x8142E0F: nv_colon (normal.c:5218)
==20458==    by 0x8144EAF: normal_cmd (normal.c:1189)
==20458==    by 0x81044D6: main_loop (main.c:1180)
==20458==    by 0x81078B2: main (main.c:939)

Attached patch makes cursor() return 0 if success, -1 if failure.

2/ Function setpos() returns 'none' according to ":help functions"
but looking at the code, it actually returns 0 in case of success
and -1 in case of error.

Patch fixes documentation.

3/ Function complete() returns a String according to ":help functions"
but it may return something initialized in case of error.
:echo complete('', '') for example prints something uninitialized
and valgrind also reports an error.

Patch makes it return an empty string in case of error.

4/ Function feedkeys() always returns 0 according to ":help feedkeys()"
but it may return something uninitialized when doing:

":sandbox echo feedkeys('')

Attached patch makes it always return 0 as stated in documentation.

5/ The following functions do not return anything:

    clearmatches()
    garbagecollect()
    winrestview()

So doing ":echo garbagecollect()" prints something uninitialized
and valgrind reports uninitialized memory access.

Making them return something is better I think. So
":echo garbagecollect()" prints something deterministic.
Attached patch makes them always return 0, just like what
is already done for "feedkeys()".

Regards
-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Index: src/eval.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/eval.c,v
retrieving revision 1.280
diff -c -r1.280 eval.c
*** src/eval.c	4 Feb 2009 15:27:06 -0000	1.280
--- src/eval.c	21 Mar 2009 20:41:21 -0000
***************
*** 1285,1291 ****
--- 1285,1293 ----
      typval_T	tv;
      char_u	*retval;
      garray_T	ga;
+ #ifdef FEAT_FLOAT
      char_u	numbuf[NUMBUFLEN];
+ #endif
  
      if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
  	retval = NULL;
***************
*** 8859,8864 ****
--- 8861,8867 ----
      typval_T	*argvars;
      typval_T	*rettv;
  {
+     rettv->vval.v_number = 0;
  #ifdef FEAT_SEARCH_EXTRA
      clear_matches(curwin);
  #endif
***************
*** 8929,8934 ****
--- 8932,8940 ----
  {
      int	    startcol;
  
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = NULL;
+ 
      if ((State & INSERT) == 0)
      {
  	EMSG(_("E785: complete() can only be used in Insert mode"));
***************
*** 9189,9195 ****
  /*
   * "cursor(lnum, col)" function
   *
!  * Moves the cursor to the specified line and column
   */
  /*ARGSUSED*/
      static void
--- 9195,9202 ----
  /*
   * "cursor(lnum, col)" function
   *
!  * Moves the cursor to the specified line and column.
!  * Returns 0 when the position could be set, -1 otherwise.
   */
  /*ARGSUSED*/
      static void
***************
*** 9202,9207 ****
--- 9209,9215 ----
      long	coladd = 0;
  #endif
  
+     rettv->vval.v_number = -1;
      if (argvars[1].v_type == VAR_UNKNOWN)
      {
  	pos_T	    pos;
***************
*** 9246,9251 ****
--- 9254,9260 ----
  #endif
  
      curwin->w_set_curswant = TRUE;
+     rettv->vval.v_number = 0;
  }
  
  /*
***************
*** 9727,9739 ****
      int		typed = FALSE;
      char_u	*keys_esc;
  
      /* This is not allowed in the sandbox.  If the commands would still be
       * executed in the sandbox it would be OK, but it probably happens later,
       * when "sandbox" is no longer set. */
      if (check_secure())
  	return;
  
-     rettv->vval.v_number = 0;
      keys = get_tv_string(&argvars[0]);
      if (*keys != NUL)
      {
--- 9736,9749 ----
      int		typed = FALSE;
      char_u	*keys_esc;
  
+     rettv->vval.v_number = 0;
+ 
      /* This is not allowed in the sandbox.  If the commands would still be
       * executed in the sandbox it would be OK, but it probably happens later,
       * when "sandbox" is no longer set. */
      if (check_secure())
  	return;
  
      keys = get_tv_string(&argvars[0]);
      if (*keys != NUL)
      {
***************
*** 10385,10390 ****
--- 10395,10401 ----
      /* This is postponed until we are back at the toplevel, because we may be
       * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
      want_garbage_collect = TRUE;
+     rettv->vval.v_number = 0;
  
      if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
  	garbage_collect_at_exit = TRUE;
***************
*** 17529,17534 ****
--- 17540,17546 ----
  {
      dict_T	*dict;
  
+     rettv->vval.v_number = 0;
      if (argvars[0].v_type != VAR_DICT
  	    || (dict = argvars[0].vval.v_dict) == NULL)
  	EMSG(_(e_invarg));
*** ../vim-runtime/doc/eval.txt	2009-01-14 21:14:54.000000000 +0100
--- runtime/doc/eval.txt	2009-03-21 21:34:46.000000000 +0100
***************
*** 1681,1687 ****
  changenr()			Number	current change number
  char2nr( {expr})		Number	ASCII value of first char in {expr}
  cindent( {lnum})		Number	C indent for line {lnum}
! clearmatches()			None	clear all matches
  col( {expr})			Number	column nr of cursor or mark
  complete({startcol}, {matches})	String	set Insert mode completion
  complete_add( {expr})		Number	add completion match
--- 1681,1687 ----
  changenr()			Number	current change number
  char2nr( {expr})		Number	ASCII value of first char in {expr}
  cindent( {lnum})		Number	C indent for line {lnum}
! clearmatches()			Number	clear all matches
  col( {expr})			Number	column nr of cursor or mark
  complete({startcol}, {matches})	String	set Insert mode completion
  complete_add( {expr})		Number	add completion match
***************
*** 1731,1737 ****
  foldtextresult( {lnum})		String	text for closed fold at {lnum}
  foreground( )			Number	bring the Vim window to the foreground
  function( {name})		Funcref reference to function {name}
! garbagecollect( [at_exit])	none	free memory, breaking cyclic references
  get( {list}, {idx} [, {def}])	any	get item {idx} from {list} or {def}
  get( {dict}, {key} [, {def}])	any	get item {key} from {dict} or {def}
  getbufline( {expr}, {lnum} [, {end}])
--- 1731,1737 ----
  foldtextresult( {lnum})		String	text for closed fold at {lnum}
  foreground( )			Number	bring the Vim window to the foreground
  function( {name})		Funcref reference to function {name}
! garbagecollect( [at_exit])	Number	free memory, breaking cyclic references
  get( {list}, {idx} [, {def}])	any	get item {idx} from {list} or {def}
  get( {dict}, {key} [, {def}])	any	get item {key} from {dict} or {def}
  getbufline( {expr}, {lnum} [, {end}])
***************
*** 1871,1877 ****
  setloclist( {nr}, {list}[, {action}])
  				Number	modify location list using {list}
  setmatches( {list})		Number	restore a list of matches
! setpos( {expr}, {list})		none	set the {expr} position to {list}
  setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
  setreg( {n}, {v}[, {opt}])	Number	set register to value and type
  settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
--- 1871,1877 ----
  setloclist( {nr}, {list}[, {action}])
  				Number	modify location list using {list}
  setmatches( {list})		Number	restore a list of matches
! setpos( {expr}, {list})		Number	set the {expr} position to {list}
  setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
  setreg( {n}, {v}[, {opt}])	Number	set register to value and type
  settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
***************
*** 1933,1939 ****
  winline()			Number	window line of the cursor
  winnr( [{expr}])		Number	number of current window
  winrestcmd()			String	returns command to restore window sizes
! winrestview({dict})		None	restore view of current window
  winsaveview()			Dict	save view of current window
  winwidth( {nr})			Number	width of window {nr}
  writefile({list}, {fname} [, {binary}])
--- 1933,1939 ----
  winline()			Number	window line of the cursor
  winnr( [{expr}])		Number	number of current window
  winrestcmd()			String	returns command to restore window sizes
! winrestview({dict})		Number	restore view of current window
  winsaveview()			Dict	save view of current window
  winwidth( {nr})			Number	width of window {nr}
  writefile({list}, {fname} [, {binary}])
***************
*** 2202,2207 ****
--- 2202,2208 ----
  clearmatches()						*clearmatches()*
  		Clears all matches previously defined by |matchadd()| and the
  		|:match| commands.
+ 		Return value is always 0.
  
  							*col()*
  col({expr})	The result is a Number, which is the byte index of the column
***************
*** 2249,2255 ****
  		{matches} must be a |List|.  Each |List| item is one match.
  		See |complete-items| for the kind of items that are possible.
  		Note that the after calling this function you need to avoid
! 		inserting anything that would completion to stop.
  		The match can be selected with CTRL-N and CTRL-P as usual with
  		Insert mode completion.  The popup menu will appear if
  		specified, see |ins-completion-menu|.
--- 2250,2256 ----
  		{matches} must be a |List|.  Each |List| item is one match.
  		See |complete-items| for the kind of items that are possible.
  		Note that the after calling this function you need to avoid
! 		inserting anything that would cause completion to stop.
  		The match can be selected with CTRL-N and CTRL-P as usual with
  		Insert mode completion.  The popup menu will appear if
  		specified, see |ins-completion-menu|.
***************
*** 2418,2423 ****
--- 2419,2425 ----
  		When 'virtualedit' is used {off} specifies the offset in
  		screen columns from the start of the character.  E.g., a
  		position within a <Tab> or after the last character.
+ 		Returns 0 when the position could be set, -1 otherwise.
  
  
  deepcopy({expr}[, {noref}])				*deepcopy()* *E698*
***************
*** 2939,2944 ****
--- 2941,2947 ----
  		When the optional "at_exit" argument is one, garbage
  		collection will also be done when exiting Vim, if it wasn't
  		done before.  This is useful when checking for memory leaks.
+ 		Return value is always 0.
  
  get({list}, {idx} [, {default}])			*get()*
  		Get item {idx} from |List| {list}.  When this item is not
***************
*** 5696,5701 ****
--- 5699,5705 ----
  		the view of the current window.
  		If you have changed the values the result is unpredictable.
  		If the window size changed the result won't be the same.
+ 		Return value is always 0.
  
  							*winsaveview()*
  winsaveview()	Returns a |Dictionary| that contains information to restore

Raspunde prin e-mail lui