Why is this code not triggering a warning with `-Wlifetime`?
Asked Answered
K

0

6

I was reading the lifetime safety core guidelines paper and was eager to try the -Wlifetime flag in practice. For starters, I wrote the following simple example:

class Wrapper
{
public:
    Wrapper(std::string s)
        : str_(std::move(s))
    { }

    const std::string& GetString() const
    {
        return str_;
    }

private:
    std::string str_;
};

const std::string& example() {
    return Wrapper("abc").GetString();
}

It does emit some warnings, but apparently they arise within stdlib and are not related to my code:

In file included from <built-in>:1:
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3233:38: warning: returning a pointer with points-to set (*(*this).m_first) where points-to set ((null), **this) is expected [-Wlifetime]
  consteval iterator begin() const { return m_first; }
                                     ^~~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3235:36: warning: returning a pointer with points-to set (*(*this).m_last) where points-to set ((null), **this) is expected [-Wlifetime]
  consteval iterator end() const { return m_last; }
                                   ^~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3263:3: warning: returning a dangling pointer [-Wlifetime]
  return range(reflection, pred);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3276:10: note: in instantiation of function template specialization 'std::experimental::meta::v1::members_of<std::experimental::meta::v1::detail::always_true_fn>' requested here
  return members_of(reflection, detail::always_true);
         ^
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3263:10: note: it was never initialized here
  return range(reflection, pred);
         ^~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3281:3: warning: returning a dangling pointer [-Wlifetime]
  return param_range(reflection);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3281:10: note: it was never initialized here
  return param_range(reflection);
         ^~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3289:3: warning: returning a dangling pointer [-Wlifetime]
  return __reflect(detail::query_get_begin, reflection);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-cppx-trunk/include/experimental/meta:3289:10: note: it was never initialized here
  return __reflect(detail::query_get_begin, reflection);

(these warnings remain no matter what code I write, so I consider them irrelevant)

I am surprised by the lack of warnings in my code. As far as I understood the paper, the returned string should have a lifetime of Wrapper, since it is an implicit argument to Wrapper::GetString (1.1.4: "by default we assume that a function returns values that are derived from it's arguments"). I even added [[gsl::Owner(std::string)]] to the class definition, but with no luck.

Godbolt example with -Wlifetime enabled

Why does my code produce no warnings and is there a way to make the static analysis work in this case?

Kronick answered 8/11, 2020 at 20:21 Comment(13)
C++ compilers are pretty smart, but humans are smarter. You cannot rely on the compiler detecting every possible instance of undefined behavior.Peepul
@SamVarshavchik This is literally the purpose of -Wlifetime.Bromidic
@SamVarshavchik I know, but my question is simple: according to the paper as I understood it, this should produce warning, but it does not. Did I get it wrong or is it the imperfect implementation to blame?Kronick
I understand what it's purpose is. I also understand that every attempt to make something idiot-proof will only result in nature inventing a better idiot. As such, I would not expect such an option to be 100% idiotproof. P.S. gcc 10.2 emits a warning, and is able to detect undefined behavior, with the only option being -O2.Peepul
OP didn't expect anything to be "idiotproof", but asked a simple question about a specific compiler option and a specific piece of code. If you don't have a useful answer to that question, just move on instead of writing pointless insulting comments.Bromidic
I'm not sure what you mean. The demo you linked emits 5 warnings.Epirogeny
Agreed with @cigien, you do have to add -Wlifetime to the command to enable itSlump
The linked demo does emit the warnings you're asking about. Voting to close as not reproducible.Epirogeny
@Epirogeny The warnings it gives are unrelated to my code and they remain no matter what code I write. Edited the question to reflect that. Please kindly reopen the question.Kronick
Huh, you're absolutely right, those warnings are emitted from the header. Thanks for editing to clarify that. Voting to reopen.Epirogeny
This should be posted as an issue in the repo of the tool.Christophe
@Christophe You are probably right; I just wanted to make sure that it's not some silly mistake of mine that is the reason.Kronick
Btw "the tool" is clang.Kronick

© 2022 - 2024 — McMap. All rights reserved.