Index: include/type_traits
===================================================================
--- include/type_traits	(revision 176578)
+++ include/type_traits	(working copy)
@@ -802,17 +802,13 @@
 
 #else
 
-template <class _Tp> struct __is_polymorphic1 : public _Tp {};
-template <class _Tp> struct __is_polymorphic2 : public _Tp {virtual ~__is_polymorphic2() throw();};
+template<typename _Tp> char &__is_polymorphic_impl(
+    typename enable_if<sizeof((_Tp*)dynamic_cast<const volatile void*>(declval<_Tp*>())) != 0,
+                       int>::type);
+template<typename _Tp> __two &__is_polymorphic_impl(...);
 
-template <class _Tp, bool = is_class<_Tp>::value>
-struct __libcpp_polymorphic
-    : public integral_constant<bool, sizeof(__is_polymorphic1<_Tp>) == sizeof(__is_polymorphic2<_Tp>)> {};
-
-template <class _Tp> struct __libcpp_polymorphic<_Tp, false> : public false_type {};
-
 template <class _Tp> struct _LIBCPP_VISIBLE is_polymorphic
-    : public __libcpp_polymorphic<_Tp> {};
+    : public integral_constant<bool, sizeof(__is_polymorphic_impl<_Tp>(0)) == 1> {};
 
 #endif // __has_feature(is_polymorphic)
 
Index: test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp
===================================================================
--- test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp	(revision 176578)
+++ test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp	(working copy)
@@ -52,6 +52,9 @@
     virtual ~Abstract() = 0;
 };
 
+class Final final {
+};
+
 int main()
 {
     test_is_not_polymorphic<void>();
@@ -65,6 +68,9 @@
     test_is_not_polymorphic<Union>();
     test_is_not_polymorphic<Empty>();
     test_is_not_polymorphic<bit_zero>();
+    test_is_not_polymorphic<Final>();
+    test_is_not_polymorphic<NotEmpty&>();
+    test_is_not_polymorphic<Abstract&>();
 
     test_is_polymorphic<NotEmpty>();
     test_is_polymorphic<Abstract>();
