brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 3eedef3 Raw
125 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s2// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify=expected,cxx17 %s3 4// A converted constant expression of type T is a core constant expression,5int nonconst = 8; // expected-note 3 {{here}}6enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}}7template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}}8void NonConstF() {9  switch (nonconst) {10    case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}}11      break;12  }13  NonConstT<> V; // expected-note {{while checking a default template argument used here}}14  return;15}16 17// implicitly converted to a prvalue of type T, where the converted expression18// is a literal constant expression19 20bool a(int n) {21  constexpr char vowels[] = "aeiou";22  switch (n) {23  case vowels[0]:24  case vowels[1]:25  case vowels[2]:26  case vowels[3]:27  case vowels[4]:28    static_assert(!vowels[5], "unexpected number of vowels");29    return true;30  }31  return false;32}33 34// and the implicit conversion sequence contains only35//36//  user-defined conversions,37struct S { constexpr operator int() const { return 5; } };38enum E : unsigned char { E5 = S(), E6, E10 = S() * 2, E1 = E5 / 5 };39 40//  lvalue-to-rvalue conversions,41const E e10 = E10;42template<E> struct T {};43T<e10> s10;44 45//  integral promotions,46enum class EE { EE32 = ' ', EE65 = 'A', EE1 = (short)1, EE5 = E5 };47 48//  integral conversions other than narrowing conversions,49int b(unsigned n) {50  switch (n) {51    case E6:52    case EE::EE32: // expected-error {{not implicitly convertible}}53    case (int)EE::EE32:54    case 1000:55    case (long long)1e10: // expected-error {{case value evaluates to 10000000000, which cannot be narrowed to type 'unsigned int'}}56    case -3: // expected-error {{case value evaluates to -3, which cannot be narrowed to type 'unsigned int'}}57      return n;58  }59  return 0;60}61enum class EEE : unsigned short {62  a = E6,63  b = EE::EE32, // expected-error {{not implicitly convertible}}64  c = (int)EE::EE32,65  d = 1000,66  e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}}67  f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}}68};69template<unsigned char> using A = int; // cxx17-note 2{{template parameter is declared here}}70 71using Int = A<E6>;72using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}}73using Int = A<(int)EE::EE32>;74using Int = A<200>;75using Int = A<1000>; // expected-error {{template argument evaluates to 1000, which cannot be narrowed to type 'unsigned char'}}76using Int = A<-3>; // expected-error {{template argument evaluates to -3, which cannot be narrowed to type 'unsigned char'}}77 78// Note, conversions from integral or unscoped enumeration types to bool are79// integral conversions as well as boolean conversions.80// FIXME: Per core issue 1407, this is not correct.81template<typename T, T v> struct Val { static constexpr T value = v; };82// cxx17-note@-1 2{{template parameter is declared here}}83static_assert(Val<bool, E1>::value == 1, ""); // ok84static_assert(Val<bool, '\0'>::value == 0, ""); // ok85static_assert(Val<bool, U'\1'>::value == 1, ""); // ok86static_assert(Val<bool, E5>::value == 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}}87 88//  function pointer conversions [C++17]89void noexcept_false() noexcept(false);90void noexcept_true() noexcept(true);91Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept;92Val<decltype(&noexcept_true), &noexcept_false> add_noexcept;93#if __cplusplus > 201402L94// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'decltype(&noexcept_true)' (aka 'void (*)() noexcept(true)')}}95#endif96 97// (no other conversions are permitted)98using Int = A<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}}99enum B : bool {100  True = &a, // expected-error {{conversion from 'bool (*)(int)' to 'bool' is not allowed in a converted constant expression}}101  False = 0.0, // expected-error {{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}102};103void c() {104  // Note, promoted type of switch is 'int'.105  switch (bool b = a(5)) { // expected-warning {{boolean value}}106  case 0.0f: // expected-error {{conversion from 'float' to 'int' is not allowed in a converted constant expression}}107    break;108  }109}110template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}}111template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}112template int f<(bool)&S::operator int>();113 114int n = Val<bool, &S::operator int>::value; // expected-error-re {{conversion from 'int (S::*)(){{( __attribute__\(\(thiscall\)\))?}} const' to 'bool' is not allowed in a converted constant expression}}115 116namespace NonConstLValue {117  struct S {118    constexpr operator int() const { return 10; }119  };120  S s; // not constexpr121  // Under the FDIS, this is not a converted constant expression.122  // Under the new proposed wording, it is.123  enum E : char { e = s };124}125