473 lines · cpp
1// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -Wno-ext-cxx-type-aware-allocators -fexceptions -fsized-deallocation -faligned-allocation2// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -Wno-ext-cxx-type-aware-allocators -fexceptions -fno-sized-deallocation -faligned-allocation3// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -Wno-ext-cxx-type-aware-allocators -fexceptions -fsized-deallocation -fno-aligned-allocation4// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -Wno-ext-cxx-type-aware-allocators -fexceptions -fno-sized-deallocation -fno-aligned-allocation5 6namespace std {7 template <class T> struct type_identity {};8 enum class align_val_t : __SIZE_TYPE__ {};9 struct destroying_delete_t { explicit destroying_delete_t() = default; };10}11 12#if defined(__cpp_aligned_new)13#define ALLOCATION_ALIGNMENT , std::align_val_t14#else15#define ALLOCATION_ALIGNMENT16#endif17 18using size_t = __SIZE_TYPE__;19 20void *operator new(size_t);21void *operator new(size_t, std::align_val_t);22void operator delete(void *);23 24struct UntypedInclassNew {25 void *operator new(size_t) = delete; // #126 void operator delete(void *) = delete; //#227};28void *operator new(std::type_identity<UntypedInclassNew>, size_t, std::align_val_t); // #329void operator delete(std::type_identity<UntypedInclassNew>, void*, size_t, std::align_val_t); // #430 31 32struct __attribute__((aligned(128))) UntypedInclassNewOveraligned_NoAlignedAlloc {33 void *operator new(size_t) = delete; // #534 void operator delete(void *) = delete; // #635};36void *operator new(std::type_identity<UntypedInclassNewOveraligned_NoAlignedAlloc>, size_t, std::align_val_t); // #737void operator delete(std::type_identity<UntypedInclassNewOveraligned_NoAlignedAlloc>, void *, size_t, std::align_val_t); // #838 39struct __attribute__((aligned(128))) UntypedInclassNewOveraligned_AlignedAlloc {40 void *operator new(size_t ALLOCATION_ALIGNMENT) = delete; // #941 void operator delete(void * ALLOCATION_ALIGNMENT) = delete; // #1042};43void *operator new(std::type_identity<UntypedInclassNewOveraligned_AlignedAlloc>, size_t, std::align_val_t); // #1144void operator delete(std::type_identity<UntypedInclassNewOveraligned_AlignedAlloc>, void *, size_t, std::align_val_t); // #1245 46struct BasicClass {};47void *operator new(std::type_identity<BasicClass>, size_t, std::align_val_t) = delete; // #1348void operator delete(std::type_identity<BasicClass>, void *, size_t, std::align_val_t) = delete; // #1449 50struct InclassNew1 {51 void *operator new(std::type_identity<InclassNew1>, size_t, std::align_val_t) = delete; // #1552 void operator delete(std::type_identity<InclassNew1>, void *, size_t, std::align_val_t) = delete; // #1653};54void *operator new(std::type_identity<InclassNew1>, size_t, std::align_val_t); // #1755void operator delete(std::type_identity<InclassNew1>, void *, size_t, std::align_val_t); // #1856 57struct InclassNew2 {58 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t) = delete; // #1959 template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t) = delete; // #2060};61void *operator new(std::type_identity<InclassNew2>, size_t, std::align_val_t); // #2162void operator delete(std::type_identity<InclassNew2>, void *, size_t, std::align_val_t); // #2263 64struct InclassNew3 {65 void *operator new(std::type_identity<InclassNew3>, size_t, std::align_val_t) = delete; // #2366 void operator delete(std::type_identity<InclassNew3>, void*, size_t, std::align_val_t) = delete; // #2467 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #2568 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t); // #2669};70 71struct __attribute__((aligned(128))) InclassNew4 {72 void *operator new(std::type_identity<InclassNew4>, size_t, std::align_val_t); // #2773 void operator delete(std::type_identity<InclassNew4>, void*, size_t, std::align_val_t); // #2874 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t) = delete; // #2975 template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t) = delete; // #3076};77 78struct InclassNew5 {79 InclassNew5();80 void *operator new(std::type_identity<InclassNew5>, size_t, std::align_val_t); // #3181 void operator delete(void *); // #3282 void operator delete(std::type_identity<InclassNew5>, void*, size_t, std::align_val_t) = delete; // #3383};84 85struct InclassNew6 {86 // expected-error@-1 {{declaration of type aware 'operator delete' in 'InclassNew6' must have matching type aware 'operator new'}}87 // expected-note@#36 {{unmatched type aware 'operator delete' declared here}}88 InclassNew6();89 void *operator new(size_t); // #3490 void operator delete(void *) = delete; // #3591 void operator delete(std::type_identity<InclassNew6>, void*, size_t, std::align_val_t) = delete; // #3692};93 94struct InclassNew7 {95 InclassNew7();96 void *operator new(std::type_identity<InclassNew7>, size_t, std::align_val_t); // #3797 void operator delete(std::type_identity<InclassNew7>, void*, size_t, std::align_val_t); // #3898 void operator delete(InclassNew7 *, std::destroying_delete_t) = delete; // #3999};100 101struct InclassNew8 {102 // expected-error@-1 {{declaration of type aware 'operator new' in 'InclassNew8' must have matching type aware 'operator delete'}}103 // expected-note@#40 {{unmatched type aware 'operator new' declared here}}104 InclassNew8();105 void *operator new(std::type_identity<InclassNew8>, size_t, std::align_val_t); // #40106 void operator delete(void*); // #41107};108 109struct InclassNew9 {110 // expected-error@-1 {{declaration of type aware 'operator new' in 'InclassNew9' must have matching type aware 'operator delete'}}111 // expected-note@#42 {{unmatched type aware 'operator new' declared here}}112 InclassNew9();113 void *operator new(std::type_identity<InclassNew9>, size_t, std::align_val_t); // #42114};115 116void operator delete(std::type_identity<InclassNew9>, void*, size_t, std::align_val_t); // #43117 118struct BaseClass1 {119 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #44120 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t) = delete; // #45121 virtual ~BaseClass1();122};123BaseClass1::~BaseClass1() {124 // expected-error@-1 {{attempt to use a deleted function}}125 // expected-note@#45 {{'operator delete<BaseClass1>' has been explicitly marked deleted here}}126}127 128struct SubClass1 : BaseClass1 { 129 virtual ~SubClass1();130};131 132SubClass1::~SubClass1() {133 // expected-error@-1 {{attempt to use a deleted function}}134 // expected-note@#45 {{'operator delete<SubClass1>' has been explicitly marked deleted here}}135}136 137struct BaseClass2 {138 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #46139 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t) = delete; // #47140 void operator delete(BaseClass2 *, std::destroying_delete_t); // #48141 virtual ~BaseClass2();142};143BaseClass2::~BaseClass2(){144};145 146struct SubClass2 : BaseClass2 {147 SubClass2(); // Force exception cleanup which should invoke type aware delete148 virtual ~SubClass2();149};150SubClass2::~SubClass2(){151}152 153struct BaseClass3 {154 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #49155 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t); // #50156 void operator delete(BaseClass3 *, std::destroying_delete_t) = delete; // #51157 virtual ~BaseClass3();158};159BaseClass3::~BaseClass3(){160 // expected-error@-1 {{attempt to use a deleted function}}161 // expected-note@#51 {{'operator delete' has been explicitly marked deleted here}}162}163 164struct SubClass3 : BaseClass3 {165 virtual ~SubClass3();166};167SubClass3::~SubClass3(){168 // expected-error@-1 {{attempt to use a deleted function}}169 // expected-note@#51 {{'operator delete' has been explicitly marked deleted here}}170}171 172template <typename A, typename B> concept Derived = requires (A * a, B *b) { a = b; };173template <typename A, typename B> concept Same = requires (std::type_identity<A> * a, std::type_identity<B> *b) { a = b; };174 175struct SubClass4;176struct BaseClass4 {177 template <Derived<SubClass4> T> void *operator new(std::type_identity<T>, size_t, std::align_val_t) = delete; // #52178 template <Derived<SubClass4> T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t) = delete; // #53179 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #54180 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t); // #55181 182 virtual ~BaseClass4();183};184BaseClass4::~BaseClass4() {185}186 187struct SubClass4 : BaseClass4 {188 virtual ~SubClass4();189};190SubClass4::~SubClass4(){191 // expected-error@-1 {{attempt to use a deleted function}}192 // expected-note@#53 {{'operator delete<SubClass4>' has been explicitly marked deleted here}}193}194 195struct SubClass4_1 : SubClass4 {196 SubClass4_1();197};198struct SubClass4_2 : BaseClass4 {199};200 201struct SubClass5;202struct BaseClass5 {203 template <Same<SubClass5> T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #56204 template <Same<SubClass5> T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t); // #57205 template <Derived<SubClass5> T> requires (!Same<SubClass5, T>) void *operator new(std::type_identity<T>, size_t, std::align_val_t) = delete; // #58206 template <Derived<SubClass5> T> requires (!Same<SubClass5, T>) void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t) = delete; // #59207};208 209struct SubClass5 : BaseClass5 {210};211struct SubClass5_1 : SubClass5 {212};213 214 215struct BaseClass6 {216 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #60217 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t); // #61218 BaseClass6();219 virtual ~BaseClass6();220};221BaseClass6::~BaseClass6(){222}223 224struct SubClass6_1 : BaseClass6 {225 // expected-error@-1 {{declaration of type aware 'operator new' in 'SubClass6_1' must have matching type aware 'operator delete'}}226 // expected-note@#62 {{unmatched type aware 'operator new' declared here}}227 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #62228 SubClass6_1();229};230struct SubClass6_2 : BaseClass6 {231 // expected-error@-1 {{declaration of type aware 'operator delete' in 'SubClass6_2' must have matching type aware 'operator new'}}232 // expected-note@#63 {{unmatched type aware 'operator delete' declared here}}233 template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t); // #63234 SubClass6_2();235};236 237struct MultiDimensionArrayTest1 {238 int i;239 MultiDimensionArrayTest1();240 template <typename T, unsigned N> void *operator new[](std::type_identity<T[N]>, size_t, std::align_val_t) = delete; // #64241 template <typename T, unsigned N> void operator delete[](std::type_identity<T[N]>, void*, size_t, std::align_val_t) = delete; // #65242};243 244struct MultiDimensionArrayTest2 {245 int i;246 MultiDimensionArrayTest2();247 template <unsigned N> void *operator new[](std::type_identity<MultiDimensionArrayTest2[N]>, size_t, std::align_val_t) = delete; // #66248 template <unsigned N> void operator delete[](std::type_identity<MultiDimensionArrayTest2[N]>, void*, size_t, std::align_val_t) = delete; // #67249};250 251struct MultiDimensionArrayTest3 {252 int i;253 MultiDimensionArrayTest3();254 template <unsigned N> requires (N%4 == 0) void *operator new[](std::type_identity<MultiDimensionArrayTest3[N]>, size_t, std::align_val_t) = delete; // #68255 template <unsigned N> requires (N%4 == 0) void operator delete[](std::type_identity<MultiDimensionArrayTest3[N]>, void*, size_t, std::align_val_t) = delete; // #69256};257 258struct ClassScopedTemplatePackStruct {259 template <class T, class... Pack> void *operator new(std::type_identity<T>, size_t, std::align_val_t, Pack...);260 template <class T, class... Pack> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t, Pack...); // #70261};262 263void test() {264 265 // untyped in class declaration wins266 UntypedInclassNew *O1 = new UntypedInclassNew;267 // expected-error@-1 {{call to deleted function 'operator new'}}268 // expected-note@#1 {{candidate function has been explicitly deleted}}269 delete O1;270 // expected-error@-1 {{attempt to use a deleted function}}271 // expected-note@#2 {{'operator delete' has been explicitly marked deleted here}}272 273 // untyped in class declaration wins, even though global is aligned and in class is not274 UntypedInclassNewOveraligned_NoAlignedAlloc *O2 = new UntypedInclassNewOveraligned_NoAlignedAlloc;275 // expected-error@-1 {{call to deleted function 'operator new'}}276 // expected-note@#5 {{candidate function has been explicitly deleted}}277 delete O2;278 // expected-error@-1 {{attempt to use a deleted function}}279 // expected-note@#6 {{'operator delete' has been explicitly marked deleted here}}280 281 // untyped in class declaration wins282 UntypedInclassNewOveraligned_AlignedAlloc *O3 = new UntypedInclassNewOveraligned_AlignedAlloc;283 // expected-error@-1 {{call to deleted function 'operator new'}}284 // expected-note@#9 {{candidate function has been explicitly deleted}}285 delete O3;286 // expected-error@-1 {{attempt to use a deleted function}}287 // expected-note@#10 {{'operator delete' has been explicitly marked deleted here}}288 289 // We resolve the explicitly typed free operator290 BasicClass *O4 = new BasicClass;291 // expected-error@-1 {{call to deleted function 'operator new'}}292 // expected-note@#13 {{candidate function has been explicitly deleted}}293 // expected-note@#3 {{candidate function not viable: no known conversion from 'type_identity<BasicClass>' to 'type_identity<UntypedInclassNew>' for 1st argument}}294 // expected-note@#17 {{candidate function not viable: no known conversion from 'type_identity<BasicClass>' to 'type_identity<InclassNew1>' for 1st argument}}295 // expected-note@#21 {{candidate function not viable: no known conversion from 'type_identity<BasicClass>' to 'type_identity<InclassNew2>' for 1st argument}}296 // expected-note@#7 {{candidate function not viable: no known conversion from 'type_identity<BasicClass>' to 'type_identity<UntypedInclassNewOveraligned_NoAlignedAlloc>' for 1st argument}}297 // expected-note@#11 {{candidate function not viable: no known conversion from 'type_identity<BasicClass>' to 'type_identity<UntypedInclassNewOveraligned_AlignedAlloc>' for 1st argument}}298 299 delete O4;300 // expected-error@-1 {{attempt to use a deleted function}}301 // expected-note@#14 {{'operator delete' has been explicitly marked deleted here}}302 303 // We resolve the explicitly typed in class operator304 InclassNew1 *O5 = new InclassNew1;305 // expected-error@-1 {{call to deleted function 'operator new'}}306 // expected-note@#15 {{candidate function has been explicitly deleted}}307 delete O5;308 // expected-error@-1 {{attempt to use a deleted function}}309 // expected-note@#16 {{'operator delete' has been explicitly marked deleted here}}310 311 // We resolve the unconstrained in class operators over the constrained free operators312 InclassNew2 *O6 = new InclassNew2;313 // expected-error@-1 {{call to deleted function 'operator new'}}314 // expected-note@#19 {{candidate function [with T = InclassNew2] has been explicitly deleted}}315 delete O6;316 // expected-error@-1 {{attempt to use a deleted function}}317 // expected-note@#20 {{'operator delete<InclassNew2>' has been explicitly marked deleted here}}318 319 // We prefer the constrained in class operators over the unconstrained variants320 InclassNew3 *O7 = new InclassNew3;321 // expected-error@-1 {{call to deleted function 'operator new'}}322 // expected-note@#23 {{candidate function has been explicitly deleted}}323 // expected-note@#25 {{candidate function [with T = InclassNew3]}}324 delete O7;325 // expected-error@-1 {{attempt to use a deleted function}}326 // expected-note@#24 {{'operator delete' has been explicitly marked deleted here}}327 328 // Constructor clean up invokes typed operator if typed new was used329 InclassNew5 *O9 = new InclassNew5;330 // expected-error@-1 {{attempt to use a deleted function}}331 // expected-note@#33 {{'operator delete' has been explicitly marked deleted here}}332 delete O9;333 // expected-error@-1 {{attempt to use a deleted function}}334 // expected-note@#33 {{'operator delete' has been explicitly marked deleted here}}335 336 // Constructor clean up invokes untyped delete if untyped delete was used337 InclassNew6 *O10 = new InclassNew6;338 // expected-error@-1 {{attempt to use a deleted function}}339 // expected-note@#36 {{'operator delete' has been explicitly marked deleted here}}340 // expected-error@-3 {{type aware 'operator delete' requires a matching type aware 'operator new' to be declared in the same scope}}341 // expected-note@#34 {{non-type aware 'operator new' declared here in 'InclassNew6'}}342 // expected-note@#36 {{type aware 'operator delete' declared here}}343 delete O10;344 // expected-error@-1 {{attempt to use a deleted function}}345 // expected-note@#36 {{'operator delete' has been explicitly marked deleted here}}346 347 // Destroying delete is prefered over typed delete348 InclassNew7 *O11 = new InclassNew7;349 delete O11;350 // expected-error@-1 {{attempt to use a deleted function}}351 // expected-note@#39 {{'operator delete' has been explicitly marked deleted here}}352 353 InclassNew8 *O12 = new InclassNew8;354 // expected-error@-1 {{type aware 'operator new' requires a matching type aware 'operator delete' to be declared in the same scope}}355 // expected-note@#40 {{type aware 'operator new' declared here in 'InclassNew8'}}356 // expected-note@#41 {{non-type aware 'operator delete' declared here}}357 delete O12;358 359 InclassNew9 *O13 = new InclassNew9;360 // expected-error@-1 {{type aware 'operator new' requires a matching type aware 'operator delete' to be declared in the same scope}}361 // expected-note@#42 {{type aware 'operator new' declared here in 'InclassNew9'}}362 363 delete O13;364 365 // Creating the virtual destructor for an type requires the deleting destructor366 // for that type367 SubClass1 *O14 = new SubClass1;368 // expected-error@-1 {{attempt to use a deleted function}}369 // expected-note@#45 {{'operator delete<SubClass1>' has been explicitly marked deleted here}}370 371 delete O14;372 // expected-error@-1 {{attempt to use a deleted function}}373 // expected-note@#45 {{'operator delete<SubClass1>' has been explicitly marked deleted here}}374 375 SubClass2 *O15 = new SubClass2;376 // expected-error@-1 {{attempt to use a deleted function}}377 // expected-note@#47 {{'operator delete<SubClass2>' has been explicitly marked deleted here}}378 delete O15;379 380 // Deletion triggers destroying delete despite type aware delete381 SubClass3 *O16 = new SubClass3;382 delete O16;383 // expected-error@-1 {{attempt to use a deleted function}}384 // expected-note@#51 {{'operator delete' has been explicitly marked deleted here}}385 386 SubClass4 *O17 = new SubClass4;387 // expected-error@-1 {{call to deleted function 'operator new'}}388 // expected-note@#52 {{candidate function [with T = SubClass4] has been explicitly deleted}}389 // expected-note@#54 {{candidate function [with T = SubClass4]}}390 delete O17;391 // expected-error@-1 {{attempt to use a deleted function}}392 // expected-note@#53 {{'operator delete<SubClass4>' has been explicitly marked deleted here}}393 394 SubClass4_1 *O18 = new SubClass4_1;395 delete O18;396 397 SubClass4_2 *O19 = new SubClass4_2;398 delete O19;399 400 SubClass5 *O20 = new SubClass5;401 delete O20;402 403 SubClass5_1 *O21 = new SubClass5_1;404 // expected-error@-1 {{no matching function for call to 'operator new'}}405 delete O21;406 // expected-error@-1 {{no suitable member 'operator delete' in 'SubClass5_1'}}407 // expected-note@#57 {{member 'operator delete' declared here}}408 // expected-note@#59 {{member 'operator delete' declared here}}409 410 SubClass6_1 *O22 = new SubClass6_1;411 // expected-error@-1 {{type aware 'operator new' requires a matching type aware 'operator delete' to be declared in the same scope}}412 // expected-note@#62 {{type aware 'operator new' declared here in 'SubClass6_1'}}413 // expected-note@#61 {{type aware 'operator delete' declared here in 'BaseClass6'}}414 delete O22;415 416 SubClass6_2 *O23 = new SubClass6_2;417 // expected-error@-1 {{type aware 'operator new' requires a matching type aware 'operator delete' to be declared in the same scope}}418 // expected-note@#60 {{type aware 'operator new' declared here in 'BaseClass6'}}419 // expected-note@#63 {{type aware 'operator delete' declared here in 'SubClass6_2'}}420 delete O23;421 422 MultiDimensionArrayTest1 *O24 = new MultiDimensionArrayTest1;423 delete O24;424 425 MultiDimensionArrayTest1 *O25 = new MultiDimensionArrayTest1[10];426 // expected-error@-1 {{no matching function for call to 'operator new[]'}}427 delete [] O25;428 // expected-error@-1 {{no suitable member 'operator delete[]' in 'MultiDimensionArrayTest1'}}429 // expected-note@#65 {{member 'operator delete[]' declared here}}430 431 {432 using InnerArray = MultiDimensionArrayTest1[3];433 InnerArray *O26 = new InnerArray[7];434 // expected-error@-1 {{call to deleted function 'operator new[]'}}435 // expected-note@#64 {{candidate function [with T = MultiDimensionArrayTest1, N = 3] has been explicitly deleted}}436 delete [] O26;437 // expected-error@-1 {{attempt to use a deleted function}}438 // expected-note@#65 {{'operator delete[]<MultiDimensionArrayTest1, 3U>' has been explicitly marked deleted here}}439 }440 {441 using InnerArray = MultiDimensionArrayTest2[3];442 InnerArray *O27 = new InnerArray[7];443 // expected-error@-1 {{call to deleted function 'operator new[]'}}444 // expected-note@#66 {{candidate function [with N = 3] has been explicitly deleted}}445 delete [] O27;446 // expected-error@-1 {{attempt to use a deleted function}}447 // expected-note@#67 {{'operator delete[]<3U>' has been explicitly marked deleted here}}448 }449 {450 using InnerArray = MultiDimensionArrayTest3[3];451 InnerArray *O28 = new InnerArray[3];452 // expected-error@-1 {{no matching function for call to 'operator new[]'}}453 delete [] O28;454 // expected-error@-1 {{no suitable member 'operator delete[]' in 'MultiDimensionArrayTest3'}}455 // expected-note@#69 {{member 'operator delete[]' declared here}}456 }457 {458 using InnerArray = MultiDimensionArrayTest3[4];459 InnerArray *O29 = new InnerArray[3];460 // expected-error@-1 {{call to deleted function 'operator new[]'}}461 // expected-note@#68 {{candidate function [with N = 4] has been explicitly deleted}}462 delete [] O29;463 // expected-error@-1 {{attempt to use a deleted function}}464 // expected-note@#69 {{'operator delete[]<4U>' has been explicitly marked deleted here}}465 }466 {467 ClassScopedTemplatePackStruct *O30 = new ClassScopedTemplatePackStruct;468 delete O30;469 // expected-error@-1 {{no suitable member 'operator delete' in 'ClassScopedTemplatePackStruct'}}470 // expected-note@#70 {{member 'operator delete' declared here}}471 }472}473