Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -773,6 +773,14 @@ return true; } + /// Returns true if the target doesn't support c++17's aligned new and + /// delete operators. For example, if the deployment target is old and the + /// operators are not available in the c++ standard library, this function + /// should return true. + virtual bool disableAlignedAllocation() const { + return false; + } + /// \brief Returns the target triple of the primary target. const llvm::Triple &getTriple() const { return Triple; Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -292,6 +292,29 @@ // and therefore doesn't guarantee 16-byte alignment. return 64; } + + bool disableAlignedAllocation() const override { + unsigned Major, Minor, Micro; + const llvm::Triple &T = this->getTriple(); + T.getOSVersion(Major, Minor, Micro); + + switch (T.getOS()) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: // Earlier than 10.13. + if (Major > 10) + return false; + if (Major < 10) + return true; + return Minor < 13; + case llvm::Triple::IOS: + case llvm::Triple::TvOS: // Earlier than 11.0. + return Major < 11; + case llvm::Triple::WatchOS: // Earlier than 4.0. + return Major < 4; + default: + llvm_unreachable("unexpected OS"); + } + } }; Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -2580,7 +2580,8 @@ // Create up to four variants of the function (sized/aligned). bool HasSizedVariant = getLangOpts().SizedDeallocation && (Kind == OO_Delete || Kind == OO_Array_Delete); - bool HasAlignedVariant = getLangOpts().AlignedAllocation; + bool HasAlignedVariant = getLangOpts().AlignedAllocation && + !Context.getTargetInfo().disableAlignedAllocation(); int NumSizeVariants = (HasSizedVariant ? 2 : 1); int NumAlignVariants = (HasAlignedVariant ? 2 : 1); Index: test/CodeGenCXX/cxx1z-aligned-allocation.cpp =================================================================== --- test/CodeGenCXX/cxx1z-aligned-allocation.cpp +++ test/CodeGenCXX/cxx1z-aligned-allocation.cpp @@ -3,10 +3,15 @@ // RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s // RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s // RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-apple-darwin10.13 -o - | FileCheck %s // Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z. // RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED // RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED +// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-apple-darwin10.12 -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED +// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple arm64-apple-ios10 -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED +// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple arm64-apple-tvos10 -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED +// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple thumbv7k-apple-watchos4 -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED // CHECK-UNALIGNED-NOT: _Znwm_St11align_val_t // CHECK-UNALIGNED-NOT: _Znam_St11align_val_t