0

使用 分配堆栈空间时alloca(),是否需要清除内存或保证只包含零?

我想出了以下 LLVM 代码。尽管它可以编译,但它会导致核心转储。

在代码中,我试图实现对象的实例化,然后将其分配给“成员变量”。

%Main = type { %A*, i32 }
%A = type { %String, %String }
%String = type { i32, i8* }

define i32 @main() {
body:
  %Main = alloca %Main
  %0 = bitcast %Main* %Main to i8*
  call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 4, i32 4, i1 false)
  call void @test(%Main* %Main)
  ret i32 0
}

define void @test(%Main* %self) {
body:
  %0 = load %Main* %self
  %1 = extractvalue %Main %0, 0

  ; Overwrite the object A in Main by a new instance.
  %A = alloca %A

  ; Set to zero.
  %2 = bitcast %A* %A to i8*
  call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 4, i32 4, i1 false)

  ; ... execute the constructor of A ...

  ; Set the new instance in Main.
  %3 = load %A* %A
  store %A %3, %A* %1

  br label %return

return:                                           ; preds = %body
  ret void
}

; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0

declare i32 @printf(i8*, ...)
4

1 回答 1

1

不,使用创建的内存alloca不是 0 初始化的 - 由您来初始化它。

至于下一个问题,我强烈建议使用 Clang 将 C 代码片段编译为 LLVM IR,而不是手工制作后者。这是一个例子:

#include <memory.h>

struct Foo {
  int a, b;
};

void test() {
  Foo f;
  memset(&f, 0, sizeof(f));
}

编译(没有优化)这会产生:

%struct.Foo = type { i32, i32 }

; Function Attrs: nounwind uwtable
define void @_Z4testv() #0 {
entry:
  %f = alloca %struct.Foo, align 4
  %0 = bitcast %struct.Foo* %f to i8*
  call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 8, i32 4, i1 false)
  ret void
}

; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #1

attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
于 2014-02-04T01:41:23.627 回答