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

            Bug ID: 120467
           Summary: Analyzer: Diagnose cases where C++
                    'std::basic_string_view::data()' is used as
                    NUL-terminated string, but isn't
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: tschwinge at gcc dot gnu.org
  Target Milestone: ---

I guess this is too much to ask for GCC's standard diagnostics, but could the
analyzer maybe detect this case, where C++ 'std::basic_string_view::data()' is
used as NUL-terminated string, but isn't?

As is noted on
<https://en.cppreference.com/w/cpp/string/basic_string_view/data.html#Notes>:

> Unlike 'std::basic_string::data()' and string literals, 
> 'std::basic_string_view::data()' returns a pointer to a buffer that is not 
> necessarily null-terminated, for example a substring view (e.g. from 
> 'remove_suffix'). Therefore, it is typically a mistake to pass 'data()' to a 
> routine that takes just a 'const CharT*' and expects a null-terminated string.

Guess who just wrote code similar to this:

    #include <ostream>
    #include <sstream>

    int main()
    {
      /* Manually set up a buffer we can stream into, similar to 'cout <<
[...]', and print it at the end.  */
      std::stringbuf out_b;
      std::ostream out(&out_b);

      out << "Yo\n";

    #if 0
      /* Terminate with a NUL.  Otherwise, we'd have to use:
             __builtin_printf("%.*s", (int) out_b_sv.size(), out_b_sv.data());
      */
      out << '\0';
    #endif
      std::string_view out_b_sv = out_b.view();
      __builtin_printf("%s", out_b_sv.data());

      return 0;
    }

(The analyzer currently only reports PR120466 "Analyzer report for C++
'std::stringbuf' instantiation".)

    $ valgrind ./a.out 
    [...] Memcheck, a memory error detector
    [...] [...]
    [...] Conditional jump or move depends on uninitialised value(s)
    [...]    at 0x484ED28: strlen (vg_replace_strmem.c:494)
    [...]    by 0x4C78D30: __vfprintf_internal (vfprintf-internal.c:1517)
    [...]    by 0x4C6279E: printf (printf.c:33)
    [...]    by 0x401232: main (s.C:19)

Reply via email to