aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
authorDaniel Paoliello <danpao@microsoft.com>2024-11-20 16:48:30 -0800
committerGitHub <noreply@github.com>2024-11-20 16:48:30 -0800
commitc86899d2d218e19f5a69d9f97f6ff43abc6c897c (patch)
treeb79edd0868a8e3d6c773b9857a2140952cbc81ff /clang/lib/CodeGen/CGDecl.cpp
parent905e831f8c8341e53e7e3adc57fd20b8e08eb999 (diff)
downloadllvm-c86899d2d218e19f5a69d9f97f6ff43abc6c897c.zip
llvm-c86899d2d218e19f5a69d9f97f6ff43abc6c897c.tar.gz
llvm-c86899d2d218e19f5a69d9f97f6ff43abc6c897c.tar.bz2
[clang] Add support for `__declspec(no_init_all)` (#116847)
In MSVC, when `/d1initall` is enabled, `__declspec(no_init_all)` can be applied to a type to suppress auto-initialization for all instances of that type or to a function to suppress auto-initialization for all locals within that function. This change does the same for Clang, except that it applies to the `-ftrivial-auto-var-init` flag instead. NOTE: I did not add a Clang-specific spelling for this but would be happy to make a followup PR if folks are interested in that.
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp22
1 files changed, 12 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 6e9d28c..47b21bc 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1899,13 +1899,16 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
const Address Loc =
locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;
+ auto hasNoTrivialAutoVarInitAttr = [&](const Decl *D) {
+ return D && D->hasAttr<NoTrivialAutoVarInitAttr>();
+ };
// Note: constexpr already initializes everything correctly.
LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
- (D.isConstexpr()
+ ((D.isConstexpr() || D.getAttr<UninitializedAttr>() ||
+ hasNoTrivialAutoVarInitAttr(type->getAsTagDecl()) ||
+ hasNoTrivialAutoVarInitAttr(CurFuncDecl))
? LangOptions::TrivialAutoVarInitKind::Uninitialized
- : (D.getAttr<UninitializedAttr>()
- ? LangOptions::TrivialAutoVarInitKind::Uninitialized
- : getContext().getLangOpts().getTrivialAutoVarInit()));
+ : getContext().getLangOpts().getTrivialAutoVarInit());
auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
if (trivialAutoVarInit ==
@@ -1944,13 +1947,13 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
replaceUndef(CGM, isPattern, constant));
}
- if (constant && D.getType()->isBitIntType() &&
- CGM.getTypes().typeRequiresSplitIntoByteArray(D.getType())) {
+ if (constant && type->isBitIntType() &&
+ CGM.getTypes().typeRequiresSplitIntoByteArray(type)) {
// Constants for long _BitInt types are split into individual bytes.
// Try to fold these back into an integer constant so it can be stored
// properly.
- llvm::Type *LoadType = CGM.getTypes().convertTypeForLoadStore(
- D.getType(), constant->getType());
+ llvm::Type *LoadType =
+ CGM.getTypes().convertTypeForLoadStore(type, constant->getType());
constant = llvm::ConstantFoldLoadFromConst(
constant, LoadType, llvm::APInt::getZero(32), CGM.getDataLayout());
}
@@ -1967,8 +1970,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
// It may be that the Init expression uses other uninitialized memory,
// but auto-var-init here would not help, as auto-init would get
// overwritten by Init.
- if (!D.getType()->isScalarType() || capturedByInit ||
- isAccessedBy(D, Init)) {
+ if (!type->isScalarType() || capturedByInit || isAccessedBy(D, Init)) {
initializeWhatIsTechnicallyUninitialized(Loc);
}
}