diff options
author | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 056abd2059c65a3e908193aeae16fad98017437c (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /test/SemaTemplate/constexpr-instantiate.cpp | |
parent | cc73504950eb7b5dff2dded9bedd67bc36d64641 (diff) | |
download | FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
Diffstat (limited to 'test/SemaTemplate/constexpr-instantiate.cpp')
-rw-r--r-- | test/SemaTemplate/constexpr-instantiate.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/test/SemaTemplate/constexpr-instantiate.cpp b/test/SemaTemplate/constexpr-instantiate.cpp index 2f9fe0e..80c4aaf 100644 --- a/test/SemaTemplate/constexpr-instantiate.cpp +++ b/test/SemaTemplate/constexpr-instantiate.cpp @@ -75,3 +75,136 @@ namespace Reference { constexpr int n = const_cast<int&>(S<int>::r); static_assert(n == 5, ""); } + +namespace Unevaluated { + // We follow g++ in treating any reference to a constexpr function template + // specialization as requiring an instantiation, even if it occurs in an + // unevaluated context. + // + // We go slightly further than g++, and also trigger the implicit definition + // of a defaulted special member in the same circumstances. This seems scary, + // since a lot of classes have constexpr special members in C++11, but the + // only observable impact should be the implicit instantiation of constexpr + // special member templates (defaulted special members should only be + // generated if they are well-formed, and non-constexpr special members in a + // base or member cause the class's special member to not be constexpr). + // + // FIXME: None of this is required by the C++ standard. The rules in this + // area are poorly specified, so this is subject to change. + namespace NotConstexpr { + template<typename T> struct S { + S() : n(0) {} + S(const S&) : n(T::error) {} + int n; + }; + struct U : S<int> {}; + decltype(U(U())) u; // ok, don't instantiate S<int>::S() because it wasn't declared constexpr + } + namespace Constexpr { + template<typename T> struct S { + constexpr S() : n(0) {} + constexpr S(const S&) : n(T::error) {} // expected-error {{has no members}} + int n; + }; + struct U : S<int> {}; // expected-note {{instantiation}} + decltype(U(U())) u; // expected-note {{here}} + } + + namespace PR11851_Comment0 { + template<int x> constexpr int f() { return x; } + template<int i> void ovf(int (&x)[f<i>()]); + void f() { int x[10]; ovf<10>(x); } + } + + namespace PR11851_Comment1 { + template<typename T> + constexpr bool Integral() { + return true; + } + template<typename T, bool Int = Integral<T>()> + struct safe_make_unsigned { + typedef T type; + }; + template<typename T> + using Make_unsigned = typename safe_make_unsigned<T>::type; + template <typename T> + struct get_distance_type { + using type = int; + }; + template<typename R> + auto size(R) -> Make_unsigned<typename get_distance_type<R>::type>; + auto check() -> decltype(size(0)); + } + + namespace PR11851_Comment6 { + template<int> struct foo {}; + template<class> constexpr int bar() { return 0; } + template<class T> foo<bar<T>()> foobar(); + auto foobar_ = foobar<int>(); + } + + namespace PR11851_Comment9 { + struct S1 { + constexpr S1() {} + constexpr operator int() const { return 0; } + }; + int k1 = sizeof(short{S1(S1())}); + + struct S2 { + constexpr S2() {} + constexpr operator int() const { return 123456; } + }; + int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{override}} + } + + namespace PR12288 { + template <typename> constexpr bool foo() { return true; } + template <bool> struct bar {}; + template <typename T> bar<foo<T>()> baz() { return bar<foo<T>()>(); } + int main() { baz<int>(); } + } + + namespace PR13423 { + template<bool, typename> struct enable_if {}; + template<typename T> struct enable_if<true, T> { using type = T; }; + + template<typename T> struct F { + template<typename U> + static constexpr bool f() { return sizeof(T) < U::size; } + + template<typename U> + static typename enable_if<f<U>(), void>::type g() {} // expected-note {{disabled by 'enable_if'}} + }; + + struct U { static constexpr int size = 2; }; + + void h() { F<char>::g<U>(); } + void i() { F<int>::g<U>(); } // expected-error {{no matching function}} + } + + namespace PR14203 { + struct duration { constexpr duration() {} }; + + template <typename> + void sleep_for() { + constexpr duration max = duration(); + } + } +} + +namespace NoInstantiationWhenSelectingOverload { + // Check that we don't instantiate conversion functions when we're checking + // for the existence of an implicit conversion sequence, only when a function + // is actually chosen by overload resolution. + struct S { + template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}} + int n; + }; + + void f(S); + void f(int); + + void g() { f(0); } + void h() { (void)sizeof(f(0)); } + void i() { (void)sizeof(f("oops")); } // expected-note {{instantiation of}} +} |