0

(Edited: I oversimplified the original version, accessing S::x as a public member rather than by getter.)

More than once I've had ASAN find bugs of this form:

#include <optional>
// Using optional as the example type because the UB
// seems to express as nullopt and throw.

struct S {
    std::optional<int> x;
    std::optional<int>& getX() { return x; }
};

inline S getS(int x) { return S{x}; }

// If we use this, below, it's OK because the S stays alive.
inline S& getSByRef(int x) {
    static S s{};
    s.x = x;
    return s;
}

int main() {
    const auto& x = getS(42).getX(); // If we do getS(42).x then it's OK because S's lifetime is extended.
    return x.value(); //< Use after scope!
}

https://godbolt.org/z/vxoG6T58b

If I use getSByRef() (returned by reference), this is fine (https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/). Likewise if I use getS(42).x. But since getS() returns by value, the temporary S goes out of scope by the next line, meaning the reference is dangling. ASAN can see these, but this seems like an obvious thing the compiler could catch, like it catches returning a local by reference (https://godbolt.org/z/1hjKPf5vM).

Is there a tool that can statically catch this?

Ben
  • 9,184
  • 1
  • 43
  • 56
  • 1
    This code is actually okay. The compiler is going to extend the lifetime of the entire `S` object, not just the `int` member. Trying to find the right dupe target. – NathanOliver Jun 14 '21 at 20:18
  • 1
    related/dupe: https://stackoverflow.com/questions/35947296/about-binding-a-const-reference-to-a-sub-object-of-a-temporary – NathanOliver Jun 14 '21 at 20:20
  • _"...Whenever a reference is bound to a temporary object __or to a subobject thereof__, the lifetime of the temporary object is extended to match the lifetime of the reference..."_ https://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary – Richard Critten Jun 14 '21 at 22:34
  • I need to double-check what case I had. Is the same true if the reference to a member is returned from an accessor? – Ben Jun 14 '21 at 22:56
  • No lifetime extension is not transative. – Richard Critten Jun 14 '21 at 23:04

0 Answers0