brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 974240c Raw
159 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only %s -verify2// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify3// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify4 5struct AnyT {6  template<typename T>7  operator T();8};9 10void test_cvqual_ref(AnyT any) {11  const int &cir = any;  12}13 14struct AnyThreeLevelPtr {15  template<typename T>16  operator T***() const {17    T x = 0; // expected-note 2{{declared const here}}18    x = 0; // expected-error 2{{const-qualified type}}19    T ***p;20    return p;21  }22};23 24struct X { };25 26void test_deduce_with_qual(AnyThreeLevelPtr a3) {27  int * const * const * const ip1 = a3;28  // FIXME: This is wrong; we are supposed to deduce 'T = int' here.29  const int * const * const * const ip2 = a3; // expected-note {{instantiation of}}30  // This one is correct, though.31  const double * * * ip3 = a3; // expected-note {{instantiation of}}32}33 34struct AnyPtrMem {35  template<typename Class, typename T>36  operator T Class::*() const37  {38    // This is correct: we don't need a qualification conversion here, so we39    // deduce 'T = const float'.40    T x = 0; // expected-note {{declared const here}}41    x = 0; // expected-error {{const-qualified type}}42    return 0;43  }44};45 46void test_deduce_ptrmem_with_qual(AnyPtrMem apm) {47  const float X::* pm = apm; // expected-note {{instantiation of}}48}49 50struct TwoLevelPtrMem {51  template<typename Class1, typename Class2, typename T>52  operator T Class1::*Class2::*() const53  {54    T x = 0; // expected-note 2{{declared const here}}55    x = 0; // expected-error 2{{const-qualified type}}56    return 0;57  }58};59 60void test_deduce_two_level_ptrmem_with_qual(TwoLevelPtrMem apm) {61  // FIXME: This is wrong: we should deduce T = 'float'62  const float X::* const X::* pm2 = apm; // expected-note {{instantiation of}}63  // This is correct: we don't need a qualification conversion, so we directly64  // deduce T = 'const double'65  const double X::* X::* pm1 = apm; // expected-note {{instantiation of}}66}67 68namespace non_ptr_ref_cv_qual {69  template<typename Expected>70  struct ConvToT {71    template<typename T> operator T() {72      using Check = T;73      using Check = Expected;74    }75  };76  const int test_conv_to_t_1 = ConvToT<int>();77  // We intentionally deviate from [temp.deduct.conv]p4 here, and also remove78  // the top-level cv-quaifiers from A *after* removing the reference type, if79  // P is not also a reference type. This matches what other compilers are80  // doing, and is necessary to support real-world code.81  const int &test_conv_to_t_2 = ConvToT<int>();82 83  // Example code that would be broken by the standard's rule.84  struct Dest {};85  Dest d1a((ConvToT<Dest>()));86  Dest d1b = ConvToT<Dest>();87  Dest &d2 = (d1a = ConvToT<Dest>());88 89  template<typename Expected>90  struct ConvToTRef {91    template<typename T> operator T&() {92      using Check = T;93      using Check = Expected;94    }95  };96  const int test_conv_to_t_ref_1 = ConvToTRef<int>();97  const int &test_conv_to_t_ref_2 = ConvToTRef<const int>();98 99  Dest d3a((ConvToTRef<const Dest>())); // initialize the copy ctor parameter with 'const Dest&'100  Dest d3b = ConvToTRef<Dest>(); // convert to non-const T via [over.match.copy]/1.2101  Dest &d4 = (d3a = ConvToTRef<const Dest>());102 103  template<typename Expected>104  struct ConvToConstT {105    template<typename T> operator const T() {106      using Check = T;107      using Check = Expected;108    }109  };110  const int test_conv_to_const_t_1 = ConvToConstT<int>();111  const int &test_conv_to_const_t_2 = ConvToConstT<int>();112 113  template<typename Expected>114  struct ConvToConstTRef {115    template<typename T> operator const T&() {116      using Check = T;117      using Check = Expected;118    }119  };120  const int test_conv_to_const_t_ref_1 = ConvToConstTRef<int>();121  const int &test_conv_to_const_t_ref_2 = ConvToConstTRef<int>();122 123  template <typename T, int N> using Arr = T[N];124  struct ConvToArr {125    template <int N>126    operator Arr<int, N> &() {127      static_assert(N == 3, "");128    }129  };130  int (&test_conv_to_arr_1)[3] = ConvToArr(); // ok131  const int (&test_conv_to_arr_2)[3] = ConvToArr(); // ok, with qualification conversion132 133  struct ConvToConstArr {134    template <int N>135    operator const Arr<int, N> &() { // expected-note {{candidate}}136      static_assert(N == 3, "");137    }138  };139  Arr<int, 3> &test_conv_to_const_arr_1 = ConvToConstArr(); // expected-error {{no viable}}140  const Arr<int, 3> &test_conv_to_const_arr_2 = ConvToConstArr(); // ok141 142#if __cplusplus >= 201702L143  template<bool Noexcept, typename T, typename ...U> using Function = T(U...) noexcept(Noexcept);144  template<bool Noexcept> struct ConvToFunction {145    template <typename T, typename ...U> operator Function<Noexcept, T, U...>&(); // expected-note {{candidate}}146  };147  void (&fn1)(int) noexcept(false) = ConvToFunction<false>();148  void (&fn2)(int) noexcept(true)  = ConvToFunction<false>(); // expected-error {{no viable}}149  void (&fn3)(int) noexcept(false) = ConvToFunction<true>();150  void (&fn4)(int) noexcept(true)  = ConvToFunction<true>();151 152  struct ConvToFunctionDeducingNoexcept {153    template <bool Noexcept, typename T, typename ...U> operator Function<Noexcept, T, U...>&();154  };155  void (&fn5)(int) noexcept(false) = ConvToFunctionDeducingNoexcept();156  void (&fn6)(int) noexcept(true)  = ConvToFunctionDeducingNoexcept();157#endif158}159