X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-common.c;h=1e2f6c5c0bb7c4cf814b89e7a18abea0234c8622;hb=faaf6e4c6d466e9f63f0f4b92a037d34d437106d;hp=c74a1a80d9ad41b3c13d545865b956258589ad5c;hpb=207bece5fd7c2724f659faef35a593e392b1877c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-common.c b/gcc/c-common.c index c74a1a80d9a..1e2f6c5c0bb 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -37,6 +37,10 @@ Boston, MA 02111-1307, USA. */ extern struct obstack permanent_obstack; +/* Nonzero means the expression being parsed will never be evaluated. + This is a count, since unevaluated expressions can nest. */ +int skip_evaluation; + enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION, A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED, A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS}; @@ -284,7 +288,7 @@ init_attributes () /* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES and install them in NODE, which is either a DECL (including a TYPE_DECL) or a TYPE. PREFIX_ATTRIBUTES can appear after the declaration specifiers - and declaration modifiers but before the declaration proper. */ + and declaration modifiers but before the declaration proper. */ void decl_attributes (node, attributes, prefix_attributes) @@ -498,7 +502,8 @@ decl_attributes (node, attributes, prefix_attributes) && TREE_CODE (TREE_VALUE (args)) == STRING_CST) { if (TREE_CODE (decl) == VAR_DECL - && current_function_decl != NULL_TREE) + && current_function_decl != NULL_TREE + && ! TREE_STATIC (decl)) error_with_decl (decl, "section attribute cannot be specified for local variables"); /* The decl may have already been given a section attribute from @@ -645,7 +650,7 @@ decl_attributes (node, attributes, prefix_attributes) if (first_arg_num != 0) { /* Verify that first_arg_num points to the last arg, - the ... */ + the ... */ while (argument) arg_num++, argument = TREE_CHAIN (argument); if (arg_num != first_arg_num) @@ -732,7 +737,7 @@ decl_attributes (node, attributes, prefix_attributes) case A_ALIAS: if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) - || TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)) + || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))) error_with_decl (decl, "`%s' defined both normally and as an alias"); else if (decl_function_context (decl) == 0) @@ -751,6 +756,76 @@ decl_attributes (node, attributes, prefix_attributes) } } } + +/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two + lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE). + + The head of the declspec list is stored in DECLSPECS. + The head of the attribute list is stored in PREFIX_ATTRIBUTES. + + Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of + the list elements. We drop the containing TREE_LIST nodes and link the + resulting attributes together the way decl_attributes expects them. */ + +void +split_specs_attrs (specs_attrs, declspecs, prefix_attributes) + tree specs_attrs; + tree *declspecs, *prefix_attributes; +{ + tree t, s, a, next, specs, attrs; + + /* This can happen in c++ (eg: decl: typespec initdecls ';'). */ + if (specs_attrs != NULL_TREE + && TREE_CODE (specs_attrs) != TREE_LIST) + { + *declspecs = specs_attrs; + *prefix_attributes = NULL_TREE; + return; + } + + /* Remember to keep the lists in the same order, element-wise. */ + + specs = s = NULL_TREE; + attrs = a = NULL_TREE; + for (t = specs_attrs; t; t = next) + { + next = TREE_CHAIN (t); + /* Declspecs have a non-NULL TREE_VALUE. */ + if (TREE_VALUE (t) != NULL_TREE) + { + if (specs == NULL_TREE) + specs = s = t; + else + { + TREE_CHAIN (s) = t; + s = t; + } + } + else + { + if (attrs == NULL_TREE) + attrs = a = TREE_PURPOSE (t); + else + { + TREE_CHAIN (a) = TREE_PURPOSE (t); + a = TREE_PURPOSE (t); + } + /* More attrs can be linked here, move A to the end. */ + while (TREE_CHAIN (a) != NULL_TREE) + a = TREE_CHAIN (a); + } + } + + /* Terminate the lists. */ + if (s != NULL_TREE) + TREE_CHAIN (s) = NULL_TREE; + if (a != NULL_TREE) + TREE_CHAIN (a) = NULL_TREE; + + /* All done. */ + *declspecs = specs; + *prefix_attributes = attrs; +} /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against a parameter list. */ @@ -922,7 +997,7 @@ record_function_format (name, assembler_name, is_scan, the number of the argument which is the format control string (starting from 1). */ -void +static void record_international_format (name, assembler_name, format_num) tree name; tree assembler_name; @@ -1366,7 +1441,7 @@ check_format_info (info, params) || format_char == 'x' || format_char == 'x')) { sprintf (message, - "precision and `0' flag not both allowed with `%c' format", + "`0' flag ignored with precision specifier and `%c' format", format_char); warning (message); } @@ -1531,7 +1606,8 @@ overflow_warning (value) && TREE_OVERFLOW (value)) { TREE_OVERFLOW (value) = 0; - warning ("integer overflow in expression"); + if (skip_evaluation == 0) + warning ("integer overflow in expression"); } else if ((TREE_CODE (value) == REAL_CST || (TREE_CODE (value) == COMPLEX_CST @@ -1539,7 +1615,8 @@ overflow_warning (value) && TREE_OVERFLOW (value)) { TREE_OVERFLOW (value) = 0; - warning ("floating point overflow in expression"); + if (skip_evaluation == 0) + warning ("floating point overflow in expression"); } } @@ -1555,6 +1632,7 @@ unsigned_conversion_warning (result, operand) if (TREE_CODE (operand) == INTEGER_CST && TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE && TREE_UNSIGNED (TREE_TYPE (result)) + && skip_evaluation == 0 && !int_fits_type_p (operand, TREE_TYPE (result))) { if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result)))) @@ -1590,10 +1668,11 @@ convert_and_check (type, expr) && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr)))) /* If EXPR fits in the unsigned version of TYPE, don't warn unless pedantic. */ - if (pedantic - || TREE_UNSIGNED (type) - || ! int_fits_type_p (expr, unsigned_type (type))) - warning ("overflow in implicit constant conversion"); + if ((pedantic + || TREE_UNSIGNED (type) + || ! int_fits_type_p (expr, unsigned_type (type))) + && skip_evaluation == 0) + warning ("overflow in implicit constant conversion"); } else unsigned_conversion_warning (t, expr); @@ -2292,7 +2371,7 @@ truthvalue_conversion (expr) if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE) break; - /* fall through... */ + /* fall through... */ case NOP_EXPR: /* If this is widening the argument, we can ignore it. */ if (TYPE_PRECISION (TREE_TYPE (expr)) @@ -2306,7 +2385,7 @@ truthvalue_conversion (expr) if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE) break; - /* fall through... */ + /* fall through... */ case BIT_XOR_EXPR: /* This and MINUS_EXPR can be changed into a comparison of the two objects. */