[PATCH] D92361: [trivial-abi] Support types without a copy or move constructor.

Arthur O'Dwyer via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 3 20:38:33 PST 2020


Quuxplusone added a comment.

> You're right; thinking about it in the context of four value operations is helpful.

FWIW, I think dragging "value operations" into the mix is exactly wrong (and referring to "destructive move" is extra wrong, in the specific context of C++). For a C++ object, we do have language-level operations for "original initialization, copy, and destruction" (I'm willing to grant that "move" is just a special form of "copy"); but we don't have "destructive move," neither at the language level nor at the ABI level. `[[trivial_abi]]` isn't about //language//-level operations at all. It's about granting the compiler the freedom to //make up and insert// bitwise-teleportations of the object from point A to point B, //even when the language spec says no operation is happening.// So for example, in C++, if we have `struct T { T() { print(this); } }; void f(T a) { print(&a); }`, and we do `f(T())`, there is no "copy" happening — from C++'s point of view, there is only one `T` constructor called. However, the pointer value printed inside `T()` is permitted to be //different// from the pointer value printed inside `f` — basically, after the `T` object is "constructed," it gets bitwise-teleported to a different location in memory, //without being copied, moved, or anything else// at the language level. https://godbolt.org/z/e6hzPP

You can see that the code still compiles even when `T`'s copy and move operations are deleted. https://godbolt.org/z/hfr14v This is because those operations //are not happening//, at the C++ language level. As far as C++ is concerned, we've got just one `T` object. We're not destroying-it-and-moving-it-elsewhere; that'd be the "relocation" operation described in my P1144 <https://wg21.link/p1144> and D50119 <https://reviews.llvm.org/D50119>. A `[[trivially_relocatable]]` type permits the compiler to //replace// single pairs of "copy" and "destroy" operations with "bitwise-teleports." A `[[trivial_abi]]` type, on the other hand, permits the compiler to act at the //ABI// level and //insert// arbitrarily many "bitwise-teleport" operations even when the language spec calls for the object to remain in one place.

FWIW, (1) I doubt there's any reason to permit immovable objects to be `[[trivial_abi]]`; (2) I wish this attribute worked more like D50119 <https://reviews.llvm.org/D50119> `[[trivially_relocatable]]` and less like D50119 <https://reviews.llvm.org/D50119> `[[maybe_trivially_relocatable]]` (but I know @rjmccall feels exactly the opposite way). IMO, if the attribute simply meant "yes this thing is trivial for purposes of ABI and you can bitwise-teleport it whenever you like, full stop," then you wouldn't need to have these intricate discussions on precisely how triviality should be inherited in different situations — it would all "just work," as naturally as `[[trivially_relocatable]]`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92361/new/

https://reviews.llvm.org/D92361



More information about the cfe-commits mailing list