Bug 61579 - -Wwrite-strings does not behave as a warning option
Summary: -Wwrite-strings does not behave as a warning option
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2014-06-21 11:34 UTC by Rich Felker
Modified: 2022-02-21 15:31 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-07-22 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rich Felker 2014-06-21 11:34:50 UTC
Unlike other -W family options, -Wwrite-strings does not actually behave as a warning option but as an option that alters the language semantics. I think this inconsistency should be considered a bug and fixed. It leads to multiple issues:

1. Warning messages wrongly show as [enabled by default] rather than [-Wwrite-strings], since discarding const qualifier is enabled by default.

2. Some code which should produce a warning actually produces an error. As a trivial but stupid example, if(0)*""=0; One can of course construct non-trivial, non-stupid examples of this, particularly with the ?: operator.

3. The semantics of code using __typeof__, ?:, and now more importantly with C11, _Generic, are changed by -Wwrite-strings. As a particularly bad case, I think this could lead to the introduction of aliasing violations and undefined behavior in code that had well-defined behavior without -Wwrite-strings.

Ideally the current implementation of -Wwrite-strings should be scrapped and replaced with one that actually detects particular usage that's deemed dangerous rather than changing the language semantics.
Comment 1 Manuel López-Ibáñez 2014-06-21 15:45:07 UTC
Agreed. It seems that in order to get the desired warning, the solution was to change the type and warn implicitly, rather than detect the potential cases explicitly. This is a quite ugly hack.

On the other hand, I don't expect an existing GCC developer to fix this, given the long history of -Wwrite-strings. Someone new will have to step up, implement it and defend it in front of the C FE maintainers.
Comment 2 Marek Polacek 2014-07-22 16:50:46 UTC
Confirmed.  I might possibly get to this.
Comment 3 Eric Gallager 2018-06-11 05:31:44 UTC
(In reply to Marek Polacek from comment #2)
> Confirmed.  I might possibly get to this.

For gcc 9 maybe?
Comment 4 Marek Polacek 2018-06-11 20:04:36 UTC
Wow, how has it been 4 years already?  Maybe this time around then.  :)
Comment 5 Eric Gallager 2018-10-19 04:48:36 UTC
(In reply to Marek Polacek from comment #4)
> Wow, how has it been 4 years already?  Maybe this time around then.  :)

Hopefully! I keep seeing it come up places...
Comment 6 Rich Felker 2019-12-15 01:20:03 UTC
Ping.
Comment 7 David Brown 2020-07-22 13:22:37 UTC
Could "-Wwrite-strings" be split into two options?  The warning could remain (and become part of -Wall for C as well as C++) if the compiler can spot and warn about attempts to write to string literals, while keeping these of type "char[len]" as required by C.

A new option "-fconst-strings" could be put under "Code Gen Options" which makes C string literals be type "const char[len]" for those that want it, encouraging a slightly safer code style that is not standard C.
Comment 8 Manuel López-Ibáñez 2020-07-22 13:42:46 UTC
(In reply to David Brown from comment #7)
> Could "-Wwrite-strings" be split into two options?  The warning could remain
> (and become part of -Wall for C as well as C++) if the compiler can spot and
> warn about attempts to write to string literals, while keeping these of type
> "char[len]" as required by C.

I think the issue is that the warning is implemented by changing the type of string literals and then using the already existing warning for passing const char* to char*. Someone would need to reimplement the warning to explicitly detect string literals instead of changing their type, probably somewhere in this function: https://github.com/gcc-mirror/gcc/blob/259c3965b1ba04f7ee022846af6173fb1c343bc8/gcc/c/c-typeck.c#L6585
 
> A new option "-fconst-strings" could be put under "Code Gen Options" which
> makes C string literals be type "const char[len]" for those that want it,
> encouraging a slightly safer code style that is not standard C.

I am not sure this is a good solution, since the only benefit of -fconst-strings would be to trigger the warnings. I'm pretty sure it will not affect optimization, so it is useless as a codegen option. It doesn't solve all the issues described in comment #0.

The fix is the one outlined above: detect that the argument or assigment is a literal string and special case the "discarding const qualifier" to trigger in that case with -Write-strings.

But, the only way to find out for sure is to submit a patch to gcc-patches and start the discussion.
Comment 9 Martin Sebor 2020-07-22 17:32:24 UTC
pr90404 is somewhat related to this: it requests a new warning option to flag attempts to modify a const object of any type/kind.  In my prototype implementation of it that I hope to submit for GCC 11 I call the option -Wwrite-const.  It's implemented in the middle end so it detects all such attempts, including for instance things like '*strchr("x", 'x') = 0', and avoids triggering on provably unreachable code.  It's just as capable as other late warnings, but, of course, also subject to just as many false positives and negatives as they are.