summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/TargetInfo.cpp10
-rw-r--r--clang/lib/Basic/Targets.cpp1
-rw-r--r--clang/lib/Driver/Tools.cpp18
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp13
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp9
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp4
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);
OpenPOWER on IntegriCloud