Skip to content

translate-c: emit alignCast when casting pointers #2316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 50 additions & 10 deletions src/translate_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,30 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
return expr;
}
if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) {
AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
ptr_cast_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
ptr_cast_node->data.fn_call_expr.params.append(expr);
return ptr_cast_node;
const clang::PointerType *dest_ptr_type = reinterpret_cast<const clang::PointerType*>(qual_type_canon(dest_type));
ZigClangQualType dest_pointee = bitcast(dest_ptr_type->getPointeeType());
unsigned int dest_pointee_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_pointee);

const clang::PointerType *src_pte = reinterpret_cast<const clang::PointerType*>(qual_type_canon(src_type));
ZigClangQualType src_pointee_qual_type = bitcast(src_pte->getPointeeType());
unsigned int src_pointee_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_pointee_qual_type);

if (src_pointee_align_bits < dest_pointee_align_bits) {
AstNode *align_of_node = trans_create_node_builtin_fn_call_str(c, "alignOf");
align_of_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
AstNode *align_cast_node = trans_create_node_builtin_fn_call_str(c, "alignCast");
align_cast_node->data.fn_call_expr.params.append(align_of_node);
align_cast_node->data.fn_call_expr.params.append(expr);
AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
ptr_cast_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
ptr_cast_node->data.fn_call_expr.params.append(align_cast_node);
return ptr_cast_node;
} else {
AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
ptr_cast_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
ptr_cast_node->data.fn_call_expr.params.append(expr);
return ptr_cast_node;
}
}
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
Expand Down Expand Up @@ -1843,12 +1863,32 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra
return target_node;
}

AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);

AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
node->data.fn_call_expr.params.append(dest_type_node);
node->data.fn_call_expr.params.append(target_node);
return maybe_suppress_result(c, result_used, node);
ZigClangQualType dest_qual_type = get_expr_qual_type(c, (const ZigClangExpr *)stmt);
const clang::PointerType *pointer_ty = reinterpret_cast<const clang::PointerType*>(qual_type_canon(dest_qual_type));
ZigClangQualType child_qt = bitcast(pointer_ty->getPointeeType());
unsigned int dest_pointee_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, child_qt);

ZigClangQualType src_qual_type = get_expr_qual_type(c, bitcast(stmt->getSubExpr()));
const clang::PointerType *src_pointer_ty = reinterpret_cast<const clang::PointerType*>(qual_type_canon(src_qual_type));
ZigClangQualType src_pointee_qual_type = bitcast(src_pointer_ty->getPointeeType());
unsigned int src_pointee_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_pointee_qual_type);

if (src_pointee_align_bits < dest_pointee_align_bits) {
AstNode *align_of_node = trans_create_node_builtin_fn_call_str(c, "alignOf");
align_of_node->data.fn_call_expr.params.append(get_expr_type(c, (const ZigClangExpr *)stmt));
AstNode *align_cast_node = trans_create_node_builtin_fn_call_str(c, "alignCast");
align_cast_node->data.fn_call_expr.params.append(align_of_node);
align_cast_node->data.fn_call_expr.params.append(target_node);
AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
ptr_cast_node->data.fn_call_expr.params.append(get_expr_type(c, (const ZigClangExpr *)stmt));
ptr_cast_node->data.fn_call_expr.params.append(align_cast_node);
return maybe_suppress_result(c, result_used, ptr_cast_node);
} else {
AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
ptr_cast_node->data.fn_call_expr.params.append(get_expr_type(c, (const ZigClangExpr *)stmt));
ptr_cast_node->data.fn_call_expr.params.append(target_node);
return maybe_suppress_result(c, result_used, ptr_cast_node);
}
}
case ZigClangCK_NullToPointer:
return trans_create_node_unsigned(c, 0);
Expand Down
4 changes: 4 additions & 0 deletions src/zig_clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,10 @@ ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext* sel
return bitcast(reinterpret_cast<const clang::ASTContext *>(self)->getPointerType(bitcast(T)));
}

unsigned ZigClangASTContext_getTypeAlignIfKnown(const ZigClangASTContext* self, ZigClangQualType T) {
return reinterpret_cast<const clang::ASTContext *>(self)->getTypeAlignIfKnown(bitcast(T));
}

ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *self) {
clang::ASTContext *result = &reinterpret_cast<clang::ASTUnit *>(self)->getASTContext();
return reinterpret_cast<ZigClangASTContext *>(result);
Expand Down
1 change: 1 addition & 0 deletions src/zig_clang.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const ZigClangSo
ZigClangSourceLocation SL);

ZIG_EXTERN_C ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext*, ZigClangQualType T);
ZIG_EXTERN_C unsigned ZigClangASTContext_getTypeAlignIfKnown(const ZigClangASTContext* self, ZigClangQualType T);

ZIG_EXTERN_C ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *);
ZIG_EXTERN_C ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *);
Expand Down