From: Justin Seyster Date: Tue, 24 Aug 2010 20:04:51 +0000 (-0400) Subject: Detailed comments for "all signed" and "all unsigned" types. X-Git-Tag: release-v1.0~63 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=c211443383f365b91325201e4d8caa9cc8ba1583;p=interaspect.git Detailed comments for "all signed" and "all unsigned" types. --- diff --git a/src/aop-pc-fun-call.c b/src/aop-pc-fun-call.c index 04834a5..f87c587 100644 --- a/src/aop-pc-fun-call.c +++ b/src/aop-pc-fun-call.c @@ -73,20 +73,102 @@ get_function_name (gimple call_stmt) } } -/* Given a GIMPLE_CALL statement, return the type of the nth parameter - passed if there is an nth parameter or NULL if there is no nth - parameter. */ +/* Given a GIMPLE_CALL statement, return the FUNCTION_TYPE tree node + that represents the function prototype. */ static tree -get_param_type (gimple call_stmt, int n) +get_function_prototype (gimple call_stmt) { + tree func; + tree func_type_pointer; + tree func_type; + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + func = gimple_call_fn (call_stmt); + + /* Get the function type. The func tree should have a pointer type, + pointing to the actual function type. */ + func_type_pointer = TREE_TYPE (func); + aop_assert (TREE_CODE (func_type_pointer) == POINTER_TYPE); + func_type = TREE_TYPE (func_type_pointer); + aop_assert (TREE_CODE (func_type) == FUNCTION_TYPE); + + return func_type; +} + +/* Unfortunately, the type for a parameter is encoded in two different + places: the _formal_ parameter and the _actual_ parameter. These + two types should always be the same, but in some edge cases they + are not. In general, we give priority to the formal parameter type + when possible. + + The formal parameter type is the type that the function expects to + be passed as encoded in the function declaration. + + The actual parameter type is the type of the value passed at the + call site as encoded in the GIMPLE_CALL statement. + + In particular, when passing a literal integer constant to a + function that expects a uint8 or uint16, GCC sometimes incorrectly + allows the actual parameter to have a signed type (whereas the + formal parameter has an unsigned type). + + C vararg functions are not type safe, so there is no formal + parameter for any varargs argument. In the case of a vararg + argument, we must resort to the actual parameter type. */ +static tree +get_formal_param_type (gimple call_stmt, int n) +{ + int i; + tree func_type; + tree type_list_node; + tree formal_type = NULL; + + func_type = get_function_prototype (call_stmt); + type_list_node = TYPE_ARG_TYPES (func_type); + i = 0; + while (type_list_node != void_list_node && type_list_node != NULL) + { + if (i == n) + { + formal_type = TREE_VALUE (type_list_node); + break; + } + + type_list_node = TREE_CHAIN (type_list_node); + i++; + } + + return formal_type; +} + +/* See comment for get_formal_param_type(). */ +static tree +get_actual_param_type (gimple call_stmt, int n) +{ if (n < gimple_call_num_args (call_stmt)) return TREE_TYPE (gimple_call_arg (call_stmt, n)); else return NULL; } +/* Given a GIMPLE_CALL statement, return the type of the nth parameter + passed if there is an nth parameter or NULL if there is no nth + parameter. */ +static tree +get_param_type (gimple call_stmt, int n) +{ + tree param_type; + + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + + param_type = get_formal_param_type (call_stmt, n); + if (param_type == NULL) + param_type = get_actual_param_type (call_stmt, n); + + return param_type; +} + /* Return true if a call statement matches the pointcut's criteria for name, return type, and argument types. */ static bool