f466f0beda59af1af182deb3cc8c006093d5a169 added a (non-suppressible) error when a [[trivial_abi]] struct's copy/move operations are all deleted. But that doesn't seem well-motivated to me. Whether a struct should be copied is a separate concern from whether it should be passed in registers / callee-destroyed.
#define ATTR [[clang::trivial_abi]]
struct ATTR S {
int i = 42;
S() { puts("constructed"); }
S(const S&) { __builtin_unreachable(); }
~S() { puts("destroyed"); }
};
int f(S s) { return 0; }
int main() {
return (f(S()), puts("hello"), 0);
}
This program correctly prints
constructed
destroyed
hello
because f's S parameter is trivial-abi and thus callee-destroy. S's copy constructor is unused, so we'd like to just delete it to avoid accidental calls. But if we do that, then the compiler starts ignoring the [[clang::trivial_abi]] attribute and the behavior of our code changes!
https://godbolt.org/z/68cTbr1aM
#define ATTR [[clang::trivial_abi]]
struct ATTR S {
int i = 42;
S() { puts("constructed"); }
S(const S&) = delete;
~S() { puts("destroyed"); }
};
int f(S s) { return 0; }
int main() {
return (f(S()), puts("hello"), 0);
}
This program prints
constructed
hello
destroyed
because the attribute is now being ignored. The compiler does print a warning (if you don't pass -w or -Wno-attributes):
<source>:4:8: warning: 'trivial_abi' cannot be applied to 'S' [-Wignored-attributes]
4 | struct ATTR S {
| ^
<source>:4:8: note: 'trivial_abi' is disallowed on 'S' because its copy constructors and move constructors are all deleted
I don't object to the warning; but it shouldn't ignore the attribute! It should obey the attribute and leave S as trivial-abi / callee-destroy. This would make for a simpler mental model.
f466f0beda59af1af182deb3cc8c006093d5a169 added a (non-suppressible) error when a
[[trivial_abi]]
struct's copy/move operations are all deleted. But that doesn't seem well-motivated to me. Whether a struct should be copied is a separate concern from whether it should be passed in registers / callee-destroyed.https://godbolt.org/z/TPaarh3sa
This program correctly prints
because
f
'sS
parameter is trivial-abi and thus callee-destroy.S
's copy constructor is unused, so we'd like to just delete it to avoid accidental calls. But if we do that, then the compiler starts ignoring the[[clang::trivial_abi]]
attribute and the behavior of our code changes! https://godbolt.org/z/68cTbr1aMThis program prints
because the attribute is now being ignored. The compiler does print a warning (if you don't pass
-w
or-Wno-attributes
):I don't object to the warning; but it shouldn't ignore the attribute! It should obey the attribute and leave
S
as trivial-abi / callee-destroy. This would make for a simpler mental model.https://github.com/llvm/llvm-project/issues/39031 is arguably related.