Update aosp/master libcxx rebase to r263688
Change-Id: Ic3f4fb33a091ff4b7366ab9e6ca8ee99589c5c9f
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..bf9ee58
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,110 @@
+//
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// host + device static lib
+cc_library_static {
+ host_supported: true,
+ name: "libc++_static",
+ clang: true,
+ srcs: [
+ "src/algorithm.cpp",
+ "src/any.cpp",
+ "src/bind.cpp",
+ "src/chrono.cpp",
+ "src/condition_variable.cpp",
+ "src/debug.cpp",
+ "src/exception.cpp",
+ "src/future.cpp",
+ "src/hash.cpp",
+ "src/ios.cpp",
+ "src/iostream.cpp",
+ "src/locale.cpp",
+ "src/memory.cpp",
+ "src/mutex.cpp",
+ "src/new.cpp",
+ "src/optional.cpp",
+ "src/random.cpp",
+ "src/regex.cpp",
+ "src/shared_mutex.cpp",
+ "src/stdexcept.cpp",
+ "src/string.cpp",
+ "src/strstream.cpp",
+ "src/system_error.cpp",
+ "src/thread.cpp",
+ "src/typeinfo.cpp",
+ "src/utility.cpp",
+ "src/valarray.cpp",
+ ],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ cppflags: [
+ "-std=c++14",
+ "-nostdinc++",
+ "-fexceptions",
+ "-DLIBCXX_BUILDING_LIBCXXABI",
+ ],
+ rtti: true,
+ whole_static_libs: [
+ "libc++abi",
+ ],
+ stl: "none",
+}
+
+// host + device dynamic lib
+cc_library_shared {
+ host_supported: true,
+ name: "libc++",
+ clang: true,
+ whole_static_libs: ["libc++_static"],
+ stl: "none",
+
+ target: {
+ android: {
+ shared_libs: ["libdl"],
+ },
+ android_arm: {
+ static_libs: ["libunwind_llvm"],
+ ldflags: ["-Wl,--exclude-libs,libunwind_llvm.a"],
+ },
+ host: {
+ ldflags: ["-nodefaultlibs"],
+ },
+ darwin: {
+ unexported_symbols_list: "lib/libc++unexp.exp",
+ force_symbols_not_weak_list: "lib/notweak.exp",
+ force_symbols_weak_list: "lib/weak.exp",
+ },
+
+ linux: {
+ host_ldlibs: [
+ "-lrt",
+ "-lpthread",
+ "-ldl",
+ ],
+ },
+ },
+}
+
+
+// ANDROIDMK TRANSLATION ERROR: unsupported conditional
+// ifdef LIBCXX_TESTING
+// ANDROIDMK TRANSLATION ERROR: unsupported include
+// include $(LOCAL_PATH)/buildcmds/Android.mk
+
+// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
+// endif
+// TARGET_BUILD_APPS
+
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..7e28736
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,119 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+LIBCXX_SRC_FILES := \
+ src/algorithm.cpp \
+ src/any.cpp \
+ src/bind.cpp \
+ src/chrono.cpp \
+ src/condition_variable.cpp \
+ src/debug.cpp \
+ src/exception.cpp \
+ src/future.cpp \
+ src/hash.cpp \
+ src/ios.cpp \
+ src/iostream.cpp \
+ src/locale.cpp \
+ src/memory.cpp \
+ src/mutex.cpp \
+ src/new.cpp \
+ src/optional.cpp \
+ src/random.cpp \
+ src/regex.cpp \
+ src/shared_mutex.cpp \
+ src/stdexcept.cpp \
+ src/string.cpp \
+ src/strstream.cpp \
+ src/system_error.cpp \
+ src/thread.cpp \
+ src/typeinfo.cpp \
+ src/utility.cpp \
+ src/valarray.cpp \
+
+LIBCXX_C_INCLUDES := \
+ $(LOCAL_PATH)/include/ \
+
+LIBCXX_CPPFLAGS := \
+ -std=c++14 \
+ -nostdinc++ \
+ -fexceptions \
+ -DLIBCXX_BUILDING_LIBCXXABI \
+
+# target static lib
+include $(CLEAR_VARS)
+LOCAL_MODULE := libc++_static
+LOCAL_CLANG := true
+LOCAL_SRC_FILES := $(LIBCXX_SRC_FILES)
+LOCAL_C_INCLUDES := $(LIBCXX_C_INCLUDES)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include
+LOCAL_CPPFLAGS := $(LIBCXX_CPPFLAGS)
+LOCAL_RTTI_FLAG := -frtti
+LOCAL_WHOLE_STATIC_LIBRARIES := libc++abi
+LOCAL_CXX_STL := none
+include $(BUILD_STATIC_LIBRARY)
+
+# target dynamic lib
+include $(CLEAR_VARS)
+LOCAL_MODULE := libc++
+LOCAL_CLANG := true
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include
+LOCAL_WHOLE_STATIC_LIBRARIES := libc++_static
+LOCAL_SHARED_LIBRARIES := libdl
+LOCAL_CXX_STL := none
+LOCAL_STATIC_LIBRARIES_arm := libunwind_llvm
+LOCAL_LDFLAGS_arm := -Wl,--exclude-libs,libunwind_llvm.a
+include $(BUILD_SHARED_LIBRARY)
+
+# host static lib
+include $(CLEAR_VARS)
+LOCAL_MODULE := libc++_static
+LOCAL_CLANG := true
+LOCAL_SRC_FILES := $(LIBCXX_SRC_FILES)
+LOCAL_C_INCLUDES := $(LIBCXX_C_INCLUDES)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include
+LOCAL_CPPFLAGS := $(LIBCXX_CPPFLAGS)
+LOCAL_RTTI_FLAG := -frtti
+LOCAL_WHOLE_STATIC_LIBRARIES := libc++abi
+LOCAL_MULTILIB := both
+LOCAL_CXX_STL := none
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# host dynamic lib
+include $(CLEAR_VARS)
+LOCAL_MODULE := libc++
+LOCAL_CLANG := true
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include
+LOCAL_LDFLAGS := -nodefaultlibs
+LOCAL_WHOLE_STATIC_LIBRARIES := libc++_static
+LOCAL_MULTILIB := both
+LOCAL_CXX_STL := none
+
+ifeq ($(HOST_OS), darwin)
+LOCAL_LDFLAGS += \
+ -Wl,-unexported_symbols_list,external/libcxx/lib/libc++unexp.exp \
+ -Wl,-force_symbols_not_weak_list,external/libcxx/lib/notweak.exp \
+ -Wl,-force_symbols_weak_list,external/libcxx/lib/weak.exp
+else
+LOCAL_LDLIBS += -lrt -lpthread -ldl
+endif
+
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+ifdef LIBCXX_TESTING
+include $(LOCAL_PATH)/buildcmds/Android.mk
+endif
diff --git a/MODULE_LICENSE_BSD_LIKE b/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD_LIKE
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..41ca5d1
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,76 @@
+==============================================================================
+libc++ License
+==============================================================================
+
+The libc++ library is dual licensed under both the University of Illinois
+"BSD-Like" license and the MIT license. As a user of this code you may choose
+to use it under either license. As a contributor, you agree to allow your code
+to be used under both.
+
+Full text of the relevant licenses is included below.
+
+==============================================================================
+
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+
+Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.version b/README.version
new file mode 100644
index 0000000..ec7580e
--- /dev/null
+++ b/README.version
@@ -0,0 +1,4 @@
+URL: http://llvm.org/git/libcxx.git
+Version: ba865ff66b36f99a1dc5d9e31af3d8943f94e349
+BugComponent: 117395
+Owners: danalbert, srhines, android-llvm
diff --git a/buildcmds/.gitignore b/buildcmds/.gitignore
new file mode 100644
index 0000000..a77d525
--- /dev/null
+++ b/buildcmds/.gitignore
@@ -0,0 +1,4 @@
+cxx_under_test
+cxx.cmds
+link.cmds
+testconfig.mk
diff --git a/buildcmds/Android.mk b/buildcmds/Android.mk
new file mode 100644
index 0000000..33d01ef
--- /dev/null
+++ b/buildcmds/Android.mk
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# Don't build for unbundled branches
+ifeq (,$(TARGET_BUILD_APPS))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libc++_build_commands_$(ANDROID_DEVICE)
+LOCAL_SRC_FILES := dummy.cpp
+LOCAL_CXX_STL := libc++
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/../test/support
+LOCAL_CPPFLAGS := \
+ -std=c++14 \
+ -fsized-deallocation \
+ -fexceptions \
+ -UNDEBUG \
+ -w \
+ -Wno-error=non-virtual-dtor \
+
+# Optimization is causing relocation for nothrow new to be thrown away.
+# http://llvm.org/bugs/show_bug.cgi?id=21421
+LOCAL_CPPFLAGS += -O0
+
+LOCAL_RTTI_FLAG := -frtti
+include $(LOCAL_PATH)/testconfig.mk
+
+endif
diff --git a/buildcmds/buildcmdscc b/buildcmds/buildcmdscc
new file mode 100755
index 0000000..b169e92
--- /dev/null
+++ b/buildcmds/buildcmdscc
@@ -0,0 +1,16 @@
+#!/bin/bash
+CXX=$1
+ARGS=${*:2}
+DIR=external/libcxx/buildcmds
+echo $ANDROID_BUILD_TOP/$CXX > $DIR/cxx_under_test
+
+echo $ARGS | grep -P '\S+\.cpp\b' > /dev/null
+if [ $? -eq 0 ]; then
+ echo $ARGS | perl -ne 's/\S+\.cpp\b/%SOURCE%/; print' \
+ | perl -ne 's/\S+\.o\b/%OUT%/; print' > $DIR/cxx.cmds
+else
+ echo $ARGS | perl -ne 's/out\/\S+\/EXECUTABLES\/\S+\.o\b/%SOURCE%/; print' \
+ | perl -ne 's/-o\s+\S+\b/-o %OUT%/; print' > $DIR/link.cmds
+fi
+
+$CXX $ARGS
diff --git a/buildcmds/dummy.cpp b/buildcmds/dummy.cpp
new file mode 100644
index 0000000..4cce7f6
--- /dev/null
+++ b/buildcmds/dummy.cpp
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/include/__config b/include/__config
index bbddcbc..f64cce3 100644
--- a/include/__config
+++ b/include/__config
@@ -710,7 +710,7 @@
#endif
#ifndef _LIBCPP_EXTERN_TEMPLATE
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+#define _LIBCPP_EXTERN_TEMPLATE(...)
#endif
#ifndef _LIBCPP_EXTERN_TEMPLATE2
diff --git a/include/__cxxabi_config.h b/include/__cxxabi_config.h
new file mode 120000
index 0000000..431af26
--- /dev/null
+++ b/include/__cxxabi_config.h
@@ -0,0 +1 @@
+../../libcxxabi/include/__cxxabi_config.h
\ No newline at end of file
diff --git a/include/__hash_table b/include/__hash_table
index 13ab928..8f6fc4d 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -109,6 +109,8 @@
template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+ class _LIBCPP_TYPE_VIS_ONLY unordered_map;
template <class _Tp>
struct __hash_key_value_types {
diff --git a/include/__tree b/include/__tree
index 89707e3..62178e3 100644
--- a/include/__tree
+++ b/include/__tree
@@ -28,6 +28,14 @@
class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;
template <class _Tp, class _ConstNodePtr, class _DiffType>
class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+ class _LIBCPP_TYPE_VIS_ONLY map;
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+ class _LIBCPP_TYPE_VIS_ONLY multimap;
+template <class _Key, class _Compare, class _Allocator>
+ class _LIBCPP_TYPE_VIS_ONLY set;
+template <class _Key, class _Compare, class _Allocator>
+ class _LIBCPP_TYPE_VIS_ONLY multiset;
template <class _Pointer> class __tree_end_node;
template <class _VoidPtr> class __tree_node_base;
diff --git a/include/iterator b/include/iterator
index 9314d6a..15be793 100644
--- a/include/iterator
+++ b/include/iterator
@@ -1120,6 +1120,8 @@
>::type
__unwrap_iter(__wrap_iter<_Tp*>);
+template <class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY vector;
+
template <class _Iter>
class __wrap_iter
{
@@ -1249,7 +1251,7 @@
template <class _Up> friend class __wrap_iter;
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
- template <class _Tp, class _Alloc> friend class _LIBCPP_TYPE_VIS_ONLY vector;
+ template <class _Tp, class _Alloc> friend class vector;
template <class _Iter1, class _Iter2>
friend
diff --git a/include/regex b/include/regex
index 1139d8f..3724204 100644
--- a/include/regex
+++ b/include/regex
@@ -974,9 +974,15 @@
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
typedef locale locale_type;
+#ifdef __ANDROID__
+ typedef uint16_t char_class_type;
+#else
typedef ctype_base::mask char_class_type;
+#endif
-#if defined(__mips__) && defined(__GLIBC__)
+#ifdef __ANDROID__
+ static const char_class_type __regex_word = 0x8000;
+#elif defined(__mips__) && defined(__GLIBC__)
static const char_class_type __regex_word = static_cast<char_class_type>(_ISbit(15));
#else
static const char_class_type __regex_word = 0x80;
diff --git a/lit.site.cfg b/lit.site.cfg
new file mode 100644
index 0000000..efc75d0
--- /dev/null
+++ b/lit.site.cfg
@@ -0,0 +1,42 @@
+import os
+import sys
+
+# Tell pylint that we know config and lit_config exist somewhere.
+if 'PYLINT_IMPORT' in os.environ:
+ config = object()
+ lit_config = object()
+
+ndk = os.getenv('NDK')
+if ndk is None:
+ sys.exit('The environment variable NDK must point to an NDK toolchain.')
+
+top = os.getenv('ANDROID_BUILD_TOP')
+out_dir = os.getenv('ANDROID_PRODUCT_OUT')
+
+if top is None or out_dir is None:
+ sys.exit('ANDROID_BUILD_TOP or ANDROID_PRODUCT_OUT is not set. Have you '
+ 'run lunch?')
+
+config.cxx_under_test = os.path.join(
+ top, "prebuilts/clang/linux-x86/host/3.6/bin/clang++")
+config.std = "c++11"
+config.libcxx_src_root = os.path.join(top, "external/libcxx")
+config.libcxx_obj_root = os.path.join(top, "external/libcxx")
+config.cxx_library_root = os.path.join(out_dir, 'system/lib')
+config.enable_exceptions = "True"
+config.enable_rtti = "True"
+config.enable_shared = "False"
+config.enable_32bit = "False"
+config.enable_threads = "True"
+config.enable_monotonic_clock = "True"
+config.cxx_abi = "libcxxabi"
+config.use_sanitizer = ""
+config.configuration_variant = "libcxx.ndk"
+config.target_triple = "armv7a-linux-androideabi"
+config.sysroot = os.path.join(ndk, "platforms/android-21/arch-arm/")
+config.gcc_toolchain = os.path.join(
+ top, "prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9")
+
+# Let the main config do the real work.
+lit_config.load_config(
+ config, os.path.join(top, "external/libcxx/test/lit.cfg"))
diff --git a/ndk-test.sh b/ndk-test.sh
new file mode 100755
index 0000000..b98b22d
--- /dev/null
+++ b/ndk-test.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# This file should reside in test/, but it seems that if there is already one
+# lit.site.cfg in the test/ directory it is impossible to tell LIT to use
+# another. This will need to be fixed upstream before this can get a proper
+# home. The downside of this is that there isn't a way to run a subset of the
+# libc++ tests against the NDK.
+if [ -z "$ANDROID_PRODUCT_OUT" ]; then
+ >&2 echo "Error: ANDROID_PRODUCT_OUT is not set. Have you run lunch?"
+ exit 1
+fi
+
+if [ ! -f $ANDROID_PRODUCT_OUT/system/lib/libc++_ndk.so ]; then
+ >&2 echo "Error: libc++_ndk.so has not been built for this target."
+ exit 1
+fi
+
+adb push $ANDROID_PRODUCT_OUT/system/lib/libc++_ndk.so /data/local/tmp
+lit -sv $* .
diff --git a/run-tests.py b/run-tests.py
new file mode 100644
index 0000000..44c4e3d
--- /dev/null
+++ b/run-tests.py
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from __future__ import print_function
+
+import argparse
+import os
+import subprocess
+import sys
+
+
+THIS_DIR = os.path.dirname(os.path.realpath(__file__))
+ANDROID_DIR = os.path.realpath(os.path.join(THIS_DIR, '../..'))
+
+
+class ArgParser(argparse.ArgumentParser):
+ def __init__(self):
+ super(ArgParser, self).__init__()
+ self.add_argument(
+ '--compiler', choices=('clang', 'gcc'), default='clang')
+ self.add_argument(
+ '--bitness', choices=(32, 64), type=int, default=32)
+ self.add_argument('--host', action='store_true')
+
+
+def gen_test_config(bitness, compiler, host):
+ testconfig_mk_path = os.path.join(THIS_DIR, 'buildcmds/testconfig.mk')
+ with open(testconfig_mk_path, 'w') as test_config:
+ if compiler == 'clang':
+ print('LOCAL_CLANG := true', file=test_config)
+ elif compiler == 'gcc':
+ print('LOCAL_CLANG := false', file=test_config)
+
+ if bitness == 32:
+ print('LOCAL_MULTILIB := 32', file=test_config)
+ elif bitness == 64:
+ print('LOCAL_MULTILIB := 64', file=test_config)
+
+ if compiler == 'clang':
+ print('LOCAL_CXX := $(LOCAL_PATH)/buildcmdscc $(CLANG_CXX)',
+ file=test_config)
+ else:
+ if host:
+ prefix = 'HOST_'
+ else:
+ prefix = 'TARGET_'
+ print('LOCAL_CXX := $(LOCAL_PATH)/buildcmdscc '
+ '$($(LOCAL_2ND_ARCH_VAR_PREFIX){}CXX)'.format(prefix),
+ file=test_config)
+
+ if host:
+ print('include $(BUILD_HOST_EXECUTABLE)', file=test_config)
+ else:
+ print('include $(BUILD_EXECUTABLE)', file=test_config)
+
+
+def mmm(path):
+ makefile = os.path.join(path, 'Android.mk')
+ main_mk = 'build/core/main.mk'
+
+ env = dict(os.environ)
+ env['ONE_SHOT_MAKEFILE'] = makefile
+ env['LIBCXX_TESTING'] = 'true'
+ cmd = ['make', '-C', ANDROID_DIR, '-f', main_mk, 'all_modules']
+ subprocess.check_call(cmd, env=env)
+
+
+def gen_build_cmds(bitness, compiler, host):
+ gen_test_config(bitness, compiler, host)
+ mmm(os.path.join(THIS_DIR, 'buildcmds'))
+
+
+def main():
+ args, lit_args = ArgParser().parse_known_args()
+ lit_path = os.path.join(ANDROID_DIR, 'external/llvm/utils/lit/lit.py')
+ gen_build_cmds(args.bitness, args.compiler, args.host)
+
+ mode_str = 'host' if args.host else 'device'
+ android_mode_arg = '--param=android_mode=' + mode_str
+ test_path = os.path.join(THIS_DIR, 'test')
+
+ lit_args = ['-sv', android_mode_arg] + lit_args
+ cmd = ['python', lit_path] + lit_args + [test_path]
+ sys.exit(subprocess.call(cmd))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/algorithm.cpp b/src/algorithm.cpp
index e9752b0..0840323 100644
--- a/src/algorithm.cpp
+++ b/src/algorithm.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#undef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
#include "algorithm"
#include "random"
#include "mutex"
diff --git a/src/ios.cpp b/src/ios.cpp
index 23e3ee0..6364eec 100644
--- a/src/ios.cpp
+++ b/src/ios.cpp
@@ -9,6 +9,9 @@
#include "__config"
+#undef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
#include "ios"
#include <stdlib.h>
diff --git a/src/locale.cpp b/src/locale.cpp
index bc2427b..5c526cb 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#undef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
// On Solaris, we need to define something to make the C99 parts of localeconv
// visible.
#ifdef __sun__
diff --git a/src/string.cpp b/src/string.cpp
index d3f29df..a00ed8b 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#undef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
#include "string"
#include "cstdlib"
#include "cwchar"
diff --git a/src/valarray.cpp b/src/valarray.cpp
index 2d8db52..f6745df 100644
--- a/src/valarray.cpp
+++ b/src/valarray.cpp
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#undef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
#include "valarray"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/test.mk b/test.mk
new file mode 100644
index 0000000..040040f
--- /dev/null
+++ b/test.mk
@@ -0,0 +1,4 @@
+.NOTPARALLEL:
+default:
+ python $(LIT) -sv --param android_mode=$(LIT_MODE) $(LIT_ARGS) \
+ $(ANDROID_BUILD_TOP)/external/libcxx/test
diff --git a/test/libcxx/android/__init__.py b/test/libcxx/android/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/libcxx/android/__init__.py
diff --git a/test/libcxx/android/adb.py b/test/libcxx/android/adb.py
new file mode 100644
index 0000000..43bd2b5
--- /dev/null
+++ b/test/libcxx/android/adb.py
@@ -0,0 +1,24 @@
+import lit.util # pylint: disable=import-error
+
+
+class AdbError(RuntimeError):
+ def __init__(self, cmd, out, err, exit_code):
+ super(AdbError, self).__init__(err)
+ self.cmd = cmd
+ self.out = out
+ self.err = err
+ self.exit_code = exit_code
+
+
+def mkdir(path):
+ cmd = ['adb', 'shell', 'mkdir', path]
+ out, err, exit_code = lit.util.executeCommand(cmd)
+ if exit_code != 0:
+ raise AdbError(cmd, out, err, exit_code)
+
+
+def push(src, dst):
+ cmd = ['adb', 'push', src, dst]
+ out, err, exit_code = lit.util.executeCommand(cmd)
+ if exit_code != 0:
+ raise AdbError(cmd, out, err, exit_code)
diff --git a/test/libcxx/android/build.py b/test/libcxx/android/build.py
new file mode 100644
index 0000000..56c7649
--- /dev/null
+++ b/test/libcxx/android/build.py
@@ -0,0 +1,13 @@
+import os
+import subprocess
+
+
+def mm(path, android_build_top):
+ env = os.environ
+ env['ONE_SHOT_MAKEFILE'] = os.path.join(path, 'Android.mk')
+
+ cmd = [
+ 'make', '-C', android_build_top, '-f', 'build/core/main.mk',
+ 'all_modules', '-B'
+ ]
+ return not subprocess.Popen(cmd, stdout=None, stderr=None, env=env).wait()
diff --git a/test/libcxx/android/compiler.py b/test/libcxx/android/compiler.py
new file mode 100644
index 0000000..2dcfc88
--- /dev/null
+++ b/test/libcxx/android/compiler.py
@@ -0,0 +1,75 @@
+import os
+import re
+import shlex
+import subprocess
+
+import libcxx.compiler
+
+
+class AndroidCXXCompiler(libcxx.compiler.CXXCompiler):
+ def __init__(self, cxx_under_test, cxx_template, link_template):
+ super(AndroidCXXCompiler, self).__init__(cxx_under_test)
+ self.cxx_template = cxx_template
+ self.link_template = link_template
+ self.build_top = os.getenv('ANDROID_BUILD_TOP')
+
+ def get_triple(self):
+ if 'clang' in self.path:
+ return self.get_clang_triple()
+ else:
+ return self.get_gcc_triple()
+
+ raise RuntimeError('Could not determine target triple.')
+
+ def get_clang_triple(self):
+ match = re.search(r'-target\s+(\S+)', self.cxx_template)
+ if match:
+ return match.group(1)
+ return None
+
+ def get_gcc_triple(self):
+ proc = subprocess.Popen([self.path, '-v'],
+ stderr=subprocess.PIPE)
+ _, stderr = proc.communicate()
+ for line in stderr.split('\n'):
+ print 'Checking {}'.format(line)
+ match = re.search(r'^Target: (.+)$', line)
+ if match:
+ return match.group(1)
+ return None
+
+ def compile(self, source_files, out=None, flags=None, env=None, cwd=None):
+ flags = [] if flags is None else flags
+ return super(AndroidCXXCompiler, self).compile(source_files, out, flags,
+ env, self.build_top)
+
+ def link(self, source_files, out=None, flags=None, env=None, cwd=None):
+ flags = [] if flags is None else flags
+ return super(AndroidCXXCompiler, self).link(source_files, out, flags,
+ env, self.build_top)
+
+ def compileCmd(self, source_files, out=None, flags=None):
+ if out is None:
+ raise RuntimeError('The Android compiler requires an out path.')
+
+ if isinstance(source_files, str):
+ source_files = [source_files]
+ cxx_args = self.cxx_template.replace('%OUT%', out)
+ cxx_args = cxx_args.replace('%SOURCE%', ' '.join(source_files))
+ return [self.path] + shlex.split(cxx_args)
+
+ def linkCmd(self, source_files, out=None, flags=None):
+ if out is None:
+ raise RuntimeError('The Android compiler requires an out path.')
+
+ if isinstance(source_files, str):
+ source_files = [source_files]
+ link_args = self.link_template.replace('%OUT%', out)
+ link_args = link_args.replace('%SOURCE%', ' '.join(source_files))
+ return [self.path] + shlex.split(link_args)
+
+ def _basicCmd(self, source_files, out, is_link=False, input_is_cxx=False):
+ raise NotImplementedError()
+
+ def _initTypeAndVersion(self):
+ pass
diff --git a/test/libcxx/android/executors.py b/test/libcxx/android/executors.py
new file mode 100644
index 0000000..7bf3413
--- /dev/null
+++ b/test/libcxx/android/executors.py
@@ -0,0 +1,65 @@
+import time
+
+import libcxx.test.executor
+
+from libcxx.android import adb
+from lit.util import executeCommand # pylint: disable=import-error
+
+
+class AdbExecutor(libcxx.test.executor.RemoteExecutor):
+ def __init__(self, serial=None):
+ # TODO(danalbert): Should factor out the shared pieces of SSHExecutor
+ # so we don't have this ugly parent constructor...
+ super(AdbExecutor, self).__init__()
+ self.serial = serial
+ self.local_run = executeCommand
+
+ def _remote_temp(self, is_dir):
+ dir_arg = '-d' if is_dir else ''
+ cmd = 'mktemp -q {} /data/local/tmp/libcxx.XXXXXXXXXX'.format(dir_arg)
+ _, temp_path, err, exitCode = self._execute_command_remote([cmd])
+ temp_path = temp_path.strip()
+ if exitCode != 0:
+ raise RuntimeError(err)
+ return temp_path
+
+ def _copy_in_file(self, src, dst): # pylint: disable=no-self-use
+ adb.push(src, dst)
+
+ def _execute_command_remote(self, cmd, remote_work_dir='.', env=None):
+ adb_cmd = ['adb', 'shell']
+ if self.serial:
+ adb_cmd.extend(['-s', self.serial])
+
+ delimiter = 'x'
+ probe_cmd = ' '.join(cmd) + '; echo {}$?'.format(delimiter)
+
+ env_cmd = []
+ if env is not None:
+ env_cmd = ['env'] + ['%s=%s' % (k, v) for k, v in env.items()]
+
+ remote_cmd = ' '.join(env_cmd + [probe_cmd])
+ if remote_work_dir != '.':
+ remote_cmd = 'cd {} && {}'.format(remote_work_dir, remote_cmd)
+
+ adb_cmd.append(remote_cmd)
+
+ # Tests will commonly fail with ETXTBSY. Possibly related to this bug:
+ # https://code.google.com/p/android/issues/detail?id=65857. Work around
+ # it by just waiting a second and then retrying.
+ for _ in range(10):
+ out, err, exit_code = self.local_run(adb_cmd)
+ if 'Text file busy' in out:
+ time.sleep(1)
+ else:
+ out, delim, rc_str = out.rpartition(delimiter)
+ if delim == '':
+ continue
+
+ out = out.strip()
+ try:
+ exit_code = int(rc_str)
+ break
+ except ValueError:
+ continue
+ return adb_cmd, out, err, exit_code
diff --git a/test/libcxx/android/test/__init__.py b/test/libcxx/android/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/libcxx/android/test/__init__.py
diff --git a/test/libcxx/android/test/config.py b/test/libcxx/android/test/config.py
new file mode 100644
index 0000000..bff0c45
--- /dev/null
+++ b/test/libcxx/android/test/config.py
@@ -0,0 +1,88 @@
+import os
+import re
+
+import libcxx.test.config
+import libcxx.android.build
+import libcxx.android.compiler
+import libcxx.android.test.format
+
+
+class Configuration(libcxx.test.config.Configuration):
+ def __init__(self, lit_config, config):
+ super(Configuration, self).__init__(lit_config, config)
+ self.build_cmds_dir = None
+
+ def configure(self):
+ self.configure_src_root()
+ self.configure_build_cmds()
+ self.configure_obj_root()
+
+ self.configure_cxx()
+ self.configure_triple()
+ self.configure_features()
+
+ def print_config_info(self):
+ self.lit_config.note(
+ 'Using compiler: {}'.format(self.cxx.path))
+ self.lit_config.note(
+ 'Using compile template: {}'.format(self.cxx.cxx_template))
+ self.lit_config.note(
+ 'Using link template: {}'.format(self.cxx.link_template))
+ self.lit_config.note('Using available_features: %s' %
+ list(self.config.available_features))
+
+ def configure_obj_root(self):
+ test_config_file = os.path.join(self.build_cmds_dir, 'testconfig.mk')
+ if 'HOST_NATIVE_TEST' in open(test_config_file).read():
+ self.libcxx_obj_root = os.getenv('ANDROID_HOST_OUT')
+ else:
+ self.libcxx_obj_root = os.getenv('ANDROID_PRODUCT_OUT')
+
+ def configure_build_cmds(self):
+ os.chdir(self.config.android_root)
+ self.build_cmds_dir = os.path.join(self.libcxx_src_root, 'buildcmds')
+ if not libcxx.android.build.mm(self.build_cmds_dir,
+ self.config.android_root):
+ raise RuntimeError('Could not generate build commands.')
+
+ def configure_cxx(self):
+ cxx_under_test_file = os.path.join(self.build_cmds_dir,
+ 'cxx_under_test')
+ cxx_under_test = open(cxx_under_test_file).read().strip()
+
+ cxx_template_file = os.path.join(self.build_cmds_dir, 'cxx.cmds')
+ cxx_template = open(cxx_template_file).read().strip()
+
+ link_template_file = os.path.join(self.build_cmds_dir, 'link.cmds')
+ link_template = open(link_template_file).read().strip()
+
+ self.cxx = libcxx.android.compiler.AndroidCXXCompiler(
+ cxx_under_test, cxx_template, link_template)
+
+ def configure_triple(self):
+ self.config.target_triple = self.cxx.get_triple()
+
+ def configure_features(self):
+ self.config.available_features.add('long_tests')
+ std_pattern = re.compile(r'-std=(c\+\+\d[0-9x-z])')
+ match = std_pattern.search(self.cxx.cxx_template)
+ if match:
+ self.config.available_features.add(match.group(1))
+
+ def get_test_format(self):
+ mode = self.lit_config.params.get('android_mode', 'device')
+ if mode == 'device':
+ return libcxx.android.test.format.TestFormat(
+ self.cxx,
+ self.libcxx_src_root,
+ self.libcxx_obj_root,
+ getattr(self.config, 'device_dir', '/data/local/tmp/'),
+ getattr(self.config, 'timeout', '60'))
+ elif mode == 'host':
+ return libcxx.android.test.format.HostTestFormat(
+ self.cxx,
+ self.libcxx_src_root,
+ self.libcxx_obj_root,
+ getattr(self.config, 'timeout', '60'))
+ else:
+ raise RuntimeError('Invalid android_mode: {}'.format(mode))
diff --git a/test/libcxx/android/test/format.py b/test/libcxx/android/test/format.py
new file mode 100644
index 0000000..228272c
--- /dev/null
+++ b/test/libcxx/android/test/format.py
@@ -0,0 +1,91 @@
+import os
+
+import lit.util # pylint: disable=import-error
+
+from libcxx.android.executors import AdbExecutor
+from libcxx.test.executor import LocalExecutor, TimeoutExecutor
+import libcxx.test.format
+import libcxx.android.adb as adb
+
+
+class HostTestFormat(libcxx.test.format.LibcxxTestFormat):
+ # pylint: disable=super-init-not-called
+ def __init__(self, cxx, libcxx_src_root, libcxx_obj_root, timeout,
+ exec_env=None):
+ self.cxx = cxx
+ self.libcxx_src_root = libcxx_src_root
+ self.libcxx_obj_root = libcxx_obj_root
+ self.use_verify_for_fail = False
+ self.executor = TimeoutExecutor(timeout, LocalExecutor())
+
+ # We need to use LD_LIBRARY_PATH because the build system's rpath is
+ # relative, which won't work since we're running from /tmp. We can
+ # either scan `cxx_under_test`/`link_template` to determine whether
+ # we're 32-bit or 64-bit, scan testconfig.mk, or just add both
+ # directories and let the linker sort it out. I'm choosing the lazy
+ # option.
+ outdir = os.getenv('ANDROID_HOST_OUT')
+ libpath = os.pathsep.join([
+ os.path.join(outdir, 'lib'),
+ os.path.join(outdir, 'lib64'),
+ ])
+ default_env = {'LD_LIBRARY_PATH': libpath}
+ self.exec_env = default_env if exec_env is None else exec_env
+
+
+class TestFormat(HostTestFormat):
+ def __init__(self, cxx, libcxx_src_root, libcxx_obj_root, device_dir,
+ timeout, exec_env=None):
+ HostTestFormat.__init__(
+ self,
+ cxx,
+ libcxx_src_root,
+ libcxx_obj_root,
+ timeout,
+ exec_env)
+ self.device_dir = device_dir
+ self.executor = TimeoutExecutor(timeout, AdbExecutor())
+
+ def _working_directory(self, file_name):
+ return os.path.join(self.device_dir, file_name)
+
+ def _wd_path(self, test_name, file_name):
+ return os.path.join(self._working_directory(test_name), file_name)
+
+ def _build(self, exec_path, source_path, compile_only=False,
+ use_verify=False):
+ # pylint: disable=protected-access
+ cmd, report, rc = libcxx.test.format.LibcxxTestFormat._build(
+ self, exec_path, source_path, compile_only, use_verify)
+ if rc != 0:
+ return cmd, report, rc
+
+ try:
+ exec_file = os.path.basename(exec_path)
+
+ adb.mkdir(self._working_directory(exec_file))
+ adb.push(exec_path, self._wd_path(exec_file, exec_file))
+
+ # Push any .dat files in the same directory as the source to the
+ # working directory.
+ src_dir = os.path.dirname(source_path)
+ data_files = [f for f in os.listdir(src_dir) if f.endswith('.dat')]
+ for data_file in data_files:
+ df_path = os.path.join(src_dir, data_file)
+ df_dev_path = self._wd_path(exec_file, data_file)
+ adb.push(df_path, df_dev_path)
+ return cmd, report, rc
+ except adb.AdbError as ex:
+ return self._make_report(ex.cmd, ex.out, ex.err, ex.exit_code)
+
+ def _clean(self, exec_path):
+ exec_file = os.path.basename(exec_path)
+ cmd = ['adb', 'shell', 'rm', '-rf', self._working_directory(exec_file)]
+ lit.util.executeCommand(cmd)
+ try:
+ os.remove(exec_path)
+ except OSError:
+ pass
+
+ def _run(self, exec_path, _, in_dir=None):
+ raise NotImplementedError()
diff --git a/test/libcxx/ndk/__init__.py b/test/libcxx/ndk/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/libcxx/ndk/__init__.py
diff --git a/test/libcxx/ndk/test/__init__.py b/test/libcxx/ndk/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/libcxx/ndk/test/__init__.py
diff --git a/test/libcxx/ndk/test/config.py b/test/libcxx/ndk/test/config.py
new file mode 100644
index 0000000..85ccd84
--- /dev/null
+++ b/test/libcxx/ndk/test/config.py
@@ -0,0 +1,59 @@
+import os
+
+import libcxx.test.config
+import libcxx.android.build
+import libcxx.android.test.format
+
+
+class Configuration(libcxx.test.config.Configuration):
+ def __init__(self, lit_config, config):
+ super(Configuration, self).__init__(lit_config, config)
+ self.cxx_under_test = None
+ self.build_cmds_dir = None
+ self.cxx_template = None
+ self.link_template = None
+
+ def configure(self):
+ self.configure_cxx()
+ self.configure_triple()
+ self.configure_src_root()
+ self.configure_obj_root()
+ self.configure_cxx_library_root()
+ self.configure_compile_flags()
+ self.configure_link_flags()
+ self.configure_features()
+
+ def configure_link_flags(self):
+ self.link_flags.append('-nodefaultlibs')
+
+ # Configure libc++ library paths.
+ self.link_flags.append('-L' + self.cxx_library_root)
+
+ # Add libc_ndk's output path to the library search paths.
+ libdir = '{}/obj/STATIC_LIBRARIES/libc_ndk_intermediates'.format(
+ os.getenv('ANDROID_PRODUCT_OUT'))
+ self.link_flags.append('-L' + libdir)
+
+ self.link_flags.append('-lc++_ndk')
+ self.link_flags.append('-lc_ndk')
+ self.link_flags.append('-lc')
+
+ def configure_features(self):
+ self.config.available_features.add('long_tests')
+
+ def get_test_format(self):
+ cxx_template = ' '.join(
+ self.compile_flags + ['-c', '-o', '%OUT%', '%SOURCE%'])
+ link_template = ' '.join(
+ ['-o', '%OUT%', '%SOURCE%'] + self.compile_flags + self.link_flags)
+ tmp_dir = getattr(self.config, 'device_dir', '/data/local/tmp/')
+
+ return libcxx.android.test.format.TestFormat(
+ self.cxx,
+ self.libcxx_src_root,
+ self.obj_root,
+ cxx_template,
+ link_template,
+ tmp_dir,
+ getattr(self.config, 'timeout', '300'),
+ exec_env={'LD_LIBRARY_PATH': tmp_dir})
diff --git a/test/lit.site.cfg b/test/lit.site.cfg
new file mode 100644
index 0000000..c9dbdfb
--- /dev/null
+++ b/test/lit.site.cfg
@@ -0,0 +1,12 @@
+import os
+
+config.configuration_variant = 'libcxx.android'
+config.android_root = os.getenv('ANDROID_BUILD_TOP')
+config.libcxx_src_root = os.path.join(config.android_root, 'external/libcxx')
+config.python_executable = '/usr/bin/python'
+
+config.timeout = '300'
+
+# Let the main config do the real work.
+lit_config.load_config(
+ config, os.path.join(config.libcxx_src_root, 'test/lit.cfg'))
diff --git a/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp
index a52c2c7..100fd9d 100644
--- a/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp
+++ b/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: android
+
// <locale>
// class num_put<charT, OutputIterator>
diff --git a/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
index d9e7f3c..d74b6b5 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: android
+
// <locale>
// class time_put<charT, OutputIterator>