diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 4 |
6 files changed, 53 insertions, 2 deletions
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index d455fa3956d..19cab14cbf4 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -39,6 +39,13 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { SuitableAlign = 64; DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; + // From the glibc documentation, on GNU systems, malloc guarantees 16-byte + // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See + // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html + if (T.isGNUEnvironment()) + NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; + else + NewAlign = 0; // Infer from basic type alignment. HalfWidth = 16; HalfAlign = 16; FloatWidth = 32; @@ -320,6 +327,9 @@ void TargetInfo::adjust(const LangOptions &Opts) { FloatFormat = &llvm::APFloat::IEEEsingle; LongDoubleFormat = &llvm::APFloat::IEEEquad; } + + if (Opts.NewAlignOverride) + NewAlign = Opts.NewAlignOverride * getCharWidth(); } bool TargetInfo::initFeatureMap( diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 8e30ba1713b..f4710fa5493 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -1768,6 +1768,7 @@ public: LongLongWidth = HostTarget->getLongLongWidth(); LongLongAlign = HostTarget->getLongLongAlign(); MinGlobalAlign = HostTarget->getMinGlobalAlign(); + NewAlign = HostTarget->getNewAlign(); DefaultAlignForAttributeAligned = HostTarget->getDefaultAlignForAttributeAligned(); SizeType = HostTarget->getSizeType(); diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 543d95804f6..dfd4ce73cdd 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -5821,6 +5821,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_sized_deallocation, false)) CmdArgs.push_back("-fsized-deallocation"); + // -faligned-allocation is on by default in C++17 onwards and otherwise off + // by default. + if (Arg *A = Args.getLastArg(options::OPT_faligned_allocation, + options::OPT_fno_aligned_allocation, + options::OPT_faligned_new_EQ)) { + if (A->getOption().matches(options::OPT_fno_aligned_allocation)) + CmdArgs.push_back("-fno-aligned-allocation"); + else + CmdArgs.push_back("-faligned-allocation"); + } + + // The default new alignment can be specified using a dedicated option or via + // a GCC-compatible option that also turns on aligned allocation. + if (Arg *A = Args.getLastArg(options::OPT_fnew_alignment_EQ, + options::OPT_faligned_new_EQ)) + CmdArgs.push_back( + Args.MakeArgString(Twine("-fnew-alignment=") + A->getValue())); + // -fconstant-cfstrings is default, and may be subject to argument translation // on Darwin. if (!Args.hasFlag(options::OPT_fconstant_cfstrings, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6b2df349f8b..3406c324645 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1625,6 +1625,8 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.GNUKeywords = Opts.GNUMode; Opts.CXXOperatorNames = Opts.CPlusPlus; + Opts.AlignedAllocation = Opts.CPlusPlus1z; + Opts.DollarIdents = !Opts.AsmPreprocessor; } @@ -1937,6 +1939,17 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs); Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin); Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation); + Opts.AlignedAllocation = + Args.hasFlag(OPT_faligned_allocation, OPT_fno_aligned_allocation, + Opts.AlignedAllocation); + Opts.NewAlignOverride = + getLastArgIntValue(Args, OPT_fnew_alignment_EQ, 0, Diags); + if (Opts.NewAlignOverride && !llvm::isPowerOf2_32(Opts.NewAlignOverride)) { + Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ); + Diags.Report(diag::err_fe_invalid_alignment) << A->getAsString(Args) + << A->getValue(); + Opts.NewAlignOverride = 0; + } Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts); Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); Opts.AccessControl = !Args.hasArg(OPT_fno_access_control); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 7d15e4cd589..d7dccb1340b 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -392,6 +392,15 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, // C++ translation unit. else Builder.defineMacro("__cplusplus", "199711L"); + + // C++1z [cpp.predefined]p1: + // An integer literal of type std::size_t whose value is the alignment + // guaranteed by a call to operator new(std::size_t) + // + // We provide this in all language modes, since it seems generally useful. + Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__", + Twine(TI.getNewAlign() / TI.getCharWidth()) + + TI.getTypeConstantSuffix(TI.getSizeType())); } // In C11 these are environment macros. In C++11 they are only defined diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index fc55661febc..be1a597c07e 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2340,7 +2340,7 @@ void Sema::DeclareGlobalNewDelete() { nullptr); getStdBadAlloc()->setImplicit(true); } - if (!StdAlignValT && getLangOpts().CPlusPlus1z) { + if (!StdAlignValT && getLangOpts().AlignedAllocation) { // The "std::align_val_t" enum class has not yet been declared, so build it // implicitly. auto *AlignValT = EnumDecl::Create( @@ -2365,7 +2365,7 @@ void Sema::DeclareGlobalNewDelete() { // Create up to four variants of the function (sized/aligned). bool HasSizedVariant = getLangOpts().SizedDeallocation && (Kind == OO_Delete || Kind == OO_Array_Delete); - bool HasAlignedVariant = getLangOpts().CPlusPlus1z; + bool HasAlignedVariant = getLangOpts().AlignedAllocation; int NumSizeVariants = (HasSizedVariant ? 2 : 1); int NumAlignVariants = (HasAlignedVariant ? 2 : 1); |