https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106148
Bug ID: 106148
Summary: RFE: warn about =- typos
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Keywords: diagnostic
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: dmalcolm at gcc dot gnu.org
Target Milestone: ---
Spot the mistake in the following code:
inbuf += OCB_BLOCK_LEN;
inbuflen -= OCB_BLOCK_LEN;
outbuf += OCB_BLOCK_LEN;
outbuflen =- OCB_BLOCK_LEN;
The C and C++ frontends should warn that the:
outbuflen =- OCB_BLOCK_LEN;
is parsed as:
outbuflen = -OCB_BLOCK_LEN;
when presumably the user meant to write:
outbuflen -= OCB_BLOCK_LEN;
but transposed the - and =.
A similar thing was seen in OpenJDK's java code:
https://bugs.openjdk.org/browse/JDK-8286689
which had:
to =- (int) TimeUnit.NANOSECONDS.toMillis(adjust);
rather than:
to -= (int) TimeUnit.NANOSECONDS.toMillis(adjust);
fixed by:
https://github.com/openjdk/jdk/commit/0be1f3e1b0f4ac515a86e9f8e1999dc090b1bdd2
I wondered if any other operators could be confused this way: you need a unary
prefix operator that can also be part of an assignment operator.
Comparing
https://en.cppreference.com/w/c/language/operator_assignment
and the unary prefix operators on:
https://en.cppreference.com/w/c/language/expressions
I think the confusable operators are: +, -, *, and &
i.e.
=+ vs +=
=- vs -=
=* vs *=
=& vs &=
of which I think the * and & are likely to result in type errors, whereas =+
and =- are probably most likely typos to lead to silently doing what a casual
reader doesn't expect. =+ has only a shift key difference; - and = seem most
likely due to visual impact and U.S. keyboard location.
Proposed implementation: if the C/C++ tokenizers see:
[..., EQUAL token, no whitespace, OPERATOR token, whitespace, ...]
where OPERATOR is PLUS or MINUS
then complain that "=OP" is not "OP=" or somesuch.
What to call it? (bikeshed alert)
-Wmisleading-unary-operator
-Wprobable-typo
-Wmisleading-whitespace
-Wsuspicious-token
Clang warns about this:
https://godbolt.org/z/Kqd9nja3E
but doesn't seem to have a command-line option to control the warning.