summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/constexpr-instantiate.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
committerdim <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
commit056abd2059c65a3e908193aeae16fad98017437c (patch)
tree2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /test/SemaTemplate/constexpr-instantiate.cpp
parentcc73504950eb7b5dff2dded9bedd67bc36d64641 (diff)
downloadFreeBSD-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.cpp133
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}}
+}
OpenPOWER on IntegriCloud