p3-0x.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
  2. // A converted constant expression of type T is a core constant expression,
  3. int nonconst = 8; // expected-note 3 {{here}}
  4. enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}}
  5. template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}}
  6. void NonConstF() {
  7. switch (nonconst) {
  8. case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}}
  9. break;
  10. }
  11. return;
  12. }
  13. // implicitly converted to a prvalue of type T, where the converted expression
  14. // is a literal constant expression
  15. bool a(int n) {
  16. constexpr char vowels[] = "aeiou";
  17. switch (n) {
  18. case vowels[0]:
  19. case vowels[1]:
  20. case vowels[2]:
  21. case vowels[3]:
  22. case vowels[4]:
  23. static_assert(!vowels[5], "unexpected number of vowels");
  24. return true;
  25. }
  26. return false;
  27. }
  28. // and the implicit conversion sequence contains only
  29. //
  30. // user-defined conversions,
  31. struct S { constexpr operator int() const { return 5; } };
  32. enum E : unsigned char { E5 = S(), E6, E10 = S() * 2, E1 = E5 / 5 };
  33. // lvalue-to-rvalue conversions,
  34. const E e10 = E10;
  35. template<E> struct T {};
  36. T<e10> s10;
  37. // integral promotions, and
  38. enum class EE { EE32 = ' ', EE65 = 'A', EE1 = (short)1, EE5 = E5 };
  39. // integral conversions other than narrowing conversions
  40. int b(unsigned n) {
  41. switch (n) {
  42. case E6:
  43. case EE::EE32: // expected-error {{not implicitly convertible}}
  44. case (int)EE::EE32:
  45. case 1000:
  46. case (long long)1e10: // expected-error {{case value evaluates to 10000000000, which cannot be narrowed to type 'unsigned int'}}
  47. case -3: // expected-error {{case value evaluates to -3, which cannot be narrowed to type 'unsigned int'}}
  48. return n;
  49. }
  50. return 0;
  51. }
  52. enum class EEE : unsigned short {
  53. a = E6,
  54. b = EE::EE32, // expected-error {{not implicitly convertible}}
  55. c = (int)EE::EE32,
  56. d = 1000,
  57. e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}}
  58. f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}}
  59. };
  60. template<unsigned char> using A = int;
  61. using Int = A<E6>;
  62. using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}}
  63. using Int = A<(int)EE::EE32>;
  64. using Int = A<200>;
  65. using Int = A<1000>; // expected-error {{template argument evaluates to 1000, which cannot be narrowed to type 'unsigned char'}}
  66. using Int = A<-3>; // expected-error {{template argument evaluates to -3, which cannot be narrowed to type 'unsigned char'}}
  67. // Note, conversions from integral or unscoped enumeration types to bool are
  68. // integral conversions as well as boolean conversions.
  69. template<typename T, T v> struct Val { static constexpr T value = v; };
  70. static_assert(Val<bool, E1>::value == 1, ""); // ok
  71. static_assert(Val<bool, '\0'>::value == 0, ""); // ok
  72. static_assert(Val<bool, U'\1'>::value == 1, ""); // ok
  73. static_assert(Val<bool, E5>::value == 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}}
  74. // (no other conversions are permitted)
  75. using Int = A<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}}
  76. enum B : bool {
  77. True = &a, // expected-error {{conversion from 'bool (*)(int)' to 'bool' is not allowed in a converted constant expression}}
  78. False = nullptr // expected-error {{conversion from 'nullptr_t' to 'bool' is not allowed in a converted constant expression}}
  79. };
  80. void c() {
  81. // Note, promoted type of switch is 'int'.
  82. switch (bool b = a(5)) { // expected-warning {{boolean value}}
  83. case 0.0f: // expected-error {{conversion from 'float' to 'int' is not allowed in a converted constant expression}}
  84. break;
  85. }
  86. }
  87. template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}}
  88. template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}
  89. template int f<(bool)&S::operator int>();
  90. int 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}}
  91. namespace NonConstLValue {
  92. struct S {
  93. constexpr operator int() const { return 10; }
  94. };
  95. S s; // not constexpr
  96. // Under the FDIS, this is not a converted constant expression.
  97. // Under the new proposed wording, it is.
  98. enum E : char { e = s };
  99. }