diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1f5255dae7ff..9a31dd8ef872 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3871,6 +3871,10 @@ void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) {
     // FIXME: a compatible, but different, explicit exception specification
     // will be silently overridden. We should issue a warning if this happens.
     EPI.ExtInfo = CtorType->getExtInfo();
+
+    // Such a function is also trivial if the implicitly-declared function
+    // would have been.
+    CD->setTrivial(CD->getParent()->hasTrivialDefaultConstructor());
   }
 
   if (HadError) {
@@ -3966,6 +3970,10 @@ void Sema::CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *CD) {
     //  -- [...] it shall have the same parameter type as if it had been
     //     implicitly declared.
     CD->setType(Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI));
+
+    // Such a function is also trivial if the implicitly-declared function
+    // would have been.
+    CD->setTrivial(CD->getParent()->hasTrivialCopyConstructor());
   }
 
   if (HadError) {
@@ -4053,6 +4061,10 @@ void Sema::CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *MD) {
     EPI.RefQualifier = OperType->getRefQualifier();
     EPI.ExtInfo = OperType->getExtInfo();
     MD->setType(Context.getFunctionType(ReturnType, &ArgType, 1, EPI));
+
+    // Such a function is also trivial if the implicitly-declared function
+    // would have been.
+    MD->setTrivial(MD->getParent()->hasTrivialCopyAssignment());
   }
 
   if (HadError) {
@@ -4146,6 +4158,10 @@ void Sema::CheckExplicitlyDefaultedMoveConstructor(CXXConstructorDecl *CD) {
     //  -- [...] it shall have the same parameter type as if it had been
     //     implicitly declared.
     CD->setType(Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI));
+
+    // Such a function is also trivial if the implicitly-declared function
+    // would have been.
+    CD->setTrivial(CD->getParent()->hasTrivialMoveConstructor());
   }
 
   if (HadError) {
@@ -4231,6 +4247,10 @@ void Sema::CheckExplicitlyDefaultedMoveAssignment(CXXMethodDecl *MD) {
     EPI.RefQualifier = OperType->getRefQualifier();
     EPI.ExtInfo = OperType->getExtInfo();
     MD->setType(Context.getFunctionType(ReturnType, &ArgType, 1, EPI));
+
+    // Such a function is also trivial if the implicitly-declared function
+    // would have been.
+    MD->setTrivial(MD->getParent()->hasTrivialMoveAssignment());
   }
 
   if (HadError) {
@@ -4278,6 +4298,10 @@ void Sema::CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *DD) {
     // There are no parameters.
     EPI.ExtInfo = DtorType->getExtInfo();
     DD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
+
+    // Such a function is also trivial if the implicitly-declared function
+    // would have been.
+    DD->setTrivial(DD->getParent()->hasTrivialDestructor());
   }
 
   if (ShouldDeleteSpecialMember(DD, CXXDestructor)) {
@@ -10254,6 +10278,35 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
     // recovery.
   }
   Fn->setDeletedAsWritten();
+
+  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Dcl);
+  if (!MD)
+    return;
+
+  // A deleted special member function is trivial if the corresponding
+  // implicitly-declared function would have been.
+  switch (getSpecialMember(MD)) {
+  case CXXInvalid:
+    break;
+  case CXXDefaultConstructor:
+    MD->setTrivial(MD->getParent()->hasTrivialDefaultConstructor());
+    break;
+  case CXXCopyConstructor:
+    MD->setTrivial(MD->getParent()->hasTrivialCopyConstructor());
+    break;
+  case CXXMoveConstructor:
+    MD->setTrivial(MD->getParent()->hasTrivialMoveConstructor());
+    break;
+  case CXXCopyAssignment:
+    MD->setTrivial(MD->getParent()->hasTrivialCopyAssignment());
+    break;
+  case CXXMoveAssignment:
+    MD->setTrivial(MD->getParent()->hasTrivialMoveAssignment());
+    break;
+  case CXXDestructor:
+    MD->setTrivial(MD->getParent()->hasTrivialDestructor());
+    break;
+  }
 }
 
 void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
diff --git a/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
index d401a97ca25c..06dd1bb05560 100644
--- a/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -35,7 +35,8 @@ struct S3 {
 };
 constexpr S3 s3a = S3(0);
 constexpr S3 s3b = s3a;
-constexpr S3 s3c = S3(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+constexpr S3 s3c = S3();
+constexpr S3 s3d; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
 
 struct S4 {
   S4() = default;
diff --git a/clang/test/CXX/special/class.ctor/p5-0x.cpp b/clang/test/CXX/special/class.ctor/p5-0x.cpp
index b2fa0cf29844..b81755dcd33e 100644
--- a/clang/test/CXX/special/class.ctor/p5-0x.cpp
+++ b/clang/test/CXX/special/class.ctor/p5-0x.cpp
@@ -25,10 +25,8 @@ union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{defined here}}
 Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
 union NotDeleted1a { DefaultedDefCtor1 nu; };
 NotDeleted1a nd1a;
-// FIXME: clang implements the pre-FDIS rule, under which DefaultedDefCtor2's
-// default constructor is non-trivial.
-union NotDeleted1b { DefaultedDefCtor2 nu; }; // unexpected-note {{defined here}}
-NotDeleted1b nd1b; // unexpected-error {{implicitly-deleted default constructor}}
+union NotDeleted1b { DefaultedDefCtor2 nu; };
+NotDeleted1b nd1b;
 
 // - any non-static data member with no brace-or-equal-initializer is of
 // reference type,
@@ -170,4 +168,3 @@ static_assert(__has_trivial_constructor(Trivial4<int>), "Trivial4 is trivial");
 
 template<typename T> class Trivial5 { Trivial5() = delete; };
 static_assert(__has_trivial_constructor(Trivial5<int>), "Trivial5 is trivial");
-
diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp
index 6af5188a41f6..9f808f6680ed 100644
--- a/clang/test/CodeGenCXX/constructor-init.cpp
+++ b/clang/test/CodeGenCXX/constructor-init.cpp
@@ -201,7 +201,7 @@ namespace PR10720 {
     pair2(const pair2&) = default;
   };
 
-  struct pair {
+  struct pair : X { // Make the copy constructor non-trivial, so we actually generate it.
     int second[4];
     // CHECK-PR10720: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_
     // CHECK-PR10720-NOT: ret
@@ -220,4 +220,3 @@ namespace PR10720 {
   }
 
 }
-
diff --git a/clang/test/CodeGenCXX/pr9965.cpp b/clang/test/CodeGenCXX/pr9965.cpp
index f625f48c33f6..0d267ff70372 100644
--- a/clang/test/CodeGenCXX/pr9965.cpp
+++ b/clang/test/CodeGenCXX/pr9965.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+struct A { A(); };
 template<typename T>
-struct X
+struct X : A // default constructor is not trivial
 {
     X() = default;
     ~X() {} // not a literal type
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index fd41c17ab276..f53939ac1790 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -932,6 +932,41 @@ struct NonTCStruct {
   NonTCStruct(const NonTCStruct&) {}
 };
 
+struct AllDefaulted {
+  AllDefaulted() = default;
+  AllDefaulted(const AllDefaulted &) = default;
+  AllDefaulted(AllDefaulted &&) = default;
+  AllDefaulted &operator=(const AllDefaulted &) = default;
+  AllDefaulted &operator=(AllDefaulted &&) = default;
+  ~AllDefaulted() = default;
+};
+
+struct AllDeleted {
+  AllDeleted() = delete;
+  AllDeleted(const AllDeleted &) = delete;
+  AllDeleted(AllDeleted &&) = delete;
+  AllDeleted &operator=(const AllDeleted &) = delete;
+  AllDeleted &operator=(AllDeleted &&) = delete;
+  ~AllDeleted() = delete;
+};
+
+struct ExtDefaulted {
+  ExtDefaulted();
+  ExtDefaulted(const ExtDefaulted &);
+  ExtDefaulted(ExtDefaulted &&);
+  ExtDefaulted &operator=(const ExtDefaulted &);
+  ExtDefaulted &operator=(ExtDefaulted &&);
+  ~ExtDefaulted();
+};
+
+// Despite being defaulted, these functions are not trivial.
+ExtDefaulted::ExtDefaulted() = default;
+ExtDefaulted::ExtDefaulted(const ExtDefaulted &) = default;
+ExtDefaulted::ExtDefaulted(ExtDefaulted &&) = default;
+ExtDefaulted &ExtDefaulted::operator=(const ExtDefaulted &) = default;
+ExtDefaulted &ExtDefaulted::operator=(ExtDefaulted &&) = default;
+ExtDefaulted::~ExtDefaulted() = default;
+
 void is_trivial2()
 {
   int t01[T(__is_trivial(char))];
@@ -956,11 +991,14 @@ void is_trivial2()
   int t20[T(__is_trivial(Union))];
   int t21[T(__is_trivial(UnionAr))];
   int t22[T(__is_trivial(TrivialStruct))];
+  int t23[T(__is_trivial(AllDefaulted))];
+  int t24[T(__is_trivial(AllDeleted))];
 
   int t30[F(__is_trivial(void))];
   int t31[F(__is_trivial(NonTrivialStruct))];
   int t32[F(__is_trivial(SuperNonTrivialStruct))];
   int t33[F(__is_trivial(NonTCStruct))];
+  int t34[F(__is_trivial(ExtDefaulted))];
 }
 
 void is_trivially_copyable2()
@@ -988,10 +1026,13 @@ void is_trivially_copyable2()
   int t21[T(__is_trivially_copyable(UnionAr))];
   int t22[T(__is_trivially_copyable(TrivialStruct))];
   int t23[T(__is_trivially_copyable(NonTrivialStruct))];
+  int t24[T(__is_trivially_copyable(AllDefaulted))];
+  int t25[T(__is_trivially_copyable(AllDeleted))];
 
   int t30[F(__is_trivially_copyable(void))];
-  int t32[F(__is_trivially_copyable(SuperNonTrivialStruct))];
-  int t31[F(__is_trivially_copyable(NonTCStruct))];
+  int t31[F(__is_trivially_copyable(SuperNonTrivialStruct))];
+  int t32[F(__is_trivially_copyable(NonTCStruct))];
+  int t33[F(__is_trivially_copyable(ExtDefaulted))];
 }
 
 struct CStruct {
@@ -1147,6 +1188,8 @@ void has_trivial_default_constructor() {
   { int arr[T(__has_trivial_constructor(HasCopyAssign))]; }
   { int arr[T(__has_trivial_constructor(HasMoveAssign))]; }
   { int arr[T(__has_trivial_constructor(const Int))]; }
+  { int arr[T(__has_trivial_constructor(AllDefaulted))]; }
+  { int arr[T(__has_trivial_constructor(AllDeleted))]; }
 
   { int arr[F(__has_trivial_constructor(HasCons))]; }
   { int arr[F(__has_trivial_constructor(HasRef))]; }
@@ -1157,6 +1200,7 @@ void has_trivial_default_constructor() {
   { int arr[F(__has_trivial_constructor(cvoid))]; }
   { int arr[F(__has_trivial_constructor(HasTemplateCons))]; }
   { int arr[F(__has_trivial_constructor(AllPrivate))]; }
+  { int arr[F(__has_trivial_constructor(ExtDefaulted))]; }
 }
 
 void has_trivial_copy_constructor() {
@@ -1177,6 +1221,8 @@ void has_trivial_copy_constructor() {
   { int arr[T(__has_trivial_copy(HasCopyAssign))]; }
   { int arr[T(__has_trivial_copy(HasMoveAssign))]; }
   { int arr[T(__has_trivial_copy(const Int))]; }
+  { int arr[T(__has_trivial_copy(AllDefaulted))]; }
+  { int arr[T(__has_trivial_copy(AllDeleted))]; }
 
   { int arr[F(__has_trivial_copy(HasCopy))]; }
   { int arr[F(__has_trivial_copy(HasTemplateCons))]; }
@@ -1185,6 +1231,7 @@ void has_trivial_copy_constructor() {
   { int arr[F(__has_trivial_copy(void))]; }
   { int arr[F(__has_trivial_copy(cvoid))]; }
   { int arr[F(__has_trivial_copy(AllPrivate))]; }
+  { int arr[F(__has_trivial_copy(ExtDefaulted))]; }
 }
 
 void has_trivial_copy_assignment() {
@@ -1201,6 +1248,8 @@ void has_trivial_copy_assignment() {
   { int arr[T(__has_trivial_assign(HasCopy))]; }
   { int arr[T(__has_trivial_assign(HasMove))]; }
   { int arr[T(__has_trivial_assign(HasMoveAssign))]; }
+  { int arr[T(__has_trivial_assign(AllDefaulted))]; }
+  { int arr[T(__has_trivial_assign(AllDeleted))]; }
 
   { int arr[F(__has_trivial_assign(IntRef))]; }
   { int arr[F(__has_trivial_assign(HasCopyAssign))]; }
@@ -1212,6 +1261,7 @@ void has_trivial_copy_assignment() {
   { int arr[F(__has_trivial_assign(void))]; }
   { int arr[F(__has_trivial_assign(cvoid))]; }
   { int arr[F(__has_trivial_assign(AllPrivate))]; }
+  { int arr[F(__has_trivial_assign(ExtDefaulted))]; }
 }
 
 void has_trivial_destructor() {
@@ -1234,11 +1284,14 @@ void has_trivial_destructor() {
   { int arr[T(__has_trivial_destructor(const Int))]; }
   { int arr[T(__has_trivial_destructor(DerivesAr))]; }
   { int arr[T(__has_trivial_destructor(VirtAr))]; }
+  { int arr[T(__has_trivial_destructor(AllDefaulted))]; }
+  { int arr[T(__has_trivial_destructor(AllDeleted))]; }
 
   { int arr[F(__has_trivial_destructor(HasDest))]; }
   { int arr[F(__has_trivial_destructor(void))]; }
   { int arr[F(__has_trivial_destructor(cvoid))]; }
   { int arr[F(__has_trivial_destructor(AllPrivate))]; }
+  { int arr[F(__has_trivial_destructor(ExtDefaulted))]; }
 }
 
 struct A { ~A() {} };
@@ -1460,13 +1513,11 @@ void is_base_of() {
   isBaseOfF<DerivedB<int>, BaseA<int> >();
 }
 
-#if 0
 template<class T, class U>
 class TemplateClass {};
 
 template<class T>
 using TemplateAlias = TemplateClass<T, int>;
-#endif
 
 typedef class Base BaseTypedef;
 
@@ -1474,9 +1525,7 @@ void is_same()
 {
   int t01[T(__is_same(Base, Base))];
   int t02[T(__is_same(Base, BaseTypedef))];
-#if 0
   int t03[T(__is_same(TemplateClass<int, int>, TemplateAlias<int>))];
-#endif
 
   int t10[F(__is_same(Base, const Base))];
   int t11[F(__is_same(Base, Base&))];
@@ -1668,10 +1717,25 @@ void trivial_checks()
                                             const NonTrivialDefault&)))]; }
   { int arr[T((__is_trivially_constructible(NonTrivialDefault,
                                             NonTrivialDefault&&)))]; }
+  { int arr[T((__is_trivially_constructible(AllDefaulted)))]; }
+  { int arr[T((__is_trivially_constructible(AllDefaulted,
+                                            const AllDefaulted &)))]; }
+  { int arr[T((__is_trivially_constructible(AllDefaulted,
+                                            AllDefaulted &&)))]; }
 
   { int arr[F((__is_trivially_constructible(int, int*)))]; }
   { int arr[F((__is_trivially_constructible(NonTrivialDefault)))]; }
   { int arr[F((__is_trivially_constructible(ThreeArgCtor, int*, char*, int&)))]; }
+  { int arr[F((__is_trivially_constructible(AllDeleted)))]; }
+  { int arr[F((__is_trivially_constructible(AllDeleted,
+                                            const AllDeleted &)))]; }
+  { int arr[F((__is_trivially_constructible(AllDeleted,
+                                            AllDeleted &&)))]; }
+  { int arr[F((__is_trivially_constructible(ExtDefaulted)))]; }
+  { int arr[F((__is_trivially_constructible(ExtDefaulted,
+                                            const ExtDefaulted &)))]; }
+  { int arr[F((__is_trivially_constructible(ExtDefaulted,
+                                            ExtDefaulted &&)))]; }
 
   { int arr[T((__is_trivially_assignable(int&, int)))]; }
   { int arr[T((__is_trivially_assignable(int&, int&)))]; }
@@ -1682,6 +1746,10 @@ void trivial_checks()
   { int arr[T((__is_trivially_assignable(POD&, POD&&)))]; }
   { int arr[T((__is_trivially_assignable(POD&, const POD&)))]; }
   { int arr[T((__is_trivially_assignable(int*&, int*)))]; }
+  { int arr[T((__is_trivially_assignable(AllDefaulted,
+                                         const AllDefaulted &)))]; }
+  { int arr[T((__is_trivially_assignable(AllDefaulted,
+                                         AllDefaulted &&)))]; }
 
   { int arr[F((__is_trivially_assignable(int*&, float*)))]; }
   { int arr[F((__is_trivially_assignable(HasCopyAssign&, HasCopyAssign)))]; }
@@ -1692,18 +1760,22 @@ void trivial_checks()
                                         TrivialMoveButNotCopy&)))]; }
   { int arr[F((__is_trivially_assignable(TrivialMoveButNotCopy&,
                                         const TrivialMoveButNotCopy&)))]; }
+  { int arr[F((__is_trivially_assignable(AllDeleted,
+                                         const AllDeleted &)))]; }
+  { int arr[F((__is_trivially_assignable(AllDeleted,
+                                         AllDeleted &&)))]; }
+  { int arr[F((__is_trivially_assignable(ExtDefaulted,
+                                         const ExtDefaulted &)))]; }
+  { int arr[F((__is_trivially_assignable(ExtDefaulted,
+                                         ExtDefaulted &&)))]; }
 
-  // FIXME: The following answers are wrong, because we don't properly
-  // mark user-declared constructors/assignment operators/destructors
-  // that are defaulted on their first declaration as trivial when we
-  // can.
-  { int arr[F((__is_trivially_assignable(HasDefaultTrivialCopyAssign&,
+  { int arr[T((__is_trivially_assignable(HasDefaultTrivialCopyAssign&,
                                          HasDefaultTrivialCopyAssign&)))]; }
-  { int arr[F((__is_trivially_assignable(HasDefaultTrivialCopyAssign&,
+  { int arr[T((__is_trivially_assignable(HasDefaultTrivialCopyAssign&,
                                        const HasDefaultTrivialCopyAssign&)))]; }
-  { int arr[F((__is_trivially_assignable(TrivialMoveButNotCopy&,
+  { int arr[T((__is_trivially_assignable(TrivialMoveButNotCopy&,
                                          TrivialMoveButNotCopy)))]; }
-  { int arr[F((__is_trivially_assignable(TrivialMoveButNotCopy&,
+  { int arr[T((__is_trivially_assignable(TrivialMoveButNotCopy&,
                                          TrivialMoveButNotCopy&&)))]; }
 }