[clang] [clang][CodeGen] Zero init unspecified fields in initializers in C (PR #97121)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 30 15:52:38 PDT 2024


yabinc wrote:




> It probably makes sense to add a helper like the following to CodeGenModule or something like that:
> 
> ```
> bool shouldZeroInitPadding() { 
>   // Comment explaining reasoning for this rule
>   return !CGM.getLangOpts().CPlusPlus;
> }
> ```
> 
> So we don't have `// See comment in getPadding().` all over the place.

Done.

> 
> Is there any relevant code using EmitNullConstant()? As far as I can tell, this patch doesn't zero-fill implicit padding in null constants (like in `struct { int x; long y; }`.

I ran all tests in clang/tests and found two places using it:
1. One is used in CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty), when !CGM.getTypes().isZeroInitializable(Ty). This seems to only happen in C++ code (when a class contains a pointer pointing
  to data member).
2. Another is used in CodeGenModule::getOrCreateStaticVarDecl(), which is further called in three places:
  a. CodeGenFunction::AddInitializerToStaticVarDecl(): it later calls ConstantEmitter::tryEmitForInitializer() if an initializer is used.
  b. CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) in CGExpr.cpp 
  c. ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) in CGExprConstant.cpp
  Not sure what b and c are doing.
When running tests for non c++ code, I only found the 2.a path, used in CodeGenOpenCL/amdgpu-nullptr.cl.
So I didn't find any C code using EmitNullConstant(), that results in uninitialized fields with initializers.

For the implementation of EmitNullConstant(), it returns ConstantStruct::get(llvm::ConstantStruct::get(structure, elements). In ConstantStruct::get(), if all elements are zero, then it returns ConstantAggregateZero::get(ST).
>From  https://llvm.org/docs/LangRef.html:
`The string ‘zeroinitializer’ can be used to zero initialize a value to zero of any type, including scalar and [aggregate](https://llvm.org/docs/LangRef.html#t-aggregate) types. This is often used to avoid having to print large zero initializers (e.g. for large arrays) and is always exactly equivalent to using explicit zero initializers.`

>From the above words, I feel using `%struct.S2 zeroinitializer` may not guarantee the padding in the struct are zero initialized. But if it is used for a static variable created by CodeGenModule::getOrCreateStaticVarDecl(), it's
as good as a static/global variable without initializer.





https://github.com/llvm/llvm-project/pull/97121


More information about the cfe-commits mailing list