From 157913982257a665acccd2bd7590385e318b8c4e Mon Sep 17 00:00:00 2001 From: raulgrell Date: Sat, 20 Apr 2019 14:37:49 +0100 Subject: [PATCH 1/4] translate-c: emit alignCast when casting pointers --- src/translate_c.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 43783cf1c0f4..9dbb914f45e3 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -709,9 +709,14 @@ 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 *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(expr); + ptr_cast_node->data.fn_call_expr.params.append(align_cast_node); return ptr_cast_node; } // TODO: maybe widen to increase size @@ -4740,9 +4745,16 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok inner_if_then->data.fn_call_expr.params.append(node_to_cast); AstNode *inner_if_else = trans_create_node_cast(c, inner_node, node_to_cast); AstNode *inner_if = trans_create_node_if(c, inner_if_cond, inner_if_then, inner_if_else); + + AstNode *align_of_node = trans_create_node_builtin_fn_call_str(c, "alignOf"); + align_of_node->data.fn_call_expr.params.append(inner_node); + 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(node_to_cast); AstNode *outer_if_then = trans_create_node_builtin_fn_call_str(c, "ptrCast"); outer_if_then->data.fn_call_expr.params.append(inner_node); - outer_if_then->data.fn_call_expr.params.append(node_to_cast); + outer_if_then->data.fn_call_expr.params.append(align_cast_node); + return trans_create_node_if(c, outer_if_cond, outer_if_then, inner_if); } case CTokIdDot: From 2e4dfbf47421e551c9f49da3fd96e7983384a961 Mon Sep 17 00:00:00 2001 From: raulgrell Date: Sat, 20 Apr 2019 17:16:42 +0100 Subject: [PATCH 2/4] tranlsate-c: only align-cast when destination alignment is greater than source alignment --- src/translate_c.cpp | 36 +++++++++++++++++++----------------- src/zig_clang.cpp | 4 ++++ src/zig_clang.h | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 9dbb914f45e3..3a55e2da85a8 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -709,15 +709,24 @@ 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 *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; + unsigned int src_align = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_type); + unsigned int dest_align = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_type); + if (src_align < dest_align) { + 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 @@ -4745,16 +4754,9 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok inner_if_then->data.fn_call_expr.params.append(node_to_cast); AstNode *inner_if_else = trans_create_node_cast(c, inner_node, node_to_cast); AstNode *inner_if = trans_create_node_if(c, inner_if_cond, inner_if_then, inner_if_else); - - AstNode *align_of_node = trans_create_node_builtin_fn_call_str(c, "alignOf"); - align_of_node->data.fn_call_expr.params.append(inner_node); - 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(node_to_cast); AstNode *outer_if_then = trans_create_node_builtin_fn_call_str(c, "ptrCast"); outer_if_then->data.fn_call_expr.params.append(inner_node); - outer_if_then->data.fn_call_expr.params.append(align_cast_node); - + outer_if_then->data.fn_call_expr.params.append(node_to_cast); return trans_create_node_if(c, outer_if_cond, outer_if_then, inner_if); } case CTokIdDot: diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 6142c808ade7..a802ba54e780 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -870,6 +870,10 @@ ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext* sel return bitcast(reinterpret_cast(self)->getPointerType(bitcast(T))); } +unsigned ZigClangASTContext_getTypeAlignIfKnown(const ZigClangASTContext* self, ZigClangQualType T) { + return reinterpret_cast(self)->getTypeAlignIfKnown(bitcast(T)); +} + ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *self) { clang::ASTContext *result = &reinterpret_cast(self)->getASTContext(); return reinterpret_cast(result); diff --git a/src/zig_clang.h b/src/zig_clang.h index 78d6e1589d4c..dc91a8b37dd6 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -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 *); From df9eb7a4fae6407e99b2b7374d6c11fcabe3f332 Mon Sep 17 00:00:00 2001 From: raulgrell Date: Sat, 20 Apr 2019 19:35:01 +0100 Subject: [PATCH 3/4] also handle align in implicit casts --- src/translate_c.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 3a55e2da85a8..f6b762f08ad3 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -709,9 +709,9 @@ 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)) { - unsigned int src_align = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_type); - unsigned int dest_align = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_type); - if (src_align < dest_align) { + unsigned int src_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_type); + unsigned int dest_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_type); + if (src_align_bits < dest_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"); @@ -1857,12 +1857,28 @@ 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); + unsigned int dest_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_qual_type); + + ZigClangQualType src_qual_type = get_expr_qual_type(c, bitcast(stmt->getSubExpr())); + unsigned int src_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_qual_type); + + if (src_align_bits < dest_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); From 28d01964295dd23fe44c402c2c02ac9969c5fe99 Mon Sep 17 00:00:00 2001 From: raulgrell Date: Sun, 21 Apr 2019 00:38:40 +0100 Subject: [PATCH 4/4] look at pointee size instead of pointer size --- src/translate_c.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index f6b762f08ad3..ec80330aa8a8 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -709,9 +709,15 @@ 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)) { - unsigned int src_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_type); - unsigned int dest_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_type); - if (src_align_bits < dest_align_bits) { + const clang::PointerType *dest_ptr_type = reinterpret_cast(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(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"); @@ -1858,12 +1864,16 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra } ZigClangQualType dest_qual_type = get_expr_qual_type(c, (const ZigClangExpr *)stmt); - unsigned int dest_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, dest_qual_type); + const clang::PointerType *pointer_ty = reinterpret_cast(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())); - unsigned int src_align_bits = ZigClangASTContext_getTypeAlignIfKnown(c->ctx, src_qual_type); + const clang::PointerType *src_pointer_ty = reinterpret_cast(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_align_bits < dest_align_bits) { + 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");