commit f7c07930b581b1bcfdfb1874b6883233516bdf11 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Tue May 16 14:19:36 2017 -0700 Fix minor timezone memory leak * src/editfns.c (wall_clock_tz): Remove; unused. diff --git a/src/editfns.c b/src/editfns.c index ecb8e3f083..75eb75a729 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -81,10 +81,8 @@ static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool); enum { tzeqlen = sizeof "TZ=" - 1 }; -/* Time zones equivalent to current local time, to wall clock time, - and to UTC, respectively. */ +/* Time zones equivalent to current local time and to UTC, respectively. */ static timezone_t local_tz; -static timezone_t wall_clock_tz; static timezone_t const utc_tz = 0; /* The cached value of Vsystem_name. This is used only to compare it @@ -269,7 +267,6 @@ init_editfns (bool dumping) /* Set the time zone rule now, so that the call to putenv is done before multiple threads are active. */ - wall_clock_tz = xtzalloc (0); tzlookup (tz ? build_string (tz) : Qwall, true); pw = getpwuid (getuid ()); commit 69d0a8500cabc4c034e2d6d873af54a8e8362e3b Author: Paul Eggert Date: Tue May 16 14:30:37 2017 -0700 Do not discard AddressSanitizer stderr * src/emacs.c (close_output_streams) [ADDRESS_SANITIZER]: Do not close stderr. diff --git a/src/emacs.c b/src/emacs.c index 9339d60866..3aa914f22f 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -657,8 +657,11 @@ close_output_streams (void) _exit (EXIT_FAILURE); } - if (close_stream (stderr) != 0) - _exit (EXIT_FAILURE); + /* Do not close stderr if addresses are being sanitized, as the + sanitizer might report to stderr after this function is + invoked. */ + if (!ADDRESS_SANITIZER && close_stream (stderr) != 0) + _exit (EXIT_FAILURE); } /* ARGSUSED */ commit be9e60fc3c43cc49cc5d749924c3e96737ae297c Author: Paul Eggert Date: Tue May 16 14:29:18 2017 -0700 Simplify procname code to avoid GCC bug * src/process.c (server_accept_connection): Simplify and avoid multiple calls and struct literals in the last case of a switch. The old code ran afoul of GCC bug 80659, which caused an internal compiler error. Problem reported by Jim Meyering in: http://lists.gnu.org/archive/html/emacs-devel/2017-05/msg00182.html https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80659 diff --git a/src/process.c b/src/process.c index 4a286391f8..fdea97722f 100644 --- a/src/process.c +++ b/src/process.c @@ -4659,7 +4659,7 @@ static EMACS_INT connect_counter = 0; static void server_accept_connection (Lisp_Object server, int channel) { - Lisp_Object proc, caller, name, buffer; + Lisp_Object buffer; Lisp_Object contact, host, service; struct Lisp_Process *ps = XPROCESS (server); struct Lisp_Process *p; @@ -4701,49 +4701,43 @@ server_accept_connection (Lisp_Object server, int channel) information for this process. */ host = Qt; service = Qnil; + Lisp_Object args[11]; + int nargs = 0; + AUTO_STRING (procname_format_in, "%s <%d.%d.%d.%d:%d>"); + AUTO_STRING (procname_format_in6, "%s <[%x:%x:%x:%x:%x:%x:%x:%x]:%d>"); + AUTO_STRING (procname_format_default, "%s <%d>"); switch (saddr.sa.sa_family) { case AF_INET: { + args[nargs++] = procname_format_in; + nargs++; unsigned char *ip = (unsigned char *)&saddr.in.sin_addr.s_addr; - - AUTO_STRING (ipv4_format, "%d.%d.%d.%d"); - host = CALLN (Fformat, ipv4_format, - make_number (ip[0]), make_number (ip[1]), - make_number (ip[2]), make_number (ip[3])); service = make_number (ntohs (saddr.in.sin_port)); - AUTO_STRING (caller_format, " <%s:%d>"); - caller = CALLN (Fformat, caller_format, host, service); + for (int i = 0; i < 4; i++) + args[nargs++] = make_number (ip[i]); + args[nargs++] = service; } break; #ifdef AF_INET6 case AF_INET6: { - Lisp_Object args[9]; + args[nargs++] = procname_format_in6; + nargs++; uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr; - int i; - - AUTO_STRING (ipv6_format, "%x:%x:%x:%x:%x:%x:%x:%x"); - args[0] = ipv6_format; - for (i = 0; i < 8; i++) - args[i + 1] = make_number (ntohs (ip6[i])); - host = CALLMANY (Fformat, args); service = make_number (ntohs (saddr.in.sin_port)); - AUTO_STRING (caller_format, " <[%s]:%d>"); - caller = CALLN (Fformat, caller_format, host, service); + for (int i = 0; i < 8; i++) + args[nargs++] = make_number (ip6[i]); + args[nargs++] = service; } break; #endif -#ifdef HAVE_LOCAL_SOCKETS - case AF_LOCAL: -#endif default: - caller = Fnumber_to_string (make_number (connect_counter)); - AUTO_STRING (space_less_than, " <"); - AUTO_STRING (greater_than, ">"); - caller = concat3 (space_less_than, caller, greater_than); + args[nargs++] = procname_format_default; + nargs++; + args[nargs++] = make_number (connect_counter); break; } @@ -4764,16 +4758,17 @@ server_accept_connection (Lisp_Object server, int channel) buffer = ps->name; if (!NILP (buffer)) { - buffer = concat2 (buffer, caller); - buffer = Fget_buffer_create (buffer); + args[1] = buffer; + buffer = Fget_buffer_create (Fformat (nargs, args)); } } /* Generate a unique name for the new server process. Combine the server process name with the caller identification. */ - name = concat2 (ps->name, caller); - proc = make_process (name); + args[1] = ps->name; + Lisp_Object name = Fformat (nargs, args); + Lisp_Object proc = make_process (name); chan_process[s] = proc; commit c4ac34f22794344d44022b9c497b2f12cdb0f4a6 Author: Paul Eggert Date: Tue May 16 13:24:33 2017 -0700 Pacify GCC 7 with --enable-gcc-warnings * src/regex.c (regex_compile): Swap labels, so that the FALLTHROUGH immediately precedes the case label. diff --git a/src/regex.c b/src/regex.c index ed84890208..240a91f2ba 100644 --- a/src/regex.c +++ b/src/regex.c @@ -2637,8 +2637,8 @@ regex_compile (const_re_char *pattern, size_t size, || (syntax & RE_LIMITED_OPS)) goto normal_char; FALLTHROUGH; - handle_plus: case '*': + handle_plus: /* If there is no previous pattern... */ if (!laststart) { commit 2e1bebe279b7108f74c3a1e7e30e8a43c2cfa31f Author: Paul Eggert Date: Tue May 16 10:24:19 2017 -0700 Merge with gnulib, pacifying GCC 7 This incorporates: 2017-05-16 manywarnings: update for GCC 7 2017-05-15 sys_select: Avoid "was expanded before it was required" * configure.ac (nw): Suppress GCC 7’s new -Wduplicated-branches and -Wformat-overflow=2 options, due to too many false alarms. * doc/misc/texinfo.tex, lib/strftime.c, m4/manywarnings.m4: Copy from gnulib. * m4/gnulib-comp.m4: Regenerate. * src/coding.c (decode_coding_iso_2022): Fix bug uncovered by -Wimplicit-fallthrough. * src/conf_post.h (FALLTHROUGH): New macro. Use it to mark all switch cases that fall through. * src/editfns.c (styled_format): Use !, not ~, on bool. * src/gtkutil.c (xg_check_special_colors): When using sprintf, don’t trust Gtk to output colors in [0, 1] range. (xg_update_scrollbar_pos): Avoid use of possibly-uninitialized bool; this bug was actually caught by Clang. * src/search.c (boyer_moore): Tell GCC that CHAR_BASE, if nonzero, must be a non-ASCII character. * src/xterm.c (x_draw_glyphless_glyph_string_foreground): Tell GCC that glyph->u.glyphless.ch must be a character. diff --git a/configure.ac b/configure.ac index d085552ffe..34b75a768b 100644 --- a/configure.ac +++ b/configure.ac @@ -921,6 +921,8 @@ AS_IF([test $gl_gcc_warnings = no], [gl_WARN_ADD([-Werror], [WERROR_CFLAGS])]) AC_SUBST([WERROR_CFLAGS]) + nw="$nw -Wduplicated-branches" # Too many false alarms + nw="$nw -Wformat-overflow=2" # False alarms due to GCC bug 80776 nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings nw="$nw -Woverlength-strings" # Not a problem these days nw="$nw -Wformat-nonliteral" # we do this a lot diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 9cd73101c1..8204f3e3ae 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2017-04-14.11} +\def\texinfoversion{2017-05-14.14} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -9118,7 +9118,13 @@ \xdef\safexrefname{#1}% }% % - \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + \bgroup + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% + \egroup + % We put the \gdef inside a group to avoid the definitions building up on + % TeX's save stack, which can cause it to run out of space for aux files with + % thousands of lines. \gdef doesn't use the save stack, but \csname does + % when it defines an unknown control sequence as \relax. % % Was that xref control sequence that we just defined for a float? \expandafter\iffloat\csname XR\safexrefname\endcsname diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index 623911027c..51d181997b 100644 --- a/lib-src/ebrowse.c +++ b/lib-src/ebrowse.c @@ -3059,8 +3059,7 @@ class_definition (struct sym *containing, int tag, int flags, int nested) MATCH until we see something like `;' or `{'. */ while (!LOOKING_AT3 (';', YYEOF, '{')) MATCH (); - done = 1; - + FALLTHROUGH; case '{': done = 1; break; @@ -3184,7 +3183,7 @@ declaration (int flags) free (id); return; } - + FALLTHROUGH; case '=': /* Assumed to be the start of an initialization in this context. */ diff --git a/lib-src/etags.c b/lib-src/etags.c index 015cbbe0ef..6f280d8ab4 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -1157,7 +1157,7 @@ main (int argc, char **argv) case 'c': /* Backward compatibility: support obsolete --ignore-case-regexp. */ optarg = concat (optarg, "i", ""); /* memory leak here */ - /* FALLTHRU */ + FALLTHROUGH; case 'r': argbuffer[current_arg].arg_type = at_regexp; argbuffer[current_arg].what = optarg; @@ -1192,7 +1192,7 @@ main (int argc, char **argv) case 't': typedefs = true; break; case 'T': typedefs = typedefs_or_cplusplus = true; break; case 'u': update = true; break; - case 'v': vgrind_style = true; /*FALLTHRU*/ + case 'v': vgrind_style = true; FALLTHROUGH; case 'x': cxref_style = true; break; case 'w': no_warnings = true; break; default: @@ -2564,7 +2564,7 @@ hash (const char *str, int len) { default: hval += asso_values[(unsigned char) str[2]]; - /*FALLTHROUGH*/ + FALLTHROUGH; case 2: hval += asso_values[(unsigned char) str[1]]; break; @@ -3013,7 +3013,7 @@ consider_token (char *str, int len, int c, int *c_extp, *c_extp = (*c_extp | C_PLPL) & ~C_AUTO; if (toktype == st_C_template) break; - /* FALLTHRU */ + FALLTHROUGH; case st_C_struct: case st_C_enum: if (parlev == 0 @@ -3176,7 +3176,7 @@ consider_token (char *str, int len, int c, int *c_extp, default: break; } - /* FALLTHRU */ + FALLTHROUGH; case fvnameseen: if (len >= 10 && strneq (str+len-10, "::operator", 10)) { @@ -3387,7 +3387,7 @@ C_entries (int c_ext, FILE *inf) case '\0': /* Hmmm, something went wrong. */ CNL (); - /* FALLTHRU */ + FALLTHROUGH; case '\'': inchar = false; break; @@ -3828,7 +3828,7 @@ C_entries (int c_ext, FILE *inf) || (members && plainc && instruct)) make_C_tag (true); /* a function */ - /* FALLTHRU */ + FALLTHROUGH; default: fvextern = false; fvdef = fvnone; @@ -3838,7 +3838,7 @@ C_entries (int c_ext, FILE *inf) else token.valid = false; } /* switch (fvdef) */ - /* FALLTHRU */ + FALLTHROUGH; default: if (!instruct) typdef = tnone; @@ -3926,7 +3926,7 @@ C_entries (int c_ext, FILE *inf) || (globals && bracelev == 0 && (!fvextern || declarations))) make_C_tag (false); /* a variable */ - /* FALLTHRU */ + FALLTHROUGH; default: fvdef = fvnone; } @@ -3959,7 +3959,7 @@ C_entries (int c_ext, FILE *inf) fvdef = fignore; break; } - /* FALLTHRU */ + FALLTHROUGH; case foperator: fvdef = fstartlist; break; @@ -4049,7 +4049,7 @@ C_entries (int c_ext, FILE *inf) } } make_C_tag (true); /* a function */ - /* FALLTHRU */ + FALLTHROUGH; case fignore: fvdef = fvnone; break; @@ -4142,7 +4142,7 @@ C_entries (int c_ext, FILE *inf) if ((members && bracelev == 1) || (globals && bracelev == 0 && (!fvextern || declarations))) make_C_tag (false); /* a variable */ - /* FALLTHRU */ + FALLTHROUGH; default: fvdef = vignore; } @@ -4169,7 +4169,7 @@ C_entries (int c_ext, FILE *inf) objdef = omethodsign; break; } - /* FALLTHRU */ + FALLTHROUGH; resetfvdef: case '#': case '~': case '&': case '%': case '/': case '|': case '^': case '!': case '.': case '?': @@ -6354,7 +6354,7 @@ add_regex (char *regexp_pattern, language *lang) break; case 's': single_line = true; - /* FALLTHRU */ + FALLTHROUGH; case 'm': multi_line = true; need_filebuf = true; diff --git a/lib/strftime.c b/lib/strftime.c index e4d78ef701..99bee4ef97 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -68,6 +68,14 @@ extern char *tzname[]; #include #include +#ifndef FALLTHROUGH +# if __GNUC__ < 7 +# define FALLTHROUGH ((void) 0) +# else +# define FALLTHROUGH __attribute__ ((__fallthrough__)) +# endif +#endif + #ifdef COMPILE_WIDE # include # define CHAR_T wchar_t @@ -1138,8 +1146,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) #ifndef _NL_CURRENT format_char = L_('p'); #endif - /* FALLTHROUGH */ - + FALLTHROUGH; case L_('p'): if (change_case) { @@ -1474,7 +1481,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) case L_('\0'): /* GNU extension: % at end of format. */ --f; - /* Fall through. */ + FALLTHROUGH; default: /* Unknown format; output the format, including the '%', since this is most likely the right thing to do if a diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 8295e48358..3f196d4f1d 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -375,7 +375,7 @@ AC_DEFUN([gl_INIT], AC_LIBOBJ([symlink]) fi gl_UNISTD_MODULE_INDICATOR([symlink]) - gl_HEADER_SYS_SELECT + AC_REQUIRE([gl_HEADER_SYS_SELECT]) AC_PROG_MKDIR_P gl_HEADER_SYS_STAT_H AC_PROG_MKDIR_P diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4 index 0f06adecfb..2d35eff6a2 100644 --- a/m4/manywarnings.m4 +++ b/m4/manywarnings.m4 @@ -99,12 +99,11 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], # comm -3 \ # <(sed -n 's/^ *\(-[^ ]*\) .*/\1/p' manywarnings.m4 | sort) \ # <(gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort | - # grep -v -x -f <( + # grep -v -x -F -f <( # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec)) gl_manywarn_set= - for gl_manywarn_item in \ - -fno-common \ + for gl_manywarn_item in -fno-common \ -W \ -Wabi \ -Waddress \ @@ -113,6 +112,8 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wattributes \ -Wbad-function-cast \ -Wbool-compare \ + -Wbool-operation \ + -Wbuiltin-declaration-mismatch \ -Wbuiltin-macro-redefined \ -Wcast-align \ -Wchar-subscripts \ @@ -122,6 +123,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wcomments \ -Wcoverage-mismatch \ -Wcpp \ + -Wdangling-else \ -Wdate-time \ -Wdeprecated \ -Wdeprecated-declarations \ @@ -131,10 +133,13 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wdiscarded-qualifiers \ -Wdiv-by-zero \ -Wdouble-promotion \ + -Wduplicated-branches \ -Wduplicated-cond \ + -Wduplicate-decl-specifier \ -Wempty-body \ -Wendif-labels \ -Wenum-compare \ + -Wexpansion-to-defined \ -Wextra \ -Wformat-contains-nul \ -Wformat-extra-args \ @@ -155,6 +160,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Winit-self \ -Winline \ -Wint-conversion \ + -Wint-in-bool-context \ -Wint-to-pointer-cast \ -Winvalid-memory-model \ -Winvalid-pch \ @@ -163,6 +169,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wlogical-op \ -Wmain \ -Wmaybe-uninitialized \ + -Wmemset-elt-size \ -Wmemset-transposed-args \ -Wmisleading-indentation \ -Wmissing-braces \ @@ -188,9 +195,12 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wpacked-bitfield-compat \ -Wparentheses \ -Wpointer-arith \ + -Wpointer-compare \ -Wpointer-sign \ -Wpointer-to-int-cast \ -Wpragmas \ + -Wpsabi \ + -Wrestrict \ -Wreturn-local-addr \ -Wreturn-type \ -Wscalar-storage-order \ @@ -214,6 +224,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wswitch \ -Wswitch-bool \ -Wswitch-default \ + -Wswitch-unreachable \ -Wsync-nand \ -Wsystem-headers \ -Wtautological-compare \ @@ -247,10 +258,18 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], # gcc --help=warnings outputs an unusual form for these options; list # them here so that the above 'comm' command doesn't report a false match. + # Would prefer "min (PTRDIFF_MAX, SIZE_MAX)", but it must be a literal: + ptrdiff_max_max=9223372036854775807 + gl_manywarn_set="$gl_manywarn_set -Walloc-size-larger-than=$ptrdiff_max_max" gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2" + gl_manywarn_set="$gl_manywarn_set -Wformat-overflow=2" + gl_manywarn_set="$gl_manywarn_set -Wformat-truncation=2" + gl_manywarn_set="$gl_manywarn_set -Wimplicit-fallthrough=5" gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc" gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2" + gl_manywarn_set="$gl_manywarn_set -Wstringop-overflow=2" gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2" + gl_manywarn_set="$gl_manywarn_set -Wvla-larger-than=4031" # These are needed for older GCC versions. if test -n "$GCC"; then diff --git a/src/bidi.c b/src/bidi.c index b75ad93362..dce0bf695f 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -2092,7 +2092,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) type = RLI; bidi_it->orig_type = type; } - /* FALLTHROUGH */ + FALLTHROUGH; case RLI: /* X5a */ if (override == NEUTRAL_DIR) bidi_it->type_after_wn = type; diff --git a/src/callint.c b/src/callint.c index d96454883c..96436116c8 100644 --- a/src/callint.c +++ b/src/callint.c @@ -690,6 +690,7 @@ invoke it. If KEYS is omitted or nil, the return value of case 'N': /* Prefix arg as number, else number from minibuffer. */ if (!NILP (prefix_arg)) goto have_prefix_arg; + FALLTHROUGH; case 'n': /* Read number from minibuffer. */ args[i] = call1 (Qread_number, callint_message); /* Passing args[i] directly stimulates compiler bug. */ diff --git a/src/ccl.c b/src/ccl.c index 90bd2f4679..b2caf413f7 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -1000,7 +1000,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_ReadBranch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ CCL_READ_CHAR (reg[rrr]); - /* fall through ... */ + FALLTHROUGH; case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ { int ioff = 0 <= reg[rrr] && reg[rrr] < field1 ? reg[rrr] : field1; @@ -1174,6 +1174,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_ReadJumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ CCL_READ_CHAR (reg[rrr]); + FALLTHROUGH; case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ i = reg[rrr]; jump_address = ic + ADDR; @@ -1184,6 +1185,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_ReadJumpCondExprReg: /* A--D--D--R--E--S--S-rrrXXXXX */ CCL_READ_CHAR (reg[rrr]); + FALLTHROUGH; case CCL_JumpCondExprReg: i = reg[rrr]; jump_address = ic + ADDR; diff --git a/src/coding.c b/src/coding.c index 367a975984..5682fc015a 100644 --- a/src/coding.c +++ b/src/coding.c @@ -3611,7 +3611,7 @@ decode_coding_iso_2022 (struct coding_system *coding) || CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS) goto invalid_code; /* This is a graphic character, we fall down ... */ - + FALLTHROUGH; case ISO_graphic_plane_1: if (charset_id_1 < 0) goto invalid_code; @@ -3646,6 +3646,7 @@ decode_coding_iso_2022 (struct coding_system *coding) case ISO_single_shift_2_7: if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)) goto invalid_code; + FALLTHROUGH; case ISO_single_shift_2: if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)) goto invalid_code; @@ -3797,6 +3798,7 @@ decode_coding_iso_2022 (struct coding_system *coding) { case ']': /* end of the current direction */ coding->mode &= ~CODING_MODE_DIRECTION; + break; case '0': /* end of the current direction */ case '1': /* start of left-to-right direction */ diff --git a/src/conf_post.h b/src/conf_post.h index 95ebd5511c..4fc0428df5 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -244,6 +244,12 @@ extern int emacs_setenv_TZ (char const *); # define ATTRIBUTE_FORMAT(spec) /* empty */ #endif +#if GNUC_PREREQ (7, 0, 0) +# define FALLTHROUGH __attribute__ ((__fallthrough__)) +#else +# define FALLTHROUGH ((void) 0) +#endif + #if GNUC_PREREQ (4, 4, 0) && defined __GLIBC_MINOR__ # define PRINTF_ARCHETYPE __gnu_printf__ #elif GNUC_PREREQ (4, 4, 0) && defined __MINGW32__ diff --git a/src/data.c b/src/data.c index 44f7ba0e88..3ff2a80974 100644 --- a/src/data.c +++ b/src/data.c @@ -2153,7 +2153,7 @@ If the current binding is global (the default), the value is nil. */) else if (!BUFFER_OBJFWDP (valcontents)) return Qnil; } - /* FALLTHROUGH */ + FALLTHROUGH; case SYMBOL_LOCALIZED: /* For a local variable, record both the symbol and which buffer's or frame's value we are saving. */ diff --git a/src/doprnt.c b/src/doprnt.c index 09051adc05..bed9350f4a 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -352,6 +352,7 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, case 'S': string[-1] = 's'; + FALLTHROUGH; case 's': if (fmtcpy[1] != 's') minlen = atoi (&fmtcpy[1]); diff --git a/src/editfns.c b/src/editfns.c index 38530437a2..ecb8e3f083 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -1595,10 +1595,10 @@ time_arith (Lisp_Object a, Lisp_Object b, { default: val = Fcons (make_number (t.ps), val); - /* Fall through. */ + FALLTHROUGH; case 3: val = Fcons (make_number (t.us), val); - /* Fall through. */ + FALLTHROUGH; case 2: val = Fcons (make_number (t.lo), val); val = Fcons (make_number (t.hi), val); @@ -4072,8 +4072,8 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) } /* Ignore flags when sprintf ignores them. */ - space_flag &= ~ plus_flag; - zero_flag &= ~ minus_flag; + space_flag &= ! plus_flag; + zero_flag &= ! minus_flag; char *num_end; uintmax_t raw_field_width = strtoumax (format, &num_end, 10); @@ -4311,7 +4311,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) { memcpy (f, pMd, pMlen); f += pMlen; - zero_flag &= ~ precision_given; + zero_flag &= ! precision_given; } *f++ = conversion; *f = '\0'; diff --git a/src/eval.c b/src/eval.c index 848955c279..98d25cc4fe 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3212,7 +3212,7 @@ do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, set_default_internal (specpdl_symbol (bind), value, bindflag); return; } - /* FALLTHROUGH */ + FALLTHROUGH; case SYMBOL_LOCALIZED: set_internal (specpdl_symbol (bind), value, Qnil, bindflag); break; @@ -3390,12 +3390,10 @@ do_one_unbind (union specbinding *this_binding, bool unwinding, Qnil, bindflag); break; } - else - { /* FALLTHROUGH!! - NOTE: we only ever come here if make_local_foo was used for - the first time on this var within this let. */ - } } + /* Come here only if make_local_foo was used for the first time + on this var within this let. */ + FALLTHROUGH; case SPECPDL_LET_DEFAULT: set_default_internal (specpdl_symbol (this_binding), specpdl_old_value (this_binding), @@ -3676,12 +3674,10 @@ backtrace_eval_unrewind (int distance) SET_SYMBOL_VAL (XSYMBOL (sym), old_value); break; } - else - { /* FALLTHROUGH!! - NOTE: we only ever come here if make_local_foo was used for - the first time on this var within this let. */ - } } + /* Come here only if make_local_foo was used for the first + time on this var within this let. */ + FALLTHROUGH; case SPECPDL_LET_DEFAULT: { Lisp_Object sym = specpdl_symbol (tmp); @@ -3837,7 +3833,7 @@ mark_specpdl (union specbinding *first, union specbinding *ptr) case SPECPDL_LET_DEFAULT: case SPECPDL_LET_LOCAL: mark_object (specpdl_where (pdl)); - /* Fall through. */ + FALLTHROUGH; case SPECPDL_LET: mark_object (specpdl_symbol (pdl)); mark_object (specpdl_old_value (pdl)); diff --git a/src/filelock.c b/src/filelock.c index 67e8dbd34e..bfa1d63d83 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -569,7 +569,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) if (! (boot[0] == '\200' && boot[1] == '\242')) return -1; boot += 2; - /* Fall through. */ + FALLTHROUGH; case ':': if (! c_isdigit (boot[0])) return -1; diff --git a/src/gnutls.c b/src/gnutls.c index 28ab10de05..2078ad88f2 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -605,6 +605,7 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) max_log_level, "retry:", str); + FALLTHROUGH; default: GNUTLS_LOG2 (1, max_log_level, diff --git a/src/gtkutil.c b/src/gtkutil.c index 1b63293fe5..16eb284d7c 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -554,10 +554,11 @@ xg_check_special_colors (struct frame *f, else gtk_style_context_get_background_color (gsty, state, &col); - sprintf (buf, "rgb:%04x/%04x/%04x", - (unsigned) (col.red * 65535), - (unsigned) (col.green * 65535), - (unsigned) (col.blue * 65535)); + unsigned short + r = col.red * 65535, + g = col.green * 65535, + b = col.blue * 65535; + sprintf (buf, "rgb:%04x/%04x/%04x", r, g, b); success_p = x_parse_color (f, buf, color) != 0; #else GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f)); @@ -3856,7 +3857,6 @@ xg_update_scrollbar_pos (struct frame *f, GtkWidget *wparent = gtk_widget_get_parent (wscroll); gint msl; int scale = xg_get_gdk_scale (); - bool hidden; top /= scale; left /= scale; @@ -3875,13 +3875,13 @@ xg_update_scrollbar_pos (struct frame *f, /* Move and resize to new values. */ gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top); gtk_widget_style_get (wscroll, "min-slider-length", &msl, NULL); - if (msl > height) + bool hidden = height < msl; + if (hidden) { /* No room. Hide scroll bar as some themes output a warning if the height is less than the min size. */ gtk_widget_hide (wparent); gtk_widget_hide (wscroll); - hidden = true; } else { diff --git a/src/indent.c b/src/indent.c index f630ebb847..adecc3622a 100644 --- a/src/indent.c +++ b/src/indent.c @@ -925,6 +925,7 @@ position_indentation (ptrdiff_t pos_byte) case 0240: if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) return column; + FALLTHROUGH; case ' ': column++; break; diff --git a/src/lread.c b/src/lread.c index c03aad4f72..5e737d690c 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2309,6 +2309,7 @@ read_escape (Lisp_Object readcharfun, bool stringp) c = READCHAR; if (c != '-') error ("Invalid escape character syntax"); + FALLTHROUGH; case '^': c = READCHAR; if (c == '\\') @@ -2399,6 +2400,7 @@ read_escape (Lisp_Object readcharfun, bool stringp) case 'U': /* Post-Unicode-2.0: Up to eight hex chars. */ unicode_hex_count = 8; + FALLTHROUGH; case 'u': /* A Unicode escape. We only permit them in strings and characters, @@ -3278,11 +3280,11 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) *pch = c; return Qnil; } - - /* Otherwise, we fall through! Note that the atom-reading loop - below will now loop at least once, assuring that we will not - try to UNREAD two characters in a row. */ } + /* The atom-reading loop below will now loop at least once, + assuring that we will not try to UNREAD two characters in a + row. */ + FALLTHROUGH; default: default_label: if (c <= 040) goto retry; diff --git a/src/regex.c b/src/regex.c index 8e38a920cd..ed84890208 100644 --- a/src/regex.c +++ b/src/regex.c @@ -2636,6 +2636,7 @@ regex_compile (const_re_char *pattern, size_t size, if ((syntax & RE_BK_PLUS_QM) || (syntax & RE_LIMITED_OPS)) goto normal_char; + FALLTHROUGH; handle_plus: case '*': /* If there is no previous pattern... */ @@ -3086,6 +3087,7 @@ regex_compile (const_re_char *pattern, size_t size, with non-0. */ if (regnum == 0) FREE_STACK_RETURN (REG_BADPAT); + FALLTHROUGH; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': regnum = 10*regnum + (c - '0'); break; @@ -3905,8 +3907,7 @@ analyze_first (const_re_char *p, const_re_char *pend, char *fastmap, j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; } - - /* Fallthrough */ + FALLTHROUGH; case charset: if (!fastmap) break; not = (re_opcode_t) *(p - 1) == charset_not; @@ -6182,8 +6183,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1, case on_failure_jump_nastyloop: assert ((re_opcode_t)pat[-2] == no_op); PUSH_FAILURE_POINT (pat - 2, str); - /* Fallthrough */ - + FALLTHROUGH; case on_failure_jump_loop: case on_failure_jump: case succeed_n: diff --git a/src/search.c b/src/search.c index 1223cbf07c..19e789dfa8 100644 --- a/src/search.c +++ b/src/search.c @@ -1804,6 +1804,7 @@ boyer_moore (EMACS_INT n, unsigned char *base_pat, { /* Setup translate_prev_byte1/2/3/4 from CHAR_BASE. Only a byte following them are the target of translation. */ + eassume (0x80 <= char_base && char_base <= MAX_CHAR); unsigned char str[MAX_MULTIBYTE_LENGTH]; int cblen = CHAR_STRING (char_base, str); diff --git a/src/syntax.c b/src/syntax.c index 7aa43e6e5c..dcaca22f0e 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -810,6 +810,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, case Sstring_fence: case Scomment_fence: c = (code == Sstring_fence ? ST_STRING_STYLE : ST_COMMENT_STYLE); + FALLTHROUGH; case Sstring: /* Track parity of quotes. */ if (string_style == -1) @@ -2690,6 +2691,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) goto lose; INC_BOTH (from, from_byte); /* Treat following character as a word constituent. */ + FALLTHROUGH; case Sword: case Ssymbol: if (depth || !sexpflag) break; @@ -2721,7 +2723,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) case Scomment_fence: comstyle = ST_COMMENT_STYLE; - /* FALLTHROUGH */ + FALLTHROUGH; case Scomment: if (!parse_sexp_ignore_comments) break; UPDATE_SYNTAX_TABLE_FORWARD (from); @@ -2753,7 +2755,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) goto close1; } mathexit = 1; - + FALLTHROUGH; case Sopen: if (!++depth) goto done; break; @@ -2909,7 +2911,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) goto open2; } mathexit = 1; - + FALLTHROUGH; case Sclose: if (!++depth) goto done2; break; diff --git a/src/xterm.c b/src/xterm.c index e9068830f8..c8836b7ca7 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2005,9 +2005,9 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) } else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE) { - sprintf (buf, "%0*X", - glyph->u.glyphless.ch < 0x10000 ? 4 : 6, - glyph->u.glyphless.ch + 0u); + unsigned int ch = glyph->u.glyphless.ch; + eassume (ch <= MAX_CHAR); + sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch); str = buf; } @@ -8949,7 +8949,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, { case MappingModifier: x_find_modifier_meanings (dpyinfo); - /* This is meant to fall through. */ + FALLTHROUGH; case MappingKeyboard: XRefreshKeyboardMapping ((XMappingEvent *) &event->xmapping); } commit 138c8256f41f242341c7d146c99f4e6fa267a638 Author: Michael Albinus Date: Tue May 16 15:55:06 2017 +0200 Make autoloading Tramp more robust * lisp/net/tramp.el (tramp-file-name-for-operation): Use `default-directory' where appropriate. (tramp-file-name-handler): Do not autoload. (tramp-autoload-file-name-handler): Reintroduce function. (tramp-register-autoload-file-name-handlers): Use it. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 99cb7d19b0..5b1e478db0 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1996,7 +1996,7 @@ ARGS are the arguments OPERATION has been called with." file-name-case-insensitive-p)) (if (file-name-absolute-p (nth 0 args)) (nth 0 args) - (expand-file-name (nth 0 args)))) + default-directory)) ;; FILE DIRECTORY resp FILE1 FILE2. ((member operation '(add-name-to-file copy-directory copy-file expand-file-name @@ -2008,10 +2008,12 @@ ARGS are the arguments OPERATION has been called with." (cond ((tramp-tramp-file-p (nth 0 args)) (nth 0 args)) ((tramp-tramp-file-p (nth 1 args)) (nth 1 args)) - (t (buffer-file-name (current-buffer)))))) + (t default-directory)))) ;; START END FILE. ((eq operation 'write-region) - (nth 2 args)) + (if (file-name-absolute-p (nth 2 args)) + (nth 2 args) + default-directory)) ;; BUFFER. ((member operation '(make-auto-save-file-name @@ -2058,13 +2060,6 @@ ARGS are the arguments OPERATION has been called with." `(let ((debug-on-error tramp-debug-on-error)) (tramp-compat-condition-case-unless-debug ,var ,bodyform ,@handlers))) -;; This is to avoid recursive load. -;;;###autoload(defun tramp-file-name-handler (operation &rest args) -;;;###autoload "Load Tramp file name handler, and perform OPERATION." -;;;###autoload (let ((default-directory temporary-file-directory)) -;;;###autoload (load "tramp" nil t)) -;;;###autoload (apply operation args)) - ;; Main function. (defun tramp-file-name-handler (operation &rest args) "Invoke Tramp file name handler. @@ -2193,15 +2188,23 @@ Falls back to normal file name handler if no Tramp file name handler exists." (save-match-data (apply (cdr fn) args)) (tramp-run-real-handler operation args)))) -;; `tramp-file-name-handler' must be registered before evaluation of -;; site-start and init files, because there might exist remote files -;; already, f.e. files kept via recentf-mode. +;;;###autoload +(progn (defun tramp-autoload-file-name-handler (operation &rest args) + "Load Tramp file name handler, and perform OPERATION." + (let ((default-directory temporary-file-directory)) + (load "tramp" 'noerror 'nomessage)) + (apply operation args))) + +;; `tramp-autoload-file-name-handler' must be registered before +;; evaluation of site-start and init files, because there might exist +;; remote files already, f.e. files kept via recentf-mode. ;;;###autoload (progn (defun tramp-register-autoload-file-name-handlers () "Add Tramp file name handlers to `file-name-handler-alist' during autoload." (add-to-list 'file-name-handler-alist - (cons tramp-initial-file-name-regexp 'tramp-file-name-handler)) - (put 'tramp-file-name-handler 'safe-magic t) + (cons tramp-initial-file-name-regexp + 'tramp-autoload-file-name-handler)) + (put 'tramp-autoload-file-name-handler 'safe-magic t) (add-to-list 'file-name-handler-alist (cons tramp-initial-completion-file-name-regexp @@ -2220,7 +2223,6 @@ Falls back to normal file name handler if no Tramp file name handler exists." ;; if `tramp-syntax' has been changed. (dolist (fnh '(tramp-file-name-handler tramp-completion-file-name-handler - ;; This is autoloaded in Emacs 24 & 25. tramp-autoload-file-name-handler)) (let ((a1 (rassq fnh file-name-handler-alist))) (setq file-name-handler-alist (delq a1 file-name-handler-alist)))) @@ -2438,42 +2440,55 @@ They are collected by `tramp-completion-dissect-file-name1'." (tramp-postfix-ipv6-format)))) ;; "/method" "/[method" (tramp-completion-file-name-structure1 - (list (concat (tramp-prefix-regexp) "\\(" (tramp-method-regexp) x-nil "\\)$") - 1 nil nil nil)) + (list + (concat + (tramp-prefix-regexp) + "\\(" (tramp-method-regexp) x-nil "\\)$") + 1 nil nil nil)) ;; "/method:user" "/[method/user" (tramp-completion-file-name-structure2 - (list (concat (tramp-prefix-regexp) - "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) - "\\(" tramp-user-regexp x-nil "\\)$") - 1 2 nil nil)) + (list + (concat + (tramp-prefix-regexp) + "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) + "\\(" tramp-user-regexp x-nil "\\)$") + 1 2 nil nil)) ;; "/method:host" "/[method/host" (tramp-completion-file-name-structure3 - (list (concat (tramp-prefix-regexp) - "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) - "\\(" tramp-host-regexp x-nil "\\)$") - 1 nil 2 nil)) + (list + (concat + (tramp-prefix-regexp) + "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) + "\\(" tramp-host-regexp x-nil "\\)$") + 1 nil 2 nil)) ;; "/method:[ipv6" "/[method/ipv6" (tramp-completion-file-name-structure4 - (list (concat (tramp-prefix-regexp) - "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) - (tramp-prefix-ipv6-regexp) - "\\(" tramp-completion-ipv6-regexp x-nil "\\)$") - 1 nil 2 nil)) + (list + (concat + (tramp-prefix-regexp) + "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) + (tramp-prefix-ipv6-regexp) + "\\(" tramp-completion-ipv6-regexp x-nil "\\)$") + 1 nil 2 nil)) ;; "/method:user@host" "/[method/user@host" (tramp-completion-file-name-structure5 - (list (concat (tramp-prefix-regexp) - "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) - "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp - "\\(" tramp-host-regexp x-nil "\\)$") - 1 2 3 nil)) + (list + (concat + (tramp-prefix-regexp) + "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) + "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp + "\\(" tramp-host-regexp x-nil "\\)$") + 1 2 3 nil)) ;; "/method:user@[ipv6" "/[method/user@ipv6" (tramp-completion-file-name-structure6 - (list (concat (tramp-prefix-regexp) - "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) - "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp - (tramp-prefix-ipv6-regexp) - "\\(" tramp-completion-ipv6-regexp x-nil "\\)$") - 1 2 3 nil))) + (list + (concat + (tramp-prefix-regexp) + "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) + "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp + (tramp-prefix-ipv6-regexp) + "\\(" tramp-completion-ipv6-regexp x-nil "\\)$") + 1 2 3 nil))) (delq nil (mapcar commit 712a5faa2c95596db2d4d94dada575ad16b317c5 Author: Michael Albinus Date: Tue May 16 14:49:51 2017 +0200 Extend tramp-tests.el * test/lisp/net/tramp-tests.el (tramp-change-syntax): Remove declaration, not needed anymore. (tramp-test05-expand-file-name-relative): New test. (tramp-test10-write-region): Extend test. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index d3a93d27b2..bcf2e840fd 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -45,7 +45,6 @@ (require 'vc-git) (require 'vc-hg) -(declare-function tramp-change-syntax "tramp-cmds") (declare-function tramp-find-executable "tramp-sh") (declare-function tramp-get-remote-path "tramp-sh") (declare-function tramp-get-remote-stat "tramp-sh") @@ -1616,6 +1615,21 @@ handled properly. BODY shall not contain a timeout." (expand-file-name "/method:host:/:/~/path/./file") "/method:host:/:/~/path/file"))) +;; The following test is inspired by Bug#26911. It is rather a bug in +;; `expand-file-name', and it fails for all Emacs versions. Test +;; added for later, when it is fixed. +(ert-deftest tramp-test05-expand-file-name-relative () + "Check `expand-file-name'." + ;; Mark as failed until bug has been fixed. + :expected-result :failed + (should + (string-equal + (let ((default-directory + (concat + (file-remote-p tramp-test-temporary-file-directory) "/path"))) + (expand-file-name ".." "./")) + (concat (file-remote-p tramp-test-temporary-file-directory) "/")))) + (ert-deftest tramp-test06-directory-file-name () "Check `directory-file-name'. This checks also `file-name-as-directory', `file-name-directory', @@ -1745,13 +1759,25 @@ This checks also `file-name-as-directory', `file-name-directory', (let ((tmp-name (tramp--test-make-temp-name nil quoted))) (unwind-protect (progn - ;; Write buffer. + ;; Write buffer. Use absolute and relative file name. (with-temp-buffer (insert "foo") (write-region nil nil tmp-name)) (with-temp-buffer (insert-file-contents tmp-name) (should (string-equal (buffer-string) "foo"))) + (delete-file tmp-name) + (with-temp-buffer + (insert "foo") + (should-not (file-exists-p tmp-name)) + (let ((default-directory (file-name-directory tmp-name))) + (should-not (file-exists-p (file-name-nondirectory tmp-name))) + (write-region nil nil (file-name-nondirectory tmp-name)) + (should (file-exists-p (file-name-nondirectory tmp-name)))) + (should (file-exists-p tmp-name))) + (with-temp-buffer + (insert-file-contents tmp-name) + (should (string-equal (buffer-string) "foo"))) ;; Append. (with-temp-buffer @@ -3721,6 +3747,7 @@ Since it unloads Tramp, it shall be the last test to run." ;; * set-file-selinux-context ;; * Work on skipped tests. Make a comment, when it is impossible. +;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'. ;; * Fix `tramp-test06-directory-file-name' for `ftp'. ;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?). ;; * Fix Bug#16928. Set expected error of `tramp-test36-asynchronous-requests'. commit 014f1cc06438f75c3fe267ae92e706855bba675d Author: Michael Albinus Date: Tue May 16 11:22:33 2017 +0200 * lisp/net/tramp.el: Avoid recursive load of Tramp. (Bug#26943) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 8c317df976..99cb7d19b0 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2058,8 +2058,14 @@ ARGS are the arguments OPERATION has been called with." `(let ((debug-on-error tramp-debug-on-error)) (tramp-compat-condition-case-unless-debug ,var ,bodyform ,@handlers))) +;; This is to avoid recursive load. +;;;###autoload(defun tramp-file-name-handler (operation &rest args) +;;;###autoload "Load Tramp file name handler, and perform OPERATION." +;;;###autoload (let ((default-directory temporary-file-directory)) +;;;###autoload (load "tramp" nil t)) +;;;###autoload (apply operation args)) + ;; Main function. -;;;###autoload (defun tramp-file-name-handler (operation &rest args) "Invoke Tramp file name handler. Falls back to normal file name handler if no Tramp file name handler exists."