https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105369

            Bug ID: 105369
           Summary: Improved diagnostics for code from statement
                    expressions documentation [C component]
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: diagnostic, documentation
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: egallager at gcc dot gnu.org
  Target Milestone: ---

So, I'm going back to reading GCC documentation again; I last left off with the
statement expressions documentation:
https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs

I made this testcase from the plain-C code on that page:

$ cat stmt_exprs.c
int foo(void);
extern int global_var;

int compound_stmt(void)
{
    global_var++;
    return ({ int y = foo(); int z;
        if (y > 0) z = y;
        else z = -y;
        z; });
}

#define max_bad(a,b) ((a) > (b) ? (a) : (b))
#define maxint(a,b) \
  ({int _a = (a), _b = (b); (_a > _b) ? _a : _b; })

int unsafe(void)
{
    /* side effects: */
    return max_bad(foo(), compound_stmt());
}

int shadowing1(void)
{
    int _a = 1, _b = 2, c;
    c = max_bad(_a, _b);
    return c;
}

int shadowing2(void)
{
    int _a = 1, _b = 2, c;
    c = maxint(_a, _b);
    return c;
}

#define maxint3(a, b, c) \
  ({int _a = (a), _b = (b), _c = (c); maxint(maxint(_a, _b), _c); })

int shadowing3(void)
{
    int _a = 1, _b = 2, _c = 3, d;
    d = maxint3(_a, _b, _c);
    return d;
}

void bar1(void);
int bar2(void);
int baz(void);

int jumping(void)
{
a:
    return foo(), (({ bar1(); goto a; 0; }) + bar2()), baz();
}
$

The documentation says that the statement expression in compound_stmt() is a
"valid (though slightly more complex than necessary) expression" (for getting
an absolute value); maybe there could be a warning to just use abs() instead?
It could go under the existing -Wabsolute-value flag. Next, in unsafe(), the
documentation says that that usage of max_bad() "computes either a or b twice,
with bad results if the operand has side effects", which deserves a warning,
IMO; Karen Pease took advantage of this property of C to win the 2014
"Underhanded C Contest": http://www.underhanded-c.org/_page_id_26.html

As for the 3 shadowing functions, there are plenty of warnings from -Wshadow
and -Wunused-variable there already, so they're probably fine, although it
might help to clean up the display of them a bit. In the final function,
jumping(), the documentation says it "calls foo and bar1 and does not call baz
but may or may not call bar2. If bar2 is called, it is called after foo and
before bar1." This behavior may be surprising. However, there is no warning for
code like that with -Wall -Wextra -Wjump-misses-init. Perhaps there should be
one? Anyways, that's it for the plain-C code from that page; I'll open a
separate bug for the C++ if it turns out that that needs one, too.

Reply via email to