Issue 174179
Summary std::optional of class annotated with clang::trivial_abi is not trivial for purpose of calls
Labels clang
Assignees
Reporter es1024
    Consider the following ([godbolt](https://godbolt.org/z/Yd6d4Y3MM)):
```c++
#include <optional>

struct TrivialDestructor {
  ~TrivialDestructor() = default;
 int x = 0;
};

struct [[clang::trivial_abi]] NontrivialDestructor {
 ~NontrivialDestructor() {}
  int x = 0;
};

TrivialDestructor trivial() { return {}; }
std::optional<TrivialDestructor> trivial_optional() { return {}; }

NontrivialDestructor nontrivial() { return {}; }
std::optional<NontrivialDestructor> nontrivial_optional() { return {}; }
```

NontrivialDestructor has a nontrivial destructor, but since it is annotated with clang::trivial_abi, nontrivial() is able to return the object in registers instead of on the stack and compiles exactly the same as trivial():
```
trivial():
        push    rbp
        mov     rbp, rsp
 mov     dword ptr [rbp - 4], 0
        mov     eax, dword ptr [rbp - 4]
        pop     rbp
        ret

nontrivial():
        push    rbp
 mov     rbp, rsp
        mov     dword ptr [rbp - 4], 0
        mov eax, dword ptr [rbp - 4]
        pop     rbp
        ret
```

But nontrivial_optional() constructs the object on the stack, even though it could be passed around in registers like trivial_optional() does:
```
trivial_optional():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        lea     rdi, [rbp - 8]
        call std::__1::optional<TrivialDestructor>::optional[abi:sqe220000]()
        mov rax, qword ptr [rbp - 8]
        add     rsp, 16
        pop     rbp
 ret

nontrivial_optional():
        push    rbp
        mov rbp, rsp
        sub     rsp, 16
        mov     rax, rdi
        mov qword ptr [rbp - 16], rax
        mov     qword ptr [rbp - 8], rdi
 call    std::__1::optional<NontrivialDestructor>::optional[abi:sqe220000]()
 mov     rax, qword ptr [rbp - 16]
        add     rsp, 16
 pop     rbp
        ret
```

The same issue was also observed for std::variant and std::expected.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to