patch 9.0.1243: :setglobal cannot use script-local function for "expr" option

Problem:    :setglobal cannot use script-local function for "expr" option.
Solution:   Use the pointer to the option value properly. (closes #11883)
diff --git a/src/optionstr.c b/src/optionstr.c
index ea96c21..29f7f87 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -2311,8 +2311,8 @@
 	    varp == &p_dex ||
 # endif
 # ifdef FEAT_FOLDING
-	    varp == &curwin->w_p_fde ||
-	    varp == &curwin->w_p_fdt ||
+	    gvarp == &curwin->w_allbuf_opt.wo_fde ||
+	    gvarp == &curwin->w_allbuf_opt.wo_fdt ||
 # endif
 	    gvarp == &p_fex ||
 # ifdef FEAT_FIND_ID
@@ -2327,52 +2327,13 @@
 # endif
 	    varp == &p_ccv)
     {
-	char_u	**p_opt = NULL;
-	char_u	*name;
-
 	// If the option value starts with <SID> or s:, then replace that with
 	// the script identifier.
-# ifdef FEAT_BEVAL
-	if (varp == &p_bexpr)		// 'balloonexpr'
-	    p_opt = (opt_flags & OPT_LOCAL) ? &curbuf->b_p_bexpr : &p_bexpr;
-# endif
-# ifdef FEAT_DIFF
-	if (varp == &p_dex)	// 'diffexpr'
-	    p_opt = &p_dex;
-# endif
-# ifdef FEAT_FOLDING
-	if (varp == &curwin->w_p_fde)	// 'foldexpr'
-	    p_opt = &curwin->w_p_fde;
-	if (varp == &curwin->w_p_fdt)	// 'foldtext'
-	    p_opt = &curwin->w_p_fdt;
-# endif
-	if (gvarp == &p_fex)	// 'formatexpr'
-	    p_opt = &curbuf->b_p_fex;
-# ifdef FEAT_FIND_ID
-	if (gvarp == &p_inex)	// 'includeexpr'
-	    p_opt = &curbuf->b_p_inex;
-# endif
-	if (gvarp == &p_inde)	// 'indentexpr'
-	    p_opt = &curbuf->b_p_inde;
-# ifdef FEAT_DIFF
-	if (varp == &p_pex)	// 'patchexpr'
-	    p_opt = &p_pex;
-# endif
-# ifdef FEAT_POSTSCRIPT
-	if (varp == &p_pexpr)	// 'printexpr'
-	    p_opt = &p_pexpr;
-# endif
-	if (varp == &p_ccv)	// 'charconvert'
-	    p_opt = &p_ccv;
-
-	if (p_opt != NULL)
+	char_u *name = get_scriptlocal_funcname(*varp);
+	if (name != NULL)
 	{
-	    name = get_scriptlocal_funcname(*p_opt);
-	    if (name != NULL)
-	    {
-		free_string_option(*p_opt);
-		*p_opt = name;
-	    }
+	    free_string_option(*varp);
+	    *varp = name;
 	}
 
 # ifdef FEAT_FOLDING
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
index a70bc45..ec824b0 100644
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -330,8 +330,23 @@
   endfunc
   set indentexpr=s:NewIndentExpr()
   call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+  call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
   set indentexpr=<SID>NewIndentExpr()
   call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+  call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
+  setlocal indentexpr=
+  setglobal indentexpr=s:NewIndentExpr()
+  call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
+  call assert_equal('', &indentexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+  bw!
+  setglobal indentexpr=<SID>NewIndentExpr()
+  call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
+  call assert_equal('', &indentexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+  bw!
   set indentexpr&
 
   bw!
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index 7f75e91..a0291a0 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
Binary files differ
diff --git a/src/testdir/test_gf.vim b/src/testdir/test_gf.vim
index 3d429f3..8317cb5 100644
--- a/src/testdir/test_gf.vim
+++ b/src/testdir/test_gf.vim
@@ -227,6 +227,7 @@
   endfunc
   set includeexpr=s:IncludeFunc()
   call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+  call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
   new | only
   call setline(1, 'TestFile1')
   let g:IncludeFname = ''
@@ -235,11 +236,35 @@
   bw!
   set includeexpr=<SID>IncludeFunc()
   call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+  call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
   new | only
   call setline(1, 'TestFile2')
   let g:IncludeFname = ''
   call assert_fails('normal! gf', 'E447:')
   call assert_equal('TestFile2', g:IncludeFname)
+  bw!
+  setlocal includeexpr=
+  setglobal includeexpr=s:IncludeFunc()
+  call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
+  call assert_equal('', &includeexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+  call setline(1, 'TestFile3')
+  let g:IncludeFname = ''
+  call assert_fails('normal! gf', 'E447:')
+  call assert_equal('TestFile3', g:IncludeFname)
+  bw!
+  setlocal includeexpr=
+  setglobal includeexpr=<SID>IncludeFunc()
+  call assert_equal(expand('<SID>') .. 'IncludeFunc()', &g:includeexpr)
+  call assert_equal('', &includeexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+  call setline(1, 'TestFile4')
+  let g:IncludeFname = ''
+  call assert_fails('normal! gf', 'E447:')
+  call assert_equal('TestFile4', g:IncludeFname)
+  bw!
   set includeexpr&
   delfunc s:IncludeFunc
   bw!
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index 51a3676..5c92052 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -262,6 +262,7 @@
   endfunc
   set formatexpr=s:Format()
   call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
   new | only
   call setline(1, range(1, 40))
   let g:FormatArgs = []
@@ -270,6 +271,7 @@
   bw!
   set formatexpr=<SID>Format()
   call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
   new | only
   call setline(1, range(1, 40))
   let g:FormatArgs = []
@@ -277,6 +279,7 @@
   call assert_equal([4, 2], g:FormatArgs)
   bw!
   let &formatexpr = 's:Format()'
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
   new | only
   call setline(1, range(1, 40))
   let g:FormatArgs = []
@@ -284,12 +287,55 @@
   call assert_equal([6, 2], g:FormatArgs)
   bw!
   let &formatexpr = '<SID>Format()'
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
   new | only
   call setline(1, range(1, 40))
   let g:FormatArgs = []
   normal! 8GVjgq
   call assert_equal([8, 2], g:FormatArgs)
+  bw!
   setlocal formatexpr=
+  setglobal formatexpr=s:Format()
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
+  call assert_equal('', &formatexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+  call setline(1, range(1, 40))
+  let g:FormatArgs = []
+  normal! 10GVjgq
+  call assert_equal([10, 2], g:FormatArgs)
+  bw!
+  setglobal formatexpr=<SID>Format()
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
+  call assert_equal('', &formatexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+  call setline(1, range(1, 40))
+  let g:FormatArgs = []
+  normal! 12GVjgq
+  call assert_equal([12, 2], g:FormatArgs)
+  bw!
+  let &g:formatexpr = 's:Format()'
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
+  call assert_equal('', &formatexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+  call setline(1, range(1, 40))
+  let g:FormatArgs = []
+  normal! 14GVjgq
+  call assert_equal([14, 2], g:FormatArgs)
+  bw!
+  let &g:formatexpr = '<SID>Format()'
+  call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
+  call assert_equal('', &formatexpr)
+  new
+  call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+  call setline(1, range(1, 40))
+  let g:FormatArgs = []
+  normal! 16GVjgq
+  call assert_equal([16, 2], g:FormatArgs)
+  bw!
+  set formatexpr=
   delfunc s:Format
   bw!
 endfunc
diff --git a/src/version.c b/src/version.c
index 5c59444..47052dd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1243,
+/**/
     1242,
 /**/
     1241,