summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-02-15 13:29:30 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-02-15 14:33:33 +0100
commit44753cf5a30b9324d2c4ac9021843674bde5cc3c (patch)
tree743687464c6e13941fdf2cb4691843c6864fe2db
parentf573a84faeb902f74b5f4b6fc1a67e7579012a9e (diff)
Do not generate code dereferencing type-punned pointers
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.
-rw-r--r--global.c1
-rw-r--r--global.h1
-rw-r--r--server.c18
-rw-r--r--user.c9
-rw-r--r--utils.c8
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);