From a4b7169407e86de24cc43ec9dc405dc6ed08f545 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:30:03 +0900 Subject: [PATCH 01/18] Remove VLA in do_assignment Part of #239. --- arith.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arith.c b/arith.c index 39dbcd58..ab55edda 100644 --- a/arith.c +++ b/arith.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* arith.c: arithmetic expansion */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -287,10 +287,10 @@ bool do_assignment(const word_T *word, const value_T *value) if (vstr == NULL) return false; - wchar_t name[word->length + 1]; - wmemcpy(name, word->contents, word->length); - name[word->length] = L'\0'; - return set_variable(name, vstr, SCOPE_GLOBAL, false); + wchar_t *name = xwcsndup(word->contents, word->length); + bool ok = set_variable(name, vstr, SCOPE_GLOBAL, false); + free(name); + return ok; } /* Converts `value' to a newly-malloced wide string. From 0360ed36132b3a03acf73ad9469d267e6669eb01 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:30:54 +0900 Subject: [PATCH 02/18] Remove VLA in value_to_string Part of #239. --- arith.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/arith.c b/arith.c index ab55edda..af10da9a 100644 --- a/arith.c +++ b/arith.c @@ -306,16 +306,21 @@ wchar_t *value_to_string(const value_T *value) return malloc_wprintf(L"%.*g", DBL_DIG, value->v_double); case VT_VAR: { - wchar_t name[value->v_var.length + 1]; - wmemcpy(name, value->v_var.contents, value->v_var.length); - name[value->v_var.length] = L'\0'; + wchar_t *name = xwcsndup( + value->v_var.contents, value->v_var.length); const wchar_t *var = getvar(name); - if (var != NULL) - return xwcsdup(var); - if (shopt_unset) - return malloc_wprintf(L"%ld", 0L); - xerror(0, Ngt("arithmetic: parameter `%ls' is not set"), name); - return NULL; + wchar_t *result; + if (var != NULL) { + result = xwcsdup(var); + } else if (shopt_unset) { + result = malloc_wprintf(L"%ld", 0L); + } else { + xerror(0, Ngt("arithmetic: parameter `%ls' is not set"), + name); + result = NULL; + } + free(name); + return result; } } UNREACHABLE(); From e66b635cf7d28a290a8095814da63acd3f579a2b Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:31:59 +0900 Subject: [PATCH 03/18] Remove VLA in parse_as_number Part of #239. --- arith.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arith.c b/arith.c index af10da9a..3d32df05 100644 --- a/arith.c +++ b/arith.c @@ -1102,14 +1102,13 @@ void parse_primary(evalinfo_T *info, value_T *result) void parse_as_number(evalinfo_T *info, value_T *result) { word_T *word = &info->atoken.word; - wchar_t wordstr[word->length + 1]; - wcsncpy(wordstr, word->contents, word->length); - wordstr[word->length] = L'\0'; + wchar_t *wordstr = xwcsndup(word->contents, word->length); long longresult; if (xwcstol(wordstr, 0, &longresult)) { result->type = VT_LONG; result->v_long = longresult; + free(wordstr); return; } if (!posixly_correct) { @@ -1123,10 +1122,12 @@ void parse_as_number(evalinfo_T *info, value_T *result) if (ok) { result->type = VT_DOUBLE; result->v_double = doubleresult; + free(wordstr); return; } } xerror(0, Ngt("arithmetic: `%ls' is not a valid number"), wordstr); + free(wordstr); info->error = true; result->type = VT_INVALID; } From 89bde24c35a3a71b2bda9c2300edb6394805a5a7 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:32:25 +0900 Subject: [PATCH 04/18] Remove VLA in coerce_number Part of #239. --- arith.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arith.c b/arith.c index 3d32df05..e9eca5c6 100644 --- a/arith.c +++ b/arith.c @@ -1143,17 +1143,17 @@ void coerce_number(evalinfo_T *info, value_T *value) const wchar_t *varvalue; { word_T *name = &value->v_var; - wchar_t namestr[name->length + 1]; - wmemcpy(namestr, name->contents, name->length); - namestr[name->length] = L'\0'; + wchar_t *namestr = xwcsndup(name->contents, name->length); varvalue = getvar(namestr); if (varvalue == NULL && !shopt_unset) { xerror(0, Ngt("arithmetic: parameter `%ls' is not set"), namestr); + free(namestr); info->error = true; value->type = VT_INVALID; return; } + free(namestr); } if (varvalue == NULL || varvalue[0] == L'\0') { value->type = VT_LONG; From 025e6a4b3fff458508654a6761aad084813f94e1 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:33:08 +0900 Subject: [PATCH 05/18] Remove VLA in print_errmsg_token Part of #239. --- parser.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/parser.c b/parser.c index b19c4688..b8a6c103 100644 --- a/parser.c +++ b/parser.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* parser.c: syntax parser */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -883,10 +883,9 @@ void print_errmsg_token(parsestate_T *ps, const char *message) assert(ps->index <= ps->next_index); assert(ps->next_index <= ps->src.length); size_t length = ps->next_index - ps->index; - wchar_t token[length + 1]; - wcsncpy(token, &ps->src.contents[ps->index], length); - token[length] = L'\0'; + wchar_t *token = xwcsndup(&ps->src.contents[ps->index], length); serror(ps, message, token); + free(token); } const char *get_errmsg_unexpected_tokentype(tokentype_T tokentype) From 6bf219787082640876e0e0e3a5804e3749d73af6 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:34:34 +0900 Subject: [PATCH 06/18] Remove VLA in wglob_parse_pattern Reuse a single xwcsbuf_T for the pattern components instead of allocating a variable-length array on the stack in each iteration. Part of #239. --- path.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/path.c b/path.c index 39cf996c..5deb2451 100644 --- a/path.c +++ b/path.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* path.c: filename-related utilities */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -717,16 +717,18 @@ plist_T wglob_parse_pattern(const wchar_t *pattern, enum wglobflags_T flags) plist_T components; pl_init(&components); + xwcsbuf_T component; + wb_init(&component); + for (;;) { const wchar_t *slash = wcschr(pattern, L'/'); size_t componentlength = (slash != NULL) ? (size_t) (slash - pattern) : wcslen(pattern); - wchar_t component[componentlength + 1]; - wcsncpy(component, pattern, componentlength); - component[componentlength] = L'\0'; + wb_clear(&component); + wb_ncat(&component, pattern, componentlength); - struct wglob_pattern *c = - wglob_parse_component(component, flags, slash != NULL); + struct wglob_pattern *c = wglob_parse_component( + component.contents, flags, slash != NULL); if (c == NULL) { pl_clear(&components, wglob_free_pattern_vp); break; @@ -738,6 +740,7 @@ plist_T wglob_parse_pattern(const wchar_t *pattern, enum wglobflags_T flags) pattern = &slash[1]; } + wb_destroy(&component); return components; } From 8a7b88fbcfb2acf8096c964a13393851093c6bb4 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:35:19 +0900 Subject: [PATCH 07/18] Remove VLA in is_pathname_matching_pattern Part of #239. --- xfnmatch.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/xfnmatch.c b/xfnmatch.c index a66c71fa..60a508c1 100644 --- a/xfnmatch.c +++ b/xfnmatch.c @@ -163,14 +163,19 @@ bool is_pathname_matching_pattern(const wchar_t *pat) { const wchar_t *p; + xwcsbuf_T buf; + wb_init(&buf); + while ((p = wcschr(pat, L'/')) != NULL) { - wchar_t buf[p - pat + 1]; - wmemcpy(buf, pat, p - pat); - buf[p - pat] = L'\0'; - if (is_matching_pattern(buf)) + wb_clear(&buf); + wb_ncat(&buf, pat, p - pat); + if (is_matching_pattern(buf.contents)) { + wb_destroy(&buf); return true; + } pat = &p[1]; } + wb_destroy(&buf); return is_matching_pattern(pat); } From 25d3432cd742a60b21bc4af9aadf4925d8cf1c35 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:35:49 +0900 Subject: [PATCH 08/18] Remove VLA in get_common_prefix_length Part of #239. --- lineedit/complete.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lineedit/complete.c b/lineedit/complete.c index 11a467da..1072f6ba 100644 --- a/lineedit/complete.c +++ b/lineedit/complete.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* complete.c: command line completion */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1157,10 +1157,9 @@ size_t get_common_prefix_length(void) common_prefix_length = cpl; if (le_state_is_compdebug) { - wchar_t value[common_prefix_length + 1]; - wmemcpy(value, cand->origvalue, common_prefix_length); - value[common_prefix_length] = L'\0'; + wchar_t *value = xwcsndup(cand->origvalue, common_prefix_length); le_compdebug("candidate common prefix: \"%ls\"", value); + free(value); } return common_prefix_length; From 8a7685aee5670ff106e05d89e91bcd5f9aa68366 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:36:06 +0900 Subject: [PATCH 09/18] Remove VLA in update_main_buffer Part of #239. --- lineedit/complete.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lineedit/complete.c b/lineedit/complete.c index 1072f6ba..32229b44 100644 --- a/lineedit/complete.c +++ b/lineedit/complete.c @@ -1216,11 +1216,9 @@ void update_main_buffer(bool subst, bool finish) assert(srclen <= cpl); cand = le_candidates.contents[0]; - size_t valuelen = cpl - srclen; - wchar_t value[valuelen + 1]; - wcsncpy(value, cand->origvalue + srclen, valuelen); - value[valuelen] = L'\0'; + wchar_t *value = xwcsndup(cand->origvalue + srclen, cpl - srclen); quote("ed, value, quotetype); + free(value); } else { // Quote the selected candidate. cand = le_candidates.contents[le_selected_candidate_index]; From b89702c4b234b6153326c7c7d7623c2ff8253481 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:37:10 +0900 Subject: [PATCH 10/18] Remove VLA in exec_external_program The mbsargv array is now allocated on the heap with xmalloce. If execve succeeds, the memory is discarded by exec; on the failure path it is freed before returning. Part of #239. --- exec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 0a904dca..6e7c77d6 100644 --- a/exec.c +++ b/exec.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* exec.c: command execution */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1118,7 +1118,7 @@ wchar_t **invoke_simple_command( void exec_external_program( const char *path, int argc, char *argv0, void **argv, char **envs) { - char *mbsargv[argc + 1]; + char **mbsargv = xmalloce(argc, 1, sizeof *mbsargv); mbsargv[0] = argv0; for (int i = 1; i < argc; i++) { mbsargv[i] = malloc_wcstombs(argv[i]); @@ -1148,6 +1148,7 @@ void exec_external_program( for (int i = 1; i < argc; i++) free(mbsargv[i]); + free(mbsargv); } /* Calls `execve' until it doesn't return EINTR. */ From 69cbeddd52c49d541f843ad93befe19ba356d197 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:37:39 +0900 Subject: [PATCH 11/18] Remove VLA in exec_fall_back_on_sh Part of #239. --- exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 6e7c77d6..36ddd7bc 100644 --- a/exec.c +++ b/exec.c @@ -1168,7 +1168,7 @@ void exec_fall_back_on_sh( { assert(argv[argc] == NULL); - char *args[argc + 3]; + char **args = xmalloce(argc, 3, sizeof *args); size_t index = 0; args[index++] = "sh"; args[index++] = (char *) "-"; @@ -1196,6 +1196,7 @@ void exec_fall_back_on_sh( xexecve(shpath, args, envp); else errno = ENOENT; + free(args); xerror(errno, Ngt("cannot invoke a new shell to execute script `%s'"), argv[0]); } From 00d5b08f4b0237f95c58b64341fa5d74bbd1df81 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:38:44 +0900 Subject: [PATCH 12/18] Remove VLA in main Part of #239. --- yash.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/yash.c b/yash.c index 8a994434..7f93ac92 100644 --- a/yash.c +++ b/yash.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* yash.c: basic functions of the shell */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -103,7 +103,7 @@ struct input_file_info_T *stdin_input_file_info; /* The "main" function. The execution of the shell starts here. */ int main(int argc, char **argv) { - void *wargv[argc + 1]; + void **wargv = xmalloce(argc, 1, sizeof *wargv); const wchar_t *shortest_name; setvbuf(stdout, NULL, _IOLBF, BUFSIZ); @@ -236,6 +236,9 @@ int main(int argc, char **argv) set_signals(); set_positional_parameters(&wargv[xoptind]); + /* Not freeing the elements of `wargv' because some of them are used. */ + free(wargv); + if (is_login_shell && !posixly_correct && !options.noprofile) if (getuid() == geteuid() && getgid() == getegid()) execute_profile(options.profile); From dd25186da2b10aeff6b8452a2f935dce39243123 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:40:45 +0900 Subject: [PATCH 13/18] Remove VLA in print_embedded_command The extended_count workaround for empty variable-length arrays is no longer needed now that the array is allocated on the heap. Part of #239. --- parser.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/parser.c b/parser.c index b8a6c103..cc461aef 100644 --- a/parser.c +++ b/parser.c @@ -4086,13 +4086,8 @@ void print_embedded_command(struct print *pr, embedcmd_T ec, unsigned indent) return; } - size_t save_count = pr->pending_heredocs.length; - size_t extended_count = save_count; - if (extended_count == 0) - extended_count = 1; // A variable-length array must not be empty. - void *save_heredocs[extended_count]; - memcpy(save_heredocs, pr->pending_heredocs.contents, sizeof save_heredocs); - pl_truncate(&pr->pending_heredocs, 0); + plist_T save_heredocs = pr->pending_heredocs; + pl_init(&pr->pending_heredocs); print_and_or_lists(pr, ec.value.preparsed, indent, true); @@ -4106,7 +4101,8 @@ void print_embedded_command(struct print *pr, embedcmd_T ec, unsigned indent) } assert(pr->pending_heredocs.length == 0); - pl_ncat(&pr->pending_heredocs, save_heredocs, save_count); + pl_destroy(&pr->pending_heredocs); + pr->pending_heredocs = save_heredocs; } void print_indent(struct print *pr, unsigned indent) From f4c26f20fc81282a927878978926c3782f6e5465 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:42:11 +0900 Subject: [PATCH 14/18] Remove VLA in array_remove_elements The extended_count workaround for empty variable-length arrays is no longer needed now that the array is allocated on the heap. Part of #239. --- variable.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/variable.c b/variable.c index fb0d1f23..b78cb82f 100644 --- a/variable.c +++ b/variable.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* variable.c: deals with shell variables and parameters */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2161,10 +2161,7 @@ void array_remove_elements( const wchar_t *name, variable_T *array, size_t count, void *const *indexwcss) { - size_t extended_count = count; - if (extended_count == 0) - extended_count = 1; // A variable-length array must not be empty. - long indices[extended_count]; + long *indices = xmallocn(count, sizeof *indices); assert((array->v_type & VF_MASK) == VF_ARRAY); @@ -2173,6 +2170,7 @@ void array_remove_elements( const wchar_t *indexwcs = indexwcss[i]; if (!xwcstol(indexwcs, 10, &indices[i])) { xerror(errno, Ngt("`%ls' is not a valid integer"), indexwcs); + free(indices); return; } @@ -2210,6 +2208,7 @@ void array_remove_elements( } array->v_valc = newcount; array->v_vals[newcount] = NULL; + free(indices); if (newcount < oldcount) { variable_set(name, array); From ac993851dfe2a193d551b61267ffbabc3e324f45 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:43:17 +0900 Subject: [PATCH 15/18] Remove VLA in which A single xstrbuf_T allocated outside the loop is now reused to build the candidate pathnames. Part of #239. --- path.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/path.c b/path.c index 5deb2451..4b8ebcf8 100644 --- a/path.c +++ b/path.c @@ -283,22 +283,25 @@ char *which( return NULL; size_t namelen = strlen(name); + xstrbuf_T path; + sb_init(&path); for (const char *dir; (dir = *dirs) != NULL; dirs++) { size_t dirlen = strlen(dir); - char path[dirlen + namelen + 3]; + sb_clear(&path); if (dirlen > 0) { /* concatenate `dir' and `name' to produce a pathname `path' */ - strcpy(path, dir); - if (path[dirlen - 1] != '/') - path[dirlen++] = '/'; - strcpy(path + dirlen, name); + sb_ncat_force(&path, dir, dirlen); + if (path.contents[dirlen - 1] != '/') + sb_ccat(&path, '/'); + sb_ncat_force(&path, name, namelen); } else { /* if `dir' is empty, it's considered to be the current directory */ - strcpy(path, name); + sb_ncat_force(&path, name, namelen); } - if (cond(path)) - return xstrdup(path); + if (cond(path.contents)) + return sb_tostr(&path); } + sb_destroy(&path); return NULL; } From cf3a3a13e48f4644a60cde2ef64673f0b374af9a Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:44:02 +0900 Subject: [PATCH 16/18] Remove VLA for supplementary group IDs Part of #239. --- path.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/path.c b/path.c index 4b8ebcf8..afc771a7 100644 --- a/path.c +++ b/path.c @@ -160,13 +160,17 @@ bool check_access(const char *path, mode_t mode, int amode) int gcount = getgroups(0, &gid); /* the second argument is a dummy */ if (gcount > 0) { - gid_t groups[gcount]; + gid_t *groups = xmallocn(gcount, sizeof *groups); gcount = getgroups(gcount, groups); if (gcount > 0) { - for (int i = 0; i < gcount; i++) - if (gid == groups[i]) + for (int i = 0; i < gcount; i++) { + if (gid == groups[i]) { + free(groups); return st.st_mode & S_IRWXG; + } + } } + free(groups); } return st.st_mode & S_IRWXO; From 0aa05b14895da5e4a169917025d3d661d3b7d059 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Wed, 29 Jul 2026 22:45:01 +0900 Subject: [PATCH 17/18] Remove VLA in cmd_emacs_just_one_space The count is clamped to a constant bound, so a fixed-size buffer suffices. The bound is now a named constant. Part of #239. --- lineedit/editing.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lineedit/editing.c b/lineedit/editing.c index 081f96b6..f4e2b503 100644 --- a/lineedit/editing.c +++ b/lineedit/editing.c @@ -1,6 +1,6 @@ /* Yash: yet another shell */ /* editing.c: main editing module */ -/* (C) 2007-2025 magicant */ +/* (C) 2007-2026 magicant */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -3247,13 +3247,14 @@ void cmd_emacs_delete_horizontal_space(wchar_t c __attribute__((unused))) * If the count is specified, blanks are replaced with `count' spaces. */ void cmd_emacs_just_one_space(wchar_t c __attribute__((unused))) { +#define MAX_SPACE_COUNT 1000 /* The count is limited to avoid overflow. */ int count = get_count(1); if (count < 0) count = 0; - else if (count > 1000) - count = 1000; + else if (count > MAX_SPACE_COUNT) + count = MAX_SPACE_COUNT; - wchar_t s[count + 1]; + wchar_t s[MAX_SPACE_COUNT + 1]; wmemset(s, L' ', count); s[count] = L'\0'; From a5750a00099dec93659aba183e5c03c398102aab Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Thu, 30 Jul 2026 00:19:05 +0900 Subject: [PATCH 18/18] Add -Wvla to CFLAGS when debugging This prevents variable-length arrays from creeping back into the codebase. Closes #239. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f099514f..69300e8b 100755 --- a/configure +++ b/configure @@ -358,7 +358,7 @@ confighdefs='' # define options for debugging if ${debug} then - cflags="${CFLAGS--pedantic -MMD -Wall -Wextra -Og -fno-inline -ggdb}" + cflags="${CFLAGS--pedantic -MMD -Wall -Wextra -Wvla -Og -fno-inline -ggdb}" else defconfigh "NDEBUG" fi