brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 4972c57 Raw
162 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s2// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s3// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s4// expected-no-diagnostics5 6// Test default template arguments for function templates.7template<typename T = int>8void f0();9 10template<typename T>11void f0();12 13void g0() {14  f0(); // okay!15} 16 17template<typename T, int N = T::value>18int &f1(T);19 20float &f1(...);21 22struct HasValue {23  static const int value = 17;24};25 26void g1() {27  float &fr = f1(15);28  int &ir = f1(HasValue());29}30 31namespace PR16689 {32  template <typename T1, typename T2> class tuple {33  public:34      template <typename = T2>35      constexpr tuple() {}36  };37  template <class X, class... Y> struct a : public X {38    using X::X;39  };40  auto x = a<tuple<int, int> >();41}42 43namespace PR16975 {44  template <typename...> struct is {45    constexpr operator bool() const { return false; }46  };47 48  template <typename... Types>49  struct bar {50    template <typename T,51              bool = is<Types...>()>52    bar(T);53  };54 55  bar<> foo{0};56 57  struct baz : public bar<> {58    using bar::bar;59  };60 61  baz data{0};62}63 64// An IRGen failure due to a symbol collision due to a default argument65// being instantiated twice.  Credit goes to Richard Smith for this66// reduction to a -fsyntax-only failure.67namespace rdar23810407 {68  // Instantiating the default argument multiple times will produce two69  // different lambda types and thus instantiate this function multiple70  // times, which will produce conflicting extern variable declarations.71  template<typename T> int f(T t) {72    extern T rdar23810407_variable;73    return 0;74  }75  template<typename T> int g(int a = f([] {}));76  void test() {77    g<int>();78    g<int>();79  }80}81 82namespace PR13986 {83  constexpr unsigned Dynamic = 0;84  template <unsigned> class A { template <unsigned = Dynamic> void m_fn1(); };85  class Test {86    ~Test() {}87    A<1> m_target;88  };89}90 91// Template B is instantiated during checking if defaulted A copy constructor92// is constexpr. For this we check if S<int> copy constructor is constexpr. And93// for this we check S constructor template with default argument that mentions94// template B. In  turn, template instantiation triggers checking defaulted95// members exception spec. The problem is that it checks defaulted members not96// for instantiated class only, but all defaulted members so far. In this case97// we try to check exception spec for A default constructor which requires98// initializer for the field _a. But initializers are added after constexpr99// check so we reject the code because cannot find _a initializer.100namespace rdar34167492 {101  template <typename T> struct B { using type = bool; };102 103  template <typename T> struct S {104    S() noexcept;105 106    template <typename U, typename B<U>::type = true>107    S(const S<U>&) noexcept;108  };109 110  class A {111    A() noexcept = default;112    A(const A&) noexcept = default;113    S<int> _a{};114  };115}116 117namespace use_of_earlier_param {118  template<typename T> void f(T a, int = decltype(a)());119  void g() { f(0); }120}121 122#if __cplusplus >= 201402L123namespace lambda {124  // Verify that a default argument in a lambda can refer to the type of a125  // previous `auto` argument without crashing.126  template <class T>127  void bar() {128    (void) [](auto c, int x = sizeof(decltype(c))) {};129  }130  void foo() {131    bar<int>();132  }133 134#if __cplusplus >= 202002L135  // PR46648: ensure we don't reject this by triggering default argument136  // instantiation spuriously.137  auto x = []<typename T>(T x = 123) {};138  void y() { x(nullptr); }139 140  template<int A> struct X {141    template<int B> constexpr int f() {142      auto l = []<int C>(int n = A + B + C) { return n; };143      return l.template operator()<3>();144    }145  };146  static_assert(X<100>().f<20>() == 123);147 148  template<> template<int B> constexpr int X<200>::f() {149    auto l = []<int C>(int n = 300 + B + C) { return n; };150    return l.template operator()<1>();151  }152  static_assert(X<200>().f<20>() == 321);153 154  template<> template<> constexpr int X<300>::f<20>() {155    auto l = []<int C>(int n = 450 + C) { return n; };156    return l.template operator()<6>();157  }158  static_assert(X<300>().f<20>() == 456);159#endif160} // namespace lambda161#endif162