public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/109548] New: Detect c_str() dangling problems
@ 2023-04-18 23:19 paul.f.fee at gmail dot com
  2023-04-18 23:34 ` [Bug c++/109548] " pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: paul.f.fee at gmail dot com @ 2023-04-18 23:19 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 109548
           Summary: Detect c_str() dangling problems
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: paul.f.fee at gmail dot com
  Target Milestone: ---

Thanks to bug 106393, G++ 13 can now catch simple dangling references, such as:

const int& f(const int& i) { return i; }
const int& i = f(10);

However, more complex examples do not trigger warnings:

#include <string>
std::string foo();
auto ptr = foo().c_str();

ASAN can detect stack-use-after-scope at runtime.  Clang can catch the issue at
build time.

$ clang++ -c small.cpp 
small.cpp:3:12: warning: object backing the pointer will be destroyed at the
end of the full-expression [-Wdangling-gsl]
auto ptr = foo().c_str();
           ^~~~~
1 warning generated.

Another example:

std::stringstream ss;
ss << "foo";
auto ptr = ss.str().c_str();

We're warned against this in the notes on cppreference.com, however it would be
better if GCC could detect such issues and warn during compilation.
https://en.cppreference.com/w/cpp/io/basic_stringstream/str

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/109548] Detect c_str() dangling problems
  2023-04-18 23:19 [Bug c++/109548] New: Detect c_str() dangling problems paul.f.fee at gmail dot com
@ 2023-04-18 23:34 ` pinskia at gcc dot gnu.org
  2023-04-19  8:59 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-04-18 23:34 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/109548] Detect c_str() dangling problems
  2023-04-18 23:19 [Bug c++/109548] New: Detect c_str() dangling problems paul.f.fee at gmail dot com
  2023-04-18 23:34 ` [Bug c++/109548] " pinskia at gcc dot gnu.org
@ 2023-04-19  8:59 ` redi at gcc dot gnu.org
  2023-04-19  9:45 ` rguenth at gcc dot gnu.org
  2023-04-19 12:38 ` redi at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2023-04-19  8:59 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2023-04-19
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
We could special-case std::basic_string::c_str() here but maybe it would be
better to add an attribute for describing the lifetime of pointers/references
returned from member functions.

We could annotate string::c_str() and string::data() and string::begin() etc.
to indicate that they share the lifetime of *this:

    [[gnu::lifetime(this)]]
    const charT*
    basic_string<charT, traits, Alloc>::c_str() const noexcept;

And maybe annotate member functions of view-like types to say that they _don't_
share the lifetime of *this:

    [[gnu::lifetime(!this)]]
    T*
    span<T, E>::data() const noexcept;

(!this) is not visually distinct from (this) though, so a different syntax
would be better. Maybe lifetime(nullptr) or lifetime(0)?

It might not be possible to use lifetime(this) annotations for non-trivial
analysis, because of cases like this:

    std::string s = "abc";
    auto p = s.c_str();  // OK
    s.clear();           // p now dangles
    *p;                  // ERR

Without creating a DSL for describing iterator invalidation of members like
string::clear() and string::insert() we can probably only use such an attribute
to allow the front-end to diagnose the simplest cases like foo().c_str() in
comment 0.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/109548] Detect c_str() dangling problems
  2023-04-18 23:19 [Bug c++/109548] New: Detect c_str() dangling problems paul.f.fee at gmail dot com
  2023-04-18 23:34 ` [Bug c++/109548] " pinskia at gcc dot gnu.org
  2023-04-19  8:59 ` redi at gcc dot gnu.org
@ 2023-04-19  9:45 ` rguenth at gcc dot gnu.org
  2023-04-19 12:38 ` redi at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-04-19  9:45 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dmalcolm at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
David possibly has inputs on how this should be done so the analyzer can do
this kind of diagnostic.  Generally I'd say we want sth like

 T * __attribute__ ((return_lifetime(1))) foo (U *p, ...);

where we specify the lifetime of the returned referenced object to be
the same as a referenced object in the argument list?  So yes, the
[[gnu::lifetime(this)]] attribution would maybe do that but can
the attribute refer to another explicitely named argument as well?

Btw, is there an API to std::move the (possibly) allocated string out of
the std::string and make it available as C string pointer?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/109548] Detect c_str() dangling problems
  2023-04-18 23:19 [Bug c++/109548] New: Detect c_str() dangling problems paul.f.fee at gmail dot com
                   ` (2 preceding siblings ...)
  2023-04-19  9:45 ` rguenth at gcc dot gnu.org
@ 2023-04-19 12:38 ` redi at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2023-04-19 12:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #2)
> Btw, is there an API to std::move the (possibly) allocated string out of
> the std::string and make it available as C string pointer?

No, ownership always belongs to a std::string object.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-04-19 12:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-18 23:19 [Bug c++/109548] New: Detect c_str() dangling problems paul.f.fee at gmail dot com
2023-04-18 23:34 ` [Bug c++/109548] " pinskia at gcc dot gnu.org
2023-04-19  8:59 ` redi at gcc dot gnu.org
2023-04-19  9:45 ` rguenth at gcc dot gnu.org
2023-04-19 12:38 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).