X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=24318777e31782d75af42c93b1a342026e64bf9f;hb=ab784d0b858991f4898623d127972b8736881286;hp=9929eb6b2c24230022d9755c881ea3129259e8d5;hpb=05a549ac5ac20b1ca6f512d994ab634fc869265b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9929eb6b2c2..24318777e31 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -789,6 +789,7 @@ wrapup_globals_for_namespace (tree namespace, void* data) if (last_time) { check_global_declarations (vec, len); + emit_debug_global_declarations (vec, len); return 0; } @@ -1008,13 +1009,15 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl) error_mark_node is returned. Otherwise, OLDDECL is returned. If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is - returned. */ + returned. + + NEWDECL_IS_FRIEND is true if NEWDECL was declared as a friend. */ tree -duplicate_decls (tree newdecl, tree olddecl) +duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) { unsigned olddecl_uid = DECL_UID (olddecl); - int olddecl_friend = 0, types_match = 0; + int olddecl_friend = 0, types_match = 0, hidden_friend = 0; int new_defines_function = 0; if (newdecl == olddecl) @@ -1068,9 +1071,11 @@ duplicate_decls (tree newdecl, tree olddecl) if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_ARTIFICIAL (olddecl)) { + gcc_assert (!DECL_HIDDEN_FRIEND_P (olddecl)); if (TREE_CODE (newdecl) != FUNCTION_DECL) { - /* Avoid warnings redeclaring anticipated built-ins. */ + /* Avoid warnings redeclaring built-ins which have not been + explicitly declared. */ if (DECL_ANTICIPATED (olddecl)) return NULL_TREE; @@ -1101,7 +1106,8 @@ duplicate_decls (tree newdecl, tree olddecl) } else if (!types_match) { - /* Avoid warnings redeclaring anticipated built-ins. */ + /* Avoid warnings redeclaring built-ins which have not been + explicitly declared. */ if (DECL_ANTICIPATED (olddecl)) { /* Deal with fileptr_type_node. FILE type is not known @@ -1130,7 +1136,8 @@ duplicate_decls (tree newdecl, tree olddecl) = TYPE_ARG_TYPES (TREE_TYPE (newdecl)); types_match = decls_match (newdecl, olddecl); if (types_match) - return duplicate_decls (newdecl, olddecl); + return duplicate_decls (newdecl, olddecl, + newdecl_is_friend); TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs; } } @@ -1162,8 +1169,9 @@ duplicate_decls (tree newdecl, tree olddecl) /* Replace the old RTL to avoid problems with inlining. */ COPY_DECL_RTL (newdecl, olddecl); } - /* Even if the types match, prefer the new declarations type - for anticipated built-ins, for exception lists, etc... */ + /* Even if the types match, prefer the new declarations type for + built-ins which have not been explicitly declared, for + exception lists, etc... */ else if (DECL_ANTICIPATED (olddecl)) { tree type = TREE_TYPE (newdecl); @@ -1459,7 +1467,7 @@ duplicate_decls (tree newdecl, tree olddecl) /* Don't warn about extern decl followed by definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) /* Don't warn about friends, let add_friend take care of it. */ - && ! (DECL_FRIEND_P (newdecl) || DECL_FRIEND_P (olddecl))) + && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))) { warning (0, "redundant redeclaration of %qD in same scope", newdecl); warning (0, "previous declaration of %q+D", olddecl); @@ -1534,6 +1542,8 @@ duplicate_decls (tree newdecl, tree olddecl) { DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); + DECL_NONTRIVIALLY_INITIALIZED_P (newdecl) + |= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl) |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl); } @@ -1684,6 +1694,9 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_INITIALIZED_IN_CLASS_P (newdecl) |= DECL_INITIALIZED_IN_CLASS_P (olddecl); olddecl_friend = DECL_FRIEND_P (olddecl); + hidden_friend = (DECL_ANTICIPATED (olddecl) + && DECL_HIDDEN_FRIEND_P (olddecl) + && newdecl_is_friend); /* Only functions have DECL_BEFRIENDING_CLASSES. */ if (TREE_CODE (newdecl) == FUNCTION_DECL @@ -1897,6 +1910,11 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_UID (olddecl) = olddecl_uid; if (olddecl_friend) DECL_FRIEND_P (olddecl) = 1; + if (hidden_friend) + { + DECL_ANTICIPATED (olddecl) = 1; + DECL_HIDDEN_FRIEND_P (olddecl) = 1; + } /* NEWDECL contains the merged attribute lists. Update OLDDECL to be the same. */ @@ -2132,16 +2150,15 @@ decl_jump_unsafe (tree decl) if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)) return 0; - if (DECL_INITIAL (decl) == NULL_TREE - && pod_type_p (TREE_TYPE (decl))) + if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) + || DECL_NONTRIVIALLY_INITIALIZED_P (decl)) + return 2; + + if (pod_type_p (TREE_TYPE (decl))) return 0; - /* This is really only important if we're crossing an initialization. - The POD stuff is just pedantry; why should it matter if the class + /* The POD stuff is just pedantry; why should it matter if the class contains a field of pointer to member type? */ - if (DECL_INITIAL (decl) - || (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))) - return 2; return 1; } @@ -2398,9 +2415,10 @@ pop_switch (void) switch_location = EXPR_LOCATION (cs->switch_stmt); else switch_location = input_location; - c_do_switch_warnings (cs->cases, switch_location, - SWITCH_STMT_TYPE (cs->switch_stmt), - SWITCH_STMT_COND (cs->switch_stmt)); + if (!processing_template_decl) + c_do_switch_warnings (cs->cases, switch_location, + SWITCH_STMT_TYPE (cs->switch_stmt), + SWITCH_STMT_COND (cs->switch_stmt)); splay_tree_delete (cs->cases); switch_stack = switch_stack->next; @@ -3141,7 +3159,7 @@ cp_make_fname_decl (tree id, int type_dep) struct cp_binding_level *b = current_binding_level; while (b->level_chain->kind != sk_function_parms) b = b->level_chain; - pushdecl_with_scope (decl, b); + pushdecl_with_scope (decl, b, /*is_friend=*/false); cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING); } else @@ -3184,8 +3202,9 @@ builtin_function_1 (const char* name, if (libname) SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname)); - /* Warn if a function in the namespace for users - is used without an occasion to consider it declared. */ + /* A function in the user's namespace should have an explicit + declaration before it is used. Mark the built-in function as + anticipated but not actually declared. */ if (name[0] != '_' || name[1] != '_') DECL_ANTICIPATED (decl) = 1; @@ -3716,9 +3735,10 @@ start_decl (const cp_declarator *declarator, declaration will have DECL_EXTERNAL set, but will have an initialization. Thus, duplicate_decls won't warn about this situation, and so we check here. */ - if (DECL_INITIAL (decl) && DECL_INITIAL (field)) + if (DECL_INITIAL (decl) + && DECL_INITIALIZED_IN_CLASS_P (field)) error ("duplicate initialization of %qD", decl); - if (duplicate_decls (decl, field)) + if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false)) decl = field; } } @@ -3729,7 +3749,8 @@ start_decl (const cp_declarator *declarator, > template_class_depth (context)) ? current_template_parms : NULL_TREE); - if (field && duplicate_decls (decl, field)) + if (field && duplicate_decls (decl, field, + /*newdecl_is_friend=*/false)) decl = field; } @@ -4642,7 +4663,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) placed in a particular register. */ if (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) { - change_decl_assembler_name (decl, get_identifier (asmspec)); + set_user_assembler_name (decl, asmspec); DECL_HARD_REGISTER (decl) = 1; } else @@ -4913,6 +4934,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { + if (init) + DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1; init = check_initializer (decl, init, flags, &cleanup); /* Thread-local storage cannot be dynamically initialized. */ if (DECL_THREAD_LOCAL_P (decl) && init) @@ -4921,10 +4944,20 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) "initialized", decl); init = NULL_TREE; } + + /* Check that the initializer for a static data member was a + constant. Although we check in the parser that the + initializer is an integral constant expression, we do not + simplify division-by-zero at the point at which it + occurs. Therefore, in: + + struct S { static const int i = 7 / 0; }; + + we issue an error at this point. It would + probably be better to forbid division by zero in + integral constant expressions. */ if (DECL_EXTERNAL (decl) && init) { - /* The static data member cannot be initialized by a - non-constant when being declared. */ error ("%qD cannot be initialized by a non-constant expression" " when being declared", decl); DECL_INITIALIZED_IN_CLASS_P (decl) = 0; @@ -5555,6 +5588,41 @@ bad_specifiers (tree object, error ("%q+D declared with an exception specification", object); } +/* DECL is a member function or static data member and is presently + being defined. Check that the definition is taking place in a + valid namespace. */ + +static void +check_class_member_definition_namespace (tree decl) +{ + /* These checks only apply to member functions and static data + members. */ + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == VAR_DECL); + /* We check for problems with specializations in pt.c in + check_specialization_namespace, where we can issue better + diagnostics. */ + if (processing_specialization) + return; + /* There are no restrictions on the placement of + explicit instantiations. */ + if (processing_explicit_instantiation) + return; + /* [class.mfct] + + A member function definition that appears outside of the + class definition shall appear in a namespace scope enclosing + the class definition. + + [class.static.data] + + The definition for a static data member shall appear in a + namespace scope enclosing the member's class definition. */ + if (!is_ancestor (current_namespace, DECL_CONTEXT (decl))) + pedwarn ("definition of %qD is not in namespace enclosing %qT", + decl, DECL_CONTEXT (decl)); +} + /* CTYPE is class type, or null if non-class. TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE or METHOD_TYPE. @@ -5633,7 +5701,11 @@ grokfndecl (tree ctype, } if (ctype) - DECL_CONTEXT (decl) = ctype; + { + DECL_CONTEXT (decl) = ctype; + if (funcdef_flag) + check_class_member_definition_namespace (decl); + } if (ctype == NULL_TREE && DECL_MAIN_P (decl)) { @@ -5859,7 +5931,7 @@ grokfndecl (tree ctype, /* Attempt to merge the declarations. This can fail, in the case of some invalid specialization declarations. */ pushed_scope = push_scope (ctype); - ok = duplicate_decls (decl, old_decl); + ok = duplicate_decls (decl, old_decl, friendp); if (pushed_scope) pop_scope (pushed_scope); if (!ok) @@ -5965,6 +6037,7 @@ grokvardecl (tree type, set_linkage_for_static_data_member (decl); /* This function is only called with out-of-class definitions. */ DECL_EXTERNAL (decl) = 0; + check_class_member_definition_namespace (decl); } /* At top level, either `static' or no s.c. makes a definition (perhaps tentative), and absence of `static' makes it public. */ @@ -7454,8 +7527,13 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id = dname; } - /* If DECLARATOR is non-NULL, we know it is a cdk_id declarator; - otherwise, we would not have exited the loop above. */ + /* If TYPE is a FUNCTION_TYPE, but the function name was explicitly + qualified with a class-name, turn it into a METHOD_TYPE, unless + we know that the function is static. We take advantage of this + opportunity to do other processing that pertains to entities + explicitly declared to be class members. Note that if DECLARATOR + is non-NULL, we know it is a cdk_id declarator; otherwise, we + would not have exited the loop above. */ if (declarator && declarator->u.id.qualifying_scope && TYPE_P (declarator->u.id.qualifying_scope)) @@ -7477,9 +7555,13 @@ grokdeclarator (const cp_declarator *declarator, is correct; there shouldn't be a `template <>' for the definition of `S::f'. */ - if (CLASSTYPE_TEMPLATE_INFO (t) - && (CLASSTYPE_TEMPLATE_INSTANTIATION (t) - || uses_template_parms (CLASSTYPE_TI_ARGS (t))) + if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t) + && !any_dependent_template_arguments_p (CLASSTYPE_TI_ARGS (t))) + /* T is an explicit (not partial) specialization. All + containing classes must therefore also be explicitly + specialized. */ + break; + if ((CLASSTYPE_USE_TEMPLATE (t) || CLASSTYPE_IS_TEMPLATE (t)) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))) template_count += 1; @@ -7488,17 +7570,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype == current_class_type) - { - /* class A { - void A::f (); - }; - - Is this ill-formed? */ - - if (pedantic) - pedwarn ("extra qualification %<%T::%> on member %qs ignored", - ctype, name); - } + pedwarn ("extra qualification %<%T::%> on member %qs", + ctype, name); else if (TREE_CODE (type) == FUNCTION_TYPE) { tree sname = declarator->u.id.unqualified_name; @@ -7542,6 +7615,8 @@ grokdeclarator (const cp_declarator *declarator, } } + /* Now TYPE has the actual type. */ + if (returned_attrs) { if (attrlist) @@ -7550,14 +7625,12 @@ grokdeclarator (const cp_declarator *declarator, attrlist = &returned_attrs; } - /* Now TYPE has the actual type. */ - /* Did array size calculations overflow? */ if (TREE_CODE (type) == ARRAY_TYPE && COMPLETE_TYPE_P (type) - && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - && TREE_OVERFLOW (TYPE_SIZE (type))) + && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST + && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) { error ("size of array %qs is too large", name); /* If we proceed with the array type as it is, we'll eventually @@ -7948,15 +8021,25 @@ grokdeclarator (const cp_declarator *declarator, } /* Check that the name used for a destructor makes sense. */ - if (sfk == sfk_destructor - && !same_type_p (TREE_OPERAND - (id_declarator->u.id.unqualified_name, 0), - ctype)) + if (sfk == sfk_destructor) { - error ("declaration of %qD as member of %qT", - id_declarator->u.id.unqualified_name, - ctype); - return error_mark_node; + if (!ctype) + { + gcc_assert (friendp); + error ("expected qualified name in friend declaration " + "for destructor %qD", + id_declarator->u.id.unqualified_name); + return error_mark_node; + } + + if (!same_type_p (TREE_OPERAND + (id_declarator->u.id.unqualified_name, 0), + ctype)) + { + error ("declaration of %qD as member of %qT", + id_declarator->u.id.unqualified_name, ctype); + return error_mark_node; + } } /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ @@ -8380,13 +8463,6 @@ check_default_argument (tree decl, tree arg) deal with it after the class is complete. */ return arg; - if (processing_template_decl || uses_template_parms (arg)) - /* We don't do anything checking until instantiation-time. Note - that there may be uninstantiated arguments even for an - instantiated function, since default arguments are not - instantiated until they are needed. */ - return arg; - if (TYPE_P (decl)) { decl_type = decl; @@ -8528,10 +8604,10 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) decl, ptr ? "pointer" : "reference", t); } - if (!any_error && init) - init = check_default_argument (decl, init); - else + if (any_error) init = NULL_TREE; + else if (init && !processing_template_decl) + init = check_default_argument (decl, init); } TREE_CHAIN (decl) = decls; @@ -9135,8 +9211,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, return error_mark_node; } else if (TREE_CODE (type) != ENUMERAL_TYPE - && tag_code == enum_type - && tag_code != typename_type) + && tag_code == enum_type) { error ("%qT referred to as enum", type); error ("%q+T has a previous declaration here", type); @@ -9679,6 +9754,8 @@ finish_enum (tree enumtype) /* Update the minimum and maximum values, if appropriate. */ value = DECL_INITIAL (decl); + if (value == error_mark_node) + value = integer_zero_node; /* Figure out what the minimum and maximum values of the enumerators are. */ if (!minnode) @@ -9781,9 +9858,14 @@ finish_enum (tree enumtype) type of the enumeration. */ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) { + location_t saved_location; + decl = TREE_VALUE (values); + saved_location = input_location; + input_location = DECL_SOURCE_LOCATION (decl); value = perform_implicit_conversion (underlying_type, DECL_INITIAL (decl)); + input_location = saved_location; /* Do not clobber shared ints. */ value = copy_node (value); @@ -9873,7 +9955,10 @@ build_enumerator (tree name, tree value, tree enumtype) overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value)); if (overflowed) - error ("overflow in enumeration values at %qD", name); + { + error ("overflow in enumeration values at %qD", name); + value = error_mark_node; + } } else value = integer_zero_node; @@ -9944,25 +10029,20 @@ check_function_type (tree decl, tree current_function_parms) return; if (!COMPLETE_OR_VOID_TYPE_P (return_type)) { - error ("return type %q#T is incomplete", TREE_TYPE (fntype)); + tree args = TYPE_ARG_TYPES (fntype); + + error ("return type %q#T is incomplete", return_type); - /* Make it return void instead, but don't change the - type of the DECL_RESULT, in case we have a named return value. */ + /* Make it return void instead. */ if (TREE_CODE (fntype) == METHOD_TYPE) - { - tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))); - TREE_TYPE (decl) - = build_method_type_directly (ctype, - void_type_node, - FUNCTION_ARG_CHAIN (decl)); - } + fntype = build_method_type_directly (TREE_TYPE (TREE_VALUE (args)), + void_type_node, + TREE_CHAIN (args)); else - TREE_TYPE (decl) - = build_function_type (void_type_node, - TYPE_ARG_TYPES (TREE_TYPE (decl))); + fntype = build_function_type (void_type_node, args); TREE_TYPE (decl) = build_exception_variant (fntype, - TYPE_RAISES_EXCEPTIONS (fntype)); + TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl))); } else abstract_virtuals_error (decl, TREE_TYPE (fntype)); @@ -9997,6 +10077,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) tree current_function_parms; struct c_fileinfo *finfo = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)))); + bool honor_interface; /* Sanity check. */ gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); @@ -10211,6 +10292,15 @@ start_preparsed_function (tree decl1, tree attrs, int flags) } } + honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1) + /* Implicitly-defined methods (like the + destructor for a class in which no destructor + is explicitly declared) must not be defined + until their definition is needed. So, we + ignore interface specifications for + compiler-generated functions. */ + && !DECL_ARTIFICIAL (decl1)); + if (DECL_INTERFACE_KNOWN (decl1)) { tree ctx = decl_function_context (decl1); @@ -10227,8 +10317,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* If this function belongs to an interface, it is public. If it belongs to someone else's interface, it is also external. This only affects inlines and template instantiations. */ - else if (finfo->interface_unknown == 0 - && ! DECL_TEMPLATE_INSTANTIATION (decl1)) + else if (!finfo->interface_unknown && honor_interface) { if (DECL_DECLARED_INLINE_P (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1) @@ -10245,7 +10334,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags) } else DECL_EXTERNAL (decl1) = 0; - DECL_NOT_REALLY_EXTERN (decl1) = 0; DECL_INTERFACE_KNOWN (decl1) = 1; /* If this function is in an interface implemented in this file, make sure that the backend knows to emit this function @@ -10254,7 +10342,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) mark_needed (decl1); } else if (finfo->interface_unknown && finfo->interface_only - && ! DECL_TEMPLATE_INSTANTIATION (decl1)) + && honor_interface) { /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface, we will have both finfo->interface_unknown and @@ -10575,14 +10663,16 @@ finish_destructor_body (void) /* Do the necessary processing for the beginning of a function body, which in this case includes member-initializers, but not the catch clauses of a function-try-block. Currently, this means opening a binding level - for the member-initializers (in a ctor) and member cleanups (in a dtor). - In other functions, this isn't necessary, but it doesn't hurt. */ + for the member-initializers (in a ctor) and member cleanups (in a dtor). */ tree begin_function_body (void) { tree stmt; + if (! FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) + return NULL_TREE; + if (processing_template_decl) /* Do nothing now. */; else @@ -10613,6 +10703,9 @@ begin_function_body (void) void finish_function_body (tree compstmt) { + if (compstmt == NULL_TREE) + return; + /* Close the block. */ finish_compound_stmt (compstmt); @@ -10624,6 +10717,20 @@ finish_function_body (tree compstmt) finish_destructor_body (); } +/* Given a function, returns the BLOCK corresponding to the outermost level + of curly braces, skipping the artificial block created for constructor + initializers. */ + +static tree +outer_curly_brace_block (tree fndecl) +{ + tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)); + if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) + /* Skip the artificial function body block. */ + block = BLOCK_SUBBLOCKS (block); + return block; +} + /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage for the function definition. @@ -10755,9 +10862,7 @@ finish_function (int flags) the function so we know that their lifetime always ends with a return; see g++.dg/opt/nrv6.C. We could be more flexible if we were to do this optimization in tree-ssa. */ - && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))) - /* Skip the artificial function body block. */ - && (outer = BLOCK_SUBBLOCKS (outer)) + && (outer = outer_curly_brace_block (fndecl)) && chain_member (r, BLOCK_VARS (outer))) finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl)); @@ -10898,7 +11003,7 @@ start_method (cp_decl_specifier_seq *declspecs, && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL) error ("%qD is already defined in class %qT", fndecl, DECL_CONTEXT (fndecl)); - return void_type_node; + return error_mark_node; } check_template_shadow (fndecl);