diff --git a/src/tag.c b/src/tag.c
index d729c4621a2c6da878765683bf49ee187fe9ce42..2e57095ba5c44ef31ede9941aeb5731cfb339320 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -3878,23 +3878,27 @@ expand_tags(
     char_u	***file)
 {
     int		i;
-    int		c;
-    int		tagnmflag;
-    char_u      tagnm[100];
+    int		extra_flag;
+    char_u	*name_buf;
+    size_t	name_buf_size = 100;
     tagptrs_T	t_p;
     int		ret;
 
+    name_buf = alloc(name_buf_size);
+    if (name_buf == NULL)
+	return FAIL;
+
     if (tagnames)
-	tagnmflag = TAG_NAMES;
+	extra_flag = TAG_NAMES;
     else
-	tagnmflag = 0;
+	extra_flag = 0;
     if (pat[0] == '/')
 	ret = find_tags(pat + 1, num_file, file,
-		TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC,
+		TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC,
 		TAG_MANY, curbuf->b_ffname);
     else
 	ret = find_tags(pat, num_file, file,
-	      TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
+	      TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
 		TAG_MANY, curbuf->b_ffname);
     if (ret == OK && !tagnames)
     {
@@ -3902,18 +3906,37 @@ expand_tags(
 	 // "<tagname>\0<kind>\0<filename>\0"
 	 for (i = 0; i < *num_file; i++)
 	 {
+	     size_t	len;
+
 	     parse_match((*file)[i], &t_p);
-	     c = (int)(t_p.tagname_end - t_p.tagname);
-	     mch_memmove(tagnm, t_p.tagname, (size_t)c);
-	     tagnm[c++] = 0;
-	     tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
-							 ? *t_p.tagkind : 'f';
-	     tagnm[c++] = 0;
-	     mch_memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
-	     (*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
-	     mch_memmove((*file)[i], tagnm, (size_t)c);
+	     len = t_p.tagname_end - t_p.tagname;
+	     if (len > name_buf_size - 3)
+	     {
+		 char_u *buf;
+
+		 name_buf_size = len + 3;
+		 buf = vim_realloc(name_buf, name_buf_size);
+		 if (buf == NULL)
+		 {
+		     vim_free(name_buf);
+		     return FAIL;
+		 }
+		 name_buf = buf;
+	     }
+
+	     mch_memmove(name_buf, t_p.tagname, len);
+	     name_buf[len++] = 0;
+	     name_buf[len++] = (t_p.tagkind != NULL && *t_p.tagkind)
+							  ? *t_p.tagkind : 'f';
+	     name_buf[len++] = 0;
+	     mch_memmove((*file)[i] + len, t_p.fname,
+						    t_p.fname_end - t_p.fname);
+	     (*file)[i][len + (t_p.fname_end - t_p.fname)] = 0;
+	     mch_memmove((*file)[i], name_buf, len);
 	}
     }
+
+    vim_free(name_buf);
     return ret;
 }
 
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index 92af0d0b0fbbd1ed8d425a5f64d52c3ab5b74168..ba55159c7a4a9afa9f836cb634e52bb83926f1b4 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -606,6 +606,16 @@ func Test_tag_line_toolong()
   call assert_equal('Xsomewhere', expand('%'))
   call assert_equal(3, getcurpos()[1])
 
+  " expansion on command line works with long lines when &wildoptions contains
+  " 'tagfile'
+  set wildoptions=tagfile
+  call writefile([
+	\ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa	file	/^pattern$/;"	f'
+	\ ], 'Xtags')
+  call feedkeys(":tag \<Tab>", 'tx')
+  " Should not crash
+  call assert_true(v:true)
+
   call delete('Xtags')
   call delete('Xsomewhere')
   set tags&
diff --git a/src/version.c b/src/version.c
index e064df3e7b590ec5c7e4c11b3c33d18f064577dc..dfe949d9d0428fc5369abad29c2b2d0a29cb8a54 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3362,
 /**/
     3361,
 /**/