|  | // Tests that the implicit declared allocation functions | 
|  | // are attached to the global module fragment. | 
|  | // RUN: rm -rf %t | 
|  | // RUN: mkdir -p %t | 
|  | // RUN: split-file %s %t | 
|  | // | 
|  | // RUN: %clang_cc1 -std=c++20 %t/foo.cppm -fsyntax-only -verify | 
|  | // RUN: %clang_cc1 -std=c++20 %t/foo2.cppm -fsyntax-only -verify | 
|  |  | 
|  | //--- foo.cppm | 
|  | export module foo; | 
|  | export void alloc_wrapper() { | 
|  | void *a = ::operator new(32); | 
|  | // [basic.stc.dynamic.general]Note2 | 
|  | //   The implicit declarations do not introduce the names std, std::size_t, | 
|  | //   std::align_val_t, ..., However, referring to std or std::size_t or | 
|  | //   std::align_val_t is ill-formed unless a standard library declaration | 
|  | //   ([cstddef.syn], [new.syn], [std.modules]) of that name precedes | 
|  | //   ([basic.lookup.general]) the use of that name. | 
|  | void *b = ::operator new((std::size_t)32); // expected-error {{use of undeclared identifier 'std'}} | 
|  | void *c = ::operator new((std::size_t)32, // expected-error {{use of undeclared identifier 'std'}} | 
|  | (std::align_val_t)64); // expected-error {{use of undeclared identifier 'std'}} | 
|  |  | 
|  | ::operator delete(a); | 
|  | ::operator delete(b, (std::size_t)32); // expected-error {{use of undeclared identifier 'std'}} | 
|  | ::operator delete(c, (std::size_t)32,  // expected-error {{use of undeclared identifier 'std'}} | 
|  | (std::align_val_t)64); // expected-error {{use of undeclared identifier 'std'}} | 
|  | } | 
|  |  | 
|  | //--- new | 
|  | namespace std { | 
|  | using size_t = decltype(sizeof(0)); | 
|  | enum class align_val_t : size_t {}; | 
|  | } | 
|  |  | 
|  | [[nodiscard]] void *operator new(std::size_t); | 
|  | [[nodiscard]] void *operator new(std::size_t, std::align_val_t); | 
|  | [[nodiscard]] void *operator new[](std::size_t); | 
|  | [[nodiscard]] void *operator new[](std::size_t, std::align_val_t); | 
|  | void operator delete(void*) noexcept; | 
|  | void operator delete(void*, std::size_t) noexcept; | 
|  | void operator delete(void*, std::align_val_t) noexcept; | 
|  | void operator delete(void*, std::size_t, std::align_val_t) noexcept; | 
|  | void operator delete[](void*, std::size_t, std::align_val_t) noexcept; | 
|  | void operator delete[](void*, std::size_t) noexcept; | 
|  | void operator delete[](void*, std::align_val_t) noexcept; | 
|  | void operator delete[](void*, std::size_t, std::align_val_t) noexcept; | 
|  |  | 
|  | //--- foo2.cppm | 
|  | // expected-no-diagnostics | 
|  | module; | 
|  | #include "new" | 
|  | export module foo2; | 
|  | export void alloc_wrapper() { | 
|  | void *a = ::operator new(32); | 
|  | void *b = ::operator new((std::size_t)32); | 
|  | void *c = ::operator new((std::size_t)32, | 
|  | (std::align_val_t)64); | 
|  |  | 
|  | ::operator delete(a); | 
|  | ::operator delete(b, (std::size_t)32); | 
|  | ::operator delete(c, (std::size_t)32, | 
|  | (std::align_val_t)64); | 
|  | } |