[Clang] Add __builtin_launder
AcceptedPublic

Authored by EricWF on Nov 18 2017, 3:03 PM.

Details

Summary

This patch adds __builtin_launder, which is required to implement std::launder. Additionally GCC provides __builtin_launder, so thing brings Clang in-line with GCC.

I'm not exactly sure what magic __builtin_launder requires, but based on previous discussions this patch applies a @llvm.invariant.group.barrier. As noted in previous discussions, this may not be enough to correctly handle vtables.

Diff Detail

EricWF created this revision.Nov 18 2017, 3:03 PM
EricWF updated this revision to Diff 123484.Nov 18 2017, 3:05 PM
  • Remove incorrect FIXME comment.

A test with restrict and __restrict might be interesting.

jroelofs added inline comments.
include/clang/Basic/Builtins.def
486

GCC's is type-generic:

#include <type_traits>

bool is_type_generic() {
  int v;
  return std::is_same<decltype(__builtin_launder(&v)),
                      decltype(&v)>::value;
}

However this BUILTIN line says that this one is not (yeah, I see it's being fixed up in Sema later in this patch). I think you need to use custom type checking here via t.

EricWF added inline comments.Nov 19 2017, 2:12 PM
include/clang/Basic/Builtins.def
486

The t is specified. It's in the third argument.

jroelofs added inline comments.Nov 19 2017, 2:13 PM
include/clang/Basic/Builtins.def
486

ohhh. duh. sorry.

EricWF updated this revision to Diff 123516.Nov 19 2017, 2:23 PM
  • Fix argument initialization.
  • Make constexpr.
EricWF updated this revision to Diff 123627.Nov 20 2017, 11:20 AM
  • Improve quality of tests.
  • Format code.
rsmith added inline comments.Dec 7 2017, 3:02 PM
lib/CodeGen/CGBuiltin.cpp
1674

It would be nice to avoid this for types that contain no const subobjects / reference subobjects / vptrs. I think we can also omit this entirely if -fstrict-vtable-ptrs is disabled, since in that case we don't generate any invariant.group metadata.

I'd be OK with the former being left to a future change, but the latter should be part of this change so we don't generate unnecessarily-inefficient code in the default mode for uses of std::launder.

lib/Sema/SemaChecking.cpp
861–865

Please also check that the pointee type is an object type -- per [ptr.launder]p3, "the program is ill-formed if T is a function type or cv void", and we don't want our builtin to need to deal with such cases.

EricWF marked 2 inline comments as done.Jan 12 2018, 5:23 PM
EricWF added inline comments.
lib/CodeGen/CGBuiltin.cpp
1674

I'll put it in this change set.

EricWF updated this revision to Diff 129740.Jan 12 2018, 5:25 PM
EricWF marked an inline comment as done.
  • Address inline comments about missing diagnostics for void pointers and function pointers.
  • Address inline comments about only enabling when -fstrict-vtable-pointers is specified, and only on types with vtables.
EricWF updated this revision to Diff 129742.Jan 12 2018, 5:49 PM
  • Improve diagnostic handling.
EricWF updated this revision to Diff 133290.Feb 7 2018, 1:17 PM
  • Rebase off master.
rsmith added inline comments.Feb 23 2018, 2:44 PM
lib/CodeGen/CGBuiltin.cpp
1947–1948

I think you also need to catch class types that contain dynamic classes as subobjects.

lib/Sema/SemaChecking.cpp
861

Might be a bit clearer to use llvm::Optional<unsigned> as the type of this.

test/CodeGenCXX/builtin-launder.cpp
94–97

I would note that this means adding optimizations for those cases later is an LTO ABI break. That's probably OK, but just something we're going to need to remember.

EricWF marked an inline comment as done.Mar 21 2018, 1:25 PM
EricWF added inline comments.
lib/CodeGen/CGBuiltin.cpp
1947–1948

Only by-value subobjects, or also reference subobjects?

EricWF marked 2 inline comments as done.Mar 21 2018, 1:46 PM
EricWF added inline comments.
test/CodeGenCXX/builtin-launder.cpp
94–97

I added your note almost verbatim to the test case.

EricWF updated this revision to Diff 139363.Mar 21 2018, 1:48 PM
EricWF marked an inline comment as done.
  • Launder types with subobjects of dynamic class type.
  • Improve diagnostic selection using llvm::Optional<unsigned>.
  • Add comment about LTO ABI concerns to test file.
  • Merge with master.
rsmith accepted this revision.May 14 2018, 11:34 AM

LGTM with a fix (and test) for pointer-to-array-of-dynamic-class-type handling.

lib/CodeGen/CGBuiltin.cpp
936–938

I think you also need to recurse through array types (use Ty->getBaseElementTypeUnsafe()->getAsCXXRecordDecl() or similar).

This revision is now accepted and ready to land.May 14 2018, 11:34 AM

Also we probably want to hold off on landing this until PR37458 is fixed, otherwise std::launder will start miscompiling code.

amharc added a subscriber: amharc.May 16 2018, 12:28 AM
EricWF updated this revision to Diff 147639.May 18 2018, 7:37 PM
  • Handle array types as requested.
  • Attempt to handle incomplete class types. They are always considered in need of laundering. Including class templates who's instantiation hasn't been forced yet. @rsmith is this the correct thing to do?