summaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 8fc68eb6fea..b822553ed87 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1765,6 +1765,28 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note)
return false;
}
+/* Like tree.c:get_narrower, but retain conversion from C++0x scoped enum
+ to integral type. */
+
+static tree
+c_common_get_narrower (tree op, int *unsignedp_ptr)
+{
+ op = get_narrower (op, unsignedp_ptr);
+
+ if (TREE_CODE (TREE_TYPE (op)) == ENUMERAL_TYPE
+ && ENUM_IS_SCOPED (TREE_TYPE (op)))
+ {
+ /* C++0x scoped enumerations don't implicitly convert to integral
+ type; if we stripped an explicit conversion to a larger type we
+ need to replace it so common_type will still work. */
+ tree type = (lang_hooks.types.type_for_size
+ (TYPE_PRECISION (TREE_TYPE (op)),
+ TYPE_UNSIGNED (TREE_TYPE (op))));
+ op = fold_convert (type, op);
+ }
+ return op;
+}
+
/* This is a helper function of build_binary_op.
For certain operations if both args were extended from the same
@@ -1777,7 +1799,8 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note)
Eg, (short)-1 | (unsigned short)-1 is (int)-1
but calculated in (unsigned short) it would be (unsigned short)-1.
*/
-tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
+tree
+shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
{
int unsigned0, unsigned1;
tree arg0, arg1;
@@ -1803,8 +1826,8 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
op0 = convert (result_type, op0);
op1 = convert (result_type, op1);
- arg0 = get_narrower (op0, &unsigned0);
- arg1 = get_narrower (op1, &unsigned1);
+ arg0 = c_common_get_narrower (op0, &unsigned0);
+ arg1 = c_common_get_narrower (op1, &unsigned1);
/* UNS is 1 if the operation to be done is an unsigned one. */
uns = TYPE_UNSIGNED (result_type);
@@ -3301,8 +3324,8 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
/* Throw away any conversions to wider types
already present in the operands. */
- primop0 = get_narrower (op0, &unsignedp0);
- primop1 = get_narrower (op1, &unsignedp1);
+ primop0 = c_common_get_narrower (op0, &unsignedp0);
+ primop1 = c_common_get_narrower (op1, &unsignedp1);
/* If primopN is first sign-extended from primopN's precision to opN's
precision, then zero-extended from opN's precision to
@@ -7479,20 +7502,23 @@ check_function_nonnull (tree attrs, int nargs, tree *argarray)
array ARGARRAY. */
static void
-check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist)
+check_function_sentinel (const_tree fntype, int nargs, tree *argarray)
{
- tree attr = lookup_attribute ("sentinel", attrs);
+ tree attr = lookup_attribute ("sentinel", TYPE_ATTRIBUTES (fntype));
if (attr)
{
int len = 0;
int pos = 0;
tree sentinel;
+ function_args_iterator iter;
+ tree t;
/* Skip over the named arguments. */
- while (typelist && len < nargs)
+ FOREACH_FUNCTION_ARGS (fntype, t, iter)
{
- typelist = TREE_CHAIN (typelist);
+ if (len == nargs)
+ break;
len++;
}
@@ -7937,26 +7963,24 @@ handle_no_split_stack_attribute (tree *node, tree name,
return NULL_TREE;
}
-/* Check for valid arguments being passed to a function.
- ATTRS is a list of attributes. There are NARGS arguments in the array
- ARGARRAY. TYPELIST is the list of argument types for the function.
- */
+/* Check for valid arguments being passed to a function with FNTYPE.
+ There are NARGS arguments in the array ARGARRAY. */
void
-check_function_arguments (tree attrs, int nargs, tree *argarray, tree typelist)
+check_function_arguments (const_tree fntype, int nargs, tree *argarray)
{
/* Check for null being passed in a pointer argument that must be
non-null. We also need to do this if format checking is enabled. */
if (warn_nonnull)
- check_function_nonnull (attrs, nargs, argarray);
+ check_function_nonnull (TYPE_ATTRIBUTES (fntype), nargs, argarray);
/* Check for errors in format strings. */
if (warn_format || warn_missing_format_attribute)
- check_function_format (attrs, nargs, argarray);
+ check_function_format (TYPE_ATTRIBUTES (fntype), nargs, argarray);
if (warn_format)
- check_function_sentinel (attrs, nargs, argarray, typelist);
+ check_function_sentinel (fntype, nargs, argarray);
}
/* Generic argument checking recursion routine. PARAM is the argument to
@@ -9370,16 +9394,16 @@ warn_for_sign_compare (location_t location,
have all bits set that are set in the ~ operand when it is
extended. */
- op0 = get_narrower (op0, &unsignedp0);
- op1 = get_narrower (op1, &unsignedp1);
+ op0 = c_common_get_narrower (op0, &unsignedp0);
+ op1 = c_common_get_narrower (op1, &unsignedp1);
if ((TREE_CODE (op0) == BIT_NOT_EXPR)
^ (TREE_CODE (op1) == BIT_NOT_EXPR))
{
if (TREE_CODE (op0) == BIT_NOT_EXPR)
- op0 = get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
+ op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
if (TREE_CODE (op1) == BIT_NOT_EXPR)
- op1 = get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
+ op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
if (host_integerp (op0, 0) || host_integerp (op1, 0))
{