public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/106393] New: Add warnings for common dangling problems
@ 2022-07-21 18:31 redi at gcc dot gnu.org
  2022-07-21 20:21 ` [Bug c++/106393] " mpolacek at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2022-07-21 18:31 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 106393
           Summary: Add warnings for common dangling problems
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Keywords: diagnostic
          Severity: enhancement
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
            Blocks: 87403
  Target Milestone: ---

It would be great if G++ was able to warn about the dangling problems below,
some of which are easier than others. Some might be too hard to do without
-fanalyze support for C++, some might be practical to do by leveraging the new
__reference_converts_from_temporary machinery to detect problems, some might
need entirely new ideas.


Simple:

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

This creates a temporary from the literal, returns a reference to the
temporary, but the temporary is destroyed at the end of the full expression.
We've had numerous bugs reported for this case when using std::max and
std::min.


Hard:

std::string_view s = std::string("blah");

This creates a temporary std::string that copies the literal "blah" to its own
memory (in this case in an internal buffer, but for longer strings into heap
buffers), then calls a member function of std::string that creates a string
view that holds a pointer to that memory, then destroys the std::string.

The analyzer should be able to tell that the pointer in the string view refers
to something that either goes out of scope with the string, or is deallocated
in the string's dtor. Doing it in the FE or ME without -fanalyze might be hard.

Maybe we could have a heuristic that warns when:

- constructing a local variable whose type is a borrowed view
- from an rvalue, non-view, non-borrowed range.

(Thanks to Ville V and Barry R for brainstorming this).
There will be some edge cases where the non-view range has iterators that do
outlive the range itself, and borrowing them is safe, but that will be rare.

The FE would either have to check the std::ranges::view and
std::ranges::borrowed_range concepts (and if they're not in scope, just don't
check ... it's probably not a view or a range if <ranges> isn't included!) or
as a simpler heuristic, just check for the value of the enable_view and
enable_borrowed_range bool variable templates.


Galaxy Brain:

#include <ranges>
#include <string>
#include <iostream>

std::string f() { return "dangle dangle dangle"; }

int main()
{
  auto v = std::string_view(f()) | std::views::transform([](char c) {
    if (c == 'l') return 'e';
    if (c == 'e') return 'r';
    return c;
  });
  for (char c : v)
    std::cout << c;
  std::cout << '\n';
}

Constructing a temporary string view from a std::string is fine, but then we
create another view of that temporary string view that outlives the thing the
string view refers to (the temporary std::string). By the time we iterate over
the range, the std::string is long gone.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87403
[Bug 87403] [Meta-bug] Issues that suggest a new warning

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

end of thread, other threads:[~2022-10-26 19:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-21 18:31 [Bug c++/106393] New: Add warnings for common dangling problems redi at gcc dot gnu.org
2022-07-21 20:21 ` [Bug c++/106393] " mpolacek at gcc dot gnu.org
2022-10-26 19:14 ` cvs-commit at gcc dot gnu.org
2022-10-26 19:15 ` mpolacek 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).