Bug 95007 - RFE: -fanalyzer should complain about writes to string literals
Summary: RFE: -fanalyzer should complain about writes to string literals
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: analyzer (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: David Malcolm
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2020-05-08 14:09 UTC by David Malcolm
Modified: 2020-10-12 16:07 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Malcolm 2020-05-08 14:09:18 UTC
(Motivated by PR analyzer/95000, which has a false-positive path to a write to a string literal)

Consider:

void test (void)
{
  char *s = "foo";
  s[0] = 'g';
}

-fanalyzer should complain about the write to s[0], but currently doesn't

See e.g.
https://wiki.sei.cmu.edu/confluence/display/c/STR30-C.+Do+not+attempt+to+modify+string+literals
Comment 1 Eric Gallager 2020-05-11 04:42:57 UTC
You don't even need the analyzer for this; -Wwrite-strings already catches it:

$ /usr/local/bin/gcc -c -Wall -Wextra -Wwrite-strings 95007.c
95007.c: In function 'test':
95007.c:3:12: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
    3 |  char *s = "foo";
      |            ^~~~~
$

If you edit the source code to make 's' const to fix the -Wdiscarded-qualifiers warning, you then get this error instead:

$ /usr/local/bin/gcc -c -Wall -Wextra -Wwrite-strings 95007.c
95007.c: In function 'test':
95007.c:4:7: error: assignment of read-only location '*s'
    4 |  s[0] = 'g';
      |       ^
$

Although, I guess it is true that there are some drawbacks to using -Wwrite-strings, for example those described in bug 61579, so maybe having a separate analyzer warning for this could still be useful...
Comment 2 David Malcolm 2020-05-11 16:25:50 UTC
I guess I'm thinking about the case where a string literal has been exposed as a non-const "char *": the RFE here is for -fanalyzer to be able to detect if we ever write to such a string (with interprocedural analysis etc etc).
Comment 3 GCC Commits 2020-10-12 16:06:06 UTC
The master branch has been updated by David Malcolm <dmalcolm@gcc.gnu.org>:

https://gcc.gnu.org/g:3175d40fc52fb8eb3c3b18cc343d773da24434fb

commit r11-3829-g3175d40fc52fb8eb3c3b18cc343d773da24434fb
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Wed Oct 7 18:34:09 2020 -0400

    analyzer: add warnings about writes to constant regions [PR95007]
    
    This patch adds two new warnings:
      -Wanalyzer-write-to-const
      -Wanalyzer-write-to-string-literal
    for code paths where the analyzer detects a write to a constant region.
    
    As noted in the documentation part of the patch, the analyzer doesn't
    prioritize detection of such writes, in that the state-merging logic
    will blithely lose the distinction between const and non-const regions.
    Hence false negatives are likely to arise due to state-merging.
    
    However, if the analyzer does happen to spot such a write, it seems worth
    reporting, hence this patch.
    
    gcc/analyzer/ChangeLog:
            * analyzer.opt (Wanalyzer-write-to-const): New.
            (Wanalyzer-write-to-string-literal): New.
            * region-model-impl-calls.cc (region_model::impl_call_memcpy):
            Call check_for_writable_region.
            (region_model::impl_call_memset): Likewise.
            (region_model::impl_call_strcpy): Likewise.
            * region-model.cc (class write_to_const_diagnostic): New.
            (class write_to_string_literal_diagnostic): New.
            (region_model::check_for_writable_region): New.
            (region_model::set_value): Call check_for_writable_region.
            * region-model.h (region_model::check_for_writable_region): New
            decl.
    
    gcc/ChangeLog:
            * doc/invoke.texi: Document -Wanalyzer-write-to-const and
            -Wanalyzer-write-to-string-literal.
    
    gcc/testsuite/ChangeLog:
            PR c/83347
            PR middle-end/90404
            PR analyzer/95007
            * gcc.dg/analyzer/write-to-const-1.c: New test.
            * gcc.dg/analyzer/write-to-string-literal-1.c: New test.
Comment 4 David Malcolm 2020-10-12 16:07:03 UTC
Implemented by the above patch, with the caveat noted there.