diff options
author | Ian Lance Taylor <iant@google.com> | 2009-06-16 05:12:15 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2009-06-16 05:12:15 +0000 |
commit | e1b7793c8ebdc72bd3d7283d70a29444da614c13 (patch) | |
tree | 8497f69348fcfb23ffa019c746e037539cb42cc0 /gcc/cp/parser.c | |
parent | dee6f5752949e9c53e1706925ad934760bcab775 (diff) | |
download | gcc-e1b7793c8ebdc72bd3d7283d70a29444da614c13.zip gcc-e1b7793c8ebdc72bd3d7283d70a29444da614c13.tar.gz gcc-e1b7793c8ebdc72bd3d7283d70a29444da614c13.tar.bz2 |
df-problems.c (df_simulate_one_insn_forwards): Fix braces in switch.
./: * df-problems.c (df_simulate_one_insn_forwards): Fix braces in
switch.
* gcov.c (read_count_file): Add braces around variables declared
before label.
* c.opt (Wjump-misses-init): New warning.
* c-opts.c (c_common_handle_option): Set warn_jump_misses_init for
-Wall and -Wc++-compat if not already set.
(c_common_post_options): Clear warn_jump_misses_init if it was not
set.
* c-decl.c (struct c_binding): Change type field to a union with
new label field. Make it the first field in the struct. Update
references to type to use u.type instead.
(struct c_spot_bindings): Define.
(struct c_goto_bindings): Define.
(c_goto_bindings_p): Define, along with VECs.
(struct c_label_vars): Define.
(struct c_scope): Add has_label_bindings field.
(bind_label, set_spot_bindings): New static functions.
(decl_jump_unsafe, update_spot_bindings): New static functions.
(update_label_decls): New static function.
(pop_scope): Call update_label_decls. Don't call c_end_vm_scope.
Update binding u.label field to shadowed field.
(c_binding_start_stmt_expr): New function.
(c_binding_end_stmt_expr): New function.
(pushdecl): Don't call c_begin_vm_scope.
(make_label): Add defining and p_label_vars parameters. Change
all callers.
(lookup_label): Correct test for whether a label has not yet been
defined. Call bind_label rather than bind.
(warn_about_goto): New static function.
(lookup_label_for_goto): New function.
(declare_label): Call bind_label rather than bind.
(check_earlier_gotos): New static function.
(define_label): Don't give errors about jumping into statement
expressions or scopes of variably modified types. Call
set_spot_bindings and check_earlier_gotos. Call bind_label
instead of bind. Don't set label_context_stack_se or
label_context_stack_vm.
(c_get_switch_bindings): New function.
(c_release_switch_bindings): New function.
(c_check_switch_jump_warnings): New function.
(start_function): Don't set label_context_stack_se or
label_context_stack_vm.
(finish_function): Likewise.
* c-typeck.c (label_context_stack_se): Don't define.
(label_context_stack_vm): Don't define.
(c_finish_goto_label): Call lookup_label_for_goto rather than
lookup_label. Don't give errors about jumping into a statement
expression or the scope of a variably modified type. Don't set
label_context_stack_se or label_context_stack_vm.
(struct c_switch): Remove blocked_stmt_expr and blocked_vm
fields. Add bindings field.
(c_start_case): Don't set deleted fields. Set bindings field.
(do_case): Rework order of tests. Don't check blocked_stmt_expr
or blocked_vm. Call c_check_switch_jump_warnings.
(c_finish_case): Don't test blocked_stmt_expr field. Call
c_release_switch_bindings.
(c_begin_stmt_expr): Don't increment blocked_stmt_expr in
c_switch_stack. Don't walk label_context_stack_se labels. Don't
set label_context_stack_se. Call c_bindings_start_stmt_expr.
(c_finish_stmt_expr): Don't decrement blocked_stmt_expr in
c_switch_stack. Don't walk label_context_stack_se labels. Don't
set label_context_stack_se. Call c_bindings_end_stmt_expr.
(c_begin_vm_scope, c_end_vm_scope): Don't define.
* c-tree.h (C_DECL_UNJUMPABLE_STMT_EXPR): Don't define.
(C_DECL_UNDEFINABLE_STMT_EXPR): Don't define.
(C_DECL_UNJUMPABLE_VM): Don't define.
(C_DECL_UNDEFINABLE_VM): Don't define.
(struct c_label_list): Don't define.
(struct c_label_context_se): Don't define.
(struct c_label_context_vm): Don't define.
(struct c_spot_bindings): Declare.
(c_bindings_start_stmt_expr): Declare.
(c_bindings_end_stmt_expr): Declare.
(lookup_label_for_goto): Declare.
(c_get_switch_bindings, c_release_switch_bindings): Declare.
(c_check_switch_jump_warnings): Declare.
(label_context_stack_se, label_context_stack_vm): Don't declare.
(c_finish_goto_label): Update declaration.
(c_begin_vm_scope, c_end_vm_scope): Don't declare.
* doc/invoke.texi (Option Summary): Mention -Wjump-misses-init.
(Warning Options): Document -Wjump-misses-init.
cp/:
* parser.c (cp_parser_direct_declarator): Add braces around
variables declared before label.
objc/:
* objc-act.c (objc_start_function): Don't set
label_context_stack_se or label_context_stack_vm.
testsuite/:
* gcc.dg/Wjump-misses-init-1.c: New testcase.
* gcc.dg/Wjump-misses-init-2.c: New testcase.
* gcc.dg/c99-vla-jump-5.c: Adjust expected error messages.
Recognize new notes.
* gcc.dg/stmt-expr-label-2.c: Likewise.
* gcc.dg/c99-vla-jump-1.c: Recognize new notes. Fix column
numbers.
* gcc.dg/c99-vla-jump-2.c: Recognize new notes.
* gcc.dg/c99-vla-jump-3.c: Recognize new notes.
* gcc.dg/c99-vla-jump-4.c: Likewise.
* gcc.dg/stmt-expr-label-1.c: Likewise.
* gcc.dg/stmt-expr-label-3.c: Likewise.
* gcc.dg/vla-8.c: Likewise. Move error message to different
line.
From-SVN: r148512
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 326 |
1 files changed, 164 insertions, 162 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 07f0375..0314bb3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13371,181 +13371,183 @@ cp_parser_direct_declarator (cp_parser* parser, } else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) { - tree qualifying_scope; - tree unqualified_name; - special_function_kind sfk; - bool abstract_ok; - bool pack_expansion_p = false; - cp_token *declarator_id_start_token; - - /* Parse a declarator-id */ - abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); - if (abstract_ok) - { - cp_parser_parse_tentatively (parser); + { + tree qualifying_scope; + tree unqualified_name; + special_function_kind sfk; + bool abstract_ok; + bool pack_expansion_p = false; + cp_token *declarator_id_start_token; + + /* Parse a declarator-id */ + abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); + if (abstract_ok) + { + cp_parser_parse_tentatively (parser); - /* If we see an ellipsis, we should be looking at a - parameter pack. */ - if (token->type == CPP_ELLIPSIS) - { - /* Consume the `...' */ - cp_lexer_consume_token (parser->lexer); + /* If we see an ellipsis, we should be looking at a + parameter pack. */ + if (token->type == CPP_ELLIPSIS) + { + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); - pack_expansion_p = true; - } - } + pack_expansion_p = true; + } + } - declarator_id_start_token = cp_lexer_peek_token (parser->lexer); - unqualified_name - = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); - qualifying_scope = parser->scope; - if (abstract_ok) - { - bool okay = false; - - if (!unqualified_name && pack_expansion_p) - { - /* Check whether an error occurred. */ - okay = !cp_parser_error_occurred (parser); - - /* We already consumed the ellipsis to mark a - parameter pack, but we have no way to report it, - so abort the tentative parse. We will be exiting - immediately anyway. */ - cp_parser_abort_tentative_parse (parser); - } - else - okay = cp_parser_parse_definitely (parser); - - if (!okay) - unqualified_name = error_mark_node; - else if (unqualified_name - && (qualifying_scope - || (TREE_CODE (unqualified_name) - != IDENTIFIER_NODE))) - { - cp_parser_error (parser, "expected unqualified-id"); - unqualified_name = error_mark_node; - } - } + declarator_id_start_token = cp_lexer_peek_token (parser->lexer); + unqualified_name + = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); + qualifying_scope = parser->scope; + if (abstract_ok) + { + bool okay = false; - if (!unqualified_name) - return NULL; - if (unqualified_name == error_mark_node) - { - declarator = cp_error_declarator; - pack_expansion_p = false; - declarator->parameter_pack_p = false; - break; - } + if (!unqualified_name && pack_expansion_p) + { + /* Check whether an error occurred. */ + okay = !cp_parser_error_occurred (parser); + + /* We already consumed the ellipsis to mark a + parameter pack, but we have no way to report it, + so abort the tentative parse. We will be exiting + immediately anyway. */ + cp_parser_abort_tentative_parse (parser); + } + else + okay = cp_parser_parse_definitely (parser); - if (qualifying_scope && at_namespace_scope_p () - && TREE_CODE (qualifying_scope) == TYPENAME_TYPE) - { - /* In the declaration of a member of a template class - outside of the class itself, the SCOPE will sometimes - be a TYPENAME_TYPE. For example, given: - - template <typename T> - int S<T>::R::i = 3; - - the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In - this context, we must resolve S<T>::R to an ordinary - type, rather than a typename type. - - The reason we normally avoid resolving TYPENAME_TYPEs - is that a specialization of `S' might render - `S<T>::R' not a type. However, if `S' is - specialized, then this `i' will not be used, so there - is no harm in resolving the types here. */ - tree type; + if (!okay) + unqualified_name = error_mark_node; + else if (unqualified_name + && (qualifying_scope + || (TREE_CODE (unqualified_name) + != IDENTIFIER_NODE))) + { + cp_parser_error (parser, "expected unqualified-id"); + unqualified_name = error_mark_node; + } + } - /* Resolve the TYPENAME_TYPE. */ - type = resolve_typename_type (qualifying_scope, - /*only_current_p=*/false); - /* If that failed, the declarator is invalid. */ - if (TREE_CODE (type) == TYPENAME_TYPE) - error ("%H%<%T::%E%> is not a type", - &declarator_id_start_token->location, - TYPE_CONTEXT (qualifying_scope), - TYPE_IDENTIFIER (qualifying_scope)); - qualifying_scope = type; - } + if (!unqualified_name) + return NULL; + if (unqualified_name == error_mark_node) + { + declarator = cp_error_declarator; + pack_expansion_p = false; + declarator->parameter_pack_p = false; + break; + } - sfk = sfk_none; + if (qualifying_scope && at_namespace_scope_p () + && TREE_CODE (qualifying_scope) == TYPENAME_TYPE) + { + /* In the declaration of a member of a template class + outside of the class itself, the SCOPE will sometimes + be a TYPENAME_TYPE. For example, given: + + template <typename T> + int S<T>::R::i = 3; + + the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In + this context, we must resolve S<T>::R to an ordinary + type, rather than a typename type. + + The reason we normally avoid resolving TYPENAME_TYPEs + is that a specialization of `S' might render + `S<T>::R' not a type. However, if `S' is + specialized, then this `i' will not be used, so there + is no harm in resolving the types here. */ + tree type; + + /* Resolve the TYPENAME_TYPE. */ + type = resolve_typename_type (qualifying_scope, + /*only_current_p=*/false); + /* If that failed, the declarator is invalid. */ + if (TREE_CODE (type) == TYPENAME_TYPE) + error ("%H%<%T::%E%> is not a type", + &declarator_id_start_token->location, + TYPE_CONTEXT (qualifying_scope), + TYPE_IDENTIFIER (qualifying_scope)); + qualifying_scope = type; + } - if (unqualified_name) - { - tree class_type; + sfk = sfk_none; - if (qualifying_scope - && CLASS_TYPE_P (qualifying_scope)) - class_type = qualifying_scope; - else - class_type = current_class_type; + if (unqualified_name) + { + tree class_type; - if (TREE_CODE (unqualified_name) == TYPE_DECL) - { - tree name_type = TREE_TYPE (unqualified_name); - if (class_type && same_type_p (name_type, class_type)) - { - if (qualifying_scope - && CLASSTYPE_USE_TEMPLATE (name_type)) - { - error ("%Hinvalid use of constructor as a template", - &declarator_id_start_token->location); - inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to " - "name the constructor in a qualified name", - class_type, - DECL_NAME (TYPE_TI_TEMPLATE (class_type)), - class_type, name_type); - declarator = cp_error_declarator; - break; - } - else - unqualified_name = constructor_name (class_type); - } - else - { - /* We do not attempt to print the declarator - here because we do not have enough - information about its original syntactic - form. */ - cp_parser_error (parser, "invalid declarator"); - declarator = cp_error_declarator; - break; - } - } + if (qualifying_scope + && CLASS_TYPE_P (qualifying_scope)) + class_type = qualifying_scope; + else + class_type = current_class_type; - if (class_type) - { - if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) - sfk = sfk_destructor; - else if (IDENTIFIER_TYPENAME_P (unqualified_name)) - sfk = sfk_conversion; - else if (/* There's no way to declare a constructor - for an anonymous type, even if the type - got a name for linkage purposes. */ - !TYPE_WAS_ANONYMOUS (class_type) - && constructor_name_p (unqualified_name, - class_type)) - { - unqualified_name = constructor_name (class_type); - sfk = sfk_constructor; - } + if (TREE_CODE (unqualified_name) == TYPE_DECL) + { + tree name_type = TREE_TYPE (unqualified_name); + if (class_type && same_type_p (name_type, class_type)) + { + if (qualifying_scope + && CLASSTYPE_USE_TEMPLATE (name_type)) + { + error ("%Hinvalid use of constructor as a template", + &declarator_id_start_token->location); + inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to " + "name the constructor in a qualified name", + class_type, + DECL_NAME (TYPE_TI_TEMPLATE (class_type)), + class_type, name_type); + declarator = cp_error_declarator; + break; + } + else + unqualified_name = constructor_name (class_type); + } + else + { + /* We do not attempt to print the declarator + here because we do not have enough + information about its original syntactic + form. */ + cp_parser_error (parser, "invalid declarator"); + declarator = cp_error_declarator; + break; + } + } - if (ctor_dtor_or_conv_p && sfk != sfk_none) - *ctor_dtor_or_conv_p = -1; - } - } - declarator = make_id_declarator (qualifying_scope, - unqualified_name, - sfk); - declarator->id_loc = token->location; - declarator->parameter_pack_p = pack_expansion_p; + if (class_type) + { + if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) + sfk = sfk_destructor; + else if (IDENTIFIER_TYPENAME_P (unqualified_name)) + sfk = sfk_conversion; + else if (/* There's no way to declare a constructor + for an anonymous type, even if the type + got a name for linkage purposes. */ + !TYPE_WAS_ANONYMOUS (class_type) + && constructor_name_p (unqualified_name, + class_type)) + { + unqualified_name = constructor_name (class_type); + sfk = sfk_constructor; + } - if (pack_expansion_p) - maybe_warn_variadic_templates (); + if (ctor_dtor_or_conv_p && sfk != sfk_none) + *ctor_dtor_or_conv_p = -1; + } + } + declarator = make_id_declarator (qualifying_scope, + unqualified_name, + sfk); + declarator->id_loc = token->location; + declarator->parameter_pack_p = pack_expansion_p; + + if (pack_expansion_p) + maybe_warn_variadic_templates (); + } handle_declarator:; scope = get_scope_of_declarator (declarator); |