Revert "Revert "Update aosp/master libcxx rebase to r263688""

This reverts commit 1d4a1edbc7.

Change-Id: I2909937fe582f2c5552bc86e7f4d2d5cff0de0aa
This commit is contained in:
Dan Austin
2016-06-08 22:25:43 +00:00
parent 1d4a1edbc7
commit ee226c05af
1396 changed files with 38992 additions and 11535 deletions

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
// <atomic>
// struct atomic_flag
// TESTING EXTENSION atomic_flag(bool)
#include <atomic>
#include <cassert>
int main()
{
{
std::atomic_flag f(false);
assert(f.test_and_set() == 0);
}
{
std::atomic_flag f(true);
assert(f.test_and_set() == 1);
}
}

View File

@@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <atomic>
// Test that including <atomic> fails to compile when _LIBCPP_HAS_NO_THREADS
// is defined.
#ifndef _LIBCPP_HAS_NO_THREADS
#define _LIBCPP_HAS_NO_THREADS
#endif
#include <atomic>
int main()
{
}

View File

@@ -0,0 +1,18 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// XFAIL: libcpp-has-no-threads
#ifdef _LIBCPP_HAS_NO_THREADS
#error This should be XFAIL'd for the purpose of detecting that the LIT feature\
'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined
#endif
int main()
{
}

View File

@@ -1,3 +1,12 @@
#===----------------------------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===##
import os
import lit.util
import libcxx.util
@@ -161,3 +170,28 @@ class CXXCompiler(object):
return True
else:
return False
def addWarningFlagIfSupported(self, flag):
"""
addWarningFlagIfSupported - Add a warning flag if the compiler
supports it. Unlike addCompileFlagIfSupported, this function detects
when "-Wno-<warning>" flags are unsupported. If flag is a
"-Wno-<warning>" GCC will not emit an unknown option diagnostic unless
another error is triggered during compilation.
"""
assert isinstance(flag, str)
if not flag.startswith('-Wno-'):
return self.addCompileFlagIfSupported(flag)
flags = ['-Werror', flag]
cmd = self.compileCmd('-', os.devnull, flags)
# Remove '-v' because it will cause the command line invocation
# to be printed as part of the error output.
# TODO(EricWF): Are there other flags we need to worry about?
if '-v' in cmd:
cmd.remove('-v')
out, err, rc = lit.util.executeCommand(cmd, input='#error\n')
assert rc != 0
if flag in err:
return False
self.compile_flags += [flag]
return True

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <__tree>
#include <map>
#include <set>
#include <type_traits>
#include "test_macros.h"
#include "min_allocator.h"
void testKeyValueTrait() {
{
typedef int Tp;
typedef std::__tree_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, int>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
static_assert(Traits::__is_map == false, "");
}
{
typedef std::pair<int, int> Tp;
typedef std::__tree_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, Tp>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
static_assert(Traits::__is_map == false, "");
}
{
typedef std::pair<const int, int> Tp;
typedef std::__tree_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, Tp>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
static_assert(Traits::__is_map == false, "");
}
{
typedef std::__value_type<int, int> Tp;
typedef std::__tree_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, int>::value), "");
static_assert((std::is_same<Traits::mapped_type, int>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type,
std::pair<const int, int> >::value), "");
static_assert((std::is_same<Traits::__map_value_type,
std::pair<const int, int> >::value), "");
static_assert(Traits::__is_map == true, "");
}
}
int main() {
testKeyValueTrait();
}

View File

@@ -0,0 +1,98 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Not a portable test
// Precondition: __x->__right_ != nullptr
// template <class _NodePtr>
// void
// __tree_left_rotate(_NodePtr __x);
#include <__tree>
#include <cassert>
struct Node
{
Node* __left_;
Node* __right_;
Node* __parent_;
Node() : __left_(), __right_(), __parent_() {}
};
void
test1()
{
Node root;
Node x;
Node y;
root.__left_ = &x;
x.__left_ = 0;
x.__right_ = &y;
x.__parent_ = &root;
y.__left_ = 0;
y.__right_ = 0;
y.__parent_ = &x;
std::__tree_left_rotate(&x);
assert(root.__parent_ == 0);
assert(root.__left_ == &y);
assert(root.__right_ == 0);
assert(y.__parent_ == &root);
assert(y.__left_ == &x);
assert(y.__right_ == 0);
assert(x.__parent_ == &y);
assert(x.__left_ == 0);
assert(x.__right_ == 0);
}
void
test2()
{
Node root;
Node x;
Node y;
Node a;
Node b;
Node c;
root.__left_ = &x;
x.__left_ = &a;
x.__right_ = &y;
x.__parent_ = &root;
y.__left_ = &b;
y.__right_ = &c;
y.__parent_ = &x;
a.__parent_ = &x;
b.__parent_ = &y;
c.__parent_ = &y;
std::__tree_left_rotate(&x);
assert(root.__parent_ == 0);
assert(root.__left_ == &y);
assert(root.__right_ == 0);
assert(y.__parent_ == &root);
assert(y.__left_ == &x);
assert(y.__right_ == &c);
assert(x.__parent_ == &y);
assert(x.__left_ == &a);
assert(x.__right_ == &b);
assert(a.__parent_ == &x);
assert(a.__left_ == 0);
assert(a.__right_ == 0);
assert(b.__parent_ == &x);
assert(b.__left_ == 0);
assert(b.__right_ == 0);
assert(c.__parent_ == &y);
assert(c.__left_ == 0);
assert(c.__right_ == 0);
}
int main()
{
test1();
test2();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Not a portable test
// Precondition: __x->__left_ != nullptr
// template <class _NodePtr>
// void
// __tree_right_rotate(_NodePtr __x);
#include <__tree>
#include <cassert>
struct Node
{
Node* __left_;
Node* __right_;
Node* __parent_;
Node() : __left_(), __right_(), __parent_() {}
};
void
test1()
{
Node root;
Node x;
Node y;
root.__left_ = &x;
x.__left_ = &y;
x.__right_ = 0;
x.__parent_ = &root;
y.__left_ = 0;
y.__right_ = 0;
y.__parent_ = &x;
std::__tree_right_rotate(&x);
assert(root.__parent_ == 0);
assert(root.__left_ == &y);
assert(root.__right_ == 0);
assert(y.__parent_ == &root);
assert(y.__left_ == 0);
assert(y.__right_ == &x);
assert(x.__parent_ == &y);
assert(x.__left_ == 0);
assert(x.__right_ == 0);
}
void
test2()
{
Node root;
Node x;
Node y;
Node a;
Node b;
Node c;
root.__left_ = &x;
x.__left_ = &y;
x.__right_ = &c;
x.__parent_ = &root;
y.__left_ = &a;
y.__right_ = &b;
y.__parent_ = &x;
a.__parent_ = &y;
b.__parent_ = &y;
c.__parent_ = &x;
std::__tree_right_rotate(&x);
assert(root.__parent_ == 0);
assert(root.__left_ == &y);
assert(root.__right_ == 0);
assert(y.__parent_ == &root);
assert(y.__left_ == &a);
assert(y.__right_ == &x);
assert(x.__parent_ == &y);
assert(x.__left_ == &b);
assert(x.__right_ == &c);
assert(a.__parent_ == &y);
assert(a.__left_ == 0);
assert(a.__right_ == 0);
assert(b.__parent_ == &x);
assert(b.__left_ == 0);
assert(b.__right_ == 0);
assert(c.__parent_ == &x);
assert(c.__left_ == 0);
assert(c.__right_ == 0);
}
int main()
{
test1();
test2();
}

View File

@@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <ext/hash_map>
namespace __gnu_cxx {
template class hash_map<int, int>;
}
int main() {
typedef __gnu_cxx::hash_map<int, int> Map;
Map m;
Map m2(m);
((void)m2);
}

View File

@@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <ext/hash_set>
namespace __gnu_cxx {
template class hash_set<int>;
}
int main() {
typedef __gnu_cxx::hash_set<int> Set;
Set s;
Set s2(s);
((void)s2);
}

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <deque>
// deque()
// deque::iterator()
#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
#include <deque>
#include <cassert>
struct A {
std::deque<A> d;
std::deque<A>::iterator it;
std::deque<A>::reverse_iterator it2;
};
int main()
{
A a;
assert(a.d.size() == 0);
a.it = a.d.begin();
a.it2 = a.d.rend();
}

View File

@@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <list>
// template <class T, class Alloc>
// void swap(list<T,Alloc>& x, list<T,Alloc>& y);
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#endif
#include <list>
#include <cassert>
#include <__debug>
#include "min_allocator.h"
int main()
{
#if _LIBCPP_DEBUG >= 1
{
int a1[] = {1, 3, 7, 9, 10};
int a2[] = {0, 2, 4, 5, 6, 8, 11};
std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
std::list<int>::iterator i1 = c1.begin();
std::list<int>::iterator i2 = c2.begin();
swap(c1, c2);
c1.erase(i2);
c2.erase(i1);
std::list<int>::iterator j = i1;
c1.erase(i1);
assert(false);
}
#if __cplusplus >= 201103L
{
int a1[] = {1, 3, 7, 9, 10};
int a2[] = {0, 2, 4, 5, 6, 8, 11};
std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
std::list<int, min_allocator<int>>::iterator i1 = c1.begin();
std::list<int, min_allocator<int>>::iterator i2 = c2.begin();
swap(c1, c2);
c1.erase(i2);
c2.erase(i1);
std::list<int, min_allocator<int>>::iterator j = i1;
c1.erase(i1);
assert(false);
}
#endif
#endif
}

View File

@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5
// <vector>
// reference operator[](size_type n);
@@ -21,8 +23,11 @@
#include "test_macros.h"
#ifndef _LIBCPP_HAS_NO_ASAN
extern "C" void __asan_set_error_exit_code(int);
extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
void do_exit() {
exit(0);
}
int main()
{
@@ -48,7 +53,7 @@ int main()
assert(is_contiguous_container_asan_correct(v));
}
__asan_set_error_exit_code(0);
__sanitizer_set_death_callback(do_exit);
{
typedef int T;
typedef std::vector<T> C;

View File

@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
// XFAIL: libcpp-no-exceptions
// Test asan vector annotations with a class that throws in a CTOR.
#include <vector>

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <vector>
// vector<const int> v; // an extension
#include <vector>
#include <type_traits>
int main()
{
std::vector<const int> v = {1, 2, 3};
}

View File

@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Call back() on empty container.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
assert(c.back() == 0);
c.clear();
assert(c.back() == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
assert(c.back() == 0);
c.clear();
assert(c.back() == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Call back() on empty const container.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
const C c;
assert(c.back() == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
const C c;
assert(c.back() == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Call front() on empty const container.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
const C c;
assert(c.front() == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
const C c;
assert(c.front() == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Index const vector out of bounds.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
const C c(1);
assert(c[0] == 0);
assert(c[1] == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
const C c(1);
assert(c[0] == 0);
assert(c[1] == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Call front() on empty container.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
assert(c.front() == 0);
c.clear();
assert(c.front() == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
assert(c.front() == 0);
c.clear();
assert(c.front() == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Index vector out of bounds.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
assert(c[0] == 0);
c.clear();
assert(c[0] == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
assert(c[0] == 0);
c.clear();
assert(c[0] == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Compare iterators from different containers with <.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c1;
C c2;
bool b = c1.begin() < c2.begin();
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c1;
C c2;
bool b = c1.begin() < c2.begin();
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Subtract iterators from different containers.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c1;
C c2;
int i = c1.begin() - c2.begin();
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c1;
C c2;
int i = c1.begin() - c2.begin();
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Index iterator out of bounds.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
C::iterator i = c.begin();
assert(i[0] == 0);
assert(i[1] == 0);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
C::iterator i = c.begin();
assert(i[0] == 0);
assert(i[1] == 0);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Add to iterator out of bounds.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
C::iterator i = c.begin();
i += 1;
assert(i == c.end());
i = c.begin();
i += 2;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
C::iterator i = c.begin();
i += 1;
assert(i == c.end());
i = c.begin();
i += 2;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Decrement iterator prior to begin.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
C::iterator i = c.end();
--i;
assert(i == c.begin());
--i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
C::iterator i = c.end();
--i;
assert(i == c.begin());
--i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Increment iterator past end.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
C::iterator i = c.begin();
++i;
assert(i == c.end());
++i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
C::iterator i = c.begin();
++i;
assert(i == c.end());
++i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <vector>
// Dereference non-dereferenceable iterator.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <vector>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef int T;
typedef std::vector<T> C;
C c(1);
C::iterator i = c.end();
T j = *i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
C c(1);
C::iterator i = c.end();
T j = *i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <__hash_table>
#include <unordered_map>
#include <unordered_set>
#include <type_traits>
#include "test_macros.h"
#include "min_allocator.h"
void testKeyValueTrait() {
{
typedef int Tp;
typedef std::__hash_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, int>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
static_assert(Traits::__is_map == false, "");
}
{
typedef std::pair<int, int> Tp;
typedef std::__hash_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, Tp>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
static_assert(Traits::__is_map == false, "");
}
{
typedef std::pair<const int, int> Tp;
typedef std::__hash_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, Tp>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
static_assert(Traits::__is_map == false, "");
}
{
typedef std::__hash_value_type<int, int> Tp;
typedef std::__hash_key_value_types<Tp> Traits;
static_assert((std::is_same<Traits::key_type, int>::value), "");
static_assert((std::is_same<Traits::mapped_type, int>::value), "");
static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
static_assert((std::is_same<Traits::__container_value_type,
std::pair<const int, int> >::value), "");
static_assert((std::is_same<Traits::__map_value_type,
std::pair<const int, int> >::value), "");
static_assert(Traits::__is_map == true, "");
}
}
int main() {
testKeyValueTrait();
}

View File

@@ -0,0 +1,51 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// REQUIRES: long_tests
// Not a portable test
// <__hash_table>
// size_t __next_prime(size_t n);
// If n == 0, return 0, else return the lowest prime greater than or equal to n
#include <__hash_table>
#include <cassert>
bool
is_prime(size_t n)
{
switch (n)
{
case 0:
case 1:
return false;
}
for (size_t i = 2; i*i <= n; ++i)
{
if (n % i == 0)
return false;
}
return true;
}
int main()
{
assert(std::__next_prime(0) == 0);
for (std::size_t n = 1; n <= 100000; ++n)
{
std::size_t p = std::__next_prime(n);
assert(p >= n);
for (std::size_t i = n; i < p; ++i)
assert(!is_prime(i));
assert(is_prime(p));
}
}

View File

@@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <unordered_map>
// Increment iterator past end.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <unordered_map>
#include <string>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
C c;
c.insert(std::make_pair(1, "one"));
C::iterator i = c.begin();
++i;
assert(i == c.end());
++i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
C c;
c.insert(std::make_pair(1, "one"));
C::iterator i = c.begin();
++i;
assert(i == c.end());
++i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <unordered_map>
// Dereference non-dereferenceable iterator.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <unordered_map>
#include <string>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
C c;
c.insert(std::make_pair(1, "one"));
C::iterator i = c.end();
C::value_type j = *i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
C c;
c.insert(std::make_pair(1, "one"));
C::iterator i = c.end();
C::value_type j = *i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,57 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <unordered_map>
// Increment local_iterator past end.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <unordered_map>
#include <string>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
C c(1);
C::local_iterator i = c.begin(0);
++i;
++i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
C c(1);
C::local_iterator i = c.begin(0);
++i;
++i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <unordered_map>
// Dereference non-dereferenceable iterator.
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <unordered_map>
#include <string>
#include <cassert>
#include <iterator>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
C c(1);
C::local_iterator i = c.end(0);
C::value_type j = *i;
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
C c(1);
C::local_iterator i = c.end(0);
C::value_type j = *i;
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -1,48 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Check that we don't allocate when trying to insert a duplicate value into a
// unordered_set. See PR12999 http://llvm.org/bugs/show_bug.cgi?id=12999
#include <cassert>
#include <unordered_set>
#include "count_new.hpp"
#include "MoveOnly.h"
int main()
{
{
std::unordered_set<int> s;
assert(globalMemCounter.checkNewCalledEq(0));
for(int i=0; i < 100; ++i)
s.insert(3);
assert(s.size() == 1);
assert(s.count(3) == 1);
assert(globalMemCounter.checkNewCalledEq(2));
}
assert(globalMemCounter.checkOutstandingNewEq(0));
globalMemCounter.reset();
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
std::unordered_set<MoveOnly> s;
assert(globalMemCounter.checkNewCalledEq(0));
for(int i=0; i<100; i++)
s.insert(MoveOnly(3));
assert(s.size() == 1);
assert(s.count(MoveOnly(3)) == 1);
assert(globalMemCounter.checkNewCalledEq(2));
}
assert(globalMemCounter.checkOutstandingNewEq(0));
globalMemCounter.reset();
#endif
}

View File

@@ -0,0 +1,43 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Sometimes C++'s <foo.h> headers get included within extern "C" contexts. This
// is ill-formed (no diagnostic required), per [using.headers]p3, but we permit
// it as an extension.
extern "C" {
#include <assert.h>
// complex.h is not supported in extern "C".
#include <ctype.h>
#include <errno.h>
#include <fenv.h>
#include <float.h>
#include <inttypes.h>
#include <iso646.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdalign.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// tgmath.h is not supported in extern "C".
#include <time.h>
// FIXME: #include <uchar.h>
#include <wchar.h>
#include <wctype.h>
}
int main() {}

View File

@@ -15,6 +15,12 @@
// RUN: %cxx -o %t.exe %t.first.o %t.second.o %flags %link_flags
// RUN: %run
// Prevent <ext/hash_map> from generating deprecated warnings for this test.
#if defined(__DEPRECATED)
#undef __DEPRECATED
#endif
#include <algorithm>
#include <array>
#include <bitset>
@@ -50,6 +56,7 @@
#include <deque>
#include <exception>
#include <experimental/algorithm>
#include <experimental/any>
#include <experimental/chrono>
#include <experimental/dynarray>
#include <experimental/optional>

View File

@@ -16,6 +16,12 @@
#include <experimental/any>
#include "any_helpers.h"
constexpr std::size_t BufferSize = (sizeof(void*) * 3);
constexpr std::size_t BufferAlignment = alignof(void*);
// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986.
// So we create "DoubleBufferAlignment" instead.
constexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2;
class SmallThrowsDtor
{
public:
@@ -25,6 +31,30 @@ public:
~SmallThrowsDtor() noexcept(false) {}
};
struct alignas(1) MaxSizeType {
char buff[BufferSize];
};
struct alignas(BufferAlignment) MaxAlignType {
};
struct alignas(BufferAlignment) MaxSizeAndAlignType {
char buff[BufferSize];
};
struct alignas(1) OverSizeType {
char buff[BufferSize + 1];
};
struct alignas(DoubleBufferAlignment) OverAlignedType {
};
struct alignas(DoubleBufferAlignment) OverSizeAndAlignedType {
char buff[BufferSize + 1];
};
int main()
{
using std::experimental::any;
@@ -33,8 +63,52 @@ int main()
static_assert(_IsSmallObject<void*>::value, "");
static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
static_assert(!_IsSmallObject<large>::value, "");
// long double is over aligned.
static_assert(sizeof(long double) <= sizeof(void*) * 3, "");
static_assert(alignof(long double) > alignof(void*), "");
static_assert(!_IsSmallObject<long double>::value, "");
{
// Check a type that meets the size requirement *exactly* and has
// a lesser alignment requirement is considered small.
typedef MaxSizeType T;
static_assert(sizeof(T) == BufferSize, "");
static_assert(alignof(T) < BufferAlignment, "");
static_assert(_IsSmallObject<T>::value, "");
}
{
// Check a type that meets the alignment requirement *exactly* and has
// a lesser size is considered small.
typedef MaxAlignType T;
static_assert(sizeof(T) < BufferSize, "");
static_assert(alignof(T) == BufferAlignment, "");
static_assert(_IsSmallObject<T>::value, "");
}
{
// Check a type that meets the size and alignment requirements *exactly*
// is considered small.
typedef MaxSizeAndAlignType T;
static_assert(sizeof(T) == BufferSize, "");
static_assert(alignof(T) == BufferAlignment, "");
static_assert(_IsSmallObject<T>::value, "");
}
{
// Check a type that meets the alignment requirements but is over-sized
// is not considered small.
typedef OverSizeType T;
static_assert(sizeof(T) > BufferSize, "");
static_assert(alignof(T) < BufferAlignment, "");
static_assert(!_IsSmallObject<T>::value, "");
}
{
// Check a type that meets the size requirements but is over-aligned
// is not considered small.
typedef OverAlignedType T;
static_assert(sizeof(T) < BufferSize, "");
static_assert(alignof(T) > BufferAlignment, "");
static_assert(!_IsSmallObject<T>::value, "");
}
{
// Check a type that exceeds both the size an alignment requirements
// is not considered small.
typedef OverSizeAndAlignedType T;
static_assert(sizeof(T) > BufferSize, "");
static_assert(alignof(T) > BufferAlignment, "");
static_assert(!_IsSmallObject<T>::value, "");
}
}

View File

@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
// XFAIL: libcpp-no-exceptions
// UNSUPPORTED: c++98, c++03, c++11
// dynarray.cons
// explicit dynarray(size_type c);
@@ -16,22 +19,21 @@
// ~dynarray();
#include <__config>
#if _LIBCPP_STD_VER > 11
#include <experimental/dynarray>
#include <cassert>
#include <algorithm>
#include <complex>
#include <limits>
#include <new>
#include <string>
using std::experimental::dynarray;
template <class T>
void test ( const std::initializer_list<T> &vals ) {
void testInitList( const std::initializer_list<T> &vals ) {
typedef dynarray<T> dynA;
dynA d1 ( vals );
@@ -41,12 +43,14 @@ void test ( const std::initializer_list<T> &vals ) {
template <class T>
void test ( const T &val ) {
void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
typedef dynarray<T> dynA;
dynA d1 ( 4 );
assert ( d1.size () == 4 );
assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
if (!DefaultValueIsIndeterminate) {
assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
}
dynA d2 ( 7, val );
assert ( d2.size () == 7 );
@@ -60,27 +64,23 @@ void test ( const T &val ) {
void test_bad_length () {
try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) + 1 ); }
catch ( std::bad_array_length & ) { return ; }
catch (...) { assert(false); }
assert ( false );
}
}
void test_bad_alloc () {
try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) - 1 ); }
catch ( std::bad_alloc & ) { return ; }
assert ( false );
}
int main()
{
// test<int> ( 14 ); // ints don't get default initialized
test<long> ( 0 );
test<double> ( 14.0 );
test<int> ( 14, /* DefaultValueIsIndeterminate */ true ); // ints don't get default initialized
test<long> ( 0, true);
test<double> ( 14.0, true );
test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
test<std::string> ( "fourteen" );
test ( { 1, 1, 2, 3, 5, 8 } );
test ( { 1., 1., 2., 3., 5., 8. } );
test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
std::string("5"), std::string("8")} );
testInitList( { 1, 1, 2, 3, 5, 8 } );
testInitList( { 1., 1., 2., 3., 5., 8. } );
testInitList( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
std::string("5"), std::string("8")} );
// Make sure we don't pick up the Allocator version here
dynarray<long> d1 ( 20, 3 );
@@ -88,8 +88,4 @@ int main()
assert ( std::all_of ( d1.begin (), d1.end (), []( long item ){ return item == 3L; } ));
test_bad_length ();
test_bad_alloc ();
}
#else
int main() {}
#endif

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// XFAIL: libcpp-no-exceptions
// dynarray.cons
// explicit dynarray(size_type c);
// UNSUPPORTED: c++98, c++03, c++11
// The sanitizers replace new/delete with versions that do not throw bad_alloc.
// UNSUPPORTED: sanitizer-new-delete, ubsan
#include <experimental/dynarray>
#include <limits>
#include <new>
#include <cassert>
using std::experimental::dynarray;
int main() {
try { dynarray<int>((std::numeric_limits<size_t>::max() / sizeof(int)) - 1); }
catch (std::bad_alloc &) { return 0; }
catch (...) { assert(false); }
assert(false);
}

View File

@@ -7,15 +7,13 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11
// dynarray.data
// T* data() noexcept;
// const T* data() const noexcept;
#include <__config>
#if _LIBCPP_STD_VER > 11
#include <experimental/dynarray>
#include <cassert>
@@ -27,41 +25,44 @@
using std::experimental::dynarray;
template <class T>
void dyn_test_const ( const dynarray<T> &dyn ) {
void dyn_test_const(const dynarray<T> &dyn, bool CheckEquals = true) {
const T *data = dyn.data ();
assert ( data != NULL );
assert ( std::equal ( dyn.begin(), dyn.end(), data ));
if (CheckEquals) {
assert ( std::equal ( dyn.begin(), dyn.end(), data ));
}
}
template <class T>
void dyn_test ( dynarray<T> &dyn ) {
void dyn_test( dynarray<T> &dyn, bool CheckEquals = true) {
T *data = dyn.data ();
assert ( data != NULL );
assert ( std::equal ( dyn.begin(), dyn.end(), data ));
if (CheckEquals) {
assert ( std::equal ( dyn.begin(), dyn.end(), data ));
}
}
template <class T>
void test ( const T &val ) {
void test(const T &val, bool DefaultValueIsIndeterminate = false) {
typedef dynarray<T> dynA;
const bool CheckDefaultValues = !DefaultValueIsIndeterminate;
dynA d1(4);
dyn_test(d1, CheckDefaultValues);
dyn_test_const(d1, CheckDefaultValues);
dynA d1 ( 4 );
dyn_test ( d1 );
dyn_test_const ( d1 );
dynA d2 ( 7, val );
dynA d2 (7, val);
dyn_test ( d2 );
dyn_test_const ( d2 );
}
}
int main()
{
test<int> ( 14 );
test<double> ( 14.0 );
test<int>(14, /* DefaultValueIsIndeterminate */ true);
test<double>(14.0, true);
test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
test<std::string> ( "fourteen" );
}
#else
int main() {}
#endif

View File

@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
// XFAIL: libcpp-no-exceptions
// dynarray.overview
// const_reference at(size_type n) const;

View File

@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11
// dynarray.overview
// reference front();
@@ -14,10 +16,6 @@
// reference back();
// const_reference back() const;
#include <__config>
#if _LIBCPP_STD_VER > 11
#include <experimental/dynarray>
#include <cassert>
@@ -29,40 +27,47 @@
using std::experimental::dynarray;
template <class T>
void dyn_test_const ( const dynarray<T> &dyn ) {
void dyn_test_const ( const dynarray<T> &dyn, bool CheckValues = true ) {
const T *data = dyn.data ();
assert ( *data == dyn.front ());
assert ( *(data + dyn.size() - 1 ) == dyn.back ());
assert(data == &dyn.front());
assert((data + dyn.size() - 1) == &dyn.back());
if (CheckValues) {
assert ( *data == dyn.front ());
assert ( *(data + dyn.size() - 1 ) == dyn.back ());
}
}
template <class T>
void dyn_test ( dynarray<T> &dyn ) {
void dyn_test ( dynarray<T> &dyn, bool CheckValues = true ) {
T *data = dyn.data ();
assert ( *data == dyn.front ());
assert ( *(data + dyn.size() - 1 ) == dyn.back ());
assert(data == &dyn.front());
assert((data + dyn.size() - 1) == &dyn.back());
if (CheckValues) {
assert ( *data == dyn.front ());
assert ( *(data + dyn.size() - 1 ) == dyn.back ());
}
}
template <class T>
void test ( const T &val ) {
void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
typedef dynarray<T> dynA;
const bool CheckDefaultValues = ! DefaultValueIsIndeterminate;
dynA d1 ( 4 );
dyn_test ( d1 );
dyn_test_const ( d1 );
dyn_test ( d1, CheckDefaultValues );
dyn_test_const ( d1, CheckDefaultValues );
dynA d2 ( 7, val );
dyn_test ( d2 );
dyn_test_const ( d2 );
}
}
int main()
{
test<int> ( 14 );
test<double> ( 14.0 );
test<int> ( 14, /* DefaultValueIsIndeterminate */ true);
test<double> ( 14.0, true );
test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
test<std::string> ( "fourteen" );
}
#else
int main() {}
#endif

View File

@@ -0,0 +1,178 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// template <class T> class polymorphic_allocator
// template <class U1, class U2, class ...Args1, class ...Args2>
// void polymorphic_allocator<T>::construct(pair<T1, T2>*, piecewise_construct_t
// tuple<Args1...> x, tuple<Args2...>)
// The stardard specifiers a tranformation to uses-allocator construction as
// follows:
// - If uses_allocator_v<T1,memory_resource*> is false and
// is_constructible_v<T,Args1...> is true, then xprime is x.
// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
// is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...> is true,
// then xprime is
// tuple_cat(make_tuple(allocator_arg, this->resource()), std::move(x)).
// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
// is_constructible_v<T1,Args1...,memory_resource*> is true, then xprime is
// tuple_cat(std::move(x), make_tuple(this->resource())).
// - Otherwise the program is ill formed.
//
// The use of "xprime = tuple_cat(..., std::move(x), ...)" causes all of the
// objects in 'x' to be copied into 'xprime'. If 'x' contains any types which
// are stored by value this causes an unessary copy to occur. To prevent this
// libc++ changes this call into
// "xprime = forward_as_tuple(..., std::get<Idx>(std::move(x))..., ...)".
// 'xprime' contains references to the values in 'x' instead of copying them.
// This test checks the number of copies incurred to the elements in
// 'tuple<Args1...>' and 'tuple<Args2...>'.
#include <experimental/memory_resource>
#include <type_traits>
#include <utility>
#include <tuple>
#include <cassert>
#include <cstdlib>
#include "test_memory_resource.hpp"
namespace ex = std::experimental::pmr;
template <class T>
struct TestHarness {
TestResource R;
ex::memory_resource * M = &R;
ex::polymorphic_allocator<T> A = M;
bool constructed = false;
T * ptr;
TestHarness() : ptr(A.allocate(1)) {}
template <class ...Args>
void construct(Args&&... args) {
A.construct(ptr, std::forward<Args>(args)...);
constructed = true;
}
~TestHarness() {
if (constructed) A.destroy(ptr);
A.deallocate(ptr, 1);
}
};
struct CountCopies {
int count;
CountCopies() : count(0) {}
CountCopies(CountCopies const& o) : count(o.count + 1) {}
};
struct CountCopiesAllocV1 {
typedef ex::memory_resource* allocator_type;
allocator_type alloc;
int count;
CountCopiesAllocV1() : alloc(nullptr), count(0) {}
CountCopiesAllocV1(std::allocator_arg_t, allocator_type const& a,
CountCopiesAllocV1 const& o) : alloc(a), count(o.count + 1)
{}
CountCopiesAllocV1(CountCopiesAllocV1 const& o) : count(o.count + 1) {}
};
struct CountCopiesAllocV2 {
typedef ex::memory_resource* allocator_type;
allocator_type alloc;
int count;
CountCopiesAllocV2() : alloc(nullptr), count(0) {}
CountCopiesAllocV2(CountCopiesAllocV2 const& o, allocator_type const& a)
: alloc(a), count(o.count + 1)
{ }
CountCopiesAllocV2(CountCopiesAllocV2 const& o) : count(o.count + 1) {}
};
int main()
{
using PMR = ex::memory_resource*;
using PMA = ex::polymorphic_allocator<char>;
{
using T = CountCopies;
using U = CountCopiesAllocV1;
using P = std::pair<T, U>;
using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
TestHarness<P> h;
h.construct(std::piecewise_construct, t1, t2);
P const& p = *h.ptr;
assert(p.first.count == 2);
assert(p.second.count == 2);
assert(p.second.alloc == h.M);
}
{
using T = CountCopiesAllocV1;
using U = CountCopiesAllocV2;
using P = std::pair<T, U>;
using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
TestHarness<P> h;
h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
P const& p = *h.ptr;
assert(p.first.count == 2);
assert(p.first.alloc == h.M);
assert(p.second.count == 2);
assert(p.second.alloc == h.M);
}
{
using T = CountCopiesAllocV2;
using U = CountCopiesAllocV1;
using P = std::pair<T, U>;
using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
TestHarness<P> h;
h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
P const& p = *h.ptr;
assert(p.first.count == 2);
assert(p.first.alloc == h.M);
assert(p.second.count == 2);
assert(p.second.alloc == h.M);
}
{
using T = CountCopiesAllocV2;
using U = CountCopies;
using P = std::pair<T, U>;
using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
TestHarness<P> h;
h.construct(std::piecewise_construct, t1, t2);
P const& p = *h.ptr;
assert(p.first.count == 2);
assert(p.first.alloc == h.M);
assert(p.second.count == 2);
}
}

View File

@@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// template <class T> class polymorphic_allocator
// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
int AssertCount = 0;
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++)
#define _LIBCPP_DEBUG 0
#include <experimental/memory_resource>
#include <type_traits>
#include <cassert>
#include "test_memory_resource.hpp"
namespace ex = std::experimental::pmr;
int main()
{
using Alloc = ex::polymorphic_allocator<int>;
using Traits = std::allocator_traits<Alloc>;
NullResource R;
Alloc a(&R);
const std::size_t maxSize = Traits::max_size(a);
a.deallocate(nullptr, maxSize);
assert(AssertCount == 0);
a.deallocate(nullptr, maxSize + 1);
assert(AssertCount == 1);
}

View File

@@ -0,0 +1,64 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// template <class T> class polymorphic_allocator
// EXTENSION
// std::size_t polymorphic_allocator<T>::max_size() const noexcept
#include <experimental/memory_resource>
#include <type_traits>
#include <cassert>
#include "test_memory_resource.hpp"
namespace ex = std::experimental::pmr;
template <std::size_t S>
std::size_t getMaxSize() {
using T = typename std::aligned_storage<S>::type;
static_assert(sizeof(T) == S, "Required for test");
return ex::polymorphic_allocator<T>{}.max_size();
}
template <std::size_t S, std::size_t A>
std::size_t getMaxSize() {
using T = typename std::aligned_storage<S, A>::type;
static_assert(sizeof(T) == S, "Required for test");
return ex::polymorphic_allocator<T>{}.max_size();
}
int main()
{
{
using Alloc = ex::polymorphic_allocator<int>;
using Traits = std::allocator_traits<Alloc>;
const Alloc a;
static_assert(std::is_same<decltype(a.max_size()), Traits::size_type>::value, "");
static_assert(noexcept(a.max_size()), "");
}
{
constexpr std::size_t Max = std::numeric_limits<std::size_t>::max();
assert(getMaxSize<1>() == Max);
assert(getMaxSize<2>() == Max / 2);
assert(getMaxSize<4>() == Max / 4);
assert(getMaxSize<8>() == Max / 8);
assert(getMaxSize<16>() == Max / 16);
assert(getMaxSize<32>() == Max / 32);
assert(getMaxSize<64>() == Max / 64);
assert(getMaxSize<1024>() == Max / 1024);
assert((getMaxSize<6, 2>() == Max / 6));
assert((getMaxSize<12, 4>() == Max / 12));
}
}

View File

@@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// template <class T> class polymorphic_allocator
// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
int AssertCount = 0;
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++)
#define _LIBCPP_DEBUG 0
#include <experimental/memory_resource>
#include <type_traits>
#include <cassert>
#include "test_memory_resource.hpp"
namespace ex = std::experimental::pmr;
int main()
{
using Alloc = NullAllocator<char>;
using R = ex::resource_adaptor<Alloc>;
AllocController P;
ex::resource_adaptor<Alloc> r(Alloc{P});
ex::memory_resource & m1 = r;
std::size_t maxSize = std::numeric_limits<std::size_t>::max()
- alignof(std::max_align_t);
m1.deallocate(nullptr, maxSize);
assert(AssertCount == 0);
m1.deallocate(nullptr, maxSize + 1);
assert(AssertCount >= 1);
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/deque>
#include <experimental/deque>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/forward_list>
#include <experimental/forward_list>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/list>
#include <experimental/list>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/map>
#include <experimental/map>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/regex>
#include <experimental/regex>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/set>
#include <experimental/set>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/string>
#include <experimental/string>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/unordered_map>
#include <experimental/unordered_map>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/unordered_set>
#include <experimental/unordered_set>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/vector>
#include <experimental/vector>
#ifndef _LIBCPP_VERSION
#error header must provide _LIBCPP_VERSION
#endif
int main()
{
}

View File

@@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// memory_resource * new_delete_resource()
// The lifetime of the value returned by 'new_delete_resource()' should
// never end, even very late into program termination. This test constructs
// attempts to use 'new_delete_resource()' very late in program termination
// to detect lifetime issues.
#include <experimental/memory_resource>
#include <type_traits>
#include <cassert>
namespace ex = std::experimental::pmr;
struct POSType {
ex::memory_resource* res = nullptr;
void* ptr = nullptr;
int n = 0;
POSType() {}
POSType(ex::memory_resource* r, void* p, int s) : res(r), ptr(p), n(s) {}
~POSType() {
if (ptr) {
if (!res) res = ex::get_default_resource();
res->deallocate(ptr, n);
}
}
};
void swap(POSType & L, POSType & R) {
std::swap(L.res, R.res);
std::swap(L.ptr, R.ptr);
std::swap(L.n, R.n);
}
POSType constructed_before_resources;
POSType constructed_before_resources2;
// Constructs resources
ex::memory_resource* resource = ex::get_default_resource();
POSType constructed_after_resources(resource, resource->allocate(1024), 1024);
POSType constructed_after_resources2(nullptr, resource->allocate(1024), 1024);
int main()
{
swap(constructed_after_resources, constructed_before_resources);
swap(constructed_before_resources2, constructed_after_resources2);
}

View File

@@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// memory_resource * new_delete_resource()
// The lifetime of the value returned by 'new_delete_resource()' should
// never end, even very late into program termination. This test constructs
// attempts to use 'new_delete_resource()' very late in program termination
// to detect lifetime issues.
#include <experimental/memory_resource>
#include <type_traits>
#include <cassert>
namespace ex = std::experimental::pmr;
struct POSType {
ex::memory_resource* res = nullptr;
void* ptr = nullptr;
int n = 0;
POSType() {res = ex::new_delete_resource(); ptr = res->allocate(42); n = 42; }
POSType(ex::memory_resource* r, void* p, int s) : res(r), ptr(p), n(s) {}
~POSType() { if (ptr) res->deallocate(ptr, n); }
};
void swap(POSType & L, POSType & R) {
std::swap(L.res, R.res);
std::swap(L.ptr, R.ptr);
std::swap(L.n, R.n);
}
POSType constructed_before_resources;
// Constructs resources
ex::memory_resource* resource = ex::new_delete_resource();
POSType constructed_after_resources(resource, resource->allocate(1024), 1024);
int main()
{
swap(constructed_after_resources, constructed_before_resources);
}

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
#include <experimental/memory_resource>
#ifndef _LIBCPP_VERSION
#error _LIBCPP_VERSION not defined
#endif
int main()
{
}

View File

@@ -0,0 +1,17 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <assert.h>
#include <ext/hash_map>
#include <string>
int main()
{
assert(__gnu_cxx::hash<std::string>()(std::string()) == 0); // error
}

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// NOTE: Undefined __DEPRECATED to prevent this test from failing with -Werror
#undef __DEPRECATED
#include <assert.h>
#include <ext/hash_map>
#include <string>
int main()
{
char str[] = "test";
assert(__gnu_cxx::hash<const char *>()("test") ==
std::hash<std::string>()("test"));
assert(__gnu_cxx::hash<char *>()(str) == std::hash<std::string>()("test"));
assert(__gnu_cxx::hash<char>()(42) == 42);
assert(__gnu_cxx::hash<signed char>()(42) == 42);
assert(__gnu_cxx::hash<unsigned char>()(42) == 42);
assert(__gnu_cxx::hash<short>()(42) == 42);
assert(__gnu_cxx::hash<unsigned short>()(42) == 42);
assert(__gnu_cxx::hash<int>()(42) == 42);
assert(__gnu_cxx::hash<unsigned int>()(42) == 42);
assert(__gnu_cxx::hash<long>()(42) == 42);
assert(__gnu_cxx::hash<unsigned long>()(42) == 42);
}

View File

@@ -0,0 +1,18 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <ext/hash_map>
int main()
{
__gnu_cxx::hash_map<int, int> m;
m[1] = 1;
const __gnu_cxx::hash_map<int, int> &cm = m;
cm.find(1)->second = 2; // error
}

View File

@@ -0,0 +1,12 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
int main()
{
}

View File

@@ -0,0 +1,187 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// <iterator>
// __libcpp_is_trivial_iterator<Tp>
// __libcpp_is_trivial_iterator determines if an iterator is a "trivial" one,
// that can be used w/o worrying about its operations throwing exceptions.
// Pointers are trivial iterators. Libc++ has three "iterator wrappers":
// reverse_iterator, move_iterator, and __wrap_iter. If the underlying iterator
// is trivial, then those are as well.
//
#include <iterator>
#include <cassert>
#include <string>
#include <vector>
#include <initializer_list>
#include "test_iterators.h"
#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
#define DELETE_FUNCTION = delete
#else
#define DELETE_FUNCTION
#endif
class T; // incomplete
class my_input_iterator_tag : public std::input_iterator_tag {};
template <class It>
class my_input_iterator
{
It it_;
template <class U> friend class input_iterator;
public:
typedef my_input_iterator_tag iterator_category;
typedef typename std::iterator_traits<It>::value_type value_type;
typedef typename std::iterator_traits<It>::difference_type difference_type;
typedef It pointer;
typedef typename std::iterator_traits<It>::reference reference;
It base() const {return it_;}
my_input_iterator() : it_() {}
explicit my_input_iterator(It it) : it_(it) {}
template <class U>
my_input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
reference operator*() const {return *it_;}
pointer operator->() const {return it_;}
my_input_iterator& operator++() {++it_; return *this;}
my_input_iterator operator++(int)
{my_input_iterator tmp(*this); ++(*this); return tmp;}
friend bool operator==(const my_input_iterator& x, const my_input_iterator& y)
{return x.it_ == y.it_;}
friend bool operator!=(const my_input_iterator& x, const my_input_iterator& y)
{return !(x == y);}
template <class T>
void operator,(T const &) DELETE_FUNCTION;
};
template <class T, class U>
inline
bool
operator==(const my_input_iterator<T>& x, const my_input_iterator<U>& y)
{
return x.base() == y.base();
}
template <class T, class U>
inline
bool
operator!=(const my_input_iterator<T>& x, const my_input_iterator<U>& y)
{
return !(x == y);
}
int main()
{
// basic tests
static_assert(( std::__libcpp_is_trivial_iterator<char *>::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<const char *>::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<int *>::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<T *>::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<char *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<const char *> >::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<int *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<T *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<char *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<const char *> >::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<int *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<T *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<char *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<const char *> >::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<int *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<T *> > ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), "");
// iterators in the libc++ test suite
static_assert((!std::__libcpp_is_trivial_iterator<output_iterator <char *> >::value), "");
static_assert((!std::__libcpp_is_trivial_iterator<input_iterator <char *> >::value), "");
static_assert((!std::__libcpp_is_trivial_iterator<forward_iterator <char *> >::value), "");
static_assert((!std::__libcpp_is_trivial_iterator<bidirectional_iterator<char *> >::value), "");
static_assert((!std::__libcpp_is_trivial_iterator<random_access_iterator<char *> >::value), "");
static_assert((!std::__libcpp_is_trivial_iterator<ThrowingIterator <char *> >::value), "");
static_assert((!std::__libcpp_is_trivial_iterator<NonThrowingIterator <char *> >::value), "");
// Iterator classification
static_assert(( std::__is_input_iterator <char *>::value), "" );
static_assert(( std::__is_forward_iterator <char *>::value), "" );
static_assert(( std::__is_bidirectional_iterator<char *>::value), "" );
static_assert(( std::__is_random_access_iterator<char *>::value), "" );
static_assert((!std::__is_exactly_input_iterator<char *>::value), "" );
static_assert(( std::__is_input_iterator <input_iterator<char *> >::value), "" );
static_assert((!std::__is_forward_iterator <input_iterator<char *> >::value), "" );
static_assert((!std::__is_bidirectional_iterator<input_iterator<char *> >::value), "" );
static_assert((!std::__is_random_access_iterator<input_iterator<char *> >::value), "" );
static_assert(( std::__is_exactly_input_iterator<input_iterator<char *> >::value), "" );
static_assert(( std::__is_input_iterator <forward_iterator<char *> >::value), "" );
static_assert(( std::__is_forward_iterator <forward_iterator<char *> >::value), "" );
static_assert((!std::__is_bidirectional_iterator<forward_iterator<char *> >::value), "" );
static_assert((!std::__is_random_access_iterator<forward_iterator<char *> >::value), "" );
static_assert((!std::__is_exactly_input_iterator<forward_iterator<char *> >::value), "" );
static_assert(( std::__is_input_iterator <bidirectional_iterator<char *> >::value), "" );
static_assert(( std::__is_forward_iterator <bidirectional_iterator<char *> >::value), "" );
static_assert(( std::__is_bidirectional_iterator<bidirectional_iterator<char *> >::value), "" );
static_assert((!std::__is_random_access_iterator<bidirectional_iterator<char *> >::value), "" );
static_assert((!std::__is_exactly_input_iterator<bidirectional_iterator<char *> >::value), "" );
static_assert(( std::__is_input_iterator <random_access_iterator<char *> >::value), "" );
static_assert(( std::__is_forward_iterator <random_access_iterator<char *> >::value), "" );
static_assert(( std::__is_bidirectional_iterator<random_access_iterator<char *> >::value), "" );
static_assert(( std::__is_random_access_iterator<random_access_iterator<char *> >::value), "" );
static_assert((!std::__is_exactly_input_iterator<random_access_iterator<char *> >::value), "" );
static_assert(( std::__is_input_iterator <my_input_iterator<char *> >::value), "" );
static_assert((!std::__is_forward_iterator <my_input_iterator<char *> >::value), "" );
static_assert((!std::__is_bidirectional_iterator<my_input_iterator<char *> >::value), "" );
static_assert((!std::__is_random_access_iterator<my_input_iterator<char *> >::value), "" );
static_assert(( std::__is_exactly_input_iterator<my_input_iterator<char *> >::value), "" );
//
// iterators from libc++'s containers
//
// string
static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::const_iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::reverse_iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::const_reverse_iterator>::value), "");
// vector
static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::const_iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::reverse_iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
// Initializer list (which has no reverse iterators)
static_assert(( std::__libcpp_is_trivial_iterator<std::initializer_list<char>::iterator> ::value), "");
static_assert(( std::__libcpp_is_trivial_iterator<std::initializer_list<char>::const_iterator> ::value), "");
#endif
}

View File

@@ -0,0 +1,118 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <locale>
// Not a portable test
// __scan_keyword
// Scans [__b, __e) until a match is found in the basic_strings range
// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
// __b will be incremented (visibly), consuming CharT until a match is found
// or proved to not exist. A keyword may be "", in which will match anything.
// If one keyword is a prefix of another, and the next CharT in the input
// might match another keyword, the algorithm will attempt to find the longest
// matching keyword. If the longer matching keyword ends up not matching, then
// no keyword match is found. If no keyword match is found, __ke is returned.
// Else an iterator pointing to the matching keyword is found. If more than
// one keyword matches, an iterator to the first matching keyword is returned.
// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
// __ct is used to force to lower case before comparing characters.
// Examples:
// Keywords: "a", "abb"
// If the input is "a", the first keyword matches and eofbit is set.
// If the input is "abc", no match is found and "ab" are consumed.
//
// template <class _InputIterator, class _ForwardIterator, class _Ctype>
// _ForwardIterator
// __scan_keyword(_InputIterator& __b, _InputIterator __e,
// _ForwardIterator __kb, _ForwardIterator __ke,
// const _Ctype& __ct, ios_base::iostate& __err,
// bool __case_sensitive = true);
#include <locale>
#include <cassert>
int main()
{
const std::ctype<char>& ct = std::use_facet<std::ctype<char> >(std::locale::classic());
std::ios_base::iostate err = std::ios_base::goodbit;
{
const char input[] = "a";
const char* in = input;
std::string keys[] = {"a", "abb"};
err = std::ios_base::goodbit;
std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
keys, keys+sizeof(keys)/sizeof(keys[0]),
ct, err);
assert(k - keys == 0);
assert(in == input+1);
assert(err == std::ios_base::eofbit);
}
{
const char input[] = "abc";
const char* in = input;
std::string keys[] = {"a", "abb"};
err = std::ios_base::goodbit;
std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
keys, keys+sizeof(keys)/sizeof(keys[0]),
ct, err);
assert(k - keys == 2);
assert(in == input+2);
assert(err == std::ios_base::failbit);
}
{
const char input[] = "abb";
const char* in = input;
std::string keys[] = {"a", "abb"};
err = std::ios_base::goodbit;
std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
keys, keys+sizeof(keys)/sizeof(keys[0]),
ct, err);
assert(k - keys == 1);
assert(in == input+3);
assert(err == std::ios_base::eofbit);
}
{
const char input[] = "Tue ";
const char* in = input;
std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
err = std::ios_base::goodbit;
std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
keys, keys+sizeof(keys)/sizeof(keys[0]),
ct, err);
assert(k - keys == 2);
assert(in == input+3);
assert(err == std::ios_base::goodbit);
}
{
const char input[] = "tue ";
const char* in = input;
std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
err = std::ios_base::goodbit;
std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
keys, keys+sizeof(keys)/sizeof(keys[0]),
ct, err);
assert(k - keys == 4);
assert(in == input+0);
assert(err == std::ios_base::failbit);
}
{
const char input[] = "tue ";
const char* in = input;
std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
err = std::ios_base::goodbit;
std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
keys, keys+sizeof(keys)/sizeof(keys[0]),
ct, err, false);
assert(k - keys == 2);
assert(in == input+3);
assert(err == std::ios_base::goodbit);
}
}

View File

@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <locale>
// class locale::facet
// {
// protected:
// explicit facet(size_t refs = 0);
// virtual ~facet();
// facet(const facet&) = delete;
// void operator=(const facet&) = delete;
// };
// This test isn't portable
#include <locale>
#include <cassert>
struct my_facet
: public std::locale::facet
{
static int count;
my_facet(unsigned refs = 0)
: std::locale::facet(refs)
{++count;}
~my_facet() {--count;}
};
int my_facet::count = 0;
int main()
{
my_facet* f = new my_facet;
f->__add_shared();
assert(my_facet::count == 1);
f->__release_shared();
assert(my_facet::count == 0);
f = new my_facet(1);
f->__add_shared();
assert(my_facet::count == 1);
f->__release_shared();
assert(my_facet::count == 1);
f->__release_shared();
assert(my_facet::count == 0);
}

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <locale>
// class locale::id
// {
// public:
// id();
// void operator=(const id&) = delete;
// id(const id&) = delete;
// };
// This test isn't portable
#include <locale>
#include <cassert>
std::locale::id id0;
std::locale::id id2;
std::locale::id id1;
int main()
{
long id = id0.__get();
assert(id0.__get() == id+0);
assert(id0.__get() == id+0);
assert(id0.__get() == id+0);
assert(id1.__get() == id+1);
assert(id1.__get() == id+1);
assert(id1.__get() == id+1);
assert(id2.__get() == id+2);
assert(id2.__get() == id+2);
assert(id2.__get() == id+2);
assert(id0.__get() == id+0);
assert(id0.__get() == id+0);
assert(id0.__get() == id+0);
assert(id1.__get() == id+1);
assert(id1.__get() == id+1);
assert(id1.__get() == id+1);
assert(id2.__get() == id+2);
assert(id2.__get() == id+2);
assert(id2.__get() == id+2);
}

View File

@@ -8,51 +8,59 @@
//===----------------------------------------------------------------------===//
//
// Test the "test_macros.h" header.
#include <__config>
#include "test_macros.h"
#ifndef TEST_STD_VER
#error TEST_STD_VER must be defined
#endif
#ifndef TEST_DECLTYPE
#error TEST_DECLTYPE must be defined
#endif
#ifndef TEST_NOEXCEPT
#error TEST_NOEXCEPT must be defined
#endif
#ifndef TEST_STATIC_ASSERT
#error TEST_STATIC_ASSERT must be defined
#ifndef LIBCPP_ASSERT
#error LIBCPP_ASSERT must be defined
#endif
template <class T, class U>
struct is_same { enum { value = 0 }; };
template <class T>
struct is_same<T, T> { enum { value = 1 }; };
int foo() { return 0; }
#ifndef LIBCPP_STATIC_ASSERT
#error LIBCPP_STATIC_ASSERT must be defined
#endif
void test_noexcept() TEST_NOEXCEPT
{
}
void test_decltype()
void test_libcxx_macros()
{
typedef TEST_DECLTYPE(foo()) MyType;
TEST_STATIC_ASSERT((is_same<MyType, int>::value), "is same");
}
// ===== C++14 features =====
// defined(TEST_HAS_EXTENDED_CONSTEXPR) != defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
#ifdef TEST_HAS_EXTENDED_CONSTEXPR
# ifdef _LIBCPP_HAS_NO_CXX14_CONSTEXPR
# error "TEST_EXTENDED_CONSTEXPR mismatch (1)"
# endif
#else
# ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR
# error "TEST_EXTENDED_CONSTEXPR mismatch (2)"
# endif
#endif
void test_static_assert()
{
TEST_STATIC_ASSERT((is_same<int, int>::value), "is same");
TEST_STATIC_ASSERT((!is_same<int, long>::value), "not same");
// defined(TEST_HAS_VARIABLE_TEMPLATES) != defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
#ifdef TEST_HAS_VARIABLE_TEMPLATES
# ifdef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
# error "TEST_VARIABLE_TEMPLATES mismatch (1)"
# endif
#else
# ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
# error "TEST_VARIABLE_TEMPLATES mismatch (2)"
# endif
#endif
// ===== C++1z features =====
}
int main()
{
test_noexcept();
test_decltype();
test_static_assert();
test_libcxx_macros();
}

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// Call erase(const_iterator position) with end()
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <string>
#include <cassert>
#include <cstdlib>
#include <exception>
#include "min_allocator.h"
int main()
{
{
std::string l1("123");
std::string::const_iterator i = l1.end();
l1.erase(i);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
S::const_iterator i = l1.end();
l1.erase(i);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// Call erase(const_iterator position) with iterator from another container
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <string>
#include <cassert>
#include <cstdlib>
#include <exception>
#include "min_allocator.h"
int main()
{
{
std::string l1("123");
std::string l2("123");
std::string::const_iterator i = l2.begin();
l1.erase(i);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
S l2("123");
S::const_iterator i = l2.begin();
l1.erase(i);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// Call erase(const_iterator first, const_iterator last); with first iterator from another container
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <string>
#include <cassert>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
std::string l1("123");
std::string l2("123");
std::string::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
S l2("123");
S::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// Call erase(const_iterator first, const_iterator last); with second iterator from another container
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <string>
#include <cassert>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
std::string l1("123");
std::string l2("123");
std::string::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
S l2("123");
S::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// Call erase(const_iterator first, const_iterator last); with both iterators from another container
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <string>
#include <cassert>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
std::string l1("123");
std::string l2("123");
std::string::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
S l2("123");
S::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,48 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// Call erase(const_iterator first, const_iterator last); with a bad range
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#include <string>
#include <cassert>
#include <exception>
#include <cstdlib>
#include "min_allocator.h"
int main()
{
{
std::string l1("123");
std::string::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
assert(false);
}
#if __cplusplus >= 201103L
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
S::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
assert(false);
}
#endif
}
#else
int main()
{
}
#endif

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// void pop_back();
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#endif
#include <string>
#include <cassert>
#include "test_macros.h"
int main()
{
#if _LIBCPP_DEBUG >= 1
{
std::string s;
s.pop_back();
assert(false);
}
#endif
}

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// iterator insert(const_iterator p, charT c);
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#endif
#include <string>
#include <stdexcept>
#include <cassert>
int main()
{
#if _LIBCPP_DEBUG >= 1
{
typedef std::string S;
S s;
S s2;
s.insert(s2.begin(), '1');
assert(false);
}
#endif
}

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <string>
// iterator insert(const_iterator p, size_type n, charT c);
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
#endif
#include <string>
#include <cassert>
int main()
{
#if _LIBCPP_DEBUG >= 1
{
std::string s;
std::string s2;
s.insert(s2.begin(), 1, 'a');
assert(false);
}
#endif
}

View File

@@ -0,0 +1,80 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// XFAIL: libcpp-no-exceptions
// <iterator>
// __libcpp_is_trivial_iterator<Tp>
// __libcpp_string_gets_noexcept_iterator determines if an iterator can be used
// w/o worrying about whether or not certain operations can throw.
// This gives us a "fast path for string operations"
//
#include <iterator>
#include <cassert>
#include <string>
#include <vector>
#include <initializer_list>
#include "test_macros.h"
#include "test_iterators.h"
int main()
{
// basic tests
static_assert(( std::__libcpp_string_gets_noexcept_iterator<char *>::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<const char *>::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<char *> > ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<const char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<char *> > ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<const char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<char *> > ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<const char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), "");
// iterators in the libc++ test suite
static_assert((!std::__libcpp_string_gets_noexcept_iterator<output_iterator <char *> >::value), "");
static_assert((!std::__libcpp_string_gets_noexcept_iterator<input_iterator <char *> >::value), "");
static_assert((!std::__libcpp_string_gets_noexcept_iterator<forward_iterator <char *> >::value), "");
static_assert((!std::__libcpp_string_gets_noexcept_iterator<bidirectional_iterator<char *> >::value), "");
static_assert((!std::__libcpp_string_gets_noexcept_iterator<random_access_iterator<char *> >::value), "");
static_assert((!std::__libcpp_string_gets_noexcept_iterator<ThrowingIterator <char *> >::value), "");
#if TEST_STD_VER >= 11
static_assert(( std::__libcpp_string_gets_noexcept_iterator<NonThrowingIterator <char *> >::value), "");
#else
static_assert((!std::__libcpp_string_gets_noexcept_iterator<NonThrowingIterator <char *> >::value), "");
#endif
//
// iterators from libc++'s containers
//
// string
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::reverse_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_reverse_iterator>::value), "");
// vector
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::reverse_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
// Initializer list (which has no reverse iterators)
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::const_iterator> ::value), "");
#endif
}

View File

@@ -0,0 +1,79 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// <iterator>
// __libcpp_is_trivial_iterator<Tp>
// __libcpp_string_gets_noexcept_iterator determines if an iterator can be used
// w/o worrying about whether or not certain operations can throw.
// This gives us a "fast path for string operations".
//
// When exceptions are disabled, all iterators should get this "fast path"
//
#define _LIBCPP_NO_EXCEPTIONS
#include <iterator>
#include <cassert>
#include <string>
#include <vector>
#include <initializer_list>
#include "test_iterators.h"
int main()
{
// basic tests
static_assert(( std::__libcpp_string_gets_noexcept_iterator<char *>::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<const char *>::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<char *> > ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<const char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<char *> > ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<const char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<char *> > ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<const char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), "");
// iterators in the libc++ test suite
static_assert(( std::__libcpp_string_gets_noexcept_iterator<output_iterator <char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<input_iterator <char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<forward_iterator <char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<bidirectional_iterator<char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<random_access_iterator<char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<ThrowingIterator <char *> >::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<NonThrowingIterator <char *> >::value), "");
//
// iterators from libc++'s containers
//
// string
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::reverse_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_reverse_iterator>::value), "");
// vector
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::reverse_iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
// Initializer list (which has no reverse iterators)
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::iterator> ::value), "");
static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::const_iterator> ::value), "");
#endif
}

View File

@@ -1,4 +1,12 @@
import importlib
#===----------------------------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===##
import locale
import os
import platform
@@ -12,6 +20,7 @@ import lit.util # pylint: disable=import-error,no-name-in-module
from libcxx.test.format import LibcxxTestFormat
from libcxx.compiler import CXXCompiler
from libcxx.test.target_info import make_target_info
from libcxx.test.executor import *
from libcxx.test.tracing import *
@@ -42,16 +51,17 @@ def loadSiteConfig(lit_config, config, param_name, env_name):
ld_fn(config, site_cfg)
lit_config.load_config = ld_fn
class Configuration(object):
# pylint: disable=redefined-outer-name
def __init__(self, lit_config, config):
self.lit_config = lit_config
self.config = config
self.cxx = None
self.project_obj_root = None
self.libcxx_src_root = None
self.libcxx_obj_root = None
self.cxx_library_root = None
self.cxx_runtime_root = None
self.abi_library_root = None
self.env = {}
self.use_target = False
@@ -89,6 +99,7 @@ class Configuration(object):
self.configure_cxx_library_root()
self.configure_use_system_cxx_lib()
self.configure_use_clang_verify()
self.configure_use_thread_safety()
self.configure_execute_external()
self.configure_ccache()
self.configure_compile_flags()
@@ -141,13 +152,7 @@ class Configuration(object):
self.executor = te
def configure_target_info(self):
default = "libcxx.test.target_info.LocalTI"
info_str = self.get_lit_conf('target_info', default)
mod_path, _, info = info_str.rpartition('.')
mod = importlib.import_module(mod_path)
self.target_info = getattr(mod, info)()
if info_str != default:
self.lit_config.note("inferred target_info as: %r" % info_str)
self.target_info = make_target_info(self)
def configure_cxx(self):
# Gather various compiler parameters.
@@ -179,11 +184,20 @@ class Configuration(object):
'libcxx_src_root', os.path.dirname(self.config.test_source_root))
def configure_obj_root(self):
self.project_obj_root = self.get_lit_conf('project_obj_root')
self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
if not self.libcxx_obj_root and self.project_obj_root is not None:
possible_root = os.path.join(self.project_obj_root, 'projects', 'libcxx')
if os.path.isdir(possible_root):
self.libcxx_obj_root = possible_root
else:
self.libcxx_obj_root = self.project_obj_root
def configure_cxx_library_root(self):
self.cxx_library_root = self.get_lit_conf('cxx_library_root',
self.libcxx_obj_root)
self.cxx_runtime_root = self.get_lit_conf('cxx_runtime_root',
self.cxx_library_root)
def configure_use_system_cxx_lib(self):
# This test suite supports testing against either the system library or
@@ -208,16 +222,23 @@ class Configuration(object):
self.lit_config.note(
"inferred use_clang_verify as: %r" % self.use_clang_verify)
def configure_use_thread_safety(self):
'''If set, run clang with -verify on failing tests.'''
has_thread_safety = self.cxx.hasCompileFlag('-Werror=thread-safety')
if has_thread_safety:
self.cxx.compile_flags += ['-Werror=thread-safety']
self.config.available_features.add('thread-safety')
self.lit_config.note("enabling thread-safety annotations")
def configure_execute_external(self):
# Choose between lit's internal shell pipeline runner and a real shell.
# If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
# default value. Otherwise we default to internal on Windows and
# external elsewhere, as bash on Windows is usually very slow.
# default value. Otherwise we ask the target_info.
use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
if use_lit_shell_default is not None:
use_lit_shell_default = use_lit_shell_default != '0'
else:
use_lit_shell_default = sys.platform == 'win32'
use_lit_shell_default = self.target_info.use_lit_shell_default()
# Check for the command line parameter using the default value if it is
# not present.
use_lit_shell = self.get_lit_bool('use_lit_shell',
@@ -236,63 +257,10 @@ class Configuration(object):
if additional_features:
for f in additional_features.split(','):
self.config.available_features.add(f.strip())
self.target_info.add_locale_features(self.config.available_features)
# Figure out which of the required locales we support
locales = {
'Darwin': {
'en_US.UTF-8': 'en_US.UTF-8',
'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
'fr_FR.UTF-8': 'fr_FR.UTF-8',
'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
'ru_RU.UTF-8': 'ru_RU.UTF-8',
'zh_CN.UTF-8': 'zh_CN.UTF-8',
},
'FreeBSD': {
'en_US.UTF-8': 'en_US.UTF-8',
'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
'fr_FR.UTF-8': 'fr_FR.UTF-8',
'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
'ru_RU.UTF-8': 'ru_RU.UTF-8',
'zh_CN.UTF-8': 'zh_CN.UTF-8',
},
'Linux': {
'en_US.UTF-8': 'en_US.UTF-8',
'cs_CZ.ISO8859-2': 'cs_CZ.ISO-8859-2',
'fr_FR.UTF-8': 'fr_FR.UTF-8',
'fr_CA.ISO8859-1': 'fr_CA.ISO-8859-1',
'ru_RU.UTF-8': 'ru_RU.UTF-8',
'zh_CN.UTF-8': 'zh_CN.UTF-8',
},
'Windows': {
'en_US.UTF-8': 'English_United States.1252',
'cs_CZ.ISO8859-2': 'Czech_Czech Republic.1250',
'fr_FR.UTF-8': 'French_France.1252',
'fr_CA.ISO8859-1': 'French_Canada.1252',
'ru_RU.UTF-8': 'Russian_Russia.1251',
'zh_CN.UTF-8': 'Chinese_China.936',
},
}
target_system = self.target_info.system()
target_platform = self.target_info.platform()
if target_system in locales:
default_locale = locale.setlocale(locale.LC_ALL)
for feature, loc in locales[target_system].items():
try:
locale.setlocale(locale.LC_ALL, loc)
self.config.available_features.add(
'locale.{0}'.format(feature))
except locale.Error:
self.lit_config.warning('The locale {0} is not supported by '
'your platform. Some tests will be '
'unsupported.'.format(loc))
locale.setlocale(locale.LC_ALL, default_locale)
else:
# Warn that the user doesn't get any free XFAILs for locale issues
self.lit_config.warning("No locales entry for target_system: %s" %
target_system)
# Write an "available feature" that combines the triple when
# use_system_cxx_lib is enabled. This is so that we can easily write
# XFAIL markers for tests that are known to fail with versions of
@@ -304,17 +272,6 @@ class Configuration(object):
# Insert the platform name into the available features as a lower case.
self.config.available_features.add(target_platform)
# Some linux distributions have different locale data than others.
# Insert the distributions name and name-version into the available
# features to allow tests to XFAIL on them.
if target_platform == 'linux':
name = self.target_info.platform_name()
ver = self.target_info.platform_ver()
if name:
self.config.available_features.add(name)
if name and ver:
self.config.available_features.add('%s-%s' % (name, ver))
# Simulator testing can take a really long time for some of these tests
# so add a feature check so we can REQUIRES: long_tests in them
self.long_tests = self.get_lit_bool('long_tests')
@@ -336,6 +293,10 @@ class Configuration(object):
no_default_flags = self.get_lit_bool('no_default_flags', False)
if not no_default_flags:
self.configure_default_compile_flags()
# This include is always needed so add so add it regardless of
# 'no_default_flags'.
support_path = os.path.join(self.libcxx_src_root, 'test/support')
self.cxx.compile_flags += ['-I' + support_path]
# Configure extra flags
compile_flags_str = self.get_lit_conf('compile_flags', '')
self.cxx.compile_flags += shlex.split(compile_flags_str)
@@ -344,38 +305,33 @@ class Configuration(object):
# Try and get the std version from the command line. Fall back to
# default given in lit.site.cfg is not present. If default is not
# present then force c++11.
std = self.get_lit_conf('std', 'c++11')
std = self.get_lit_conf('std')
if not std:
# Choose the newest possible language dialect if none is given.
possible_stds = ['c++1z', 'c++14', 'c++11', 'c++03']
for s in possible_stds:
if self.cxx.hasCompileFlag('-std=%s' % s):
std = s
self.lit_config.note(
'inferred language dialect as: %s' % std)
break
if not std:
self.lit_config.fatal(
'Failed to infer a supported language dialect from one of %r'
% possible_stds)
self.cxx.compile_flags += ['-std={0}'.format(std)]
self.config.available_features.add(std)
# Configure include paths
self.cxx.compile_flags += ['-nostdinc++']
self.configure_compile_flags_header_includes()
if self.target_info.platform() == 'linux':
self.cxx.compile_flags += ['-D__STDC_FORMAT_MACROS',
'-D__STDC_LIMIT_MACROS',
'-D__STDC_CONSTANT_MACROS']
self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
# Configure feature flags.
self.configure_compile_flags_exceptions()
self.configure_compile_flags_rtti()
self.configure_compile_flags_no_global_filesystem_namespace()
self.configure_compile_flags_no_stdin()
self.configure_compile_flags_no_stdout()
self.configure_compile_flags_abi_version()
enable_32bit = self.get_lit_bool('enable_32bit', False)
if enable_32bit:
self.cxx.flags += ['-m32']
# Configure threading features.
enable_threads = self.get_lit_bool('enable_threads', True)
enable_monotonic_clock = self.get_lit_bool('enable_monotonic_clock',
True)
if not enable_threads:
self.configure_compile_flags_no_threads()
if not enable_monotonic_clock:
self.configure_compile_flags_no_monotonic_clock()
elif not enable_monotonic_clock:
self.lit_config.fatal('enable_monotonic_clock cannot be false when'
' enable_threads is true.')
self.configure_compile_flags_no_thread_unsafe_c_functions()
# Use verbose output for better errors
self.cxx.flags += ['-v']
sysroot = self.get_lit_conf('sysroot')
@@ -389,8 +345,8 @@ class Configuration(object):
def configure_compile_flags_header_includes(self):
support_path = os.path.join(self.libcxx_src_root, 'test/support')
self.cxx.compile_flags += ['-I' + support_path]
self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')]
self.configure_config_site_header()
libcxx_headers = self.get_lit_conf(
'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
if not os.path.isdir(libcxx_headers):
@@ -398,6 +354,56 @@ class Configuration(object):
% libcxx_headers)
self.cxx.compile_flags += ['-I' + libcxx_headers]
def configure_config_site_header(self):
# Check for a possible __config_site in the build directory. We
# use this if it exists.
if self.libcxx_obj_root is None:
return
config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
if not os.path.isfile(config_site_header):
return
contained_macros = self.parse_config_site_and_add_features(
config_site_header)
self.lit_config.note('Using __config_site header %s with macros: %r'
% (config_site_header, contained_macros))
# FIXME: This must come after the call to
# 'parse_config_site_and_add_features(...)' in order for it to work.
self.cxx.compile_flags += ['-include', config_site_header]
def parse_config_site_and_add_features(self, header):
""" parse_config_site_and_add_features - Deduce and add the test
features that that are implied by the #define's in the __config_site
header. Return a dictionary containing the macros found in the
'__config_site' header.
"""
# Parse the macro contents of __config_site by dumping the macros
# using 'c++ -dM -E' and filtering the predefines.
predefines = self.cxx.dumpMacros()
macros = self.cxx.dumpMacros(header)
feature_macros_keys = set(macros.keys()) - set(predefines.keys())
feature_macros = {}
for k in feature_macros_keys:
feature_macros[k] = macros[k]
# We expect the header guard to be one of the definitions
assert '_LIBCPP_CONFIG_SITE' in feature_macros
del feature_macros['_LIBCPP_CONFIG_SITE']
# The __config_site header should be non-empty. Otherwise it should
# have never been emitted by CMake.
assert len(feature_macros) > 0
# Transform each macro name into the feature name used in the tests.
# Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
for m in feature_macros:
if m == '_LIBCPP_ABI_VERSION':
self.config.available_features.add('libcpp-abi-version-v%s'
% feature_macros[m])
continue
assert m.startswith('_LIBCPP_HAS_') or m == '_LIBCPP_ABI_UNSTABLE'
m = m.lower()[1:].replace('_', '-')
self.config.available_features.add(m)
return feature_macros
def configure_compile_flags_exceptions(self):
enable_exceptions = self.get_lit_bool('enable_exceptions', True)
if not enable_exceptions:
@@ -410,43 +416,16 @@ class Configuration(object):
self.config.available_features.add('libcpp-no-rtti')
self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
def configure_compile_flags_no_global_filesystem_namespace(self):
enable_global_filesystem_namespace = self.get_lit_bool(
'enable_global_filesystem_namespace', True)
if not enable_global_filesystem_namespace:
self.config.available_features.add(
'libcpp-has-no-global-filesystem-namespace')
self.cxx.compile_flags += [
'-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE']
def configure_compile_flags_no_stdin(self):
enable_stdin = self.get_lit_bool('enable_stdin', True)
if not enable_stdin:
self.config.available_features.add('libcpp-has-no-stdin')
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDIN']
def configure_compile_flags_no_stdout(self):
enable_stdout = self.get_lit_bool('enable_stdout', True)
if not enable_stdout:
self.config.available_features.add('libcpp-has-no-stdout')
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDOUT']
def configure_compile_flags_no_threads(self):
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
self.config.available_features.add('libcpp-has-no-threads')
def configure_compile_flags_no_thread_unsafe_c_functions(self):
enable_thread_unsafe_c_functions = self.get_lit_bool(
'enable_thread_unsafe_c_functions', True)
if not enable_thread_unsafe_c_functions:
self.cxx.compile_flags += [
'-D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS']
self.config.available_features.add(
'libcpp-has-no-thread-unsafe-c-functions')
def configure_compile_flags_no_monotonic_clock(self):
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
self.config.available_features.add('libcpp-has-no-monotonic-clock')
def configure_compile_flags_abi_version(self):
abi_version = self.get_lit_conf('abi_version', '').strip()
abi_unstable = self.get_lit_bool('abi_unstable')
# Only add the ABI version when it is non-default.
# FIXME(EricWF): Get the ABI version from the "__config_site".
if abi_version and abi_version != '1':
self.cxx.compile_flags += ['-D_LIBCPP_ABI_VERSION=' + abi_version]
if abi_unstable:
self.config.available_features.add('libcpp-abi-unstable')
self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
def configure_link_flags(self):
no_default_flags = self.get_lit_bool('no_default_flags', False)
@@ -466,23 +445,11 @@ class Configuration(object):
self.cxx.link_flags += shlex.split(link_flags_str)
def configure_link_flags_cxx_library_path(self):
libcxx_library = self.get_lit_conf('libcxx_library')
# Configure libc++ library paths.
if libcxx_library is not None:
# Check that the given value for libcxx_library is valid.
if not os.path.isfile(libcxx_library):
self.lit_config.fatal(
"libcxx_library='%s' is not a valid file." %
libcxx_library)
if self.use_system_cxx_lib:
self.lit_config.fatal(
"Conflicting options: 'libcxx_library' cannot be used "
"with 'use_system_cxx_lib=true'")
self.cxx.link_flags += ['-Wl,-rpath,' +
os.path.dirname(libcxx_library)]
elif not self.use_system_cxx_lib and self.cxx_library_root:
self.cxx.link_flags += ['-L' + self.cxx_library_root,
'-Wl,-rpath,' + self.cxx_library_root]
if not self.use_system_cxx_lib:
if self.cxx_library_root:
self.cxx.link_flags += ['-L' + self.cxx_library_root]
if self.cxx_runtime_root:
self.cxx.link_flags += ['-Wl,-rpath,' + self.cxx_runtime_root]
def configure_link_flags_abi_library_path(self):
# Configure ABI library paths.
@@ -492,11 +459,20 @@ class Configuration(object):
'-Wl,-rpath,' + self.abi_library_root]
def configure_link_flags_cxx_library(self):
libcxx_library = self.get_lit_conf('libcxx_library')
if libcxx_library:
self.cxx.link_flags += [libcxx_library]
else:
libcxx_experimental = self.get_lit_bool('enable_experimental', default=False)
if libcxx_experimental:
self.config.available_features.add('c++experimental')
self.cxx.link_flags += ['-lc++experimental']
libcxx_shared = self.get_lit_bool('enable_shared', default=True)
if libcxx_shared:
self.cxx.link_flags += ['-lc++']
else:
cxx_library_root = self.get_lit_conf('cxx_library_root')
if cxx_library_root:
abs_path = os.path.join(cxx_library_root, 'libc++.a')
self.cxx.link_flags += [abs_path]
else:
self.cxx.link_flags += ['-lc++']
def configure_link_flags_abi_library(self):
cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
@@ -505,10 +481,17 @@ class Configuration(object):
elif cxx_abi == 'libsupc++':
self.cxx.link_flags += ['-lsupc++']
elif cxx_abi == 'libcxxabi':
# Don't link libc++abi explicitly on OS X because the symbols
# should be available in libc++ directly.
if self.target_info.platform() != 'darwin':
self.cxx.link_flags += ['-lc++abi']
if self.target_info.allow_cxxabi_link():
libcxxabi_shared = self.get_lit_bool('libcxxabi_shared', default=True)
if libcxxabi_shared:
self.cxx.link_flags += ['-lc++abi']
else:
cxxabi_library_root = self.get_lit_conf('abi_library_path')
if cxxabi_library_root:
abs_path = os.path.join(cxxabi_library_root, 'libc++abi.a')
self.cxx.link_flags += [abs_path]
else:
self.cxx.link_flags += ['-lc++abi']
elif cxx_abi == 'libcxxrt':
self.cxx.link_flags += ['-lcxxrt']
elif cxx_abi == 'none':
@@ -518,26 +501,7 @@ class Configuration(object):
'C++ ABI setting %s unsupported for tests' % cxx_abi)
def configure_extra_library_flags(self):
enable_threads = self.get_lit_bool('enable_threads', True)
llvm_unwinder = self.get_lit_bool('llvm_unwinder', False)
target_platform = self.target_info.platform()
if target_platform == 'darwin':
self.cxx.link_flags += ['-lSystem']
elif target_platform == 'linux':
if not llvm_unwinder:
self.cxx.link_flags += ['-lgcc_eh']
self.cxx.link_flags += ['-lc', '-lm']
if enable_threads:
self.cxx.link_flags += ['-lpthread']
self.cxx.link_flags += ['-lrt']
if llvm_unwinder:
self.cxx.link_flags += ['-lunwind', '-ldl']
else:
self.cxx.link_flags += ['-lgcc_s']
elif target_platform.startswith('freebsd'):
self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
else:
self.lit_config.fatal("unrecognized system: %r" % target_platform)
self.target_info.add_cxx_link_flags(self.cxx.link_flags)
def configure_color_diagnostics(self):
use_color = self.get_lit_conf('color_diagnostics')
@@ -572,22 +536,28 @@ class Configuration(object):
if enable_warnings:
self.cxx.compile_flags += [
'-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
'-Wall', '-Werror'
'-Wall', '-Wextra', '-Werror'
]
self.cxx.addCompileFlagIfSupported('-Wno-attributes')
if self.cxx.type == 'clang' or self.cxx.type == 'apple-clang':
self.cxx.addCompileFlagIfSupported('-Wno-pessimizing-move')
self.cxx.addCompileFlagIfSupported('-Wno-c++11-extensions')
self.cxx.addCompileFlagIfSupported('-Wno-user-defined-literals')
self.cxx.addWarningFlagIfSupported('-Wno-attributes')
self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
# TODO(EricWF) Remove the unused warnings once the test suite
# compiles clean with them.
self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
self.cxx.addWarningFlagIfSupported('-Wno-unused-variable')
self.cxx.addWarningFlagIfSupported('-Wno-unused-parameter')
self.cxx.addWarningFlagIfSupported('-Wno-sign-compare')
std = self.get_lit_conf('std', None)
if std in ['c++98', 'c++03']:
# The '#define static_assert' provided by libc++ in C++03 mode
# causes an unused local typedef whenever it is used.
self.cxx.addCompileFlagIfSupported('-Wno-unused-local-typedef')
self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
def configure_sanitizer(self):
san = self.get_lit_conf('use_sanitizer', '').strip()
if san:
self.target_info.add_sanitizer_features(san, self.config.available_features)
# Search for llvm-symbolizer along the compiler path first
# and then along the PATH env variable.
symbolizer_search_paths = os.environ.get('PATH', '')
@@ -600,8 +570,6 @@ class Configuration(object):
symbolizer_search_paths)
# Setup the sanitizer compile flags
self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
if self.target_info.platform() == 'linux':
self.cxx.link_flags += ['-ldl']
if san == 'Address':
self.cxx.flags += ['-fsanitize=address']
if llvm_symbolizer is not None:
@@ -622,9 +590,8 @@ class Configuration(object):
'-fno-sanitize=vptr,function',
'-fno-sanitize-recover']
self.cxx.compile_flags += ['-O3']
self.env['UBSAN_OPTIONS'] = 'print_stacktrace=1'
self.config.available_features.add('ubsan')
if self.target_info.platform() == 'darwin':
self.config.available_features.add('sanitizer-new-delete')
elif san == 'Thread':
self.cxx.flags += ['-fsanitize=thread']
self.config.available_features.add('tsan')
@@ -671,7 +638,7 @@ class Configuration(object):
for k, v in self.env.items():
exec_env_str += ' %s=%s' % (k, v)
# Configure run env substitution.
exec_str = ''
exec_str = exec_env_str
if self.lit_config.useValgrind:
exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
sub.append(('%exec', exec_str))
@@ -708,18 +675,4 @@ class Configuration(object):
"inferred target_triple as: %r" % self.config.target_triple)
def configure_env(self):
if self.target_info.platform() == 'darwin':
library_paths = []
# Configure the library path for libc++
libcxx_library = self.get_lit_conf('libcxx_library')
if self.use_system_cxx_lib:
pass
elif libcxx_library:
library_paths += [os.path.dirname(libcxx_library)]
elif self.cxx_library_root:
library_paths += [self.cxx_library_root]
# Configure the abi library path
if self.abi_library_root:
library_paths += [self.abi_library_root]
if library_paths:
self.env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
self.target_info.configure_env(self.env)

View File

@@ -1,3 +1,12 @@
#===----------------------------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===##
import os
from libcxx.test import tracing

View File

@@ -1,3 +1,12 @@
#===----------------------------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===##
import errno
import os
import time
@@ -64,20 +73,24 @@ class LibcxxTestFormat(object):
return (lit.Test.UNSUPPORTED,
"A lit.local.cfg marked this unsupported")
res = lit.TestRunner.parseIntegratedTestScript(
script = lit.TestRunner.parseIntegratedTestScript(
test, require_script=is_sh_test)
# Check if a result for the test was returned. If so return that
# result.
if isinstance(res, lit.Test.Result):
return res
if isinstance(script, lit.Test.Result):
return script
if lit_config.noExecute:
return lit.Test.Result(lit.Test.PASS)
# res is not an instance of lit.test.Result. Expand res into its parts.
script, tmpBase, execDir = res
# Check that we don't have run lines on tests that don't support them.
if not is_sh_test and len(script) != 0:
lit_config.fatal('Unsupported RUN line found in test %s' % name)
tmpDir, tmpBase = lit.TestRunner.getTempPaths(test)
substitutions = lit.TestRunner.getDefaultSubstitutions(test, tmpDir,
tmpBase)
script = lit.TestRunner.applySubstitutions(script, substitutions)
# Dispatch the test based on its suffix.
if is_sh_test:
if not isinstance(self.executor, LocalExecutor):
@@ -86,11 +99,11 @@ class LibcxxTestFormat(object):
return lit.Test.UNSUPPORTED, 'ShTest format not yet supported'
return lit.TestRunner._runShTest(test, lit_config,
self.execute_external, script,
tmpBase, execDir)
tmpBase)
elif is_fail_test:
return self._evaluate_fail_test(test)
elif is_pass_test:
return self._evaluate_pass_test(test, tmpBase, execDir, lit_config)
return self._evaluate_pass_test(test, tmpBase, lit_config)
else:
# No other test type is supported
assert False
@@ -98,7 +111,8 @@ class LibcxxTestFormat(object):
def _clean(self, exec_path): # pylint: disable=no-self-use
libcxx.util.cleanFile(exec_path)
def _evaluate_pass_test(self, test, tmpBase, execDir, lit_config):
def _evaluate_pass_test(self, test, tmpBase, lit_config):
execDir = os.path.dirname(test.getExecPath())
source_path = test.getSourcePath()
exec_path = tmpBase + '.exe'
object_path = tmpBase + '.o'
@@ -147,7 +161,13 @@ class LibcxxTestFormat(object):
'expected-error', 'expected-no-diagnostics']
use_verify = self.use_verify_for_fail and \
any([tag in contents for tag in verify_tags])
# FIXME(EricWF): GCC 5 does not evaluate static assertions that
# are dependant on a template parameter when '-fsyntax-only' is passed.
# This is fixed in GCC 6. However for now we only pass "-fsyntax-only"
# when using Clang.
extra_flags = []
if self.cxx.type != 'gcc':
extra_flags += ['-fsyntax-only']
if use_verify:
extra_flags += ['-Xclang', '-verify',
'-Xclang', '-verify-ignore-unexpected=note']

View File

@@ -1,55 +1,223 @@
#===----------------------------------------------------------------------===//
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===//
import importlib
import lit.util # pylint: disable=import-error,no-name-in-module
import locale
import os
import platform
import sys
class TargetInfo(object):
class DefaultTargetInfo(object):
def __init__(self, full_config):
self.full_config = full_config
def platform(self):
raise NotImplementedError
return sys.platform.lower().strip()
def system(self):
raise NotImplementedError
def add_locale_features(self, features):
self.full_config.lit_config.warning(
"No locales entry for target_system: %s" % self.platform())
def platform_ver(self):
raise NotImplementedError
def platform_name(self):
raise NotImplementedError
def supports_locale(self, loc):
raise NotImplementedError
def add_cxx_compile_flags(self, flags): pass
def add_cxx_link_flags(self, flags): pass
def configure_env(self, env): pass
def allow_cxxabi_link(self): return True
def add_sanitizer_features(self, sanitizer_type, features): pass
def use_lit_shell_default(self): return False
class LocalTI(TargetInfo):
def platform(self):
platform_name = sys.platform.lower().strip()
# Strip the '2' from linux2.
if platform_name.startswith('linux'):
platform_name = 'linux'
return platform_name
def test_locale(loc):
assert loc is not None
default_locale = locale.setlocale(locale.LC_ALL)
try:
locale.setlocale(locale.LC_ALL, loc)
return True
except locale.Error:
return False
finally:
locale.setlocale(locale.LC_ALL, default_locale)
def system(self):
return platform.system()
def platform_name(self):
if self.platform() == 'linux':
name, _, _ = platform.linux_distribution()
name = name.lower().strip()
if name:
return name
return None
def add_common_locales(features, lit_config):
# A list of locales needed by the test-suite.
# The list uses the canonical name for the locale used in the test-suite
# TODO: On Linux ISO8859 *may* needs to hyphenated.
locales = [
'en_US.UTF-8',
'fr_FR.UTF-8',
'ru_RU.UTF-8',
'zh_CN.UTF-8',
'fr_CA.ISO8859-1',
'cs_CZ.ISO8859-2'
]
for loc in locales:
if test_locale(loc):
features.add('locale.{0}'.format(loc))
else:
lit_config.warning('The locale {0} is not supported by '
'your platform. Some tests will be '
'unsupported.'.format(loc))
def platform_ver(self):
if self.platform() == 'linux':
_, ver, _ = platform.linux_distribution()
ver = ver.lower().strip()
if ver:
return ver
return None
def supports_locale(self, loc):
class DarwinLocalTI(DefaultTargetInfo):
def __init__(self, full_config):
super(DarwinLocalTI, self).__init__(full_config)
def add_locale_features(self, features):
add_common_locales(features, self.full_config.lit_config)
def add_cxx_compile_flags(self, flags):
try:
locale.setlocale(locale.LC_ALL, loc)
return True
except locale.Error:
return False
out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
res = 0
except OSError:
res = -1
if res == 0 and out:
sdk_path = out
self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
flags += ["-isysroot", sdk_path]
def add_cxx_link_flags(self, flags):
flags += ['-lSystem']
def configure_env(self, env):
library_paths = []
# Configure the library path for libc++
if self.full_config.use_system_cxx_lib:
pass
elif self.full_config.cxx_runtime_root:
library_paths += [self.full_config.cxx_runtime_root]
# Configure the abi library path
if self.full_config.abi_library_root:
library_paths += [self.full_config.abi_library_root]
if library_paths:
env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
def allow_cxxabi_link(self):
# FIXME: PR27405
# libc++ *should* export all of the symbols found in libc++abi on OS X.
# For this reason LibcxxConfiguration will not link libc++abi in OS X.
# However __cxa_throw_bad_new_array_length doesn't get exported into
# libc++ yet so we still need to explicitly link libc++abi when testing
# libc++abi
# See PR22654.
if(self.full_config.get_lit_conf('name', '') == 'libc++abi'):
return True
# Don't link libc++abi explicitly on OS X because the symbols
# should be available in libc++ directly.
return False
def add_sanitizer_features(self, sanitizer_type, features):
if san == 'Undefined':
features.add('sanitizer-new-delete')
class FreeBSDLocalTI(DefaultTargetInfo):
def __init__(self, full_config):
super(FreeBSDLocalTI, self).__init__(full_config)
def add_locale_features(self, features):
add_common_locales(features, self.full_config.lit_config)
def add_cxx_link_flags(self, flags):
flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
class LinuxLocalTI(DefaultTargetInfo):
def __init__(self, full_config):
super(LinuxLocalTI, self).__init__(full_config)
def platform(self):
return 'linux'
def platform_name(self):
name, _, _ = platform.linux_distribution()
name = name.lower().strip()
return name # Permitted to be None
def platform_ver(self):
_, ver, _ = platform.linux_distribution()
ver = ver.lower().strip()
return ver # Permitted to be None.
def add_locale_features(self, features):
add_common_locales(features, self.full_config.lit_config)
# Some linux distributions have different locale data than others.
# Insert the distributions name and name-version into the available
# features to allow tests to XFAIL on them.
name = self.platform_name()
ver = self.platform_ver()
if name:
features.add(name)
if name and ver:
features.add('%s-%s' % (name, ver))
def add_cxx_compile_flags(self, flags):
flags += ['-D__STDC_FORMAT_MACROS',
'-D__STDC_LIMIT_MACROS',
'-D__STDC_CONSTANT_MACROS']
def add_cxx_link_flags(self, flags):
enable_threads = ('libcpp-has-no-threads' not in
self.full_config.config.available_features)
llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
flags += ['-lm']
if not llvm_unwinder:
flags += ['-lgcc_s', '-lgcc']
if enable_threads:
flags += ['-lpthread']
if not shared_libcxx:
flags += ['-lrt']
flags += ['-lc']
if llvm_unwinder:
flags += ['-lunwind', '-ldl']
else:
flags += ['-lgcc_s', '-lgcc']
use_libatomic = self.full_config.get_lit_bool('use_libatomic', False)
if use_libatomic:
flags += ['-latomic']
san = self.full_config.get_lit_conf('use_sanitizer', '').strip()
if san:
# The libraries and their order are taken from the
# linkSanitizerRuntimeDeps function in
# clang/lib/Driver/Tools.cpp
flags += ['-lpthread', '-lrt', '-lm', '-ldl']
class WindowsLocalTI(DefaultTargetInfo):
def __init__(self, full_config):
super(WindowsLocalTI, self).__init__(full_config)
def add_locale_features(self, features):
add_common_locales(features, self.full_config.lit_config)
def use_lit_shell_default(self):
# Default to the internal shell on Windows, as bash on Windows is
# usually very slow.
return True
def make_target_info(full_config):
default = "libcxx.test.target_info.LocalTI"
info_str = full_config.get_lit_conf('target_info', default)
if info_str != default:
mod_path, _, info = info_str.rpartition('.')
mod = importlib.import_module(mod_path)
target_info = getattr(mod, info)(full_config)
full_config.lit_config.note("inferred target_info as: %r" % info_str)
return target_info
target_system = platform.system()
if target_system == 'Darwin': return DarwinLocalTI(full_config)
if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
if target_system == 'Linux': return LinuxLocalTI(full_config)
if target_system == 'Windows': return WindowsLocalTI(full_config)
return DefaultTargetInfo(full_config)

View File

@@ -1,3 +1,12 @@
#===----------------------------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===##
import os
import inspect
@@ -11,14 +20,14 @@ def trace_function(function, log_calls, log_results, label=''):
# Perform the call itself, logging before, after, and anything thrown.
try:
if log_calls:
print '{}: Calling {}'.format(label, call_str)
print('{}: Calling {}'.format(label, call_str))
res = function(*args, **kwargs)
if log_results:
print '{}: {} -> {}'.format(label, call_str, res)
print('{}: {} -> {}'.format(label, call_str, res))
return res
except Exception as ex:
if log_results:
print '{}: {} raised {}'.format(label, call_str, type(ex))
print('{}: {} raised {}'.format(label, call_str, type(ex)))
raise ex
return wrapper

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
// <future>
#include <future>
#ifndef _LIBCPP_VERSION
#error _LIBCPP_VERSION not defined
#endif
int main()
{
}

View File

@@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-has-no-threads
// <mutex>
// This test does not define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS so it
// should compile without any warnings or errors even though this pattern is not
// understood by the thread safety annotations.
#include <mutex>
int main() {
std::mutex m;
m.lock();
{
std::unique_lock<std::mutex> g(m, std::adopt_lock);
}
}

View File

@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-has-no-threads
// REQUIRES: thread-safety
// <mutex>
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex>
std::mutex m;
int foo __attribute__((guarded_by(m)));
int main() {
std::lock_guard<std::mutex> lock(m);
foo++;
}

View File

@@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-has-no-threads
// REQUIRES: thread-safety
// <mutex>
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex>
std::mutex m;
int foo __attribute__((guarded_by(m)));
int main() {
m.lock();
foo++;
m.unlock();
}

View File

@@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-has-no-threads
// REQUIRES: thread-safety
// <mutex>
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex>
std::mutex m;
int main() {
m.lock();
} // expected-error {{mutex 'm' is still held at the end of function}}

View File

@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-has-no-threads
// REQUIRES: thread-safety
// <mutex>
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex>
std::mutex m;
int foo __attribute__((guarded_by(m)));
void increment() __attribute__((requires_capability(m))) {
foo++;
}
int main() {
m.lock();
increment();
m.unlock();
}

View File

@@ -1,7 +1,22 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// TODO: Make this test pass for all standards.
// XFAIL: c++98, c++03
// <type_traits>
// __convert_to_integral(Tp)
// Test that the __convert_to_integral functions properly converts Tp to the
// correct type and value for integral, enum and user defined types.
#include <limits>
#include <type_traits>
#include <cstdint>

View File

@@ -0,0 +1,137 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: c++98, c++03
// <type_traits>
// __lazy_enable_if, __lazy_not, __lazy_and and __lazy_or
// Test the libc++ lazy meta-programming helpers in <type_traits>
#include <type_traits>
template <class Type>
struct Identity {
typedef Type type;
};
typedef std::true_type TrueT;
typedef std::false_type FalseT;
typedef Identity<TrueT> LazyTrueT;
typedef Identity<FalseT> LazyFalseT;
// A type that cannot be instantiated
template <class T>
struct CannotInst {
typedef T type;
static_assert(std::is_same<T, T>::value == false, "");
};
template <int Value>
struct NextInt {
typedef NextInt<Value + 1> type;
static const int value = Value;
};
template <int Value>
const int NextInt<Value>::value;
template <class Type>
struct HasTypeImp {
template <class Up, class = typename Up::type>
static TrueT test(int);
template <class>
static FalseT test(...);
typedef decltype(test<Type>(0)) type;
};
// A metafunction that returns True if Type has a nested 'type' typedef
// and false otherwise.
template <class Type>
struct HasType : HasTypeImp<Type>::type {};
void LazyEnableIfTest() {
{
typedef std::__lazy_enable_if<true, NextInt<0> > Result;
static_assert(HasType<Result>::value, "");
static_assert(Result::type::value == 1, "");
}
{
typedef std::__lazy_enable_if<false, CannotInst<int> > Result;
static_assert(!HasType<Result>::value, "");
}
}
void LazyNotTest() {
{
typedef std::__lazy_not<LazyTrueT> NotT;
static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
static_assert(NotT::value == false, "");
}
{
typedef std::__lazy_not<LazyFalseT> NotT;
static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
static_assert(NotT::value == true, "");
}
{
// Check that CannotInst<int> is not instantiated.
typedef std::__lazy_not<CannotInst<int> > NotT;
static_assert(std::is_same<NotT, NotT>::value, "");
}
}
void LazyAndTest() {
{ // Test that it acts as the identity function for a single value
static_assert(std::__lazy_and<LazyFalseT>::value == false, "");
static_assert(std::__lazy_and<LazyTrueT>::value == true, "");
}
{
static_assert(std::__lazy_and<LazyTrueT, LazyTrueT>::value == true, "");
static_assert(std::__lazy_and<LazyTrueT, LazyFalseT>::value == false, "");
static_assert(std::__lazy_and<LazyFalseT, LazyTrueT>::value == false, "");
static_assert(std::__lazy_and<LazyFalseT, LazyFalseT>::value == false, "");
}
{ // Test short circuiting - CannotInst<T> should never be instantiated.
static_assert(std::__lazy_and<LazyFalseT, CannotInst<int>>::value == false, "");
static_assert(std::__lazy_and<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
}
}
void LazyOrTest() {
{ // Test that it acts as the identity function for a single value
static_assert(std::__lazy_or<LazyFalseT>::value == false, "");
static_assert(std::__lazy_or<LazyTrueT>::value == true, "");
}
{
static_assert(std::__lazy_or<LazyTrueT, LazyTrueT>::value == true, "");
static_assert(std::__lazy_or<LazyTrueT, LazyFalseT>::value == true, "");
static_assert(std::__lazy_or<LazyFalseT, LazyTrueT>::value == true, "");
static_assert(std::__lazy_or<LazyFalseT, LazyFalseT>::value == false, "");
}
{ // Test short circuiting - CannotInst<T> should never be instantiated.
static_assert(std::__lazy_or<LazyTrueT, CannotInst<int>>::value == true, "");
static_assert(std::__lazy_or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
}
}
int main() {
LazyEnableIfTest();
LazyNotTest();
LazyAndTest();
LazyOrTest();
}

View File

@@ -1,3 +1,12 @@
#===----------------------------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is dual licensed under the MIT and the University of Illinois Open
# Source Licenses. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===##
from contextlib import contextmanager
import os
import tempfile

View File

@@ -0,0 +1,370 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <functional>
// INVOKE (f, t1, t2, ..., tN)
//------------------------------------------------------------------------------
// TESTING INVOKE(f, t1, t2, ..., tN)
// - Bullet 1 -- (t1.*f)(t2, ..., tN)
// - Bullet 2 -- (t1.get().*f)(t2, ..., tN) // t1 is a reference_wrapper
// - Bullet 3 -- ((*t1).*f)(t2, ..., tN)
//
// Overview:
// Bullets 1, 2 and 3 handle the case where 'f' is a pointer to member function.
// Bullet 1 only handles the cases where t1 is an object of type T or a
// type derived from 'T'. Bullet 2 handles the case where 't1' is a reference
// wrapper and bullet 3 handles all other cases.
//
// Concerns:
// 1) cv-qualified member function signatures are accepted.
// 2) reference qualified member function signatures are accepted.
// 3) member functions with varargs at the end are accepted.
// 4) The arguments are perfect forwarded to the member function call.
// 5) Classes that are publicly derived from 'T' are accepted as the call object
// 6) All types that dereference to T or a type derived from T can be used
// as the call object.
// 7) Pointers to T or a type derived from T can be used as the call object.
// 8) Reference return types are properly deduced.
// 9) reference_wrappers are properly handled and unwrapped.
//
//
// Plan:
// 1) Create a class that contains a set, 'S', of non-static functions.
// 'S' should include functions that cover every single combination
// of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3).
// The argument types used in the functions should be non-copyable (C-4).
// The functions should return 'MethodID::setUncheckedCall()'.
//
// 2) Create a set of supported call object, 'Objs', of different types
// and behaviors. (C-5,6,7)
//
// 3) Attempt to call each function, 'f', in 'S' with each call object, 'c',
// in 'Objs'. After every attempted call to 'f' check that 'f' was
// actually called using 'MethodID::checkCalled(<return-value>)'
//
// 3b) If 'f' is reference qualified call 'f' with the properly qualified
// call object. Otherwise call 'f' with lvalue call objects.
//
// 3a) If 'f' is const, volatile, or cv qualified then call it with call
// objects that are equally or less cv-qualified.
#include <functional>
#include <type_traits>
#include <cassert>
#include "test_macros.h"
#include "invoke_helpers.h"
//==============================================================================
// MemFun03 - C++03 compatible set of test member functions.
struct MemFun03 {
typedef void*& R;
#define F(...) \
R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \
R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \
R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \
R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); }
#
F()
F(...)
F(ArgType&)
F(ArgType&, ...)
F(ArgType&, ArgType&)
F(ArgType&, ArgType&, ...)
F(ArgType&, ArgType&, ArgType&)
F(ArgType&, ArgType&, ArgType&, ...)
#undef F
public:
MemFun03() {}
private:
MemFun03(MemFun03 const&);
MemFun03& operator=(MemFun03 const&);
};
#if TEST_STD_VER >= 11
//==============================================================================
// MemFun11 - C++11 reference qualified test member functions.
struct MemFun11 {
typedef void*& R;
typedef MemFun11 C;
#define F(...) \
R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
#
F()
F(...)
F(ArgType&&)
F(ArgType&&, ...)
F(ArgType&&, ArgType&&)
F(ArgType&&, ArgType&&, ...)
F(ArgType&&, ArgType&&, ArgType&&)
F(ArgType&&, ArgType&&, ArgType&&, ...)
#undef F
public:
MemFun11() {}
private:
MemFun11(MemFun11 const&);
MemFun11& operator=(MemFun11 const&);
};
#endif // TEST_STD_VER >= 11
//==============================================================================
// TestCase - A test case for a single member function.
// ClassType - The type of the class being tested.
// CallSig - The function signature of the method being tested.
// Arity - the arity of 'CallSig'
// CV - the cv qualifiers of 'CallSig' represented as a type tag.
// RValue - The method is RValue qualified.
// ArgRValue - Call the method with RValue arguments.
template <class ClassType, class CallSig, int Arity, class CV,
bool RValue = false, bool ArgRValue = false>
struct TestCaseImp {
public:
static void run() { TestCaseImp().doTest(); }
private:
//==========================================================================
// TEST DISPATCH
void doTest() {
// (Plan-2) Create test call objects.
typedef ClassType T;
typedef DerivedFromType<T> D;
T obj;
T* obj_ptr = &obj;
D der;
D* der_ptr = &der;
DerefToType<T> dref;
DerefPropType<T> dref2;
std::reference_wrapper<T> rref(obj);
std::reference_wrapper<D> drref(der);
// (Plan-3) Dispatch based on the CV tags.
CV tag;
Bool<!RValue> NotRValue;
runTestDispatch(tag, obj);
runTestDispatch(tag, der);
runTestDispatch(tag, dref2);
runTestDispatchIf(NotRValue, tag, dref);
runTestDispatchIf(NotRValue, tag, obj_ptr);
runTestDispatchIf(NotRValue, tag, der_ptr);
#if TEST_STD_VER >= 11
runTestDispatchIf(NotRValue, tag, rref);
runTestDispatchIf(NotRValue, tag, drref);
#endif
}
template <class QT, class Tp>
void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
runTestDispatch(q, v);
}
template <class QT, class Tp>
void runTestDispatchIf(Bool<false>, QT, Tp&) {
}
template <class Tp>
void runTestDispatch(Q_None, Tp& v) {
runTest(v);
}
template <class Tp>
void runTestDispatch(Q_Const, Tp& v) {
runTest(v);
runTest(makeConst(v));
}
template <class Tp>
void runTestDispatch(Q_Volatile, Tp& v) {
runTest(v);
runTest(makeVolatile(v));
}
template <class Tp>
void runTestDispatch(Q_CV, Tp& v) {
runTest(v);
runTest(makeConst(v));
runTest(makeVolatile(v));
runTest(makeCV(v));
}
template <class T>
void runTest(const std::reference_wrapper<T>& obj) {
typedef Caster<Q_None, RValue> SCast;
typedef Caster<Q_None, ArgRValue> ACast;
typedef CallSig (ClassType::*MemPtr);
// Delegate test to logic in invoke_helpers.h
BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
b.runTest( (MemPtr)&ClassType::f, obj);
}
template <class T>
void runTest(T* obj) {
typedef Caster<Q_None, RValue> SCast;
typedef Caster<Q_None, ArgRValue> ACast;
typedef CallSig (ClassType::*MemPtr);
// Delegate test to logic in invoke_helpers.h
BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
b.runTest( (MemPtr)&ClassType::f, obj);
}
template <class Obj>
void runTest(Obj& obj) {
typedef Caster<Q_None, RValue> SCast;
typedef Caster<Q_None, ArgRValue> ACast;
typedef CallSig (ClassType::*MemPtr);
// Delegate test to logic in invoke_helpers.h
BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
b.runTest( (MemPtr)&ClassType::f, obj);
}
};
template <class Sig, int Arity, class CV>
struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
#if TEST_STD_VER >= 11
template <class Sig, int Arity, class CV, bool RValue = false>
struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
#endif
template <class Tp>
struct DerivedFromRefWrap : public std::reference_wrapper<Tp> {
DerivedFromRefWrap(Tp& tp) : std::reference_wrapper<Tp>(tp) {}
};
#if TEST_STD_VER >= 11
void test_derived_from_ref_wrap() {
int x = 42;
std::reference_wrapper<int> r(x);
std::reference_wrapper<std::reference_wrapper<int>> r2(r);
DerivedFromRefWrap<int> d(x);
auto get_fn = &std::reference_wrapper<int>::get;
auto& ret = std::__invoke(get_fn, r);
auto& cret = std::__invoke_constexpr(get_fn, r);
assert(&ret == &x);
assert(&cret == &x);
auto& ret2 = std::__invoke(get_fn, d);
auto& cret2 = std::__invoke_constexpr(get_fn, d);
assert(&ret2 == &x);
auto& ret3 = std::__invoke(get_fn, r2);
assert(&ret3 == &x);
}
#endif
int main() {
typedef void*& R;
typedef ArgType A;
TestCase<R(), 0, Q_None>::run();
TestCase<R() const, 0, Q_Const>::run();
TestCase<R() volatile, 0, Q_Volatile>::run();
TestCase<R() const volatile, 0, Q_CV>::run();
TestCase<R(...), 0, Q_None>::run();
TestCase<R(...) const, 0, Q_Const>::run();
TestCase<R(...) volatile, 0, Q_Volatile>::run();
TestCase<R(...) const volatile, 0, Q_CV>::run();
TestCase<R(A&), 1, Q_None>::run();
TestCase<R(A&) const, 1, Q_Const>::run();
TestCase<R(A&) volatile, 1, Q_Volatile>::run();
TestCase<R(A&) const volatile, 1, Q_CV>::run();
TestCase<R(A&, ...), 1, Q_None>::run();
TestCase<R(A&, ...) const, 1, Q_Const>::run();
TestCase<R(A&, ...) volatile, 1, Q_Volatile>::run();
TestCase<R(A&, ...) const volatile, 1, Q_CV>::run();
TestCase<R(A&, A&), 2, Q_None>::run();
TestCase<R(A&, A&) const, 2, Q_Const>::run();
TestCase<R(A&, A&) volatile, 2, Q_Volatile>::run();
TestCase<R(A&, A&) const volatile, 2, Q_CV>::run();
TestCase<R(A&, A&, ...), 2, Q_None>::run();
TestCase<R(A&, A&, ...) const, 2, Q_Const>::run();
TestCase<R(A&, A&, ...) volatile, 2, Q_Volatile>::run();
TestCase<R(A&, A&, ...) const volatile, 2, Q_CV>::run();
TestCase<R(A&, A&, A&), 3, Q_None>::run();
TestCase<R(A&, A&, A&) const, 3, Q_Const>::run();
TestCase<R(A&, A&, A&) volatile, 3, Q_Volatile>::run();
TestCase<R(A&, A&, A&) const volatile, 3, Q_CV>::run();
TestCase<R(A&, A&, A&, ...), 3, Q_None>::run();
TestCase<R(A&, A&, A&, ...) const, 3, Q_Const>::run();
TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run();
TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run();
#if TEST_STD_VER >= 11
TestCase11<R() &, 0, Q_None>::run();
TestCase11<R() const &, 0, Q_Const>::run();
TestCase11<R() volatile &, 0, Q_Volatile>::run();
TestCase11<R() const volatile &, 0, Q_CV>::run();
TestCase11<R(...) &, 0, Q_None>::run();
TestCase11<R(...) const &, 0, Q_Const>::run();
TestCase11<R(...) volatile &, 0, Q_Volatile>::run();
TestCase11<R(...) const volatile &, 0, Q_CV>::run();
TestCase11<R(A&&) &, 1, Q_None>::run();
TestCase11<R(A&&) const &, 1, Q_Const>::run();
TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run();
TestCase11<R(A&&) const volatile &, 1, Q_CV>::run();
TestCase11<R(A&&, ...) &, 1, Q_None>::run();
TestCase11<R(A&&, ...) const &, 1, Q_Const>::run();
TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run();
TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run();
TestCase11<R(A&&, A&&) &, 2, Q_None>::run();
TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run();
TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run();
TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run();
TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run();
TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run();
TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run();
TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run();
TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run();
TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run();
TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run();
TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run();
TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run();
TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run();
TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run();
TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run();
TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run();
TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run();
TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run();
TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run();
TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
test_derived_from_ref_wrap();
#endif
}

View File

@@ -0,0 +1,216 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <functional>
// INVOKE (f, t1, t2, ..., tN)
//------------------------------------------------------------------------------
// TESTING INVOKE(f, t1, t2, ..., tN)
// - Bullet 4 -- t1.*f
// - Bullet 5 -- t1.get().*f // t1 is a reference wrapper.
// - Bullet 6 -- (*t1).*f
//
// Overview:
// Bullets 4, 5 and 6 handle the case where 'f' is a pointer to member object.
// Bullet 4 only handles the cases where t1 is an object of type T or a
// type derived from 'T'. Bullet 5 handles cases where 't1' is a reference_wrapper
// and bullet 6 handles all other cases.
//
// Concerns:
// 1) The return type is always an lvalue reference.
// 2) The return type is not less cv-qualified that the object that contains it.
// 3) The return type is not less cv-qualified than object type.
// 4) The call object is perfectly forwarded.
// 5) Classes that are publicly derived from 'T' are accepted as the call object
// 6) All types that dereference to T or a type derived from T can be used
// as the call object.
// 7) Pointers to T or a type derived from T can be used as the call object.
// 8) reference_wrapper's are properly unwrapped before invoking the function.
#include <functional>
#include <type_traits>
#include <cassert>
#include "test_macros.h"
#include "invoke_helpers.h"
template <class Tp>
struct TestMemberObject {
TestMemberObject() : object() {}
Tp object;
private:
TestMemberObject(TestMemberObject const&);
TestMemberObject& operator=(TestMemberObject const&);
};
template <class ObjectType>
struct TestCase {
public:
static void run() { TestCase().doTest(); }
private:
typedef TestMemberObject<ObjectType> TestType;
//==========================================================================
// TEST DISPATCH
void doTest() {
typedef DerivedFromType<TestType> Derived;
TestType obj;
TestType* obj_ptr = &obj;
Derived der;
Derived* der_ptr = &der;
DerefToType<TestType> dref;
DerefPropType<TestType> dref2;
std::reference_wrapper<TestType> rref(obj);
std::reference_wrapper<Derived> drref(der);
{
typedef ObjectType (TestType::*MemPtr);
typedef ObjectType E;
MemPtr M = &TestType::object;
runTestDispatch<E>(M, obj, &obj.object);
runTestDispatch<E>(M, der, &der.object);
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
#if TEST_STD_VER >= 11
runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
{
typedef ObjectType const (TestType::*CMemPtr);
typedef ObjectType const E;
CMemPtr M = &TestType::object;
runTestDispatch<E>(M, obj, &obj.object);
runTestDispatch<E>(M, der, &der.object);
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
#if TEST_STD_VER >= 11
runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
{
typedef ObjectType volatile (TestType::*VMemPtr);
typedef ObjectType volatile E;
VMemPtr M = &TestType::object;
runTestDispatch<E>(M, obj, &obj.object);
runTestDispatch<E>(M, der, &der.object);
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
#if TEST_STD_VER >= 11
runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
{
typedef ObjectType const volatile (TestType::*CVMemPtr);
typedef ObjectType const volatile E;
CVMemPtr M = &TestType::object;
runTestDispatch<E>(M, obj, &obj.object);
runTestDispatch<E>(M, der, &der.object);
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
#if TEST_STD_VER >= 11
runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
}
template <class Expect, class Fn, class T>
void runTestDispatch(Fn M, T& obj, ObjectType* expect) {
runTest<Expect &> (M, C_<T&>(obj), expect);
runTest<Expect const&> (M, C_<T const&>(obj), expect);
runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect);
runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect);
#if TEST_STD_VER >= 11
runTest<Expect&&> (M, C_<T&&>(obj), expect);
runTest<Expect const&&> (M, C_<T const&&>(obj), expect);
runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect);
runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect);
#endif
}
template <class Expect, class Fn, class T>
void runTestPropCVDispatch(Fn M, T& obj, ObjectType* expect) {
runTest<Expect &> (M, obj, expect);
runTest<Expect const&> (M, makeConst(obj), expect);
runTest<Expect volatile&> (M, makeVolatile(obj), expect);
runTest<Expect const volatile&>(M, makeCV(obj), expect);
}
template <class Expect, class Fn, class T>
void runTestNoPropDispatch(Fn M, T& obj, ObjectType* expect) {
runTest<Expect&>(M, C_<T &>(obj), expect);
runTest<Expect&>(M, C_<T const&>(obj), expect);
runTest<Expect&>(M, C_<T volatile&>(obj), expect);
runTest<Expect&>(M, C_<T const volatile&>(obj), expect);
#if TEST_STD_VER >= 11
runTest<Expect&>(M, C_<T&&>(obj), expect);
runTest<Expect&>(M, C_<T const&&>(obj), expect);
runTest<Expect&>(M, C_<T volatile&&>(obj), expect);
runTest<Expect&>(M, C_<T const volatile&&>(obj), expect);
#endif
}
template <class Expect, class Fn, class T>
void runTest(Fn M, const T& obj, ObjectType* expect) {
static_assert((std::is_same<
decltype(std::__invoke(M, obj)), Expect
>::value), "");
Expect e = std::__invoke(M, obj);
assert(&e == expect);
}
template <class Expect, class Fn, class T>
#if TEST_STD_VER >= 11
void runTest(Fn M, T&& obj, ObjectType* expect) {
#else
void runTest(Fn M, T& obj, ObjectType* expect ) {
#endif
{
static_assert((std::is_same<
decltype(std::__invoke(M, std::forward<T>(obj))), Expect
>::value), "");
Expect e = std::__invoke(M, std::forward<T>(obj));
assert(&e == expect);
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(M, std::forward<T>(obj))), Expect
>::value), "");
Expect e = std::__invoke_constexpr(M, std::forward<T>(obj));
assert(&e == expect);
}
#endif
}
};
int main() {
TestCase<ArgType>::run();
TestCase<ArgType const>::run();
TestCase<ArgType volatile>::run();
TestCase<ArgType const volatile>::run();
TestCase<ArgType*>::run();
}

View File

@@ -0,0 +1,327 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <functional>
// INVOKE (f, t1, t2, ..., tN)
//------------------------------------------------------------------------------
// TESTING INVOKE(f, t1, t2, ..., tN)
// - Bullet 7 -- f(t2, ..., tN)
//
// Overview:
// Bullet 7 handles the cases where the first argument is not a member
// function.
//
// Concerns:
// 1) Different types of callable objects are supported. Including
// 1a) Free Function pointers and references.
// 1b) Classes which provide a call operator
// 1c) lambdas
// 2) The callable objects are perfect forwarded.
// 3) The arguments are perfect forwarded.
// 4) Signatures which include varargs are supported.
// 5) In C++03 3 extra arguments should be allowed.
//
// Plan:
// 1) Define a set of free functions, 'SF', and class types with call
// operators, 'SC', that address concerns 4 and 5. The free functions should
// return 'FunctionID::setUncheckedCall()' and the call operators should
// return 'MethodID::setUncheckedCall()'.
//
// 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f'
// using the correct number of arguments and cv-ref qualifiers. Check that
// 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free
// function and 'MethodID::checkCall()' otherwise.
#include <functional>
#include <type_traits>
#include <cassert>
#include "test_macros.h"
#include "invoke_helpers.h"
//==============================================================================
// freeFunction03 - A C++03 free function.
void*& freeFunction03() {
return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall();
}
void*& freeFunction03(...) {
return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall();
}
template <class A0>
void*& freeFunction03(A0&) {
return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall();
}
template <class A0>
void*& freeFunction03(A0&, ...) {
return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall();
}
template <class A0, class A1>
void*& freeFunction03(A0&, A1&) {
return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall();
}
template <class A0, class A1>
void*& freeFunction03(A0&, A1&, ...) {
return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall();
}
template <class A0, class A1, class A2>
void*& freeFunction03(A0&, A1&, A2&) {
return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall();
}
template <class A0, class A1, class A2>
void*& freeFunction03(A0&, A1&, A2&, ...) {
return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall();
}
//==============================================================================
// Functor03 - C++03 compatible functor object
struct Functor03 {
typedef void*& R;
typedef Functor03 C;
#define F(Args, ...) \
__VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \
__VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \
__VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \
__VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); }
#
F(())
F((A0&), template <class A0>)
F((A0&, A1&), template <class A0, class A1>)
F((A0&, A1&, A2&), template <class A0, class A1, class A2>)
#undef F
public:
Functor03() {}
private:
Functor03(Functor03 const&);
Functor03& operator=(Functor03 const&);
};
#if TEST_STD_VER >= 11
//==============================================================================
// freeFunction11 - A C++11 free function.
template <class ...Args>
void*& freeFunction11(Args&&...) {
return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall();
}
template <class ...Args>
void*& freeFunction11(Args&&...,...) {
return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall();
}
//==============================================================================
// Functor11 - C++11 reference qualified test member functions.
struct Functor11 {
typedef void*& R;
typedef Functor11 C;
#define F(CV) \
template <class ...Args> \
R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); }
#
F(&)
F(const &)
F(volatile &)
F(const volatile &)
F(&&)
F(const &&)
F(volatile &&)
F(const volatile &&)
#undef F
public:
Functor11() {}
private:
Functor11(Functor11 const&);
Functor11& operator=(Functor11 const&);
};
#endif // TEST_STD_VER >= 11
//==============================================================================
// TestCaseFunctorImp - A test case for an operator() class method.
// ClassType - The type of the call object.
// CallSig - The function signature of the call operator being tested.
// Arity - the arity of 'CallSig'
// ObjCaster - Transformation function applied to call object.
// ArgCaster - Transformation function applied to the extra arguments.
template <class ClassType, class CallSig, int Arity,
class ObjCaster, class ArgCaster = LValueCaster>
struct TestCaseFunctorImp {
public:
static void run() {
typedef MethodID<CallSig ClassType::*> MID;
BasicTest<MID, Arity, ObjCaster, ArgCaster> t;
typedef ClassType T;
typedef DerivedFromType<T> D;
T obj;
D der;
t.runTest(obj);
t.runTest(der);
}
};
//==============================================================================
// TestCaseFreeFunction - A test case for a free function.
// CallSig - The function signature of the free function being tested.
// FnPtr - The function being tested.
// Arity - the arity of 'CallSig'
// ArgCaster - Transformation function to be applied to the extra arguments.
template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster>
struct TestCaseFreeFunction {
public:
static void run() {
typedef FunctionPtrID<CallSig, FnPtr> FID;
BasicTest<FID, Arity, LValueCaster, ArgCaster> t;
DerefToType<CallSig*> deref_to(FnPtr);
DerefToType<CallSig&> deref_to_ref(*FnPtr);
t.runTest(FnPtr);
t.runTest(*FnPtr);
t.runTest(deref_to);
t.runTest(deref_to_ref);
}
};
//==============================================================================
// runTest Helpers
//==============================================================================
#if TEST_STD_VER >= 11
template <class Sig, int Arity, class ArgCaster>
void runFunctionTestCase11() {
TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>();
}
#endif
template <class Sig, int Arity, class ArgCaster>
void runFunctionTestCase() {
TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();
#if TEST_STD_VER >= 11
runFunctionTestCase11<Sig, Arity, ArgCaster>();
#endif
}
template <class Sig, int Arity, class ObjCaster, class ArgCaster>
void runFunctorTestCase() {
TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run();
}
template <class Sig, int Arity, class ObjCaster>
void runFunctorTestCase() {
TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();
}
#if TEST_STD_VER >= 11
// runTestCase - Run a test case for C++11 class functor types
template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster>
void runFunctorTestCase11() {
TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run();
}
#endif
// runTestCase - Run a test case for both function and functor types.
template <class Sig, int Arity, class ArgCaster>
void runTestCase() {
runFunctionTestCase<Sig, Arity, ArgCaster>();
runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>();
};
int main() {
typedef void*& R;
typedef ArgType A;
typedef A const CA;
runTestCase< R(), 0, LValueCaster >();
runTestCase< R(A&), 1, LValueCaster >();
runTestCase< R(A&, A&), 2, LValueCaster >();
runTestCase< R(A&, A&, A&), 3, LValueCaster >();
runTestCase< R(CA&), 1, ConstCaster >();
runTestCase< R(CA&, CA&), 2, ConstCaster >();
runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >();
runFunctionTestCase<R(...), 0, LValueCaster >();
runFunctionTestCase<R(A&, ...), 1, LValueCaster >();
runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >();
runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >();
#if TEST_STD_VER >= 11
runFunctionTestCase11<R(A&&), 1, MoveCaster >();
runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >();
#endif
runFunctorTestCase<R(), 0, LValueCaster >();
runFunctorTestCase<R() const, 0, ConstCaster >();
runFunctorTestCase<R() volatile, 0, VolatileCaster >();
runFunctorTestCase<R() const volatile, 0, CVCaster >();
runFunctorTestCase<R(A&), 1, LValueCaster >();
runFunctorTestCase<R(A&) const, 1, ConstCaster >();
runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >();
runFunctorTestCase<R(A&) const volatile, 1, CVCaster >();
runFunctorTestCase<R(A&, A&), 2, LValueCaster >();
runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >();
runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >();
runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >();
runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >();
runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >();
runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >();
runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >();
{
typedef ConstCaster CC;
runFunctorTestCase<R(CA&), 1, LValueCaster, CC>();
runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>();
runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>();
runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>();
runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>();
runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>();
runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>();
runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>();
runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>();
runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>();
runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>();
runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>();
}
#if TEST_STD_VER >= 11
runFunctorTestCase11<R() &, 0, LValueCaster >();
runFunctorTestCase11<R() const &, 0, ConstCaster >();
runFunctorTestCase11<R() volatile &, 0, VolatileCaster >();
runFunctorTestCase11<R() const volatile &, 0, CVCaster >();
runFunctorTestCase11<R() &&, 0, MoveCaster >();
runFunctorTestCase11<R() const &&, 0, MoveConstCaster >();
runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >();
runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >();
{
typedef MoveCaster MC;
runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>();
runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>();
runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>();
runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>();
runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>();
runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>();
runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>();
runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>();
}
#endif
}

View File

@@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// [func.require]
#include <type_traits>
#include <functional>
#include "test_macros.h"
template <typename T, int N>
struct Array
{
typedef T type[N];
};
struct Type
{
Array<char, 1>::type& f1();
Array<char, 2>::type& f2() const;
#if TEST_STD_VER >= 11
Array<char, 1>::type& g1() &;
Array<char, 2>::type& g2() const &;
Array<char, 3>::type& g3() &&;
Array<char, 4>::type& g4() const &&;
#endif
};
int main()
{
static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, "");
static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, "");
#if TEST_STD_VER >= 11
static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, "");
static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, "");
static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, "");
static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, "");
#endif
}

View File

@@ -0,0 +1,456 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef INVOKE_HELPERS_H
#define INVOKE_HELPERS_H
#include <type_traits>
#include <cassert>
#include <functional>
#include "test_macros.h"
template <int I>
struct Int : public std::integral_constant<int, I> {};
template <bool P>
struct Bool : public std::integral_constant<bool, P> {};
struct Q_None {
template <class T>
struct apply { typedef T type; };
};
struct Q_Const {
template <class T>
struct apply { typedef T const type; };
};
struct Q_Volatile {
template <class T>
struct apply { typedef T volatile type; };
};
struct Q_CV {
template <class T>
struct apply { typedef T const volatile type; };
};
// Caster - A functor object that performs cv-qualifier and value category
// conversions.
// QualTag - A metafunction type that applies cv-qualifiers to its argument.
// RValue - True if the resulting object should be an RValue reference.
// False otherwise.
template <class QualTag, bool RValue = false>
struct Caster {
template <class T>
struct apply {
typedef typename std::remove_reference<T>::type RawType;
typedef typename QualTag::template apply<RawType>::type CVType;
#if TEST_STD_VER >= 11
typedef typename std::conditional<RValue,
CVType&&, CVType&
>::type type;
#else
typedef CVType& type;
#endif
};
template <class T>
typename apply<T>::type
operator()(T& obj) const {
typedef typename apply<T>::type OutType;
return static_cast<OutType>(obj);
}
};
typedef Caster<Q_None> LValueCaster;
typedef Caster<Q_Const> ConstCaster;
typedef Caster<Q_Volatile> VolatileCaster;
typedef Caster<Q_CV> CVCaster;
typedef Caster<Q_None, true> MoveCaster;
typedef Caster<Q_Const, true> MoveConstCaster;
typedef Caster<Q_Volatile, true> MoveVolatileCaster;
typedef Caster<Q_CV, true> MoveCVCaster;
template <class Tp>
Tp const& makeConst(Tp& ref) { return ref; }
template <class Tp>
Tp const* makeConst(Tp* ptr) { return ptr; }
template <class Tp>
std::reference_wrapper<const Tp> makeConst(std::reference_wrapper<Tp>& ref) {
return std::reference_wrapper<const Tp>(ref.get());
}
template <class Tp>
Tp volatile& makeVolatile(Tp& ref) { return ref; }
template <class Tp>
Tp volatile* makeVolatile(Tp* ptr) { return ptr; }
template <class Tp>
std::reference_wrapper<volatile Tp> makeVolatile(std::reference_wrapper<Tp>& ref) {
return std::reference_wrapper<volatile Tp>(ref.get());
}
template <class Tp>
Tp const volatile& makeCV(Tp& ref) { return ref; }
template <class Tp>
Tp const volatile* makeCV(Tp* ptr) { return ptr; }
template <class Tp>
std::reference_wrapper<const volatile Tp> makeCV(std::reference_wrapper<Tp>& ref) {
return std::reference_wrapper<const volatile Tp>(ref.get());
}
// A shorter name for 'static_cast'
template <class QualType, class Tp>
QualType C_(Tp& v) { return static_cast<QualType>(v); };
//==============================================================================
// ArgType - A non-copyable type intended to be used as a dummy argument type
// to test functions.
struct ArgType {
int value;
explicit ArgType(int val = 0) : value(val) {}
private:
ArgType(ArgType const&);
ArgType& operator=(ArgType const&);
};
//==============================================================================
// DerivedFromBase - A type that derives from it's template argument 'Base'
template <class Base>
struct DerivedFromType : public Base {
DerivedFromType() : Base() {}
template <class Tp>
explicit DerivedFromType(Tp const& t) : Base(t) {}
};
//==============================================================================
// DerefToType - A type that dereferences to it's template argument 'To'.
// The cv-ref qualifiers of the 'DerefToType' object do not propagate
// to the resulting 'To' object.
template <class To>
struct DerefToType {
To object;
DerefToType() {}
template <class Up>
explicit DerefToType(Up const& val) : object(val) {}
To& operator*() const volatile { return const_cast<To&>(object); }
};
//==============================================================================
// DerefPropToType - A type that dereferences to it's template argument 'To'.
// The cv-ref qualifiers of the 'DerefPropToType' object propagate
// to the resulting 'To' object.
template <class To>
struct DerefPropType {
To object;
DerefPropType() {}
template <class Up>
explicit DerefPropType(Up const& val) : object(val) {}
#if TEST_STD_VER < 11
To& operator*() { return object; }
To const& operator*() const { return object; }
To volatile& operator*() volatile { return object; }
To const volatile& operator*() const volatile { return object; }
#else
To& operator*() & { return object; }
To const& operator*() const & { return object; }
To volatile& operator*() volatile & { return object; }
To const volatile& operator*() const volatile & { return object; }
To&& operator*() && { return static_cast<To &&>(object); }
To const&& operator*() const && { return static_cast<To const&&>(object); }
To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); }
To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
#endif
};
//==============================================================================
// MethodID - A type that uniquely identifies a member function for a class.
// This type is used to communicate between the member functions being tested
// and the tests invoking them.
// - Test methods should call 'setUncheckedCall()' whenever they are invoked.
// - Tests consume the unchecked call using checkCall(<return-value>)` to assert
// that the method has been called and that the return value of `__invoke`
// matches what the method actually returned.
template <class T>
struct MethodID {
typedef void* IDType;
static int dummy; // A dummy memory location.
static void* id; // The "ID" is the value of this pointer.
static bool unchecked_call; // Has a call happened that has not been checked.
static void*& setUncheckedCall() {
assert(unchecked_call == false);
unchecked_call = true;
return id;
}
static bool checkCalled(void*& return_value) {
bool old = unchecked_call;
unchecked_call = false;
return old && id == return_value && &id == &return_value;
}
};
template <class T> int MethodID<T>::dummy = 0;
template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy;
template <class T> bool MethodID<T>::unchecked_call = false;
//==============================================================================
// FunctionPtrID - Like MethodID but for free function pointers.
template <class T, T*>
struct FunctionPtrID {
static int dummy; // A dummy memory location.
static void* id; // The "ID" is the value of this pointer.
static bool unchecked_call; // Has a call happened that has not been checked.
static void*& setUncheckedCall() {
assert(unchecked_call == false);
unchecked_call = true;
return id;
}
static bool checkCalled(void*& return_value) {
bool old = unchecked_call;
unchecked_call = false;
return old && id == return_value && &id == &return_value;
}
};
template <class T, T* Ptr> int FunctionPtrID<T, Ptr>::dummy = 0;
template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy;
template <class T, T* Ptr> bool FunctionPtrID<T, Ptr>::unchecked_call = false;
//==============================================================================
// BasicTest - The basic test structure for everything except
// member object pointers.
// ID - The "Function Identifier" type used either MethodID or FunctionPtrID.
// Arity - The Arity of the call signature.
// ObjectCaster - The object transformation functor type.
// ArgCaster - The extra argument transformation functor type.
template <class ID, int Arity, class ObjectCaster = LValueCaster,
class ArgCaster = LValueCaster>
struct BasicTest {
template <class ObjectT>
void runTest(ObjectT& object) {
Int<Arity> A;
runTestImp(A, object);
}
template <class MethodPtr, class ObjectT>
void runTest(MethodPtr ptr, ObjectT& object) {
Int<Arity> A;
runTestImp(A, ptr, object);
}
private:
typedef void*& CallRet;
ObjectCaster object_cast;
ArgCaster arg_cast;
ArgType a0, a1, a2;
//==========================================================================
// BULLET 1, 2 AND 3 TEST METHODS
//==========================================================================
template <class MethodPtr, class ObjectT>
void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object));
assert(ID::checkCalled(ret));
}
#endif
}
template <class MethodPtr, class ObjectT>
void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#endif
}
template <class MethodPtr, class ObjectT>
void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#endif
}
template <class MethodPtr, class ObjectT>
void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#endif
}
//==========================================================================
// BULLET 7 TEST METHODS
//==========================================================================
template <class ObjectT>
void runTestImp(Int<0>, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object));
assert(ID::checkCalled(ret));
}
#endif
}
template <class ObjectT>
void runTestImp(Int<1>, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#endif
}
template <class ObjectT>
void runTestImp(Int<2>, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#endif
}
template <class ObjectT>
void runTestImp(Int<3>, ObjectT& object) {
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#endif
}
};
#endif // INVOKE_HELPERS_H

Some files were not shown because too many files have changed in this diff Show More