diff --git a/clang/include/clang/Basic/AlignedAllocation.h b/clang/include/clang/Basic/AlignedAllocation.h --- a/clang/include/clang/Basic/AlignedAllocation.h +++ b/clang/include/clang/Basic/AlignedAllocation.h @@ -33,6 +33,8 @@ return llvm::VersionTuple(11U); case llvm::Triple::WatchOS: // Earliest supporting version is 4.0.0. return llvm::VersionTuple(4U); + case llvm::Triple::ZOS: + return llvm::VersionTuple(); // All z/OS versions have no support. } llvm_unreachable("Unexpected OS"); diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -825,6 +825,7 @@ .Case("macos_app_extension", "macOSApplicationExtension") .Case("tvos_app_extension", "tvOSApplicationExtension") .Case("watchos_app_extension", "watchOSApplicationExtension") + .Case("zos", "z/OS") .Default(Platform); } static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7219,8 +7219,8 @@ "guarantees %2 bytes">, InGroup, DefaultIgnore; def err_aligned_allocation_unavailable : Error< - "aligned %select{allocation|deallocation}0 function of type '%1' is only " - "available on %2 %3 or newer">; + "aligned %select{allocation|deallocation}0 function of type '%1' is " + "%select{only|not}4 available on %2%select{ %3 or newer|}4">; def note_silence_aligned_allocation_unavailable : Note< "if you supply your own aligned allocation functions, use " "-faligned-allocation to silence this diagnostic">; diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -770,6 +770,8 @@ // type is not declared as a typedef in system headers. Builder.defineMacro("__wchar_t"); } + + this->PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); } public: diff --git a/clang/lib/Driver/ToolChains/ZOS.h b/clang/lib/Driver/ToolChains/ZOS.h --- a/clang/lib/Driver/ToolChains/ZOS.h +++ b/clang/lib/Driver/ToolChains/ZOS.h @@ -27,6 +27,10 @@ bool isPICDefaultForced() const override { return false; } bool IsIntegratedAssemblerDefault() const override { return true; } + + void addClangTargetOptions( + const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadingKind) const override; }; } // end namespace toolchains diff --git a/clang/lib/Driver/ToolChains/ZOS.cpp b/clang/lib/Driver/ToolChains/ZOS.cpp --- a/clang/lib/Driver/ToolChains/ZOS.cpp +++ b/clang/lib/Driver/ToolChains/ZOS.cpp @@ -21,3 +21,13 @@ : ToolChain(D, Triple, Args) {} ZOS::~ZOS() {} + +void ZOS::addClangTargetOptions(const ArgList &DriverArgs, + ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadKind) const { + // Pass "-faligned-alloc-unavailable" only when the user hasn't manually + // enabled or disabled aligned allocations. + if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, + options::OPT_fno_aligned_allocation)) + CC1Args.push_back("-faligned-alloc-unavailable"); +} diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1843,12 +1843,13 @@ const llvm::Triple &T = getASTContext().getTargetInfo().getTriple(); StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling( getASTContext().getTargetInfo().getPlatformName()); + VersionTuple OSVersion = alignedAllocMinVersion(T.getOS()); OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator(); bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete; Diag(Loc, diag::err_aligned_allocation_unavailable) << IsDelete << FD.getType().getAsString() << OSName - << alignedAllocMinVersion(T.getOS()).getAsString(); + << OSVersion.getAsString() << OSVersion.empty(); Diag(Loc, diag::note_silence_aligned_allocation_unavailable); } } diff --git a/clang/test/Driver/unavailable_aligned_allocation.cpp b/clang/test/Driver/unavailable_aligned_allocation.cpp --- a/clang/test/Driver/unavailable_aligned_allocation.cpp +++ b/clang/test/Driver/unavailable_aligned_allocation.cpp @@ -22,6 +22,9 @@ // RUN: -c -### %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=UNAVAILABLE // +// RUN: %clang -target s390x-none-zos -c -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=UNAVAILABLE + // UNAVAILABLE: "-faligned-alloc-unavailable" // RUN: %clang -target x86_64-apple-macosx10.14 -c -### %s 2>&1 \ @@ -59,5 +62,11 @@ // // RUN: %clang -target x86_64-apple-macosx10.13 -fno-aligned-allocation -c -### %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=AVAILABLE +// +// RUN: %clang -target s390x-none-zos -faligned-allocation -c -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=AVAILABLE +// +// RUN: %clang -target s390x-none-zos -fno-aligned-allocation -c -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=AVAILABLE // AVAILABLE-NOT: "-faligned-alloc-unavailable" diff --git a/clang/test/Lexer/aligned-allocation.cpp b/clang/test/Lexer/aligned-allocation.cpp --- a/clang/test/Lexer/aligned-allocation.cpp +++ b/clang/test/Lexer/aligned-allocation.cpp @@ -6,10 +6,19 @@ // // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -std=c++17 -verify %s \ // RUN: -faligned-allocation -faligned-alloc-unavailable +// +// RUN: %clang_cc1 -triple s390x-none-zos -fexceptions -std=c++17 -verify %s \ +// RUN: -DEXPECT_DEFINED +// +// RUN: %clang_cc1 -triple s390x-none-zos -fexceptions -std=c++17 -verify %s \ +// RUN: -faligned-alloc-unavailable +// +// RUN: %clang_cc1 -triple s390x-none-zos -fexceptions -std=c++17 -verify %s \ +// RUN: -faligned-allocation -faligned-alloc-unavailable // Test that __cpp_aligned_new is not defined when CC1 is passed -// -faligned-alloc-unavailable by the Darwin driver, even when aligned -// allocation is actually enabled. +// -faligned-alloc-unavailable by the Darwin and the z/OS driver, even when +// aligned allocation is actually enabled. // expected-no-diagnostics #ifdef EXPECT_DEFINED diff --git a/clang/test/SemaCXX/unavailable_aligned_allocation.cpp b/clang/test/SemaCXX/unavailable_aligned_allocation.cpp --- a/clang/test/SemaCXX/unavailable_aligned_allocation.cpp +++ b/clang/test/SemaCXX/unavailable_aligned_allocation.cpp @@ -1,12 +1,15 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DMACOS %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify -DMACOS %s // RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DIOS %s // RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s // RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DTVOS %s // RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s // RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DWATCHOS %s // RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s +// RUN: %clang_cc1 -triple s390x-none-zos -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DZOS %s +// RUN: %clang_cc1 -triple s390x-none-zos -fexceptions -std=c++1z -verify -DNO_ERRORS %s +// RUN: %clang_cc1 -triple s390x-none-zos -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify -DZOS %s namespace std { typedef decltype(sizeof(0)) size_t; @@ -62,40 +65,40 @@ #ifdef NO_ERRORS // expected-no-diagnostics #else -// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-17 {{if you supply your own aligned allocation functions}} -// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-19 {{if you supply your own aligned allocation functions}} -// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-21 {{if you supply your own aligned allocation functions}} -// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-23 {{if you supply your own aligned allocation functions}} -// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-25 {{if you supply your own aligned allocation functions}} -// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} +// expected-error-re@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is {{only|not}} available on}} // expected-note@-27 {{if you supply your own aligned allocation functions}} -// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} +// expected-error-re@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is {{only|not}} available on}} // expected-note@-29 {{if you supply your own aligned allocation functions}} -// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-30 {{if you supply your own aligned allocation functions}} -// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-32 {{if you supply your own aligned allocation functions}} -// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-34 {{if you supply your own aligned allocation functions}} -// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-36 {{if you supply your own aligned allocation functions}} -// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-38 {{if you supply your own aligned allocation functions}} -// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} +// expected-error-re@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is {{only|not}} available on}} // expected-note@-40 {{if you supply your own aligned allocation functions}} -// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}} +// expected-error-re@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is {{only|not}} available on}} // expected-note@-42 {{if you supply your own aligned allocation functions}} #endif @@ -116,12 +119,15 @@ #elif defined(WATCHOS) // expected-error@-13 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on watchOS 4 or newer}}} // expected-error@-14 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}} -#else +#elif defined(MACOS) // expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on macOS 10.14 or newer}}} // expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.14 or newer}}} +#elif defined(ZOS) +// expected-error@-19 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is not available on z/OS}}} +// expected-error@-20 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is not available on z/OS}}} #endif -// expected-note@-20 2 {{if you supply your own aligned allocation functions}} +// expected-note@-23 2 {{if you supply your own aligned allocation functions}} #endif // Test that diagnostics are produced when an unavailable aligned deallocation @@ -145,9 +151,12 @@ #elif defined(WATCHOS) // expected-error@-12 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}} // expected-note@-13 {{if you supply your own aligned allocation functions}} -#else +#elif defined(MACOS) // expected-error@-15 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.14 or newer}}} // expected-note@-16 {{if you supply your own aligned allocation functions}} +#elif defined(ZOS) +// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is not available on z/OS}}} +// expected-note@-19 {{if you supply your own aligned allocation functions}} #endif #endif @@ -172,22 +181,22 @@ #ifdef NO_ERRORS // expected-no-diagnostics #else -// expected-error@-11 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-11 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-12 {{if you supply your own aligned allocation functions}} -// expected-error@-13 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-13 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-14 {{if you supply your own aligned allocation functions}} -// expected-error@-15 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-15 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-16 {{if you supply your own aligned allocation functions}} -// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-18 {{if you supply your own aligned allocation functions}} -// expected-error@-19 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}} +// expected-error-re@-19 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is {{only|not}} available on}} // expected-note@-20 {{if you supply your own aligned allocation functions}} -// expected-error@-21 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}} +// expected-error-re@-21 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-22 {{if you supply your own aligned allocation functions}} #endif