Quuxplusone marked 3 inline comments as done.
Quuxplusone added inline comments.


================
Comment at: docs/LanguageExtensions.rst:1096
+  equivalent to copying the underlying bytes and then dropping the source 
object
+  on the floor.
 * ``__is_destructible`` (MSVC 2013)
----------------
@rjmccall wrote:
> trivial_abi permits annotated types to be passed and returned in registers, 
> which is ABI-breaking. Skimming the blog post, it looks like 
> trivially_relocatable does not permit this — it merely signifies that 
> destruction is a no-op after a move construction or assignment.

Not necessarily a "no-op"; my canonical example is a CopyOnlyCXX03SharedPtr 
which increments a refcount on construction and decrements on destruction. But 
move-construction plus destruction should "balance out" and result in no 
observable side effects.

> This is usefully different in the design space, since it means you can safely 
> add the attribute retroactively to e.g. std::unique_ptr, and other templates 
> can then detect that std::unique_ptr is trivially-relocatable and optimize 
> themselves to use memcpy or realloc or whatever it is that they want to do. 
> So in that sense trivial_abi is a *stronger* attribute, not a *weaker* one: 
> the property it determines ought to imply trivially_relocatable.

`trivial_abi` is an "orthogonal" attribute: you can have `trivial_abi` types 
with non-trivial constructors and destructors, which can have observable side 
effects. For example,
```
struct [[clang::trivial_abi]] DestructionAnnouncer {
    ~DestructionAnnouncer() { puts("hello!"); }
};
```
is `trivial_abi` (because of the annotation) yet not trivially relocatable, 
because its "move plus destroy" operation has observable side effects.

> The only interesting question in the language design that I know of is what 
> happens if you put the attribute on a template that's instantiated to contain 
> a sub-object that is definitely not trivially relocatable / trivial-ABI. For 
> trivial_abi, we decided that the attribute is simply ignored — it implicitly 
> only applies to specializations where the attribute would be legal. I haven't 
> dug into the design enough to know what trivially_relocatable decides in this 
> situation, but the three basic options are:
>
> - the attribute always has effect and allows trivial relocation regardless of 
> the subobject types; this is obviously unsafe, so it limits the safe 
> applicability of the attribute to templates
> - the attribute is ignored, like trivial_abi is
> - the attribute is ill-formed, and you'll need to add a 
> [[trivially_relocatable(bool)]] version to support templates

What happens is basically the first thing you said, except that I disagree that 
it's "obviously unsafe." Right now, conditionally trivial relocation is 
possible via template metaprogramming; see the libcxx patch at e.g.
https://github.com/Quuxplusone/libcxx/commit/6524822c009e#diff-38adc80cec663f2f29c22e9ffc0de912
Since the attribute is an opt-in mechanism, it makes perfect sense to me that 
if you put it on a class (or class template), then it applies to the class, 
without any further sanity-checking by the compiler. The compiler has no reason 
to second-guess the programmer here.

However, there's one more interesting case. Suppose the programmer puts the 
attribute on a class that isn't relocatable at all! (For example, the union 
case @erichkeane mentioned, or a class type with a deleted destructor.) In that 
case, this patch *does* give an error... *unless* the class was produced by 
instantiating a template, in which case we *don't* give an error, because it's 
not the template-writer's fault.
https://p1144.godbolt.org/z/wSZPba


Repository:
  rC Clang

https://reviews.llvm.org/D50119



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to