Cleaup of requirements for optional. While researching LWG3196, I realized that optional did not reject 'const in_place_t' like it should. Added a test as well, and a check for arrays (which were already disallowed, but now we get a better error message). Should not affect anyone's code.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@356918 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/optional b/include/optional
index 7c136ae..1fc752e 100644
--- a/include/optional
+++ b/include/optional
@@ -592,7 +592,7 @@
 
 private:
      // Disable the reference extension using this static assert.
-    static_assert(!is_same_v<value_type, in_place_t>,
+    static_assert(!is_same_v<__uncvref_t<value_type>, in_place_t>,
         "instantiation of optional with in_place_t is ill-formed");
     static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
         "instantiation of optional with nullopt_t is ill-formed");
@@ -600,6 +600,8 @@
         "instantiation of optional with a reference type is ill-formed");
     static_assert(is_destructible_v<value_type>,
         "instantiation of optional with a non-destructible type is ill-formed");
+    static_assert(!is_array_v<value_type>,
+        "instantiation of optional with an array type is ill-formed");
 
     // LWG2756: conditionally explicit conversion from _Up
     struct _CheckOptionalArgsConstructor {
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.fail.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.fail.cpp
new file mode 100644
index 0000000..9a646a1
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.fail.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// T shall be an object type other than cv in_place_t or cv nullopt_t 
+//   and shall satisfy the Cpp17Destructible requirements.
+// Note: array types do not satisfy the Cpp17Destructible requirements.
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct NonDestructible { ~NonDestructible() = delete; };
+
+int main(int, char**)
+{
+	{
+	std::optional<char &> o1;	        // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with a reference type is ill-formed"}}
+	std::optional<NonDestructible> o2;  // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with a non-destructible type is ill-formed"}}	
+	std::optional<char[20]> o3;	        // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with an array type is ill-formed"}}	
+	}
+
+	{
+	std::optional<               std::in_place_t> o1;  // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with in_place_t is ill-formed"}}
+	std::optional<const          std::in_place_t> o2;  // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with in_place_t is ill-formed"}}
+	std::optional<      volatile std::in_place_t> o3;  // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with in_place_t is ill-formed"}}
+	std::optional<const volatile std::in_place_t> o4;  // expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with in_place_t is ill-formed"}}
+	}
+
+	{
+	std::optional<               std::nullopt_t> o1;	// expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with nullopt_t is ill-formed"}}
+	std::optional<const          std::nullopt_t> o2;	// expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with nullopt_t is ill-formed"}}
+	std::optional<      volatile std::nullopt_t> o3;	// expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with nullopt_t is ill-formed"}}
+	std::optional<const volatile std::nullopt_t> o4;	// expected-error-re@optional:* {{static_assert failed{{.*}} "instantiation of optional with nullopt_t is ill-formed"}}
+	}
+
+	return 0;
+}