diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-29 18:13:43 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-29 18:13:43 +0000 |
commit | a75b1c712f1eaddc69919461ead67f4ac21663fe (patch) | |
tree | a06c7550ad4d8d100141b10b1c0d61bf7548b888 /gcc/c-parser.c | |
parent | 088cc5d52e3bab879a7b3aa48b3de9127e948bb0 (diff) | |
download | gcc-a75b1c712f1eaddc69919461ead67f4ac21663fe.tar.gz |
PR c/456
PR c/5675
PR c/19976
PR c/29116
PR c/31871
PR c/35198
fixincludes:
* inclhack.def (glibc_tgmath): New fix.
* fixincl.x: Regenerate.
* tests/base/tgmath.h: New.
gcc:
* builtins.c (fold_builtin_sincos): Build COMPOUND_EXPR in
void_type_node.
(fold_call_expr): Return a NOP_EXPR from folding rather than the
contained expression.
* c-common.c (c_fully_fold, c_fully_fold_internal, c_save_expr):
New.
(c_common_truthvalue_conversion): Use c_save_expr. Do not fold
conditional expressions for C.
(decl_constant_value_for_optimization): Move from
decl_constant_value_for_broken_optimization in c-typeck.c. Check
whether optimizing and that the expression is a VAR_DECL not of
array type instead of doing such checks in the caller. Do not
check pedantic. Call gcc_unreachable for C++.
* c-common.def (C_MAYBE_CONST_EXPR): New.
* c-common.h (c_fully_fold, c_save_expr,
decl_constant_value_for_optimization): New prototypes.
(C_MAYBE_CONST_EXPR_PRE, C_MAYBE_CONST_EXPR_EXPR,
C_MAYBE_CONST_EXPR_INT_OPERANDS, C_MAYBE_CONST_EXPR_NON_CONST,
EXPR_INT_CONST_OPERANDS): Define.
* c-convert.c (convert): Strip nops from expression.
* c-decl.c (groktypename): Take extra parameters expr and
expr_const_operands. Update call to grokdeclarator.
(start_decl): Update call to grokdeclarator. Add statement for
expressions used in type of decl.
(grokparm): Update call to grokdeclarator.
(push_parm_decl): Update call to grokdeclarator.
(build_compound_literal): Add parameter non_const and build a
C_MAYBE_COSNT_EXPR if applicable.
(grokdeclarator): Take extra parameters expr and
expr_const_operands. Track expressions used in declaration
specifiers and declarators. Fold array sizes and track whether
they are constant expressions and whether they are integer
constant expressions.
(parser_xref_tag): Set expr and expr_const_operands fields in
return value.
(grokfield): Update call to grokdeclarator.
(start_function): Update call to grokdeclarator.
(build_null_declspecs): Set expr and expr_const_operands fields in
return value.
(declspecs_add_type): Handle expressions in typeof specifiers.
* c-parser.c (c_parser_declspecs): Set expr and
expr_const_operands fields for declaration specifiers.
(c_parser_enum_specifier): Likewise.
(c_parser_struct_or_union_specifier): Likewise.
(c_parser_typeof_specifier): Likewise. Update call to
groktypename. Fold expression as needed. Return expressions with
type instead of adding statements.
(c_parser_attributes): Update calls to c_parser_expr_list.
(c_parser_statement_after_labels): Fold expression before passing
to objc_build_throw_stmt.
(c_parser_condition): Fold expression.
(c_parser_asm_operands): Fold expression.
(c_parser_conditional_expression): Use c_save_expr. Update call
to build_conditional_expr.
(c_parser_alignof_expression): Update call to groktypename.
(c_parser_postfix_expression): Preserve C_MAYBE_CONST_EXPR as
original_code. Fold expression argument of va_arg. Create
C_MAYBE_CONST_EXPR to preserve side effects of expressions in type
argument to va_arg. Update calls to groktypename. Fold array
index for offsetof. Verify that first argument to
__builtin_choose_expr has integer type.
(c_parser_postfix_expression_after_paren_type): Update calls to
groktypename and build_compound_literal. Handle expressions with
side effects in type name.
(c_parser_postfix_expression_after_primary): Update call to
c_parser_expr_list. Set original_code for calls to
__builtin_constant_p.
(c_parser_expr_list): Take extra parameter fold_p. Fold
expressions if requested.
(c_parser_objc_type_name): Update call to groktypename.
(c_parser_objc_synchronized_statement): Fold expression.
(c_parser_objc_receiver): Fold expression.
(c_parser_objc_keywordexpr): Update call to c_parser_expr_list.
(c_parser_omp_clause_num_threads, c_parser_omp_clause_schedule,
c_parser_omp_atomic, c_parser_omp_for_loop): Fold expressions.
* c-tree.h (CONSTRUCTOR_NON_CONST): Define.
(struct c_typespec): Add elements expr and expr_const_operands.
(struct c_declspecs): Add elements expr and expr_const_operands.
(groktypename, build_conditional_expr, build_compound_literal):
Update prototypes.
(in_late_binary_op): Declare.
* c-typeck.c (note_integer_operands): New function.
(in_late_binary_op): New variable.
(decl_constant_value_for_broken_optimization): Move to c-common.c
and rename to decl_constant_value_for_optimization.
(default_function_array_conversion): Do not strip nops.
(default_conversion): Do not call
decl_constant_value_for_broken_optimization.
(build_array_ref): Do not fold result.
(c_expr_sizeof_expr): Fold operand. Use C_MAYBE_CONST_EXPR for
result when operand is a VLA.
(c_expr_sizeof_type): Update call to groktypename. Handle
expressions included in type name. Use C_MAYBE_CONST_EXPR for
result when operand names a VLA type.
(build_function_call): Update call to build_compound_literal.
Only fold result for calls to __builtin_* functions. Strip
NOP_EXPR from INTEGER_CST returned from such functions. Fold
the function designator.
(convert_arguments): Fold arguments. Update call to
convert_for_assignment.
(build_unary_op): Handle increment and decrement of
C_MAYBE_CONST_EXPR. Move lvalue checks for increment and
decrement earlier. Fold operand of increment and decrement.
Handle address of C_MAYBE_CONST_EXPR. Only fold expression being
built for integer operand. Wrap returns that are INTEGER_CSTs
without being integer constant expressions or that have integer
constant operands without being INTEGER_CSTs.
(lvalue_p): Handle C_MAYBE_CONST_EXPR.
(build_conditional_expr): Add operand ifexp_bcp. Track whether
result is an integer constant expression or can be used in
unevaluated parts of one and avoid folding and wrap as
appropriate. Fold operands before possibly doing -Wsign-compare
warnings.
(build_compound_expr): Wrap result for C99 if operands can be used
in integer constant expressions.
(build_c_cast): Update call to digest_init. Do not ignore
overflow from casting floating-point constants to integers. Wrap
results that could be confused with integer constant expressions,
null pointer constants or floating-point constants.
(c_cast_expr): Update call to groktypename. Handle expressions
included in type name.
(build_modify_expr): Handle modifying a C_MAYBE_CONST_EXPR. Fold
lhs inside possible SAVE_EXPR. Fold RHS before assignment.
Update calls to convert_for_assignment.
(convert_for_assignment): Take new parameter
null_pointer_constant. Do not strip nops or call
decl_constant_value_for_broken_optimization. Set
in_late_binary_op for conversions to boolean.
(store_init_value): Update call to digest_init.
(digest_init): Take new parameter null_pointer_constant. Do not
call decl_constant_value_for_broken_optimization. pedwarn for
initializers not constant expressions. Update calls to
convert_for_assignment.
(constructor_nonconst): New.
(struct constructor_stack): Add nonconst element.
(really_start_incremental_init, push_init_level, pop_init_level):
Handle constructor_nonconst and nonconst element.
(set_init_index): Call constant_expression_warning for array
designators.
(output_init_element): Fold value. Set constructor_nonconst as
applicable. pedwarn for initializers not constant expressions.
Update call to digest_init. Call constant_expression_warning
where constant initializers are required.
(process_init_element): Use c_save_expr.
(c_finish_goto_ptr): Fold expression.
(c_finish_return): Fold return value. Update call to
convert_for_assignment.
(c_start_case): Fold switch expression.
(c_process_expr_stmt): Fold expression.
(c_finish_stmt_expr): Create C_MAYBE_CONST_EXPR as needed to
ensure statement expression is not evaluated in constant
expression.
(build_binary_op): Track whether results are integer constant
expressions or may occur in such, disable folding and wrap results
as applicable. Fold operands for -Wsign-compare warnings unless
in_late_binary_op.
(c_objc_common_truthvalue_conversion): Handle results folded to
integer constants that are not integer constant expressions.
* doc/extend.texi: Document when typeof operands are evaluated,
that condition of __builtin_choose_expr is an integer constant
expression, and more about use of __builtin_constant_p in
initializers.
gcc/objc:
* objc-act.c (objc_finish_try_stmt): Set in_late_binary_op.
gcc/testsuite:
* gcc.c-torture/compile/20081108-1.c,
gcc.c-torture/compile/20081108-2.c,
gcc.c-torture/compile/20081108-3.c, gcc.dg/bconstp-2.c,
gcc.dg/bconstp-3.c, gcc.dg/bconstp-4.c, gcc.dg/c90-const-expr-6.c,
gcc.dg/c90-const-expr-7.c, gcc.dg/c90-const-expr-8.c,
gcc.dg/c90-const-expr-9.c, gcc.dg/c90-const-expr-10.c,
gcc.dg/c90-const-expr-11.c, gcc.dg/c99-const-expr-6.c,
gcc.dg/c99-const-expr-7.c, gcc.dg/c99-const-expr-8.c,
gcc.dg/c99-const-expr-9.c, gcc.dg/c99-const-expr-10.c,
gcc.dg/c99-const-expr-11.c, gcc.dg/c99-const-expr-12.c,
gcc.dg/c99-const-expr-13.c, gcc.dg/compare10.c,
gcc.dg/gnu89-const-expr-1.c, gcc.dg/gnu89-const-expr-2.c,
gcc.dg/gnu99-const-expr-1.c, gcc.dg/gnu99-const-expr-2.c,
gcc.dg/gnu99-const-expr-3.c, gcc.dg/vla-12.c, gcc.dg/vla-13.c,
gcc.dg/vla-14.c, gcc.dg/vla-15.c, gcc.dg/vla-16.c: New tests.
* gcc.dg/c90-const-expr-1.c, gcc.dg/c90-const-expr-2.c,
gcc.dg/c90-const-expr-3.c, gcc.dg/c99-const-expr-2.c,
gcc.dg/c99-const-expr-3.c, gcc.dg/c99-static-1.c: Remove XFAILs.
* gcc.dg/c90-const-expr-2.c: Use ZERO in place of 0 in another
case.
* gcc.dg/overflow-warn-1.c, gcc.dg/overflow-warn-2.c,
gcc.dg/overflow-warn-3.c, gcc.dg/overflow-warn-4.c: Remove
XFAILs. Update expected messages.
* gcc.dg/pr14649-1.c, gcc.dg/pr19984.c, gcc.dg/pr25682.c: Update
expected messages.
* gcc.dg/real-const-1.c: Replace with test from original PR.
* gcc.dg/vect/pr32230.c: Use intermediate cast to __PTRDIFF_TYPE__
when casting from non-constant integer to pointer.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145254 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r-- | gcc/c-parser.c | 149 |
1 files changed, 107 insertions, 42 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c index f910128de3f..4d1b4d51395 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -915,7 +915,7 @@ static struct c_expr c_parser_postfix_expression_after_primary (c_parser *, struct c_expr); static struct c_expr c_parser_expression (c_parser *); static struct c_expr c_parser_expression_conv (c_parser *); -static tree c_parser_expr_list (c_parser *, bool); +static tree c_parser_expr_list (c_parser *, bool, bool); static void c_parser_omp_construct (c_parser *); static void c_parser_omp_threadprivate (c_parser *); static void c_parser_omp_barrier (c_parser *); @@ -1455,6 +1455,8 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, /* For a typedef name, record the meaning, not the name. In case of 'foo foo, bar;'. */ t.spec = lookup_name (value); + t.expr = NULL_TREE; + t.expr_const_operands = true; } else { @@ -1464,6 +1466,8 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, if (c_parser_next_token_is (parser, CPP_LESS)) proto = c_parser_objc_protocol_refs (parser); t.spec = objc_get_protocol_qualified_type (value, proto); + t.expr = NULL_TREE; + t.expr_const_operands = true; } declspecs_add_type (specs, t); continue; @@ -1479,6 +1483,8 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, proto = c_parser_objc_protocol_refs (parser); t.kind = ctsk_objc; t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); + t.expr = NULL_TREE; + t.expr_const_operands = true; declspecs_add_type (specs, t); continue; } @@ -1526,6 +1532,8 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, parser->objc_need_raw_identifier = true; t.kind = ctsk_resword; t.spec = c_parser_peek_token (parser)->value; + t.expr = NULL_TREE; + t.expr_const_operands = true; declspecs_add_type (specs, t); c_parser_consume_token (parser); break; @@ -1687,6 +1695,8 @@ c_parser_enum_specifier (c_parser *parser) ret.spec = finish_enum (type, nreverse (values), chainon (attrs, postfix_attrs)); ret.kind = ctsk_tagdef; + ret.expr = NULL_TREE; + ret.expr_const_operands = true; return ret; } else if (!ident) @@ -1694,6 +1704,8 @@ c_parser_enum_specifier (c_parser *parser) c_parser_error (parser, "expected %<{%>"); ret.spec = error_mark_node; ret.kind = ctsk_tagref; + ret.expr = NULL_TREE; + ret.expr_const_operands = true; return ret; } ret = parser_xref_tag (ENUMERAL_TYPE, ident); @@ -1870,6 +1882,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) ret.spec = finish_struct (type, nreverse (contents), chainon (attrs, postfix_attrs)); ret.kind = ctsk_tagdef; + ret.expr = NULL_TREE; + ret.expr_const_operands = true; return ret; } else if (!ident) @@ -1877,6 +1891,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) c_parser_error (parser, "expected %<{%>"); ret.spec = error_mark_node; ret.kind = ctsk_tagref; + ret.expr = NULL_TREE; + ret.expr_const_operands = true; return ret; } ret = parser_xref_tag (code, ident); @@ -2053,6 +2069,8 @@ c_parser_typeof_specifier (c_parser *parser) struct c_typespec ret; ret.kind = ctsk_typeof; ret.spec = error_mark_node; + ret.expr = NULL_TREE; + ret.expr_const_operands = true; gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF)); c_parser_consume_token (parser); skip_evaluation++; @@ -2070,7 +2088,7 @@ c_parser_typeof_specifier (c_parser *parser) in_typeof--; if (type != NULL) { - ret.spec = groktypename (type); + ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands); pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE)); } } @@ -2086,22 +2104,10 @@ c_parser_typeof_specifier (c_parser *parser) error_at (here, "%<typeof%> applied to a bit-field"); ret.spec = TREE_TYPE (expr.value); was_vm = variably_modified_type_p (ret.spec, NULL_TREE); - /* This should be returned with the type so that when the type - is evaluated, this can be evaluated. For now, we avoid - evaluation when the context might. */ - if (!skip_evaluation && was_vm) - { - tree e = expr.value; - - /* If the expression is not of a type to which we cannot assign a line - number, wrap the thing in a no-op NOP_EXPR. */ - if (DECL_P (e) || CONSTANT_CLASS_P (e)) - e = build1 (NOP_EXPR, void_type_node, e); - - protected_set_expr_location (e, here); - - add_stmt (e); - } + /* This is returned with the type so that when the type is + evaluated, this can be evaluated. */ + if (was_vm) + ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands); pop_maybe_used (was_vm); } c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -2858,7 +2864,8 @@ c_parser_attributes (c_parser *parser) { c_parser_consume_token (parser); attr_args = tree_cons (NULL_TREE, arg1, - c_parser_expr_list (parser, false)); + c_parser_expr_list (parser, false, + true)); } } else @@ -2866,7 +2873,7 @@ c_parser_attributes (c_parser *parser) if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) attr_args = NULL_TREE; else - attr_args = c_parser_expr_list (parser, false); + attr_args = c_parser_expr_list (parser, false, true); } attr = build_tree_list (attr_name, attr_args); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) @@ -3748,8 +3755,9 @@ c_parser_statement_after_labels (c_parser *parser) } else { - stmt - = objc_build_throw_stmt (c_parser_expression (parser).value); + tree expr = c_parser_expression (parser).value; + expr = c_fully_fold (expr, false, NULL); + stmt = objc_build_throw_stmt (expr); goto expect_semicolon; } break; @@ -3810,8 +3818,9 @@ c_parser_condition (c_parser *parser) location_t loc; tree cond; loc = c_parser_peek_token (parser)->location; - cond = c_objc_common_truthvalue_conversion - (loc, c_parser_expression_conv (parser).value); + cond = c_parser_expression_conv (parser).value; + cond = c_objc_common_truthvalue_conversion (loc, cond); + cond = c_fully_fold (cond, false, NULL); protected_set_expr_location (cond, loc); if (warn_sequence_point) verify_sequence_points (cond); @@ -4304,6 +4313,7 @@ c_parser_asm_operands (c_parser *parser, bool convert_p) expr = c_parser_expression (parser); if (convert_p) expr = default_function_array_conversion (expr); + expr.value = c_fully_fold (expr.value, false, NULL); parser->lex_untranslated_string = true; if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) { @@ -4458,7 +4468,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "ISO C forbids omitting the middle term of a ?: expression"); /* Make sure first operand is calculated only once. */ - exp1.value = save_expr (default_conversion (cond.value)); + exp1.value = c_save_expr (default_conversion (cond.value)); cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value); skip_evaluation += cond.value == truthvalue_true_node; } @@ -4482,7 +4492,9 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) exp2 = c_parser_conditional_expression (parser, NULL); exp2 = default_function_array_conversion (exp2); skip_evaluation -= cond.value == truthvalue_true_node; - ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value); + ret.value = build_conditional_expr (cond.value, + cond.original_code == C_MAYBE_CONST_EXPR, + exp1.value, exp2.value); ret.original_code = ERROR_MARK; return ret; } @@ -5012,7 +5024,7 @@ c_parser_alignof_expression (c_parser *parser) /* alignof ( type-name ). */ skip_evaluation--; in_alignof--; - ret.value = c_alignof (groktypename (type_name)); + ret.value = c_alignof (groktypename (type_name, NULL, NULL)); ret.original_code = ERROR_MARK; return ret; } @@ -5200,7 +5212,8 @@ c_parser_postfix_expression (c_parser *parser) expr = c_parser_expression (parser); if (TREE_CODE (expr.value) == MODIFY_EXPR) TREE_NO_WARNING (expr.value) = 1; - expr.original_code = ERROR_MARK; + if (expr.original_code != C_MAYBE_CONST_EXPR) + expr.original_code = ERROR_MARK; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } @@ -5226,6 +5239,7 @@ c_parser_postfix_expression (c_parser *parser) break; } e1 = c_parser_expr_no_commas (parser, NULL); + e1.value = c_fully_fold (e1.value, false, NULL); if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); @@ -5243,7 +5257,17 @@ c_parser_postfix_expression (c_parser *parser) } else { - expr.value = build_va_arg (e1.value, groktypename (t1)); + tree type_expr = NULL_TREE; + expr.value = build_va_arg (e1.value, groktypename (t1, + &type_expr, + NULL)); + if (type_expr) + { + expr.value = build2 (C_MAYBE_CONST_EXPR, + TREE_TYPE (expr.value), type_expr, + expr.value); + C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true; + } expr.original_code = ERROR_MARK; } break; @@ -5270,7 +5294,7 @@ c_parser_postfix_expression (c_parser *parser) break; } { - tree type = groktypename (t1); + tree type = groktypename (t1, NULL, NULL); tree offsetof_ref; if (type == error_mark_node) offsetof_ref = error_mark_node; @@ -5319,6 +5343,7 @@ c_parser_postfix_expression (c_parser *parser) loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); idx = c_parser_expression (parser).value; + idx = c_fully_fold (idx, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); offsetof_ref = build_array_ref (offsetof_ref, idx, loc); @@ -5365,10 +5390,12 @@ c_parser_postfix_expression (c_parser *parser) tree c; c = fold (e1.value); - if (TREE_CODE (c) != INTEGER_CST) + if (TREE_CODE (c) != INTEGER_CST + || !INTEGRAL_TYPE_P (TREE_TYPE (c))) error_at (loc, "first argument to %<__builtin_choose_expr%> not" " a constant"); + constant_expression_warning (c); expr = integer_zerop (c) ? e3 : e2; } break; @@ -5406,8 +5433,8 @@ c_parser_postfix_expression (c_parser *parser) { tree e1, e2; - e1 = TYPE_MAIN_VARIANT (groktypename (t1)); - e2 = TYPE_MAIN_VARIANT (groktypename (t2)); + e1 = TYPE_MAIN_VARIANT (groktypename (t1, NULL, NULL)); + e2 = TYPE_MAIN_VARIANT (groktypename (t2, NULL, NULL)); expr.value = comptypes (e1, e2) ? build_int_cst (NULL_TREE, 1) @@ -5479,7 +5506,7 @@ c_parser_postfix_expression (c_parser *parser) c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); { - tree type = groktypename (t1); + tree type = groktypename (t1, NULL, NULL); expr.value = objc_build_encode_expr (type); expr.original_code = ERROR_MARK; } @@ -5529,10 +5556,13 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, { tree type; struct c_expr init; + bool non_const; struct c_expr expr; location_t start_loc; + tree type_expr = NULL_TREE; + bool type_expr_const = true; start_init (NULL_TREE, NULL, 0); - type = groktypename (type_name); + type = groktypename (type_name, &type_expr, &type_expr_const); start_loc = c_parser_peek_token (parser)->location; if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type)) { @@ -5545,8 +5575,26 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, if (!flag_isoc99) pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals"); - expr.value = build_compound_literal (type, init.value); + non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR) + ? CONSTRUCTOR_NON_CONST (init.value) + : init.original_code == C_MAYBE_CONST_EXPR); + non_const |= !type_expr_const; + expr.value = build_compound_literal (type, init.value, non_const); expr.original_code = ERROR_MARK; + if (type_expr) + { + if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR) + { + gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE); + C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr; + } + else + { + gcc_assert (!non_const); + expr.value = build2 (C_MAYBE_CONST_EXPR, type, + type_expr, expr.value); + } + } return c_parser_postfix_expression_after_primary (parser, expr); } @@ -5557,6 +5605,7 @@ static struct c_expr c_parser_postfix_expression_after_primary (c_parser *parser, struct c_expr expr) { + struct c_expr orig_expr; tree ident, idx, exprlist; location_t loc = c_parser_peek_token (parser)->location; while (true) @@ -5579,11 +5628,17 @@ c_parser_postfix_expression_after_primary (c_parser *parser, if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) exprlist = NULL_TREE; else - exprlist = c_parser_expr_list (parser, true); + exprlist = c_parser_expr_list (parser, true, false); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + orig_expr = expr; expr.value = build_function_call (expr.value, exprlist); expr.original_code = ERROR_MARK; + if (TREE_CODE (expr.value) == INTEGER_CST + && TREE_CODE (orig_expr.value) == FUNCTION_DECL + && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P) + expr.original_code = C_MAYBE_CONST_EXPR; break; case CPP_DOT: /* Structure element reference. */ @@ -5681,7 +5736,7 @@ c_parser_expression_conv (c_parser *parser) } /* Parse a non-empty list of expressions. If CONVERT_P, convert - functions and arrays to pointers. + functions and arrays to pointers. If FOLD_P, fold the expressions. nonempty-expr-list: assignment-expression @@ -5689,13 +5744,15 @@ c_parser_expression_conv (c_parser *parser) */ static tree -c_parser_expr_list (c_parser *parser, bool convert_p) +c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p) { struct c_expr expr; tree ret, cur; expr = c_parser_expr_no_commas (parser, NULL); if (convert_p) expr = default_function_array_conversion (expr); + if (fold_p) + expr.value = c_fully_fold (expr.value, false, NULL); ret = cur = build_tree_list (NULL_TREE, expr.value); while (c_parser_next_token_is (parser, CPP_COMMA)) { @@ -5703,6 +5760,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p) expr = c_parser_expr_no_commas (parser, NULL); if (convert_p) expr = default_function_array_conversion (expr); + if (fold_p) + expr.value = c_fully_fold (expr.value, false, NULL); cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value); } return ret; @@ -6288,7 +6347,7 @@ c_parser_objc_type_name (c_parser *parser) if (c_parser_next_token_starts_typename (parser)) type_name = c_parser_type_name (parser); if (type_name) - type = groktypename (type_name); + type = groktypename (type_name, NULL, NULL); return build_tree_list (quals, type); } @@ -6394,6 +6453,7 @@ c_parser_objc_synchronized_statement (c_parser *parser) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { expr = c_parser_expression (parser).value; + expr = c_fully_fold (expr, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } else @@ -6529,7 +6589,7 @@ c_parser_objc_receiver (c_parser *parser) c_parser_consume_token (parser); return objc_get_class_reference (id); } - return c_parser_expression (parser).value; + return c_fully_fold (c_parser_expression (parser).value, false, NULL); } /* Parse objc-message-args. @@ -6577,7 +6637,7 @@ c_parser_objc_message_args (c_parser *parser) static tree c_parser_objc_keywordexpr (c_parser *parser) { - tree list = c_parser_expr_list (parser, true); + tree list = c_parser_expr_list (parser, true, true); if (TREE_CHAIN (list) == NULL_TREE) { /* Just return the expression, remove a level of @@ -7053,6 +7113,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list) { location_t expr_loc = c_parser_peek_token (parser)->location; tree c, t = c_parser_expression (parser).value; + t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -7231,6 +7292,7 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) here = c_parser_peek_token (parser)->location; t = c_parser_expr_no_commas (parser, NULL).value; + t = c_fully_fold (t, false, NULL); if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) error_at (here, "schedule %<runtime%> does not take " @@ -7430,6 +7492,7 @@ c_parser_omp_atomic (c_parser *parser) c_parser_skip_to_pragma_eol (parser); lhs = c_parser_unary_expression (parser).value; + lhs = c_fully_fold (lhs, false, NULL); switch (TREE_CODE (lhs)) { case ERROR_MARK: @@ -7491,6 +7554,7 @@ c_parser_omp_atomic (c_parser *parser) rhs_expr = c_parser_expression (parser); rhs_expr = default_function_array_conversion (rhs_expr); rhs = rhs_expr.value; + rhs = c_fully_fold (rhs, false, NULL); break; } stmt = c_finish_omp_atomic (code, lhs, rhs); @@ -7654,6 +7718,7 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses) cond = cond_expr.value; cond = c_objc_common_truthvalue_conversion (cond_loc, cond); + cond = c_fully_fold (cond, false, NULL); switch (cond_expr.original_code) { case GT_EXPR: |