Add `__reference_binds_to_temporary` trait for checking safe reference initialization.

Summary:
The STL types `std::pair` and `std::tuple` can both store reference types. However their constructors cannot adequately check if the initialization of reference types is safe.  For example:

```
std::tuple<std::tuple<int> const&> t = 42;
// The stored reference is already dangling.
```

Libc++ has a best effort attempts in tuple to diagnose this, but they're not able to handle all valid cases (If I'm not mistaken). For example initialization of a reference from the result of a class's conversion operator.  Libc++ would benefit from having a builtin traits which can provide a much better implementation.

This patch introduce the `__reference_binds_to_temporary(T, U)` trait  that determines whether a reference of type `T` bound to an expression of type `U` would bind to a materialized temporary object.

Note that the trait simply returns false if `T` is not a reference type instead of reporting it as an error.

```
static_assert(__is_constructible(int const&, long));
static_assert(__reference_binds_to_temporary(int const&, long));
```


Reviewers: majnemer, rsmith

Reviewed By: rsmith

Subscribers: compnerd, cfe-commits

Differential Revision: https://reviews.llvm.org/D29930

llvm-svn: 322334
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 89055ae..5bbb367 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4645,11 +4645,14 @@
   if (Kind <= UTT_Last)
     return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType());
 
-  if (Kind <= BTT_Last)
+  // Evaluate BTT_ReferenceBindsToTemporary alongside the IsConstructible
+  // traits to avoid duplication.
+  if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary)
     return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
                                    Args[1]->getType(), RParenLoc);
 
   switch (Kind) {
+  case clang::BTT_ReferenceBindsToTemporary:
   case clang::TT_IsConstructible:
   case clang::TT_IsNothrowConstructible:
   case clang::TT_IsTriviallyConstructible: {
@@ -4726,6 +4729,13 @@
     if (Kind == clang::TT_IsConstructible)
       return true;
 
+    if (Kind == clang::BTT_ReferenceBindsToTemporary) {
+      if (!T->isReferenceType())
+        return false;
+
+      return !Init.isDirectReferenceBinding();
+    }
+
     if (Kind == clang::TT_IsNothrowConstructible)
       return S.canThrow(Result.get()) == CT_Cannot;