Bram Moolenaar wrote:

> Dominique Pelle wrote:
>
>> I've compiled Vim-7.3e (2539:9397d2d76340) with the clang compiler on Linux.
>>
>> All tests pass.  However, I see something wrong when doing:
>>
>>   $ vim -c 'saveas! /tmp/foo'
>>
>> Vim prints:
>>
>>   "/tmp/foo" [New File] 0 lines, 585937717901131776 characters written
>>
>> Obviously the number of characters written is not correct (should be 0).
>>
>> Valgrind also reports:
>>
>> ==18757== Conditional jump or move depends on uninitialised value(s)
>> ==18757==    at 0x496935B: _itoa (_itoa.c:442)
>> ==18757==    by 0x496CC85: vfprintf (vfprintf.c:1613)
>> ==18757==    by 0x498B70B: vsprintf (iovsprintf.c:43)
>> ==18757==    by 0x49741DA: sprintf (sprintf.c:34)
>> ==18757==    by 0x80D850C: msg_add_lines (fileio.c:5246)
>> ==18757==    by 0x80DB5EC: buf_write (fileio.c:4885)
>> ==18757==    by 0x80A24B0: do_write (ex_cmds.c:2706)
>> ==18757==    by 0x80A256B: ex_write (ex_cmds.c:2519)
>> ==18757==    by 0x80BA4D8: do_one_cmd (ex_docmd.c:2656)
>> ==18757==    by 0x80B739F: do_cmdline (ex_docmd.c:1122)
>> ==18757==    by 0x80B7F7E: do_cmdline_cmd (ex_docmd.c:728)
>> ==18757==    by 0x8100D64: exe_commands (main.c:2807)
>> ==18757==    by 0x80FE1FC: main (main.c:885)
>> ==18757==  Uninitialised value was created by a stack allocation
>> ==18757==    at 0x80D8494: msg_add_lines (fileio.c:5238)
>>
>> And while compiling, I see this warning which points to the same problem:
>>
>> fileio.c:5248:13: warning: conversion specifies type 'long long' but
>> the argument has type 'off_t' (aka 'long')
>>       [-Wformat]
>>                 "%ldL, %lldC", lnum, nchars
>>                        ~~~^~         ~~~~~~
>>
>> The number of characters is printed in fileio.c:5248:
>>
>>  5233     void
>>  5234 msg_add_lines(insert_space, lnum, nchars)
>>  5235     int     insert_space;
>>  5236     long    lnum;
>>  5237     off_t   nchars;
>>  5238 {
>>  5239     char_u  *p;
>>  5240
>>  5241     p = IObuff + STRLEN(IObuff);
>>  5242
>>  5243     if (insert_space)
>>  5244         *p++ = ' ';
>>  5245     if (shortmess(SHM_LINES))
>>  5246         sprintf((char *)p,
>>  5247 #ifdef LONG_LONG_OFF_T
>> !5248                 "%ldL, %lldC", lnum, nchars
>>  5249 #else
>>  5250                 /* Explicit typecast avoids warning on Mac OS X 10.6 */
>>  5251                 "%ldL, %ldC", lnum, (long)nchars
>>  5252 #endif
>>  5253                 );
>>
>> Adding debug printf, I see that we have with clang:
>>  * sizeof(off_t) == 4
>
> That seems to be wrong.
>
>>  * sizeof(long long) == 8
>>
>> Yet in src/auto/config.h, I see this (which is thus incorrect):
>>
>>   /* Defined to the size of off_t */
>>   #define SIZEOF_OFF_T 8
>>
>> The configure script is getting SIZEOF_OFF_T incorrectly when using
>> clang compiler.
>>
>> In src/auto/config.log, I see:
>>
>> configure:11536: checking size of off_t
>> configure:11541: clang -o conftest -g -O2   -L/usr/local/lib
>> conftest.c -lm -lncurses -lnsl  -lselinux -lacl -lattr -lgpm >&5
>> configure:11541: $? = 0
>> configure:11541: ./conftest
>> configure:11541: $? = 0
>> configure:11556: result: 8
>>
>> Why do we compute size of 'off_t' in configure script, rather than
>> simply use sizeof(off_t)?
>
> That doesn't always work in #ifdef.
>
> Perhaps the AC_SYS_LARGEFILE macro interferes?  If it's not used
> properly the sizeof(off_t) may differ depending on some flags.
>
>
>> PS:  You can install the clang compiler on Ubuntu with "sudo apt-get
>> install clang".
>> I had to add #include <wchar.h> in vim.h to be able to compile Vim
>> successfully with clang.
>
> Why?  Hmm, perhaps it's needed in charset.c, because towlower and
> towupper are used there.  I'll do that.  Does it work now?


I now understand why sizeof(off_t) was wrong. Vim did not compile
with clang and I quickly added #include <wchar.h> to make it compile
I included it *before* #include "auto/config.h" in Vim.h which was a
mistake since auto/config.h #defines _FILE_OFFSET_BITS 64.
Including <wchar.h> after "auto/config.h" makes sizeof(off_t) == 8

Anyway, your recent changeset 2540:8a156630208b makes it compile
and run without problem now with clang.

I think #include <wchar.h> was needed to compile because with clang,
I see this in auto/config.h:

 /* #undef HAVE_WCTYPE_H */

Whereas with gcc, I see this:

#define HAVE_WCTYPE_H 1

Somehow, wctype.h header file does not compile!?  (but that's not Vim's fault).

Another remark when using clang.  I see several of this kind of compilation
warnings which are easy to fix (see attached patch):

ex_cmds.c:2083:18: warning: format string is not a string literal
(potentially insecure) [-Wformat-security]
        fprintf(fp_out, _("# You may edit it if you're careful!\n\n"));
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Regards
-- Dominique
.

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff -r 20e83abf88b1 src/buffer.c
--- a/src/buffer.c	Thu Aug 12 22:19:09 2010 +0200
+++ b/src/buffer.c	Thu Aug 12 22:59:49 2010 +0200
@@ -5082,7 +5082,7 @@
     set_last_cursor(curwin);
 #endif
 
-    fprintf(fp, _("\n# Buffer list:\n"));
+    fputs(_("\n# Buffer list:\n"), fp);
     for (buf = firstbuf; buf != NULL ; buf = buf->b_next)
     {
 	if (buf->b_fname == NULL
diff -r 20e83abf88b1 src/ex_cmds.c
--- a/src/ex_cmds.c	Thu Aug 12 22:19:09 2010 +0200
+++ b/src/ex_cmds.c	Thu Aug 12 22:59:49 2010 +0200
@@ -2080,9 +2080,9 @@
 	/* Write the info: */
 	fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"),
 							  VIM_VERSION_MEDIUM);
-	fprintf(fp_out, _("# You may edit it if you're careful!\n\n"));
+	fputs(_("# You may edit it if you're careful!\n\n"), fp_out);
 #ifdef FEAT_MBYTE
-	fprintf(fp_out, _("# Value of 'encoding' when this file was written\n"));
+	fputs(_("# Value of 'encoding' when this file was written\n"), fp_out);
 	fprintf(fp_out, "*encoding=%s\n\n", p_enc);
 #endif
 	write_viminfo_search_pattern(fp_out);
@@ -5422,7 +5422,7 @@
 {
     if (get_viminfo_parameter('/') != 0 && old_sub != NULL)
     {
-	fprintf(fp, _("\n# Last Substitute String:\n$"));
+	fputs(_("\n# Last Substitute String:\n$"), fp);
 	viminfo_writestring(fp, old_sub);
     }
 }
diff -r 20e83abf88b1 src/mark.c
--- a/src/mark.c	Thu Aug 12 22:19:09 2010 +0200
+++ b/src/mark.c	Thu Aug 12 22:59:49 2010 +0200
@@ -1434,7 +1434,7 @@
     if (get_viminfo_parameter('f') == 0)
 	return;
 
-    fprintf(fp, _("\n# File marks:\n"));
+    fputs(_("\n# File marks:\n"), fp);
 
     /*
      * Find a mark that is the same file and position as the cursor.
@@ -1469,7 +1469,7 @@
 
 #ifdef FEAT_JUMPLIST
     /* Write the jumplist with -' */
-    fprintf(fp, _("\n# Jumplist (newest first):\n"));
+    fputs(_("\n# Jumplist (newest first):\n"), fp);
     setpcmark();	/* add current cursor position */
     cleanup_jumplist();
     for (fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
@@ -1570,7 +1570,7 @@
 	set_last_cursor(curwin);
 #endif
 
-    fprintf(fp_out, _("\n# History of marks within files (newest to oldest):\n"));
+    fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out);
     count = 0;
     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
     {
diff -r 20e83abf88b1 src/misc2.c
--- a/src/misc2.c	Thu Aug 12 22:19:09 2010 +0200
+++ b/src/misc2.c	Thu Aug 12 22:59:49 2010 +0200
@@ -784,7 +784,7 @@
     {
 	printf("\r\n");
 	if (mem_frees[i] > mem_allocs[i])
-	    printf(_("ERROR: "));
+	    puts(_("ERROR: "));
 	printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]);
     }
 
@@ -827,7 +827,7 @@
 {
     char_u *p;
 
-    p = (lalloc((long_u)size, TRUE));
+    p = lalloc((long_u)size, TRUE);
     if (p != NULL)
 	(void)vim_memset(p, 0, (size_t)size);
     return p;
@@ -3802,7 +3802,7 @@
 /*
  * Prepare for initializing encryption.  If already doing encryption then save
  * the state.
- * Must always be called symmetrycally with crypt_pop_state().
+ * Must always be called symmetrically with crypt_pop_state().
  */
     void
 crypt_push_state()
@@ -3828,7 +3828,7 @@
 /*
  * End encryption.  If doing encryption before crypt_push_state() then restore
  * the saved state.
- * Must always be called symmetrycally with crypt_push_state().
+ * Must always be called symmetrically with crypt_push_state().
  */
     void
 crypt_pop_state()

Raspunde prin e-mail lui