[llvm-bugs] [Bug 47377] Function pointer types defined using std::declval cannot be default initialized in a struct

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Aug 31 20:57:57 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=47377

Richard Smith <richard-llvm at metafoo.co.uk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|NEW                         |RESOLVED

--- Comment #1 from Richard Smith <richard-llvm at metafoo.co.uk> ---
Here's the diagnostic:

<source>:5:8: error: reference member 'fptr' binds to a temporary object whose
lifetime would be shorter than the lifetime of the constructed object
struct S {
       ^
<source>:10:7: note: in implicit default constructor for 'S' first required
here
    S thing;
      ^
<source>:6:17: note: initializing field 'fptr' with default member initializer
  function_type fptr = nullptr;
                ^      ~~~~~~~

So, this is telling you:

1) 'fptr' is a reference member.

   That's because declval always returns by reference, and decltype captures
that reference type. function_type is not a pointer-to-function type, it's a
reference-to-pointer-to-function type. In fact, because declval returns an
rvalue reference unless you give it an lvalue reference type, function_type is
an rvalue reference type.

2) When initializing 'fptr' using its default member initializer from the
implicit default constructor for 'S', we would bind that reference member to a
temporary object.

   That's because you provided an initializer of a different type
(std::nullptr_t) that we needed to convert to the referenced type of the
reference (the function pointer type), and that's done by creating a temporary
object of function pointer type, initialized from nullptr, and binding the
reference to the temporary.

3) The lifetime of that temporary object ends too soon to be useful.

   Temporary objects live on the stack, so they never outlive the function in
which they were constructed. In this case, that means the temporary function
pointer object would have gone away before the S default constructor returns,
so the default constructor would result in a broken object containing a
dangling reference.

4) That's an error.

   This changed in a semi-recent C++ language defect report resolution
(effectively, a bug fix for the C++ language). It used to be the case that this
situation just gave you a broken object with a dangling reference, and the
language bug fix says that that situation is simply a programming error. More
recent versions of Clang implement the language bug fix, so they reject your
(incorrect) code.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200901/a7ba03c0/attachment.html>


More information about the llvm-bugs mailing list