Skip to content

Commit

Permalink
fix issue open64-compiler#26 for global char array
Browse files Browse the repository at this point in the history
1. the w2ll will crash if compile the code like that:
```
char a[10] = {"hello"};
int main(void)
{
   return sizeof(a);
}
```

Signed-off-by: Zhijin Zeng <[email protected]>
  • Loading branch information
zengdage committed Jan 3, 2024
1 parent d3527dd commit e79841b
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions osprey/ir_tools/whirl2llvm.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,7 @@ class WHIRL2llvm {
}
return GetLVPtrTy();
} else if (MTYPE_is_str(mtype)) {
FmtAssert(TY_kind(idx) == KIND_ARRAY, ("Wty2llvmty: constant string should be array"));
FmtAssert(TY_kind(idx) == KIND_ARRAY || (TY_kind(idx) == KIND_SCALAR), ("Wty2llvmty: constant string should be array"));
auto array_ty = Get_wty2lvty(TY_IDX_index(idx), idx);
return array_ty;
} else {
Expand Down Expand Up @@ -6408,30 +6408,48 @@ LVCONST *WHIRL2llvm::INITV2llvm(const INITV &initv, TY_IDX ty_idx) {
INITV &initv0 = Initv_Table[idx];
if (INITV_kind(initv0) != INITVKIND_PAD) {
elem = INITV2llvm(initv0, elem_ty);
if (elem != nullptr) vals.push_back(elem);
} else {
if ((initv0.Pad() % elem_size) == 0) {
elem = INITV2llvm4zero(initv0, elem_ty);
UINT64 padlen = initv0.Pad() / elem_size;
for(UINT64 i = 0; i < padlen; i++)
if (elem != nullptr) vals.push_back(elem);
} else {
FmtAssert(FALSE, ("INITV2llvm: PAD in array NYI"));
}
}
if (elem != nullptr) vals.push_back(elem);
idx = INITV_next(initv0);
}

std::vector<LVCONST *> new_vals;
LVTY *lv_elem_ty = lv_array_ty->getElementType();
for (std::size_t i = 0; i < vals.size(); i++) {
LVTY *val_ty = vals[i]->getType();
if (val_ty != lv_elem_ty) {
// handle different type
if (val_ty->isPointerTy() && lv_elem_ty->isPointerTy()) {
vals[i] = llvm::ConstantExpr::getBitCast(vals[i], lv_elem_ty);
new_vals.push_back(vals[i]);
} else if (val_ty->isArrayTy()) {
LVTY *val_elem_ty = val_ty->getArrayElementType();
if (val_elem_ty != lv_elem_ty) {
FmtAssert(FALSE, ("INITV2llvm: different type NYI"));
} else {
auto *val = llvm::dyn_cast<llvm::ConstantDataArray>(vals[i]);
for(int i = 0; i < val->getNumElements(); i++) {
LVCONST *it = val->getAggregateElement(i);
new_vals.push_back(it);
}
}
} else {
FmtAssert(FALSE, ("INITV2llvm: different type NYI"));
}
} else {
new_vals.push_back(vals[i]);
}
}
init = llvm::ConstantArray::get(lv_array_ty, vals);
init = llvm::ConstantArray::get(lv_array_ty, new_vals);
} else {
FmtAssert(ty_kind == KIND_STRUCT,
("INITV2llvm: current type is(%s %u), should be struct type", TY_name(ty_idx), ty_idx));
Expand Down

0 comments on commit e79841b

Please sign in to comment.