For variable-length arrays, up to 2048 bytes are transmitted inline. If the array is larger, the data is transmitted out-of-line, and a pointer to a vm_allocated region is stored at the beginning of the array.
Previously, the generated code casted the field. Use a union instead. This fixes the gcc warning `dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]'. * global.c (OOLPostfix): New variable. * global.h (OOLPostfix): New declaration. * server.c (WriteServerCallArg): Avoid cast. (WriteDestroyArg): Likewise. (WritePackArgValue): Likewise. (WritePackArg): Likewise. * user.c (WriteExtractArgValue): Likewise. * utils.c (WriteFieldDeclPrim): Generate a union with an additional pointer field for variable-length arrays. --- global.c | 1 + global.h | 1 + server.c | 18 +++++++++--------- user.c | 9 +++++---- utils.c | 8 +++++++- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/global.c b/global.c index 0a938f2..5685186 100644 --- a/global.c +++ b/global.c @@ -48,6 +48,7 @@ const_string_t UserPrefix = ""; const_string_t ServerDemux = strNULL; const_string_t SubrPrefix = ""; const_string_t RoutinePrefix = ""; +const_string_t OOLPostfix = "P"; string_t yyinname; diff --git a/global.h b/global.h index ca4d865..8dbb6fd 100644 --- a/global.h +++ b/global.h @@ -53,6 +53,7 @@ extern const_string_t UserPrefix; extern const_string_t ServerDemux; extern const_string_t SubrPrefix; extern const_string_t RoutinePrefix; +extern const_string_t OOLPostfix; extern int yylineno; extern string_t yyinname; diff --git a/server.c b/server.c index 56ccfc7..15fc128 100644 --- a/server.c +++ b/server.c @@ -777,9 +777,9 @@ WriteServerCallArg(FILE *file, const argument_t *arg) arg->argTTName, arg->argLongForm ? ".msgtl_header" : ""); fprintf(file, "? %s ", InArgMsgField(arg)); - fprintf(file, ": *((%s **)%s)", - FetchServerType(arg->argType->itElement), - InArgMsgField(arg)); + fprintf(file, ": %s%s", + InArgMsgField(arg), + OOLPostfix); } else fprintf(file, "%s", InArgMsgField(arg)); @@ -816,8 +816,8 @@ WriteDestroyArg(FILE *file, const argument_t *arg) arg->argRequestPos, arg->argTTName, arg->argLongForm ? ".msgtl_header" : ""); - fprintf(file, "\t\t\t%smig_deallocate(* (vm_offset_t *) %s, ", - SubrPrefix, InArgMsgField(arg)); + fprintf(file, "\t\t\t%smig_deallocate((vm_offset_t) %s%s, ", + SubrPrefix, InArgMsgField(arg), OOLPostfix); if (multiplier > 1) fprintf(file, "%d * ", multiplier); fprintf(file, " %s);\n", InArgMsgField(count)); @@ -978,9 +978,9 @@ WritePackArgValue(FILE *file, const argument_t *arg) arg->argTTName, arg->argLongForm ? ".msgtl_header" : "", arg->argDealloc->argVarName); - fprintf(file, "\t\t*((%s **)OutP->%s) = %sP;\n", - FetchServerType(btype), + fprintf(file, "\t\tOutP->%s%s = %sP;\n", arg->argMsgField, + OOLPostfix, arg->argVarName); if (!arg->argRoutine->rtSimpleFixedReply) fprintf(file, "\t\tmsgh_simple = FALSE;\n"); @@ -1203,9 +1203,9 @@ WritePackArg(FILE *file, const argument_t *arg) arg->argTTName, arg->argLongForm ? ".msgtl_header" : "", arg->argDealloc->argVarName); - fprintf(file, "\t\t*((%s **)OutP->%s) = %sP;\n", - FetchServerType(it->itElement), + fprintf(file, "\t\tOutP->%s%s = %sP;\n", arg->argMsgField, + OOLPostfix, arg->argVarName); if (!arg->argRoutine->rtSimpleFixedReply) fprintf(file, "\t\tmsgh_simple = FALSE;\n"); diff --git a/user.c b/user.c index 5451a03..1f3ba3d 100644 --- a/user.c +++ b/user.c @@ -447,9 +447,9 @@ WritePackArgValue(FILE *file, const argument_t *arg) arg->argLongForm ? ".msgtl_header" : "", arg->argDealloc->argByReferenceUser ? "*" : "", arg->argDealloc->argVarName); - fprintf(file, "\t\t*((%s **)InP->%s) = %s%s;\n", - FetchUserType(btype), + fprintf(file, "\t\tInP->%s%s = %s%s;\n", arg->argMsgField, + OOLPostfix, ref, arg->argVarName); if (!arg->argRoutine->rtSimpleFixedRequest) fprintf(file, "\t\tmsgh_simple = FALSE;\n"); @@ -951,9 +951,10 @@ WriteExtractArgValue(FILE *file, const argument_t *arg) fprintf(file, "\tif (!OutP->%s%s.msgt_inline)\n", arg->argTTName, arg->argLongForm ? ".msgtl_header" : ""); - fprintf(file, "\t %s%s = *((%s **)OutP->%s);\n", + fprintf(file, "\t %s%s = OutP->%s%s;\n", ref, arg->argVarName, - FetchUserType(btype), arg->argMsgField); + arg->argMsgField, + OOLPostfix); fprintf(file, "\telse if (OutP->%s", count->argMsgField); if (btype->itNumber > 1) fprintf(file, " / %d", btype->itNumber); diff --git a/utils.c b/utils.c index 396e743..4c2a87b 100644 --- a/utils.c +++ b/utils.c @@ -239,10 +239,16 @@ WriteFieldDeclPrim(FILE *file, const argument_t *arg, * use the element type and maximum size specified. * Note arg->argCount->argMultiplier == btype->itNumber. */ - fprintf(file, "\t\t%s %s[%d];", + fprintf(file, "\t\tunion {\n"); + fprintf(file, "\t\t\t%s %s[%d];\n", (*tfunc)(btype), arg->argMsgField, it->itNumber/btype->itNumber); + fprintf(file, "\t\t\t%s *%s%s;\n", + (*tfunc)(btype), + arg->argMsgField, + OOLPostfix); + fprintf(file, "\t\t};"); } else fprintf(file, "\t\t%s %s;", (*tfunc)(it), arg->argMsgField); -- 2.1.4