C++1y: an assignment operator is implicitly 'constexpr' if it would only call 'constexpr' assignment operators for a literal class type.

llvm-svn: 181284
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index 4393727..780a420 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -63,8 +63,20 @@
 #ifndef CXX1Y
   // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
   // expected-warning@-3 {{C++1y}}
+#else
+  // expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}}
 #endif
 };
+#ifdef CXX1Y
+struct T2 {
+  int n = 0;
+  constexpr T2 &operator=(const T2&) = default; // ok
+};
+struct T3 {
+  constexpr T3 &operator=(const T3&) const = default;
+  // expected-error@-1 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
+};
+#endif
 struct U {
   constexpr U SelfReturn() const;
   constexpr int SelfParam(U) const;
diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp
index 60ec820..198b994 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -457,3 +457,46 @@
   }
   static_assert(range_for_2() == 10, "");
 }
+
+namespace assignment {
+  struct A {
+    constexpr A() : n(5) {}
+    int n;
+    struct B {
+      int k = 1;
+      union U {
+        constexpr U() : y(4) {}
+        int x;
+        int y;
+      } u;
+    } b;
+  };
+  constexpr bool testA() {
+    A a, b;
+    a.n = 7;
+    a.b.u.y = 5;
+    b = a;
+    return b.n == 7 && b.b.u.y == 5 && b.b.k == 1;
+  }
+  static_assert(testA(), "");
+
+  struct B {
+    bool assigned = false;
+    constexpr B &operator=(const B&) {
+      assigned = true;
+      return *this;
+    }
+  };
+  struct C : B {
+    B b;
+    int n = 5;
+  };
+  constexpr bool testC() {
+    C c, d;
+    c.n = 7;
+    d = c;
+    c.n = 3;
+    return d.n == 7 && d.assigned && d.b.assigned;
+  }
+  static_assert(testC(), "");
+}