diff options
author | Daniel Paoliello <danpao@microsoft.com> | 2024-11-20 16:48:30 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-20 16:48:30 -0800 |
commit | c86899d2d218e19f5a69d9f97f6ff43abc6c897c (patch) | |
tree | b79edd0868a8e3d6c773b9857a2140952cbc81ff /clang/lib/CodeGen/CGDecl.cpp | |
parent | 905e831f8c8341e53e7e3adc57fd20b8e08eb999 (diff) | |
download | llvm-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.cpp | 22 |
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); } } |