From 2b3c93a3f3c56cb6a495f4b94d4ca09ac6f7c531 Mon Sep 17 00:00:00 2001 From: sandra Date: Thu, 21 May 2009 03:06:12 +0000 Subject: [PATCH] 2009-05-20 Sandra Loosemore gcc/ * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE, TARGET_INVALID_RETURN_TYPE, TARGET_PROMOTED_TYPE, and TARGET_CONVERT_TO_TYPE. * hooks.c (hook_tree_const_tree_null): Define. * hooks.h (hook_tree_const_tree_null): Declare. * target.h (struct gcc_target): Add invalid_parameter_type, invalid_return_type, promoted_type, and convert_to_type fields. * target-def.h: (TARGET_INVALID_PARAMETER_TYPE): Define. (TARGET_INVALID_RETURN_TYPE): Define. (TARGET_PROMOTED_TYPE): Define. (TARGET_CONVERT_TO_TYPE): Define. (TARGET_INITIALIZER): Update for new fields. * c-decl.c (grokdeclarator): Check targetm.invalid_return_type. (grokparms): Check targetm.invalid_parameter_type. * c-typeck.c (default_conversion): Check targetm.promoted_type. * c-convert.c (convert): Check targetm.convert_to_type. gcc/cp/ * typeck.c (default_conversion): Check targetm.promoted_type. * decl.c (grokdeclarator): Check targetm.invalid_return_type. (grokparms): Check targetm.invalid_parameter_type. * cvt.c (ocp_convert): Check targetm.convert_to_type. (build_expr_type_conversion): Check targetm.promoted_type. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147758 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 +++++++++++++++++++ gcc/c-convert.c | 3 +++ gcc/c-decl.c | 16 ++++++++++++++++ gcc/c-typeck.c | 5 +++++ gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/cvt.c | 12 ++++++++++++ gcc/cp/decl.c | 16 ++++++++++++++++ gcc/cp/typeck.c | 6 +++++- gcc/doc/tm.texi | 32 ++++++++++++++++++++++++++++++++ gcc/hooks.c | 7 +++++++ gcc/hooks.h | 2 ++ gcc/target-def.h | 8 ++++++++ gcc/target.h | 18 ++++++++++++++++++ 13 files changed, 151 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fcc619c4c88..b5afced95de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2009-05-20 Sandra Loosemore + + * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE, + TARGET_INVALID_RETURN_TYPE, TARGET_PROMOTED_TYPE, and + TARGET_CONVERT_TO_TYPE. + * hooks.c (hook_tree_const_tree_null): Define. + * hooks.h (hook_tree_const_tree_null): Declare. + * target.h (struct gcc_target): Add invalid_parameter_type, + invalid_return_type, promoted_type, and convert_to_type fields. + * target-def.h: (TARGET_INVALID_PARAMETER_TYPE): Define. + (TARGET_INVALID_RETURN_TYPE): Define. + (TARGET_PROMOTED_TYPE): Define. + (TARGET_CONVERT_TO_TYPE): Define. + (TARGET_INITIALIZER): Update for new fields. + * c-decl.c (grokdeclarator): Check targetm.invalid_return_type. + (grokparms): Check targetm.invalid_parameter_type. + * c-typeck.c (default_conversion): Check targetm.promoted_type. + * c-convert.c (convert): Check targetm.convert_to_type. + 2009-05-20 Adam Nemet * config/mips/mips.md (*extenddi_truncate, diff --git a/gcc/c-convert.c b/gcc/c-convert.c index 4fb680063ad..5349d7a77e8 100644 --- a/gcc/c-convert.c +++ b/gcc/c-convert.c @@ -86,6 +86,9 @@ convert (tree type, tree expr) if (type == TREE_TYPE (expr)) return expr; + ret = targetm.convert_to_type (type, expr); + if (ret) + return ret; STRIP_TYPE_NOPS (e); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 0c05b2438b9..2aa018faf58 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -4202,6 +4202,7 @@ grokdeclarator (const struct c_declarator *declarator, bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; + const char *errmsg; tree expr_dummy; bool expr_const_operands_dummy; @@ -4835,6 +4836,12 @@ grokdeclarator (const struct c_declarator *declarator, error ("type name declared as function returning an array"); type = integer_type_node; } + errmsg = targetm.invalid_return_type (type); + if (errmsg) + { + error (errmsg); + type = integer_type_node; + } /* Construct the function type and go to the next inner layer of declarator. */ @@ -5381,6 +5388,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) { tree parm, type, typelt; unsigned int parmno; + const char *errmsg; /* If there is a parameter of incomplete type in a definition, this is an error. In a declaration this is valid, and a @@ -5424,6 +5432,14 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) } } + errmsg = targetm.invalid_parameter_type (type); + if (errmsg) + { + error (errmsg); + TREE_VALUE (typelt) = error_mark_node; + TREE_TYPE (parm) = error_mark_node; + } + if (DECL_NAME (parm) && TREE_USED (parm)) warn_if_shadowing (parm); } diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index ee1853a0f73..1a1b009398c 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1766,6 +1766,7 @@ default_conversion (tree exp) tree orig_exp; tree type = TREE_TYPE (exp); enum tree_code code = TREE_CODE (type); + tree promoted_type; /* Functions and arrays have been converted during parsing. */ gcc_assert (code != FUNCTION_TYPE); @@ -1793,6 +1794,10 @@ default_conversion (tree exp) if (exp == error_mark_node) return error_mark_node; + promoted_type = targetm.promoted_type (type); + if (promoted_type) + return convert (promoted_type, exp); + if (INTEGRAL_TYPE_P (type)) return perform_integral_promotions (exp); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bd81af6b406..626df30bbcc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2009-05-20 Sandra Loosemore + + * typeck.c (default_conversion): Check targetm.promoted_type. + * decl.c (grokdeclarator): Check targetm.invalid_return_type. + (grokparms): Check targetm.invalid_parameter_type. + * cvt.c (ocp_convert): Check targetm.convert_to_type. + (build_expr_type_conversion): Check targetm.promoted_type. + 2009-05-19 Andrew Pinski * typeck.c (build_binary_op): Allow % on integal vectors. diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 3fdebd7f155..daf145f90ad 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -581,6 +581,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) tree e = expr; enum tree_code code = TREE_CODE (type); const char *invalid_conv_diag; + tree e1; if (error_operand_p (e) || type == error_mark_node) return error_mark_node; @@ -629,6 +630,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags) } } + e1 = targetm.convert_to_type (type, e); + if (e1) + return e1; + if (code == VOID_TYPE && (convtype & CONV_STATIC)) { e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error); @@ -1251,11 +1256,18 @@ build_expr_type_conversion (int desires, tree expr, bool complain) tree type_promotes_to (tree type) { + tree promoted_type; + if (type == error_mark_node) return error_mark_node; type = TYPE_MAIN_VARIANT (type); + /* Check for promotions of target-defined types first. */ + promoted_type = targetm.promoted_type (type); + if (promoted_type) + return promoted_type; + /* bool always promotes to int (not unsigned), even if it's the same size. */ if (type == boolean_type_node) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e9ff87bcec9..433d08905fb 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7606,6 +7606,7 @@ grokdeclarator (const cp_declarator *declarator, bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; bool set_no_warning = false; bool template_type_arg = false; + const char *errmsg; signed_p = declspecs->specs[(int)ds_signed]; unsigned_p = declspecs->specs[(int)ds_unsigned]; @@ -8285,6 +8286,12 @@ grokdeclarator (const cp_declarator *declarator, type_quals = TYPE_UNQUALIFIED; set_no_warning = true; } + errmsg = targetm.invalid_return_type (type); + if (errmsg) + { + error (errmsg); + type = integer_type_node; + } /* Error about some types functions can't return. */ @@ -9677,6 +9684,7 @@ grokparms (tree parmlist, tree *parms) tree type = NULL_TREE; tree init = TREE_PURPOSE (parm); tree decl = TREE_VALUE (parm); + const char *errmsg; if (parm == void_list_node) break; @@ -9710,6 +9718,14 @@ grokparms (tree parmlist, tree *parms) init = NULL_TREE; } + if (type != error_mark_node + && (errmsg = targetm.invalid_parameter_type (type))) + { + error (errmsg); + type = error_mark_node; + TREE_TYPE (decl) = error_mark_node; + } + if (type != error_mark_node) { if (deprecated_state != DEPRECATED_SUPPRESS) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a5f36188f77..87138bda95c 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1699,10 +1699,14 @@ decay_conversion (tree exp) tree default_conversion (tree exp) { + /* Check for target-specific promotions. */ + tree promoted_type = targetm.promoted_type (TREE_TYPE (exp)); + if (promoted_type) + exp = cp_convert (promoted_type, exp); /* Perform the integral promotions first so that bitfield expressions (which may promote to "int", even if the bitfield is declared "unsigned") are promoted correctly. */ - if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp))) + else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp))) exp = perform_integral_promotions (exp); /* Perform the other conversions. */ exp = decay_conversion (exp); diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7f8a5d6b4c6..67e1ca6d857 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10781,6 +10781,38 @@ and @var{type2}, or @code{NULL} if validity should be determined by the front end. @end deftypefn +@deftypefn {Target Hook} {const char *} TARGET_INVALID_PARAMETER_TYPE (tree @var{type}) +If defined, this macro returns the diagnostic message when it is +invalid for functions to include parameters of type @var{type}, +or @code{NULL} if validity should be determined by +the front end. This is currently used only by the C and C++ front ends. +@end deftypefn + +@deftypefn {Target Hook} {const char *} TARGET_INVALID_RETURN_TYPE (tree @var{type}) +If defined, this macro returns the diagnostic message when it is +invalid for functions to have return type @var{type}, +or @code{NULL} if validity should be determined by +the front end. This is currently used only by the C and C++ front ends. +@end deftypefn + +@deftypefn {Target Hook} {tree} TARGET_PROMOTED_TYPE (tree @var{type}) +If defined, this target hook returns the type to which values of +@var{type} should be promoted when they appear in expressions, +analogous to the integer promotions, or @code{NULL_TREE} to use the +front end's normal promotion rules. This hook is useful when there are +target-specific types with special promotion rules. +This is currently used only by the C and C++ front ends. +@end deftypefn + +@deftypefn {Target Hook} {tree} TARGET_CONVERT_TO_TYPE (tree @var{type}, tree @var{expr}) +If defined, this hook returns the result of converting @var{expr} to +@var{type}. It should return the converted expression, +or @code{NULL_TREE} to apply the front end's normal conversion rules. +This hook is useful when there are target-specific types with special +conversion rules. +This is currently used only by the C and C++ front ends. +@end deftypefn + @defmac TARGET_USE_JCR_SECTION This macro determines whether to use the JCR section to register Java classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both diff --git a/gcc/hooks.c b/gcc/hooks.c index 796d915e1c6..5af3cd1c411 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -328,3 +328,10 @@ hook_constcharptr_int_const_tree_const_tree_null (int i ATTRIBUTE_UNUSED, { return NULL; } + +/* Generic hook that takes a const_tree and returns NULL_TREE. */ +tree +hook_tree_const_tree_null (const_tree t ATTRIBUTE_UNUSED) +{ + return NULL; +} diff --git a/gcc/hooks.h b/gcc/hooks.h index 89e7f6dbf43..b057d5d6118 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -63,6 +63,8 @@ extern int hook_int_rtx_0 (rtx); extern int hook_int_rtx_bool_0 (rtx, bool); extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int); +extern tree hook_tree_const_tree_null (const_tree); + extern tree hook_tree_tree_tree_null (tree, tree); extern tree hook_tree_tree_tree_tree_null (tree, tree, tree); extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree); diff --git a/gcc/target-def.h b/gcc/target-def.h index 99c74e406f8..2de89a001d3 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -536,6 +536,10 @@ #define TARGET_INVALID_CONVERSION hook_constcharptr_const_tree_const_tree_null #define TARGET_INVALID_UNARY_OP hook_constcharptr_int_const_tree_null #define TARGET_INVALID_BINARY_OP hook_constcharptr_int_const_tree_const_tree_null +#define TARGET_INVALID_PARAMETER_TYPE hook_constcharptr_const_tree_null +#define TARGET_INVALID_RETURN_TYPE hook_constcharptr_const_tree_null +#define TARGET_PROMOTED_TYPE hook_tree_const_tree_null +#define TARGET_CONVERT_TO_TYPE hook_tree_tree_tree_null #define TARGET_FIXED_CONDITION_CODE_REGS hook_bool_uintp_uintp_false @@ -922,6 +926,10 @@ TARGET_INVALID_CONVERSION, \ TARGET_INVALID_UNARY_OP, \ TARGET_INVALID_BINARY_OP, \ + TARGET_INVALID_PARAMETER_TYPE, \ + TARGET_INVALID_RETURN_TYPE, \ + TARGET_PROMOTED_TYPE, \ + TARGET_CONVERT_TO_TYPE, \ TARGET_IRA_COVER_CLASSES, \ TARGET_SECONDARY_RELOAD, \ TARGET_EXPAND_TO_RTL_HOOK, \ diff --git a/gcc/target.h b/gcc/target.h index 43bdfc41ada..d851425a6a7 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -913,6 +913,24 @@ struct gcc_target is not permitted on TYPE1 and TYPE2, NULL otherwise. */ const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2); + /* Return the diagnostic message string if TYPE is not valid as a + function parameter type, NULL otherwise. */ + const char *(*invalid_parameter_type) (const_tree type); + + /* Return the diagnostic message string if TYPE is not valid as a + function return type, NULL otherwise. */ + const char *(*invalid_return_type) (const_tree type); + + /* If values of TYPE are promoted to some other type when used in + expressions (analogous to the integer promotions), return that type, + or NULL_TREE otherwise. */ + tree (*promoted_type) (const_tree type); + + /* Convert EXPR to TYPE, if target-specific types with special conversion + rules are involved. Return the converted expression, or NULL to apply + the standard conversion rules. */ + tree (*convert_to_type) (tree type, tree expr); + /* Return the array of IRA cover classes for the current target. */ const enum reg_class *(*ira_cover_classes) (void); -- 2.11.0