/* { dg-additional-options "-O2" } */ extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__)); enum pipecmd_tag { PIPECMD_PROCESS, PIPECMD_SEQUENCE }; struct pipecmd { enum pipecmd_tag tag; union { struct pipecmd_process { int argc; int argv_max; char **argv; } process; struct pipecmd_sequence { int ncommands; int commands_max; struct pipecmd **commands; } sequence; } u; }; static char *argstr_get_word (const char **argstr) { while (**argstr) { switch (**argstr) { case ' ': case '\t': return (void *) 0; } } return (void *) 0; } struct pipecmd *pipecmd_new_argstr (const char *argstr) { argstr_get_word (&argstr); return (void *) 0; } void pipecmd_free (struct pipecmd *cmd) { int i; if (!cmd) return; switch (cmd->tag) { case PIPECMD_PROCESS: { struct pipecmd_process *cmdp = &cmd->u.process; for (i = 0; i < cmdp->argc; ++i) free (cmdp->argv[i]); free (cmdp->argv); break; } case PIPECMD_SEQUENCE: { struct pipecmd_sequence *cmds = &cmd->u.sequence; for (i = 0; i < cmds->ncommands; ++i) pipecmd_free (cmds->commands[i]); free (cmds->commands); break; } } free (cmd); }