rjmccall added inline comments.

================
Comment at: include/clang/AST/Type.h:1121
+  /// after it is moved, as opposed to a truely destructive move in which the
+  /// source object is placed in an uninitialized state.
+  PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const;
----------------
ahatanak wrote:
> rjmccall wrote:
> > "truly"
> > 
> > Hmm.  Now that I'm thinking more about it, I'm not sure there's any point 
> > in tracking non-triviality of a C++-style destructive move separately from 
> > the non-triviality of a copy.  It's hard to imagine that there would ever 
> > be a non-C++ type that primitively has non-trivial copies but trivial 
> > C++-style moves or vice-versa.  Type-based destructors imply that the type 
> > represents some kind of resource, and a C++-style move will always be 
> > non-trivial for resource types because ownership of the resource needs to 
> > be given up by the old location.  Otherwise, a type might be non-trivial to 
> > copy but not destroy because there's something special about how it's 
> > stored (like volatility), but it's hard to imagine what could possibly 
> > cause it to be non-trivial to destroy but not copy.
> > 
> > If we were tracking non-triviality of an *unsafe* destructive move, one 
> > that leaves the source in an uninitialized state, that's quite different.
> > 
> > I think there are three reasonable options here:
> > 
> > - Ignore the argument I just made about the types that we're *likely* to 
> > care about modeling and generalize your tracking to also distinguish 
> > construction from assignment.  In such an environment, I think you can 
> > absolutely make an argument that it's still interesting to track C++-style 
> > moves separately from copies.
> > 
> > - Drop the tracking of destructive moves completely.  If you want to keep 
> > the method around, find, but it can just call 
> > `isNonTrivialToPrimitiveCopy()`.
> > 
> > - Change the tracking of *destructive* moves to instead track 
> > *deinitializing* moves.  The implementation would stop considering 
> > `__strong` types to be non-trivial to move.
> > 
> > But as things stand today, I do not see any point in separately tracking 
> > triviality of C++-style destructive moves.
> The second option seems most reasonable to me. We can always make changes if 
> someone comes up with a type that requires tracking destructive moves 
> separately.
Well, we already have a type that would have a trivial deinitializing move: ARC 
`__strong` pointers.  What we don't have is anything in IRGen that currently 
would take advantage of that fact.  Anyway, I agree that we can wait to start 
tracking this until we add such code to the compiler.


================
Comment at: lib/CodeGen/CGNonTrivialStruct.cpp:193
+
+    TrivialFieldIsVolatile |= FT.isVolatileQualified();
+    if (Start == End)
----------------
ahatanak wrote:
> rjmccall wrote:
> > ahatanak wrote:
> > > rjmccall wrote:
> > > > I feel like maybe volatile fields should be individually copied instead 
> > > > of being aggregated into a multi-field memcpy.  This is a more natural 
> > > > interpretation of the C volatile rules than we currently do.  In fact, 
> > > > arguably we should really add a PrimitiveCopyKind enumerator for 
> > > > volatile fields (that are otherwise trivially-copyable) and force all 
> > > > copies of structs with volatile fields into this path precisely so that 
> > > > we can make a point of copying the volatile fields this way.  
> > > > (Obviously that part is not something that's your responsibility to do.)
> > > > 
> > > > To get that right with bit-fields, you'll need to propagate the actual 
> > > > FieldDecl down.  On the plus side, that should let you use 
> > > > EmitLValueForField to do the field projection in the common case.
> > > I added method visitVolatileTrivial that copies volatile fields 
> > > individually. Please see test case test_copy_constructor_Bitfield1 in 
> > > test/CodeGenObjC/strong-in-c-struct.m.
> > Okay, great!  I like the name.
> > 
> > Does this mean we're now copying all structs that contain volatile fields 
> > with one of these helper functions?  If so, please add a C test case 
> > testing just that.  Also, you should retitle this review and stress that 
> > we're changing how *all* non-trivial types are copied, and that that 
> > includes both volatile and ARC-qualified fields.
> No, the current patch doesn't copy volatile fields of a struct individually 
> unless the struct is a non-trivial type (which means its primitive copy kind 
> is PCK_Struct). I'll look into today how I can force structs with volatile 
> fields that are not non-trivial to be copied using the helper functions.
> 
> It seems like we would need a boolean flag in RecordDecl that tracks the 
> presence of volatile fields in the struct or one of its subobjects. I assume 
> we want to copy volatile fields individually in C++ too, in which case the 
> flag needs to be set in both C and C++ mode. Is that right?
Oh, I see, there's specific logic to not flag the struct trivial if a field is 
merely VolatileTrivial.  Okay, that works for me; we can think about the right 
thing to do in a follow-up commit.  It probably needs to be raised as an RFC on 
cfe-dev.

The C++ standard has explicit language about triviality that says that volatile 
fields don't make defaulted copy-constructors non-trivial.  Whatever we do here 
can't break that.  But that doesn't necessarily imply that we should continue 
to use a simple memcpy to copy the struct; we could still use the C logic to 
copy "trivial" C++ structs with volatile members.

If we do try to apply this rule to C++, you will need to propagate these bits 
appropriately for C++ types, including from bases.


================
Comment at: lib/Sema/SemaDecl.cpp:15424
+      if (FT.isNonTrivialToPrimitiveCopy() != QualType::PCK_Trivial &&
+          FT.isNonTrivialToPrimitiveCopy() != QualType::PCK_VolatileTrivial)
+        Record->setNonTrivialToPrimitiveCopy();
----------------
Please compute isNonTrivialToPrimitiveCopy once here, it's not trivial.

...arguably we should figure out a way to do all these type checks once and 
then set the bits from that.  We can do that as a separate patch, though.


https://reviews.llvm.org/D41228



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

Reply via email to