1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
// RUN: %clang_cc1 -std=c++20 -verify %s
// RUN: %clang_cc1 -std=c++17 -verify %s
// p0388 conversions to unbounded array
// dcl.init.list/3
namespace One {
int ga[1];
auto &frob1() {
int(&r1)[] = ga;
#if __cplusplus < 202002
// expected-error@-2{{cannot bind to a value of unrelated type}}
#endif
return r1;
}
auto &frob2(int (&arp)[1]) {
int(&r2)[] = arp;
#if __cplusplus < 202002
// expected-error@-2{{cannot bind to a value of unrelated type}}
#endif
return r2;
}
} // namespace One
namespace Two {
int ga[1];
auto *frob1() {
int(*r1)[] = &ga;
#if __cplusplus < 202002
// expected-error@-2{{with an rvalue of type}}
#endif
return r1;
}
auto *frob2(int (*arp)[1]) {
int(*r2)[] = arp;
#if __cplusplus < 202002
// expected-error@-2{{with an lvalue of type}}
#endif
return r2;
}
} // namespace Two
namespace Four {
using Inc = int[2];
using Mat = Inc[1];
Mat *ga[2];
auto *frob1() {
Inc(*const(*r1)[])[] = &ga;
#if __cplusplus < 202002
// expected-error@-2{{with an rvalue of type}}
#else
// missing a required 'const'
Inc(*(*r2)[])[] = &ga; // expected-error{{cannot initialize}}
#endif
return r1;
}
auto *frob2(Mat *(*arp)[1]) {
Inc(*const(*r2)[])[] = arp;
#if __cplusplus < 202002
// expected-error@-2{{with an lvalue of type}}
#else
Inc(*(*r3)[])[] = arp; // expected-error{{cannot initialize}}
#endif
return r2;
}
} // namespace Four
namespace Five {
// from the paper
char (&b(int(&&)[]))[1]; // #1
char (&b(long(&&)[]))[2]; // #2
char (&b(int(&&)[1]))[3]; // #3
char (&b(long(&&)[1]))[4]; // #4
char (&b(int(&&)[2]))[5]; // #5
#if __cplusplus < 202002
// expected-note@-6{{cannot convert initializer}}
// expected-note@-6{{cannot convert initializer}}
// expected-note@-6{{too many initializers}}
// expected-note@-6{{too many initializers}}
// expected-note@-6{{too many initializers}}
#endif
void f() {
static_assert(sizeof(b({1})) == 3);
static_assert(sizeof(b({1, 2})) == 5);
static_assert(sizeof(b({1, 2, 3})) == 1);
#if __cplusplus < 202002
// expected-error@-2{{no matching function}}
#endif
}
} // namespace Five
#if __cplusplus >= 202002
namespace Six {
// from over.ics.rank 3.1
char (&f(int(&&)[]))[1]; // #1
char (&f(double(&&)[]))[2]; // #2
char (&f(int(&&)[2]))[3]; // #3
void toto() {
// Calls #1: Better than #2 due to conversion, better than #3 due to bounds
static_assert(sizeof(f({1})) == 1);
// Calls #2: Identity conversion is better than floating-integral conversion
static_assert(sizeof(f({1.0})) == 2);
// Calls #2: Identity conversion is better than floating-integral conversion
static_assert(sizeof(f({1.0, 2.0})) == 2);
// Calls #3: Converting to array of known bound is better than to unknown
// bound, and an identity conversion is better than
// floating-integral conversion
static_assert(sizeof(f({1, 2})) == 3);
}
} // namespace Six
namespace Seven {
char (&f(int(&&)[]))[1]; // #1
char (&f(double(&&)[1]))[2]; // #2
void quux() {
// Calls #2, float-integral conversion rather than create zero-sized array
static_assert(sizeof(f({})) == 2);
}
} // namespace Seven
namespace Eight {
// brace-elision is not a thing here:
struct A {
int x, y;
};
char (&f1(int(&&)[]))[1]; // #1
char (&f1(A(&&)[]))[2]; // #2
void g1() {
// pick #1, even though that is more elements than #2
// 6 ints, as opposed to 3 As
static_assert(sizeof(f1({1, 2, 3, 4, 5, 6})) == 1);
}
void f2(A(&&)[]); // expected-note{{candidate function not viable}}
void g2() {
f2({1, 2, 3, 4, 5, 6}); // expected-error{{no matching function}}
}
void f3(A(&&)[]);
void g3() {
auto &f = f3;
f({1, 2, 3, 4, 5, 6}); // OK! We're coercing to an already-selected function
}
} // namespace Eight
#endif
|