]> granicus.if.org Git - vim/commitdiff
patch 8.2.0296: mixing up "long long" and __int64 may cause problems v8.2.0296
authorBram Moolenaar <Bram@vim.org>
Sat, 22 Feb 2020 13:27:04 +0000 (14:27 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 22 Feb 2020 13:27:04 +0000 (14:27 +0100)
Problem:    Mixing up "long long" and __int64 may cause problems. (John
            Marriott)
Solution:   Pass varnumber_T to vim_snprintf().  Add v:numbersize.

12 files changed:
runtime/doc/eval.txt
runtime/doc/various.txt
src/eval.c
src/evalvars.c
src/fileio.c
src/json.c
src/message.c
src/ops.c
src/structs.h
src/testdir/test_eval_stuff.vim
src/version.c
src/vim.h

index 62a73048b70a0f74f99f308060f5a72facf77612..4349e76ef5ddaa61882e61bfa42b6130fbfce9ab 100644 (file)
@@ -48,8 +48,7 @@ There are ten types of variables:
 
                                                        *Number* *Integer*
 Number         A 32 or 64 bit signed number.  |expr-number|
-               64-bit Numbers are available only when compiled with the
-               |+num64| feature.
+               The number of bits is available in |v:numbersize|.
                Examples:  -123  0x10  0177  0b1011
 
 Float          A floating point number. |floating-point-format| *Float*
@@ -1991,6 +1990,10 @@ v:null           An empty String. Used to put "null" in JSON.  See
                That is so that eval() can parse the string back to the same
                value.  Read-only.
 
+                                       *v:numbersize* *numbersize-variable*
+v:numbersize   Number of bits in a Number.  This is normally 64, but on some
+               systems it my be 32.
+
                                        *v:oldfiles* *oldfiles-variable*
 v:oldfiles     List of file names that is loaded from the |viminfo| file on
                startup.  These are the files that Vim remembers marks for.
index 85e18b3f621e2cf84e8d26888f5f07f80ea45292..547ca762afb6321c8ce9cda7928023ce8b5105ea 100644 (file)
@@ -1,4 +1,4 @@
-*various.txt*   For Vim version 8.2.  Last change: 2019 Dec 07
+*various.txt*   For Vim version 8.2.  Last change: 2020 Feb 22
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -407,7 +407,9 @@ N  *+multi_lang*    non-English language support |multi-lang|
 m  *+mzscheme*         Mzscheme interface |mzscheme|
 m  *+mzscheme/dyn*     Mzscheme interface |mzscheme-dynamic| |/dyn|
 m  *+netbeans_intg*    |netbeans|
-   *+num64*            64-bit Number support |Number|
+   *+num64*            64-bit Number support |Number| 
+                       Always enabled since 8.2.0271, use v:numbersize to
+                       check the actual size of a Number.
 m  *+ole*              Win32 GUI only: |ole-interface|
 N  *+packages*         Loading |packages|
 N  *+path_extra*       Up/downwards search in 'path' and 'tags'
index f01724389dc1666df267b948e0715094c445e126..dcaf2f02cc768ffb5588474ce7e82b5c161c14ba 100644 (file)
@@ -5665,7 +5665,7 @@ tv_get_string_buf_chk(typval_T *varp, char_u *buf)
     {
        case VAR_NUMBER:
            vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
-                                           (long_long_T)varp->vval.v_number);
+                                           (varnumber_T)varp->vval.v_number);
            return buf;
        case VAR_FUNC:
        case VAR_PARTIAL:
index 2bbc3553b684c595091b4ed4f09e3c5528efc66a..25d23c8606973304c48e3a3e65f267052b81f9ad 100644 (file)
@@ -120,8 +120,9 @@ static struct vimvar
     {VV_NAME("errors",          VAR_LIST), 0},
     {VV_NAME("false",           VAR_BOOL), VV_RO},
     {VV_NAME("true",            VAR_BOOL), VV_RO},
-    {VV_NAME("null",            VAR_SPECIAL), VV_RO},
     {VV_NAME("none",            VAR_SPECIAL), VV_RO},
+    {VV_NAME("null",            VAR_SPECIAL), VV_RO},
+    {VV_NAME("numbersize",      VAR_NUMBER), VV_RO},
     {VV_NAME("vim_did_enter",   VAR_NUMBER), VV_RO},
     {VV_NAME("testing",                 VAR_NUMBER), 0},
     {VV_NAME("t_number",        VAR_NUMBER), VV_RO},
@@ -229,6 +230,7 @@ evalvars_init(void)
     set_vim_var_nr(VV_TRUE, VVAL_TRUE);
     set_vim_var_nr(VV_NONE, VVAL_NONE);
     set_vim_var_nr(VV_NULL, VVAL_NULL);
+    set_vim_var_nr(VV_NUMBERSIZE, sizeof(varnumber_T) * 8);
 
     set_vim_var_nr(VV_TYPE_NUMBER,  VAR_TYPE_NUMBER);
     set_vim_var_nr(VV_TYPE_STRING,  VAR_TYPE_STRING);
index 575efafd246a12f04316c69ade0a99f9403e37a4..e80009fbe1ef7dba19501edb9503745486ce1d9f 100644 (file)
@@ -3016,14 +3016,14 @@ msg_add_lines(
        *p++ = ' ';
     if (shortmess(SHM_LINES))
        vim_snprintf((char *)p, IOSIZE - (p - IObuff),
-               "%ldL, %lldC", lnum, (long_long_T)nchars);
+               "%ldL, %lldC", lnum, (varnumber_T)nchars);
     else
     {
        sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
        p += STRLEN(p);
        vim_snprintf((char *)p, IOSIZE - (p - IObuff),
                NGETTEXT("%lld character", "%lld characters", nchars),
-               (long_long_T)nchars);
+               (varnumber_T)nchars);
     }
 }
 
index bfa5d50ddbd3787a76e042fc658edca7ae0725f7..770e144398754f13dc357c85f1f8a9dd74778c9c 100644 (file)
@@ -215,7 +215,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
 
        case VAR_NUMBER:
            vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld",
-                                             (long_long_T)val->vval.v_number);
+                                             (varnumber_T)val->vval.v_number);
            ga_concat(gap, numbuf);
            break;
 
index 9ab0eaefeb7f3859d695abbbad3fd4e547b33ee4..c2855fb34b0f5852591b700cca5eb99d10720c50 100644 (file)
@@ -4129,7 +4129,7 @@ infinity_str(int positive,
  * Limited support for floating point was added: 'f', 'F', 'e', 'E', 'g', 'G'.
  *
  * Length modifiers 'h' (short int) and 'l' (long int) and 'll' (long long int)
- * are supported.
+ * are supported.  NOTE: for 'll' the argument is varnumber_T or uvarnumber_T.
  *
  * The locale is not used, the string is used as a byte string.  This is only
  * relevant for double-byte encodings where the second byte may be '%'.
@@ -4371,7 +4371,7 @@ vim_vsnprintf_typval(
                p++;
                if (length_modifier == 'l' && *p == 'l')
                {
-                   // double l = long long
+                   // double l = __int64 / varnumber_T
                    length_modifier = 'L';
                    p++;
                }
@@ -4501,20 +4501,20 @@ vim_vsnprintf_typval(
                    // argument is never negative)
                    int arg_sign = 0;
 
-                   // only defined for length modifier h, or for no
-                   // length modifiers
+                   // only set for length modifier h, or for no length
+                   // modifiers
                    int int_arg = 0;
                    unsigned int uint_arg = 0;
 
-                   // only defined for length modifier l
+                   // only set for length modifier l
                    long int long_arg = 0;
                    unsigned long int ulong_arg = 0;
 
-                   // only defined for length modifier ll
+                   // only set for length modifier ll
                    varnumber_T llong_arg = 0;
                    uvarnumber_T ullong_arg = 0;
 
-                   // only defined for b conversion
+                   // only set for b conversion
                    uvarnumber_T bin_arg = 0;
 
                    // pointer argument value -only defined for p
index 6a6abf7837b9c9e223fa3ccf90cc649bd89ac56a..d4b842c6014463d5bbf951d5f50ba324aa99b5c5 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -3364,17 +3364,13 @@ do_addsub(
            buf2[i] = '\0';
        }
        else if (pre == 0)
-           vim_snprintf((char *)buf2, NUMBUFLEN, "%llu",
-                                                       (long_long_u_T)n);
+           vim_snprintf((char *)buf2, NUMBUFLEN, "%llu", (uvarnumber_T)n);
        else if (pre == '0')
-           vim_snprintf((char *)buf2, NUMBUFLEN, "%llo",
-                                                       (long_long_u_T)n);
+           vim_snprintf((char *)buf2, NUMBUFLEN, "%llo", (uvarnumber_T)n);
        else if (pre && hexupper)
-           vim_snprintf((char *)buf2, NUMBUFLEN, "%llX",
-                                                       (long_long_u_T)n);
+           vim_snprintf((char *)buf2, NUMBUFLEN, "%llX", (uvarnumber_T)n);
        else
-           vim_snprintf((char *)buf2, NUMBUFLEN, "%llx",
-                                                       (long_long_u_T)n);
+           vim_snprintf((char *)buf2, NUMBUFLEN, "%llx", (uvarnumber_T)n);
        length -= (int)STRLEN(buf2);
 
        /*
@@ -3773,21 +3769,21 @@ cursor_pos_info(dict_T *dict)
                            _("Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"),
                            buf1, line_count_selected,
                            (long)curbuf->b_ml.ml_line_count,
-                           (long_long_T)word_count_cursor,
-                           (long_long_T)word_count,
-                           (long_long_T)byte_count_cursor,
-                           (long_long_T)byte_count);
+                           (varnumber_T)word_count_cursor,
+                           (varnumber_T)word_count,
+                           (varnumber_T)byte_count_cursor,
+                           (varnumber_T)byte_count);
                else
                    vim_snprintf((char *)IObuff, IOSIZE,
                            _("Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of %lld Bytes"),
                            buf1, line_count_selected,
                            (long)curbuf->b_ml.ml_line_count,
-                           (long_long_T)word_count_cursor,
-                           (long_long_T)word_count,
-                           (long_long_T)char_count_cursor,
-                           (long_long_T)char_count,
-                           (long_long_T)byte_count_cursor,
-                           (long_long_T)byte_count);
+                           (varnumber_T)word_count_cursor,
+                           (varnumber_T)word_count,
+                           (varnumber_T)char_count_cursor,
+                           (varnumber_T)char_count,
+                           (varnumber_T)byte_count_cursor,
+                           (varnumber_T)byte_count);
            }
            else
            {
@@ -3805,17 +3801,17 @@ cursor_pos_info(dict_T *dict)
                        (char *)buf1, (char *)buf2,
                        (long)curwin->w_cursor.lnum,
                        (long)curbuf->b_ml.ml_line_count,
-                       (long_long_T)word_count_cursor, (long_long_T)word_count,
-                       (long_long_T)byte_count_cursor, (long_long_T)byte_count);
+                       (varnumber_T)word_count_cursor, (varnumber_T)word_count,
+                       (varnumber_T)byte_count_cursor, (varnumber_T)byte_count);
                else
                    vim_snprintf((char *)IObuff, IOSIZE,
                        _("Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte %lld of %lld"),
                        (char *)buf1, (char *)buf2,
                        (long)curwin->w_cursor.lnum,
                        (long)curbuf->b_ml.ml_line_count,
-                       (long_long_T)word_count_cursor, (long_long_T)word_count,
-                       (long_long_T)char_count_cursor, (long_long_T)char_count,
-                       (long_long_T)byte_count_cursor, (long_long_T)byte_count);
+                       (varnumber_T)word_count_cursor, (varnumber_T)word_count,
+                       (varnumber_T)char_count_cursor, (varnumber_T)char_count,
+                       (varnumber_T)byte_count_cursor, (varnumber_T)byte_count);
            }
        }
 
@@ -3825,7 +3821,7 @@ cursor_pos_info(dict_T *dict)
            size_t len = STRLEN(IObuff);
 
            vim_snprintf((char *)IObuff + len, IOSIZE - len,
-                                _("(+%lld for BOM)"), (long_long_T)bom_count);
+                                _("(+%lld for BOM)"), (varnumber_T)bom_count);
        }
        if (dict == NULL)
        {
index 823dfda3cafdfcd5086829255e612cf02262a151..4b70641711165b4e713051c358a4af7df5a26a21 100644 (file)
@@ -1248,30 +1248,40 @@ typedef long_u hash_T;          // Type for hi_hash
 // Use 64-bit Number.
 #ifdef MSWIN
 # ifdef PROTO
-typedef long               varnumber_T;
-typedef unsigned long      uvarnumber_T;
-#  define VARNUM_MIN       LONG_MIN
-#  define VARNUM_MAX       LONG_MAX
-#  define UVARNUM_MAX      ULONG_MAX
+   // workaround for cproto that doesn't recognize __int64
+   typedef long                        varnumber_T;
+   typedef unsigned long       uvarnumber_T;
+#  define VARNUM_MIN           LONG_MIN
+#  define VARNUM_MAX           LONG_MAX
+#  define UVARNUM_MAX          ULONG_MAX
 # else
-typedef __int64                    varnumber_T;
-typedef unsigned __int64    uvarnumber_T;
-#  define VARNUM_MIN       _I64_MIN
-#  define VARNUM_MAX       _I64_MAX
-#  define UVARNUM_MAX      _UI64_MAX
+   typedef __int64             varnumber_T;
+   typedef unsigned __int64    uvarnumber_T;
+#  define VARNUM_MIN           _I64_MIN
+#  define VARNUM_MAX           _I64_MAX
+#  define UVARNUM_MAX          _UI64_MAX
+# endif
+#elif defined(HAVE_NO_LONG_LONG)
+# if defined(HAVE_STDINT_H)
+   typedef int64_t             varnumber_T;
+   typedef uint64_t            uvarnumber_T;
+#  define VARNUM_MIN           INT64_MIN
+#  define VARNUM_MAX           INT64_MAX
+#  define UVARNUM_MAX          UINT64_MAX
+# else
+   // this may cause trouble for code that depends on 64 bit ints
+   typedef long                        varnumber_T;
+   typedef unsigned long       uvarnumber_T;
+#  define VARNUM_MIN           LONG_MIN
+#  define VARNUM_MAX           LONG_MAX
+#  define UVARNUM_MAX          ULONG_MAX
 # endif
-#elif defined(HAVE_STDINT_H)
-typedef int64_t                    varnumber_T;
-typedef uint64_t           uvarnumber_T;
-# define VARNUM_MIN        INT64_MIN
-# define VARNUM_MAX        INT64_MAX
-# define UVARNUM_MAX       UINT64_MAX
 #else
-typedef long               varnumber_T;
-typedef unsigned long      uvarnumber_T;
-# define VARNUM_MIN        LONG_MIN
-# define VARNUM_MAX        LONG_MAX
-# define UVARNUM_MAX       ULONG_MAX
+  typedef long long            varnumber_T;
+  typedef unsigned long long   uvarnumber_T;
+# define VARNUM_MIN            LLONG_MIN
+# define VARNUM_MAX            LLONG_MAX
+# define UVARNUM_MAX           ULLONG_MAX
 #endif
 
 typedef double float_T;
index 53627557a05d3cc135fb0eb65f816baa249442d3..b691192b4b84c594add2f136d5bc7cb9e0863f76 100644 (file)
@@ -228,3 +228,9 @@ func Test_excute_null()
     call assert_fails('execute test_null_channel()', 'E908:')
   endif
 endfunc
+
+func Test_numbersize()
+  " This will fail on systems without 64 bit int support or when not configured
+  " correctly.
+  call assert_equal(64, v:numbersize)
+endfunc
index 4b186bfee08c29adc671830eb600579b29fc5c7a..5eb0d05c980d1da2ce94692001ff810b0dce2c0d 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    296,
 /**/
     295,
 /**/
index 62cc46cd0329069106bed5675eec638af5852392..4d3ac36633eacb512e929858eaab318f9aced5cc 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -328,16 +328,6 @@ typedef unsigned char      char_u;
 typedef unsigned short short_u;
 typedef unsigned int   int_u;
 
-// Older systems do not have support for long long
-// use a typedef instead of hard-coded long long
-#ifdef HAVE_NO_LONG_LONG
- typedef long long_long_T;
- typedef long unsigned long_long_u_T;
-#else
- typedef long long long_long_T;
- typedef long long unsigned long_long_u_T;
-#endif
-
 // Make sure long_u is big enough to hold a pointer.
 // On Win64, longs are 32 bits and pointers are 64 bits.
 // For printf() and scanf(), we need to take care of long_u specifically.
@@ -1975,31 +1965,32 @@ typedef int sock_T;
 #define VV_ERRORS      67
 #define VV_FALSE       68
 #define VV_TRUE                69
-#define VV_NULL                70
-#define VV_NONE                71
-#define VV_VIM_DID_ENTER 72
-#define VV_TESTING     73
-#define VV_TYPE_NUMBER 74
-#define VV_TYPE_STRING 75
-#define VV_TYPE_FUNC   76
-#define VV_TYPE_LIST   77
-#define VV_TYPE_DICT   78
-#define VV_TYPE_FLOAT  79
-#define VV_TYPE_BOOL   80
-#define VV_TYPE_NONE   81
-#define VV_TYPE_JOB    82
-#define VV_TYPE_CHANNEL        83
-#define VV_TYPE_BLOB   84
-#define VV_TERMRFGRESP 85
-#define VV_TERMRBGRESP 86
-#define VV_TERMU7RESP  87
-#define VV_TERMSTYLERESP 88
-#define VV_TERMBLINKRESP 89
-#define VV_EVENT       90
-#define VV_VERSIONLONG 91
-#define VV_ECHOSPACE   92
-#define VV_ARGV                93
-#define VV_LEN         94      // number of v: vars
+#define VV_NONE                70
+#define VV_NULL                71
+#define VV_NUMBERSIZE  72
+#define VV_VIM_DID_ENTER 73
+#define VV_TESTING     74
+#define VV_TYPE_NUMBER 75
+#define VV_TYPE_STRING 76
+#define VV_TYPE_FUNC   77
+#define VV_TYPE_LIST   78
+#define VV_TYPE_DICT   79
+#define VV_TYPE_FLOAT  80
+#define VV_TYPE_BOOL   81
+#define VV_TYPE_NONE   82
+#define VV_TYPE_JOB    83
+#define VV_TYPE_CHANNEL        84
+#define VV_TYPE_BLOB   85
+#define VV_TERMRFGRESP 86
+#define VV_TERMRBGRESP 87
+#define VV_TERMU7RESP  88
+#define VV_TERMSTYLERESP 89
+#define VV_TERMBLINKRESP 90
+#define VV_EVENT       91
+#define VV_VERSIONLONG 92
+#define VV_ECHOSPACE   93
+#define VV_ARGV                94
+#define VV_LEN         95      // number of v: vars
 
 // used for v_number in VAR_BOOL and VAR_SPECIAL
 #define VVAL_FALSE     0L      // VAR_BOOL