From 9e49a8d2f2465030b1502031a8201354fa04f11d Mon Sep 17 00:00:00 2001 From: Dan Hipschman Date: Fri, 11 Aug 2006 17:33:40 -0700 Subject: [PATCH] widl: Improve pointer null checking logic. --- tools/widl/client.c | 22 ++++++------------- tools/widl/proxy.c | 50 +++++++++++++++++++++++++++++++++++++++--- tools/widl/widltypes.h | 2 ++ 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/tools/widl/client.c b/tools/widl/client.c index 79a4283265b..267bbfe0f45 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -83,7 +83,6 @@ static void print_message_buffer_size(const func_t *func) static void check_pointers(const func_t *func) { var_t *var; - int pointer_type; if (!func->args) return; @@ -92,21 +91,14 @@ static void check_pointers(const func_t *func) while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { - pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; - - if (pointer_type == RPC_FC_RP) + if (is_pointer(var) && cant_be_null(var)) { - if (var->ptr_level >= 1) - { - print_client("if (!%s)\n", var->name); - print_client("{\n"); - indent++; - print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); - indent--; - print_client("}\n\n"); - } + print_client("if (!%s)\n", var->name); + print_client("{\n"); + indent++; + print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); + indent--; + print_client("}\n\n"); } var = PREV_LINK(var); diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 5750159f888..9bba5c5808d 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -181,20 +181,64 @@ static void clear_output_vars( var_t *arg ) } } -static int is_pointer(var_t *arg) +int is_pointer(var_t *arg) { if (arg->ptr_level) return 1; - if (arg->type->type == RPC_FC_FP ) + + switch (ref_type(arg->type)) + { + case RPC_FC_RP: + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + case RPC_FC_FP: + case RPC_FC_OP: + case RPC_FC_UP: return 1; + } + return 0; } +int cant_be_null(var_t *v) +{ + /* Search backwards for the most recent pointer attribute. */ + const attr_t *attrs = v->attrs; + const type_t *type = v->type; + + if (! attrs && type) + { + attrs = type->attrs; + type = type->ref; + } + + while (attrs) + { + int t = get_attrv(attrs, ATTR_POINTERTYPE); + + if (t == RPC_FC_FP || t == RPC_FC_OP || t == RPC_FC_UP) + return 0; + + if (t == RPC_FC_RP) + return 1; + + if (type) + { + attrs = type->attrs; + type = type->ref; + } + else + attrs = NULL; + } + + return 1; /* Default is RPC_FC_RP. */ +} + static void proxy_check_pointers( var_t *arg ) { END_OF_LIST(arg); while (arg) { - if (is_pointer(arg)) { + if (is_pointer(arg) && cant_be_null(arg)) { print_proxy( "if(!%s)\n", arg->name ); indent++; print_proxy( "RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 926a3e2154d..d39def398c9 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -299,5 +299,7 @@ struct _typelib_t { /* Get the actual type field for a type (chase down typedef references). */ unsigned char ref_type(const type_t *type); +int is_pointer(var_t *v); +int cant_be_null(var_t *v); #endif