diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 230 | ||||
-rw-r--r-- | gcc/cp/class.c | 36 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 5 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.c | 23 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.h | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 40 | ||||
-rw-r--r-- | gcc/cp/decl.c | 100 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 25 | ||||
-rw-r--r-- | gcc/cp/error.c | 38 | ||||
-rw-r--r-- | gcc/cp/except.c | 1 | ||||
-rw-r--r-- | gcc/cp/init.c | 114 | ||||
-rw-r--r-- | gcc/cp/lex.c | 3 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 75 | ||||
-rw-r--r-- | gcc/cp/method.c | 2 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 28 | ||||
-rw-r--r-- | gcc/cp/operators.def | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 171 | ||||
-rw-r--r-- | gcc/cp/pt.c | 153 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 95 | ||||
-rw-r--r-- | gcc/cp/tree.c | 12 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 16 |
22 files changed, 795 insertions, 386 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9d1ab5a6211..54011417160 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,233 @@ +2009-03-29 Joseph Myers <joseph@codesourcery.com> + + PR preprocessor/34695 + * cp-tree.h (cp_cpp_error): Remove. + * error.c (cp_cpp_error): Remove. + * parser.c (cp_lexer_new_main): Set done_lexing instead of + client_diagnostic and error callback. + +2009-03-28 Paolo Bonzini <bonzini@gnu.org> + + * cp/cp-objcp-common.h (LANG_HOOKS_STATICP): Remove. + * cp/cp-objcp-common.c (cxx_staticp): Remove. + * cp/cp-tree.h (cxx_staticp): Remove. + +2009-03-28 Jakub Jelinek <jakub@redhat.com> + + PR c++/39554 + * parser.c (cp_parser_postfix_expression): Don't call + warning_if_disallowed_function_p. + +2009-03-27 Jan Hubicka <jh@suse.cz> + + * except.c (choose_personality_routine): Set terminate_node to abort + for java exceptions. + +2009-03-27 Dodji Seketeli <dodji@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR debug/37959 + * cp-objcp-common.h (LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P): Define. + (cp_function_decl_explicit_p): New prototype. + * cp-objcp-common.c (cp_function_decl_explicit_p): New function. + +2009-03-27 Andrew Pinski <andrew_pinski@playstation.sony.com> + + PR c++/38638 + * parser.c (cp_parser_elaborated_type_specifier): If we have a + typename tag and don't have either a TYPE_DECL or a + TEMPLATE_ID_EXPR, set the type to NULL. + +2009-03-27 Simon Martin <simartin@users.sourceforge.net> + + PR c++/37647 + * decl.c (grokdeclarator): Reject [con|de]stuctors in a non-class + scope. + +2009-03-27 Simon Martin <simartin@users.sourceforge.net> + + PR c++/29727 + * decl.c (check_array_designated_initializer): Handle error_mark_node. + +2009-03-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + + PR c++/35652 + * typeck.c (cp_pointer_sum): Adjust call to pointer_int_sum. + +2009-03-26 Andrew Haley <aph@redhat.com> + + PR C++/39380 + * decl2.c (possibly_inlined_p): If java exceptions are in use + don't inline a decl unless it is explicitly marked inline. + * lex.c: (pragma_java_exceptions): New variable. + (handle_pragma_java_exceptions): Set pragma_java_exceptions. + * cp-tree.h (pragma_java_exceptions): Declare new variable. + +2009-03-24 Jason Merrill <jason@redhat.com> + + PR c++/28274 + * name-lookup.c (pushdecl_maybe_friend): Check default args later. + +2009-03-23 Jakub Jelinek <jakub@redhat.com> + + PR c/39495 + * semantics.c (handle_omp_for_class_iterator): Swap cond operands and + code if iter is the second operand. + * parser.c (cp_parser_binary_expression): Add no_toplevel_fold_p + argument. If it is set, don't build the toplevel expression with + build_x_binary_op, but build2. + (cp_parser_assignment_expression, cp_parser_omp_for_incr): Adjust + callers. + (cp_parser_omp_for_cond): Don't assume the first operand of the + comparison must be decl. + +2009-03-23 Jason Merrill <jason@redhat.com> + + PR c++/37729 + * pt.c (make_fnparm_pack): Split out from... + (instantiate_decl): ...here. + (tsubst_pack_expansion): Handle being called in a late-specified + return type. + + PR c++/39526 + * name-lookup.c (pushdecl_maybe_friend): Don't warn about shadowing + a parm with a parm. + +2009-03-20 Jason Merrill <jason@redhat.com> + + PR c++/28879 + * parser.c (cp_parser_direct_declarator): In a template, wrap + non-constant expression in NOP_EXPR with TREE_SIDE_EFFECTS set. + * pt.c (tsubst): Preserve it in a partial instantiation. + (dependent_type_p_r): Don't check value_dependent_expression_p. + * decl.c (compute_array_index_type): Don't check + value_dependent_expression_p if TREE_SIDE_EFFECTS. + + C++ core issue 703 + * typeck2.c (check_narrowing): Don't complain about loss of + precision when converting a floating-point constant. + +2009-03-19 Jakub Jelinek <jakub@redhat.com> + + PR c/39495 + * parser.c (cp_parser_omp_for_cond): Don't check lhs if decl is NULL. + (cp_parser_omp_for_loop): Always use cp_parser_omp_for_cond. + +2009-03-18 Jakub Jelinek <jakub@redhat.com> + + * parser.c (struct cp_token): Reorder fields for 64-bit hosts. + (eof_token): Adjust. + +2009-03-18 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/39425 + * parser.c (cp_parser_explicit_specialization): Don't skip the + rest of the specialization when begin_specialization returns + false. + +2009-03-17 Jason Merrill <jason@redhat.com> + + * decl.c (grokfndecl): Set DECL_CONTEXT on parms. + (duplicate_decls): Adjust DECL_CONTEXT of newdecl's parms. + * pt.c (check_explicit_specialization): Likewise. + (tsubst_copy) [PARM_DECL]: Return a dummy parm if we don't have a + local specialization. + * tree.c (cp_tree_equal) [PARM_DECL]: Check type and index, not name. + * decl2.c (parm_index): New fn. + * semantics.c (finish_decltype_type): Don't use describable_type. + * mangle.c (write_expression): Likewise. Mangle ALIGNOF_EXPR. + Give a sorry for unsupported codes rather than crash. Mangle + conversions with other than 1 operand. New mangling for PARM_DECL. + * operators.def (ALIGNOF_EXPR): Mangle as "az". + +2009-03-17 Jing Yu <jingyu@google.com> + + PR middle-end/39378 + * method.c (use_thunk): Change is_thunk from crtl to cfun. + +2009-03-17 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/39475 + * semantics.c (check_trait_type): New. + (finish_trait_expr): Use it. + +2009-03-17 Jakub Jelinek <jakub@redhat.com> + + * name-lookup.c (cp_emit_debug_info_for_using): Emit USING_STMTs + instead of calling imported_module_or_decl debug hook if + building_stmt_tree (). + * cp-gimplify.c (cp_gimplify_expr): Don't assert the first operand + is a NAMESPACE_DECL. + + PR debug/37890 + * name-lookup.c (do_namespace_alias): Don't call global_decl debug + hook at function scope. + + PR debug/39471 + * cp-gimplify.c (cp_gimplify_expr): Don't set DECL_NAME + on IMPORTED_DECL. + +2009-03-09 Jakub Jelinek <jakub@redhat.com> + + PR c++/39371 + * semantics.c (finish_switch_cond): Don't call get_unwidened. + * decl.c (finish_case_label): Pass SWITCH_STMT_TYPE as 3rd argument + instead of TREE_TYPE (cond). + +2009-03-08 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/39060 + * parser.c (cp_parser_late_parsing_default_args): Continue + the loop when cp_parser_assignment_expression returns + error_mark_node. + +2009-03-07 Jason Merrill <jason@redhat.com> + + PR c++/39367 + * init.c (build_new_1): Don't use a VLA type. + (build_vec_init): Handle getting a pointer for BASE. + +2009-03-06 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/37520 + * cp-tree.h: Check NO_DOT_IN_LABEL before NO_DOLLAR_IN_LABEL + when mangling symbols. + +2009-03-06 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/33492 + * error.c (dump_expr): Don't try to print THROW_EXPRs in full. + +2009-03-06 Alexandre Oliva <aoliva@redhat.com> + + * decl.c (record_builtin_java_type): Use canonicalized integer + types. + +2009-03-04 Jason Merrill <jason@redhat.com> + + PR c++/38908 + * class.c (is_really_empty_class): New fn. + * cp-tree.h: Declare it. + * cp-objcp-common.c (cp_expr_size): Use it. + + PR c++/13549 + * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR. + * parser.c (cp_parser_postfix_expression): Call it for + TEMPLATE_ID_EXPR. + * tree.c (is_overloaded_fn): Look through TEMPLATE_ID_EXPR. + (get_first_fn): Likewise. + + PR c++/9634 + PR c++/29469 + PR c++/29607 + Implement DR 224. + * decl.c (make_typename_type): Do look inside currently open classes. + * parser.c (cp_parser_lookup_name): Likewise. + (cp_parser_template_name): Likewise. + * pt.c (dependent_scope_p): New function. + * cp-tree.h: Declare it. + * class.c (currently_open_class): Return fast if T isn't a class. + 2009-02-26 H.J. Lu <hongjiu.lu@intel.com> PR c++/37789 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 13fa99027aa..b8553effc03 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5787,6 +5787,9 @@ currently_open_class (tree t) { int i; + if (!CLASS_TYPE_P (t)) + return false; + /* We start looking from 1 because entry 0 is from global scope, and has no type. */ for (i = current_class_depth; i > 0; --i) @@ -6458,7 +6461,7 @@ is_empty_class (tree type) if (type == error_mark_node) return 0; - if (! MAYBE_CLASS_TYPE_P (type)) + if (! CLASS_TYPE_P (type)) return 0; /* In G++ 3.2, whether or not a class was empty was determined by @@ -6498,6 +6501,37 @@ contains_empty_class_p (tree type) return false; } +/* Returns true if TYPE contains no actual data, just various + possible combinations of empty classes. */ + +bool +is_really_empty_class (tree type) +{ + if (is_empty_class (type)) + return true; + if (CLASS_TYPE_P (type)) + { + tree field; + tree binfo; + tree base_binfo; + int i; + + for (binfo = TYPE_BINFO (type), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + if (!is_really_empty_class (BINFO_TYPE (base_binfo))) + return false; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + && !is_really_empty_class (TREE_TYPE (field))) + return false; + return true; + } + else if (TREE_CODE (type) == ARRAY_TYPE) + return is_really_empty_class (TREE_TYPE (type)); + return false; +} + /* Note that NAME was looked up while the current class was being defined and that the result of that lookup was DECL. */ diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 838a9d6fa42..bb12988d1fa 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -585,16 +585,13 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) if (block) { tree using_directive; - gcc_assert (TREE_OPERAND (*expr_p,0) - && NAMESPACE_DECL_CHECK (TREE_OPERAND (*expr_p, 0))); + gcc_assert (TREE_OPERAND (*expr_p, 0)); using_directive = make_node (IMPORTED_DECL); TREE_TYPE (using_directive) = void_type_node; IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = TREE_OPERAND (*expr_p, 0); - DECL_NAME (using_directive) - = DECL_NAME (TREE_OPERAND (*expr_p, 0)); TREE_CHAIN (using_directive) = BLOCK_VARS (block); BLOCK_VARS (block) = using_directive; } diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 7d2e870bc80..2363cd7abdb 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -1,5 +1,5 @@ /* Some code common to C++ and ObjC++ front ends. - Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Ziemowit Laski <zlaski@apple.com> This file is part of GCC. @@ -101,7 +101,7 @@ cp_expr_size (const_tree exp) constructed, this is a valid transformation. */ || CP_AGGREGATE_TYPE_P (type)) /* This would be wrong for a type with virtual bases. */ - return (is_empty_class (type) + return (is_really_empty_class (type) ? size_zero_node : CLASSTYPE_SIZE_UNIT (type)); else @@ -188,19 +188,14 @@ cxx_types_compatible_p (tree x, tree y) return same_type_ignoring_top_level_qualifiers_p (x, y); } -tree -cxx_staticp (tree arg) -{ - switch (TREE_CODE (arg)) - { - case BASELINK: - return staticp (BASELINK_FUNCTIONS (arg)); +/* Return true if DECL is explicit member function. */ - default: - break; - } - - return NULL_TREE; +bool +cp_function_decl_explicit_p (tree decl) +{ + return (decl + && FUNCTION_FIRST_USER_PARMTYPE (decl) != void_list_node + && DECL_NONCONVERTING_P (decl)); } /* Stubs to keep c-opts.c happy. */ diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index f24107598aa..1ce9d36a652 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -1,5 +1,5 @@ /* Language hooks common to C++ and ObjC++ front ends. - Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Ziemowit Laski <zlaski@apple.com> This file is part of GCC. @@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool); +extern bool cp_function_decl_explicit_p (tree decl); + /* Lang hooks that are shared between C++ and ObjC++ are defined here. Hooks specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c, respectively. */ @@ -50,12 +52,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set -#undef LANG_HOOKS_EXPAND_EXPR -#define LANG_HOOKS_EXPAND_EXPR c_expand_expr #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE c_common_parse_file -#undef LANG_HOOKS_STATICP -#define LANG_HOOKS_STATICP cxx_staticp #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME @@ -131,6 +129,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset #undef LANG_HOOKS_GIMPLIFY_EXPR #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr +#undef LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P +#define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P cp_function_decl_explicit_p #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 46ff9222b97..ca198561e93 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -43,9 +43,6 @@ along with GCC; see the file COPYING3. If not see #else #define ATTRIBUTE_GCC_CXXDIAG(m, n) ATTRIBUTE_NONNULL(m) #endif -extern void cp_cpp_error (cpp_reader *, int, - const char *, va_list *) - ATTRIBUTE_GCC_CXXDIAG(3,0); #ifdef GCC_TOPLEV_H #error \ In order for the format checking to accept the C++ front end diagnostic \ @@ -3660,20 +3657,8 @@ extern GTY(()) VEC(tree,gc) *local_classes; at a particular location, we can index into the string at any other location that provides distinguishing characters). */ -/* Define NO_DOLLAR_IN_LABEL in your favorite tm file if your assembler - doesn't allow '$' in symbol names. */ -#ifndef NO_DOLLAR_IN_LABEL - -#define JOINER '$' - -#define AUTO_TEMP_NAME "_$tmp_" -#define VFIELD_BASE "$vf" -#define VFIELD_NAME "_vptr$" -#define VFIELD_NAME_FORMAT "_vptr$%s" -#define ANON_AGGRNAME_FORMAT "$_%d" - -#else /* NO_DOLLAR_IN_LABEL */ - +/* Define NO_DOT_IN_LABEL in your favorite tm file if your assembler + doesn't allow '.' in symbol names. */ #ifndef NO_DOT_IN_LABEL #define JOINER '.' @@ -3687,6 +3672,18 @@ extern GTY(()) VEC(tree,gc) *local_classes; #else /* NO_DOT_IN_LABEL */ +#ifndef NO_DOLLAR_IN_LABEL + +#define JOINER '$' + +#define AUTO_TEMP_NAME "_$tmp_" +#define VFIELD_BASE "$vf" +#define VFIELD_NAME "_vptr$" +#define VFIELD_NAME_FORMAT "_vptr$%s" +#define ANON_AGGRNAME_FORMAT "$_%d" + +#else /* NO_DOLLAR_IN_LABEL */ + #define IN_CHARGE_NAME "__in_chrg" #define AUTO_TEMP_NAME "__tmp_" #define TEMP_NAME_P(ID_NODE) \ @@ -3709,8 +3706,8 @@ extern GTY(()) VEC(tree,gc) *local_classes; sizeof (ANON_AGGRNAME_PREFIX) - 1)) #define ANON_AGGRNAME_FORMAT "__anon_%d" -#endif /* NO_DOT_IN_LABEL */ #endif /* NO_DOLLAR_IN_LABEL */ +#endif /* NO_DOT_IN_LABEL */ #define THIS_NAME "this" @@ -4171,6 +4168,9 @@ struct tinst_level GTY(()) e.g "int f(void)". */ extern cp_parameter_declarator *no_parameters; +/* True if we saw "#pragma GCC java_exceptions". */ +extern bool pragma_java_exceptions; + /* in call.c */ extern bool check_dtor_name (tree, tree); @@ -4240,6 +4240,7 @@ extern void finish_struct_1 (tree); extern int resolves_to_fixed_type_p (tree, int *); extern void init_class_processing (void); extern int is_empty_class (tree); +extern bool is_really_empty_class (tree); extern void pushclass (tree); extern void popclass (void); extern void push_nested_class (tree); @@ -4435,6 +4436,7 @@ extern bool decl_needed_p (tree); extern void note_vague_linkage_fn (tree); extern tree build_artificial_parm (tree, tree); extern bool possibly_inlined_p (tree); +extern int parm_index (tree); /* in error.c */ extern void init_error (void); @@ -4594,6 +4596,7 @@ extern struct tinst_level *current_instantiation(void); extern tree maybe_get_template_decl_from_type_decl (tree); extern int processing_template_parmlist; extern bool dependent_type_p (tree); +extern bool dependent_scope_p (tree); extern bool any_dependent_template_arguments_p (const_tree); extern bool dependent_template_p (tree); extern bool dependent_template_id_p (tree, tree); @@ -5047,7 +5050,6 @@ extern bool cp_var_mod_type_p (tree, tree); extern void cxx_initialize_diagnostics (struct diagnostic_context *); extern int cxx_types_compatible_p (tree, tree); extern void init_shadowed_var_for_decl (void); -extern tree cxx_staticp (tree); /* in cp-gimplify.c */ extern int cp_gimplify_expr (tree *, gimple_seq *, diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 551764dc29c..b16ae262bea 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1684,8 +1684,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) = DECL_SOURCE_LOCATION (newdecl); DECL_INITIAL (old_result) = DECL_INITIAL (new_result); if (DECL_FUNCTION_TEMPLATE_P (newdecl)) - DECL_ARGUMENTS (old_result) - = DECL_ARGUMENTS (new_result); + { + tree parm; + DECL_ARGUMENTS (old_result) + = DECL_ARGUMENTS (new_result); + for (parm = DECL_ARGUMENTS (old_result); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = old_result; + } } return olddecl; @@ -1918,6 +1924,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (TREE_CODE (newdecl) == FUNCTION_DECL) { + tree parm; + if (DECL_TEMPLATE_INSTANTIATION (olddecl) && !DECL_TEMPLATE_INSTANTIATION (newdecl)) { @@ -1974,6 +1982,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Preserve abstractness on cloned [cd]tors. */ DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl); + /* Update newdecl's parms to point at olddecl. */ + for (parm = DECL_ARGUMENTS (newdecl); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = olddecl; + if (! types_match) { SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl)); @@ -2006,7 +2019,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) } DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - /* Don't clear out the arguments if we're redefining a function. */ + /* Don't clear out the arguments if we're just redeclaring a + function. */ if (DECL_ARGUMENTS (olddecl)) DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); } @@ -2806,7 +2820,8 @@ finish_case_label (tree low_value, tree high_value) if (!check_switch_goto (switch_stack->level)) return error_mark_node; - r = c_add_case_label (switch_stack->cases, cond, TREE_TYPE (cond), + r = c_add_case_label (switch_stack->cases, cond, + SWITCH_STMT_TYPE (switch_stack->switch_stmt), low_value, high_value); /* After labels, make any new cleanups in the function go into their @@ -2977,12 +2992,6 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); gcc_assert (TYPE_P (context)); - /* When the CONTEXT is a dependent type, NAME could refer to a - dependent base class of CONTEXT. So we cannot peek inside it, - even if CONTEXT is a currently open scope. */ - if (dependent_type_p (context)) - return build_typename_type (context, name, fullname, tag_type); - if (!MAYBE_CLASS_TYPE_P (context)) { if (complain & tf_error) @@ -2990,11 +2999,23 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } + /* When the CONTEXT is a dependent type, NAME could refer to a + dependent base class of CONTEXT. But look inside it anyway + if CONTEXT is a currently open scope, in case it refers to a + member of the current instantiation or a non-dependent base; + lookup will stop when we hit a dependent base. */ + if (!dependent_scope_p (context)) + /* We should only set WANT_TYPE when we're a nested typename type. + Then we can give better diagnostics if we find a non-type. */ + t = lookup_field (context, name, 0, /*want_type=*/true); + else + t = NULL_TREE; + + if (!t && dependent_type_p (context)) + return build_typename_type (context, name, fullname, tag_type); + want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR; - /* We should only set WANT_TYPE when we're a nested typename type. - Then we can give better diagnostics if we find a non-type. */ - t = lookup_field (context, name, 0, /*want_type=*/true); if (!t) { if (complain & tf_error) @@ -3162,10 +3183,18 @@ record_builtin_java_type (const char* name, int size) { tree type, decl; if (size > 0) - type = make_signed_type (size); + type = build_nonstandard_integer_type (size, 0); else if (size > -32) - { /* "__java_char" or ""__java_boolean". */ - type = make_unsigned_type (-size); + { + tree stype; + /* "__java_char" or ""__java_boolean". */ + type = build_nonstandard_integer_type (-size, 1); + /* Get the signed type cached and attached to the unsigned type, + so it doesn't get garbage-collected at "random" times, + causing potential codegen differences out of different UIDs + and different alias set numbers. */ + stype = build_nonstandard_integer_type (-size, 0); + TREE_CHAIN (type) = stype; /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/ } else @@ -4390,9 +4419,15 @@ check_array_designated_initializer (const constructor_elt *ce) { /* The parser only allows identifiers as designated initializers. */ - gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE); - error ("name %qD used in a GNU-style designated " - "initializer for an array", ce->index); + if (ce->index == error_mark_node) + error ("name used in a GNU-style designated " + "initializer for an array"); + else + { + gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE); + error ("name %qD used in a GNU-style designated " + "initializer for an array", ce->index); + } return false; } @@ -6540,6 +6575,8 @@ grokfndecl (tree ctype, parms = parm; } DECL_ARGUMENTS (decl) = parms; + for (t = parms; t; t = TREE_CHAIN (t)) + DECL_CONTEXT (t) = decl; /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; @@ -7148,13 +7185,22 @@ compute_array_index_type (tree name, tree size) type = TREE_TYPE (size); } - if (value_dependent_expression_p (size)) + /* We can only call value_dependent_expression_p on integral constant + expressions; the parser adds a dummy NOP_EXPR with TREE_SIDE_EFFECTS + set if this isn't one. */ + if (processing_template_decl + && (TREE_SIDE_EFFECTS (size) || value_dependent_expression_p (size))) { - /* We cannot do any checking for a value-dependent SIZE. Just - build the index type and mark that it requires structural - equality checks. */ + /* We cannot do any checking for a SIZE that isn't known to be + constant. Just build the index type and mark that it requires + structural equality checks. */ itype = build_index_type (build_min (MINUS_EXPR, sizetype, size, integer_one_node)); + if (!TREE_SIDE_EFFECTS (size)) + { + TYPE_DEPENDENT_P (itype) = 1; + TYPE_DEPENDENT_P_VALID (itype) = 1; + } SET_TYPE_STRUCTURAL_EQUALITY (itype); return itype; } @@ -9300,6 +9346,14 @@ grokdeclarator (const cp_declarator *declarator, error ("virtual non-class function %qs", name); virtualp = 0; } + else if (sfk == sfk_constructor + || sfk == sfk_destructor) + { + error (funcdef_flag + ? "%qs defined in a non-class scope" + : "%qs declared in a non-class scope", name); + sfk = sfk_none; + } } else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 && !NEW_DELETE_OPNAME_P (original_name)) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d57015005b4..2be621da7c5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3772,7 +3772,7 @@ possibly_inlined_p (tree decl) gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); if (DECL_UNINLINABLE (decl)) return false; - if (!optimize) + if (!optimize || pragma_java_exceptions) return DECL_DECLARED_INLINE_P (decl); /* When optimizing, we might inline everything when flatten attribute or heuristics inlining for size or autoinlining @@ -3907,4 +3907,27 @@ mark_used (tree decl) processing_template_decl = saved_processing_template_decl; } +/* Given function PARM_DECL PARM, return its index in the function's list + of parameters, beginning with 1. */ + +int +parm_index (tree parm) +{ + int index; + tree arg; + + for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm)); + arg; + ++index, arg = TREE_CHAIN (arg)) + { + if (DECL_NAME (parm) == DECL_NAME (arg)) + break; + if (DECL_ARTIFICIAL (arg)) + --index; + } + + gcc_assert (arg); + return index; +} + #include "gt-cp-decl2.h" diff --git a/gcc/cp/error.c b/gcc/cp/error.c index e2cb8bf0ecc..161fa55a17f 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1508,8 +1508,9 @@ dump_expr (tree t, int flags) break; case THROW_EXPR: - pp_cxx_identifier (cxx_pp, "throw"); - dump_expr (TREE_OPERAND (t, 0), flags); + /* While waiting for caret diagnostics, avoid printing + __cxa_allocate_exception, __cxa_throw, and the like. */ + pp_cxx_identifier (cxx_pp, "<throw-expression>"); break; case PTRMEM_CST: @@ -2665,39 +2666,6 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec, #undef next_int } -/* Callback from cpp_error for PFILE to print diagnostics arising from - interpreting strings. The diagnostic is of type LEVEL; MSG is the - translated message and AP the arguments. */ - -void -cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, - const char *msg, va_list *ap) -{ - diagnostic_info diagnostic; - diagnostic_t dlevel; - switch (level) - { - case CPP_DL_WARNING: - case CPP_DL_WARNING_SYSHDR: - dlevel = DK_WARNING; - break; - case CPP_DL_PEDWARN: - dlevel = DK_PEDWARN; - break; - case CPP_DL_ERROR: - dlevel = DK_ERROR; - break; - case CPP_DL_ICE: - dlevel = DK_ICE; - break; - default: - gcc_unreachable (); - } - diagnostic_set_info_translated (&diagnostic, msg, ap, - input_location, dlevel); - report_diagnostic (&diagnostic); -} - /* Warn about the use of C++0x features when appropriate. */ void maybe_warn_cpp0x (const char* str) diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 7813d087405..2638ccc90d9 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -353,6 +353,7 @@ choose_personality_routine (enum languages lang) case lang_java: state = chose_java; + terminate_node = built_in_decls [BUILT_IN_ABORT]; eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gcj_personality_sj0" : "__gcj_personality_v0"); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 85c496bbaf2..8e3e4895264 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1787,23 +1787,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, /* True iff this is a call to "operator new[]" instead of just "operator new". */ bool array_p = false; - /* True iff ARRAY_P is true and the bound of the array type is - not necessarily a compile time constant. For example, VLA_P is - true for "new int[f()]". */ - bool vla_p = false; - /* The type being allocated. If ARRAY_P is true, this will be an - ARRAY_TYPE. */ - tree full_type; - /* If ARRAY_P is true, the element type of the array. This is an - never ARRAY_TYPE; for something like "new int[3][4]", the + /* If ARRAY_P is true, the element type of the array. This is never + an ARRAY_TYPE; for something like "new int[3][4]", the ELT_TYPE is "int". If ARRAY_P is false, this is the same type as - FULL_TYPE. */ + TYPE. */ tree elt_type; /* The type of the new-expression. (This type is always a pointer type.) */ tree pointer_type; - /* A pointer type pointing to the FULL_TYPE. */ - tree full_pointer_type; tree outer_nelts = NULL_TREE; tree alloc_call, alloc_expr; /* The address returned by the call to "operator new". This node is @@ -1834,35 +1825,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, if (nelts) { - tree index; - outer_nelts = nelts; array_p = true; - - /* ??? The middle-end will error on us for building a VLA outside a - function context. Methinks that's not it's purvey. So we'll do - our own VLA layout later. */ - vla_p = true; - index = convert (sizetype, nelts); - index = size_binop (MINUS_EXPR, index, size_one_node); - index = build_index_type (index); - full_type = build_cplus_array_type (type, NULL_TREE); - /* We need a copy of the type as build_array_type will return a shared copy - of the incomplete array type. */ - full_type = build_distinct_type_copy (full_type); - TYPE_DOMAIN (full_type) = index; - SET_TYPE_STRUCTURAL_EQUALITY (full_type); } - else + else if (TREE_CODE (type) == ARRAY_TYPE) { - full_type = type; - if (TREE_CODE (type) == ARRAY_TYPE) - { - array_p = true; - nelts = array_type_nelts_top (type); - outer_nelts = nelts; - type = TREE_TYPE (type); - } + array_p = true; + nelts = array_type_nelts_top (type); + outer_nelts = nelts; + type = TREE_TYPE (type); } /* If our base type is an array, then make sure we know how many elements @@ -1897,21 +1868,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, size = size_in_bytes (elt_type); if (array_p) - { - size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); - if (vla_p) - { - tree n, bitsize; - - /* Do our own VLA layout. Setting TYPE_SIZE/_UNIT is - necessary in order for the <INIT_EXPR <*foo> <CONSTRUCTOR - ...>> to be valid. */ - TYPE_SIZE_UNIT (full_type) = size; - n = convert (bitsizetype, nelts); - bitsize = size_binop (MULT_EXPR, TYPE_SIZE (elt_type), n); - TYPE_SIZE (full_type) = bitsize; - } - } + size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); alloc_fn = NULL_TREE; @@ -2139,8 +2096,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, } /* Now use a pointer to the type we've actually allocated. */ - full_pointer_type = build_pointer_type (full_type); - data_addr = fold_convert (full_pointer_type, data_addr); + data_addr = fold_convert (pointer_type, data_addr); + /* Any further uses of alloc_node will want this type, too. */ + alloc_node = fold_convert (pointer_type, alloc_node); /* Now initialize the allocated object. Note that we preevaluate the initialization expression, apart from the actual constructor call or @@ -2152,8 +2110,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, bool stable; bool explicit_value_init_p = false; - init_expr = cp_build_indirect_ref (data_addr, NULL, complain); - if (init == void_zero_node) { init = NULL_TREE; @@ -2170,7 +2126,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, return error_mark_node; } init_expr - = build_vec_init (init_expr, + = build_vec_init (data_addr, cp_build_binary_op (input_location, MINUS_EXPR, outer_nelts, integer_one_node, @@ -2187,6 +2143,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, } else { + init_expr = cp_build_indirect_ref (data_addr, NULL, complain); + if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p) { init_expr = build_special_member_call (init_expr, @@ -2198,8 +2156,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, else if (explicit_value_init_p) { /* Something like `new int()'. */ - init_expr = build2 (INIT_EXPR, full_type, - init_expr, build_value_init (full_type)); + init_expr = build2 (INIT_EXPR, type, + init_expr, build_value_init (type)); } else { @@ -2240,7 +2198,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, functions that we use for finding allocation functions. */ cleanup = (build_op_delete_call (dcode, - fold_convert (full_pointer_type, alloc_node), + alloc_node, size, globally_qualified_p, placement_allocation_fn_p ? alloc_call : NULL_TREE, @@ -2323,9 +2281,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, if (init_preeval_expr) rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval); - /* Convert to the final type. */ - rval = build_nop (pointer_type, rval); - /* A new-expression is never an lvalue. */ gcc_assert (!lvalue_p (rval)); @@ -2665,9 +2620,10 @@ get_temp_regvar (tree type, tree init) /* `build_vec_init' returns tree structure that performs initialization of a vector of aggregate types. - BASE is a reference to the vector, of ARRAY_TYPE. + BASE is a reference to the vector, of ARRAY_TYPE, or a pointer + to the first element, of POINTER_TYPE. MAXINDEX is the maximum index of the array (one less than the - number of elements). It is only used if + number of elements). It is only used if BASE is a pointer or TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE. INIT is the (possibly NULL) initializer. @@ -2692,7 +2648,7 @@ build_vec_init (tree base, tree maxindex, tree init, tree size; tree itype = NULL_TREE; tree iterator; - /* The type of the array. */ + /* The type of BASE. */ tree atype = TREE_TYPE (base); /* The type of an element in the array. */ tree type = TREE_TYPE (atype); @@ -2708,7 +2664,7 @@ build_vec_init (tree base, tree maxindex, tree init, int num_initialized_elts = 0; bool is_global; - if (TYPE_DOMAIN (atype)) + if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype)) maxindex = array_type_nelts (atype); if (maxindex == NULL_TREE || maxindex == error_mark_node) @@ -2717,7 +2673,7 @@ build_vec_init (tree base, tree maxindex, tree init, if (explicit_value_init_p) gcc_assert (!init); - inner_elt_type = strip_array_types (atype); + inner_elt_type = strip_array_types (type); if (init && (from_array == 2 ? (!CLASS_TYPE_P (inner_elt_type) @@ -2734,15 +2690,20 @@ build_vec_init (tree base, tree maxindex, tree init, brace-enclosed initializers. In this case, digest_init and store_constructor will handle the semantics for us. */ + gcc_assert (TREE_CODE (atype) == ARRAY_TYPE); stmt_expr = build2 (INIT_EXPR, atype, base, init); return stmt_expr; } maxindex = cp_convert (ptrdiff_type_node, maxindex); - ptype = build_pointer_type (type); size = size_in_bytes (type); - if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE) - base = cp_convert (ptype, decay_conversion (base)); + if (TREE_CODE (atype) == ARRAY_TYPE) + { + ptype = build_pointer_type (type); + base = cp_convert (ptype, decay_conversion (base)); + } + else + ptype = atype; /* The code we are generating looks like: ({ @@ -2954,10 +2915,13 @@ build_vec_init (tree base, tree maxindex, tree init, stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt); - /* Now convert make the result have the correct type. */ - atype = build_pointer_type (atype); - stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); - stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain); + /* Now make the result have the correct type. */ + if (TREE_CODE (atype) == ARRAY_TYPE) + { + atype = build_pointer_type (atype); + stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); + stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain); + } current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; return stmt_expr; diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index d708b09658b..66377ff1564 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -81,6 +81,8 @@ struct impl_files static struct impl_files *impl_file_chain; +/* True if we saw "#pragma GCC java_exceptions". */ +bool pragma_java_exceptions; void cxx_finish (void) @@ -430,6 +432,7 @@ handle_pragma_java_exceptions (cpp_reader* dfile ATTRIBUTE_UNUSED) warning (0, "junk at end of #pragma GCC java_exceptions"); choose_personality_routine (lang_java); + pragma_java_exceptions = true; } /* Issue an error message indicating that the lookup of NAME (an diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c72747c768e..eabab7fb510 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2143,27 +2143,6 @@ write_expression (tree expr) { enum tree_code code = TREE_CODE (expr); - /* Inside decltype we can simplify some expressions, since we're only - interested in the type. */ - if (skip_evaluation) - { - tree type = describable_type (expr); - if (type == NULL_TREE) - ; - else if (TREE_CODE (type) == REFERENCE_TYPE) - { - write_string ("sT"); - write_type (TREE_TYPE (type)); - return; - } - else - { - write_string ("sR"); - write_type (type); - return; - } - } - /* Skip NOP_EXPRs. They can occur when (say) a pointer argument is converted (via qualification conversions) to another type. */ @@ -2210,10 +2189,12 @@ write_expression (tree expr) write_template_arg_literal (expr); else if (code == PARM_DECL) { - /* A function parameter used under decltype in a late-specified - return type. Represented with a type placeholder. */ - write_string ("sT"); - write_type (non_reference (TREE_TYPE (expr))); + /* A function parameter used in a late-specified return type. */ + int index = parm_index (expr); + write_string ("fp"); + if (index > 1) + write_unsigned_number (index - 2); + write_char ('_'); } else if (DECL_P (expr)) { @@ -2231,6 +2212,12 @@ write_expression (tree expr) write_string ("st"); write_type (TREE_OPERAND (expr, 0)); } + else if (TREE_CODE (expr) == ALIGNOF_EXPR + && TYPE_P (TREE_OPERAND (expr, 0))) + { + write_string ("at"); + write_type (TREE_OPERAND (expr, 0)); + } else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF) { tree scope = TREE_OPERAND (expr, 0); @@ -2298,9 +2285,16 @@ write_expression (tree expr) write_template_args (template_args); } } + else if (TREE_CODE (expr) == INDIRECT_REF + && TREE_TYPE (TREE_OPERAND (expr, 0)) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE) + { + write_expression (TREE_OPERAND (expr, 0)); + } else { int i; + const char *name; /* When we bind a variable or function to a non-type template argument with reference type, we create an ADDR_EXPR to show @@ -2338,7 +2332,14 @@ write_expression (tree expr) } /* If it wasn't any of those, recursively expand the expression. */ - write_string (operator_name_info[(int) code].mangled_name); + name = operator_name_info[(int) code].mangled_name; + if (name == NULL) + { + sorry ("mangling %C", code); + return; + } + else + write_string (name); switch (code) { @@ -2351,23 +2352,29 @@ write_expression (tree expr) case CAST_EXPR: write_type (TREE_TYPE (expr)); - /* There is no way to mangle a zero-operand cast like - "T()". */ - if (!TREE_OPERAND (expr, 0)) - sorry ("zero-operand casts cannot be mangled due to a defect " - "in the C++ ABI"); - else if (list_length (TREE_OPERAND (expr, 0)) > 1) - sorry ("mangling function-style cast with more than one argument"); - else + if (list_length (TREE_OPERAND (expr, 0)) == 1) write_expression (TREE_VALUE (TREE_OPERAND (expr, 0))); + else + { + tree args = TREE_OPERAND (expr, 0); + write_char ('_'); + for (; args; args = TREE_CHAIN (args)) + write_expression (TREE_VALUE (args)); + write_char ('E'); + } break; + /* FIXME these should have a distinct mangling. */ case STATIC_CAST_EXPR: case CONST_CAST_EXPR: write_type (TREE_TYPE (expr)); write_expression (TREE_OPERAND (expr, 0)); break; + case NEW_EXPR: + sorry ("mangling new-expression"); + break; + /* Handle pointers-to-members specially. */ case SCOPE_REF: write_type (TREE_OPERAND (expr, 0)); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 5b4c273dda9..e632fe0c9e6 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -436,7 +436,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) BLOCK_VARS (fn_block) = a; DECL_INITIAL (thunk_fndecl) = fn_block; init_function_start (thunk_fndecl); - crtl->is_thunk = 1; + cfun->is_thunk = 1; assemble_start_function (thunk_fndecl, fnname); targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b31742c669c..5a92dc6ed89 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -813,9 +813,6 @@ pushdecl_maybe_friend (tree x, bool is_friend) } } - if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x)) - check_default_args (x); - check_template_shadow (x); /* If this is a function conjured up by the back end, massage it @@ -826,11 +823,10 @@ pushdecl_maybe_friend (tree x, bool is_friend) SET_DECL_LANGUAGE (x, lang_c); } + t = x; if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x)) { t = push_overloaded_decl (x, PUSH_LOCAL, is_friend); - if (t != x) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); if (!namespace_bindings_p ()) /* We do not need to create a binding for this name; push_overloaded_decl will have already done so if @@ -842,9 +838,14 @@ pushdecl_maybe_friend (tree x, bool is_friend) t = push_overloaded_decl (x, PUSH_GLOBAL, is_friend); if (t == x) add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t))); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } + if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x)) + check_default_args (x); + + if (t != x || DECL_FUNCTION_TEMPLATE_P (t)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + /* If declaring a type as a typedef, copy the type (unless we're at line 0), and install this TYPE_DECL as the new type's typedef name. See the extensive comment in ../c-decl.c (pushdecl). */ @@ -1031,7 +1032,10 @@ pushdecl_maybe_friend (tree x, bool is_friend) } } - if (warn_shadow && !err) + if (warn_shadow && !err + /* Don't complain about the parms we push and then pop + while tentatively parsing a function declarator. */ + && !(TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE)) { warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x); warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal); @@ -3337,7 +3341,8 @@ do_namespace_alias (tree alias, tree name_space) pushdecl (alias); /* Emit debug info for namespace alias. */ - (*debug_hooks->global_decl) (alias); + if (!building_stmt_tree ()) + (*debug_hooks->global_decl) (alias); } /* Like pushdecl, only it places X in the current namespace, @@ -5386,7 +5391,12 @@ cp_emit_debug_info_for_using (tree t, tree context) /* FIXME: Handle TEMPLATE_DECLs. */ for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t)) if (TREE_CODE (t) != TEMPLATE_DECL) - (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false); + { + if (building_stmt_tree ()) + add_stmt (build_stmt (USING_STMT, t)); + else + (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false); + } } #include "gt-cp-name-lookup.h" diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index 698f0de43f4..20d811b812b 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -94,7 +94,7 @@ DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_EXPR, "pp", 1) DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1) DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1) /* These are extensions. */ -DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "v17alignof", 1) +DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "az", 1) DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1) DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 80a767ebe2d..09e19a23a5f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -77,6 +77,8 @@ typedef struct cp_token GTY (()) KEYWORD is RID_MAX) iff this name was looked up and found to be ambiguous. An error has already been reported. */ BOOL_BITFIELD ambiguous_p : 1; + /* The location at which this token was found. */ + location_t location; /* The value associated with this token, if any. */ union cp_token_value { /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */ @@ -84,8 +86,6 @@ typedef struct cp_token GTY (()) /* Use for all other tokens. */ tree GTY((tag ("0"))) value; } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u; - /* The location at which this token was found. */ - location_t location; } cp_token; /* We use a stack of token pointer for saving token sets. */ @@ -95,8 +95,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap); static cp_token eof_token = { - CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, { NULL }, - 0 + CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, 0, { NULL } }; /* The cp_lexer structure represents the C++ lexer. It is responsible @@ -310,8 +309,7 @@ cp_lexer_new_main (void) /* Subsequent preprocessor diagnostics should use compiler diagnostic functions to get the compiler source location. */ - cpp_get_options (parse_in)->client_diagnostic = true; - cpp_get_callbacks (parse_in)->error = cp_cpp_error; + done_lexing = true; gcc_assert (lexer->next_token->type != CPP_PURGED); return lexer; @@ -1616,7 +1614,7 @@ static tree cp_parser_delete_expression static tree cp_parser_cast_expression (cp_parser *, bool, bool, cp_id_kind *); static tree cp_parser_binary_expression - (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *); + (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *); static tree cp_parser_question_colon_clause (cp_parser *, tree); static tree cp_parser_assignment_expression @@ -4732,7 +4730,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } koenig_p = false; - if (idk == CP_ID_KIND_UNQUALIFIED) + if (idk == CP_ID_KIND_UNQUALIFIED + || idk == CP_ID_KIND_TEMPLATE_ID) { if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) { @@ -4823,9 +4822,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, koenig_p, tf_warning_or_error); - if (warn_disallowed_functions) - warn_if_disallowed_function_p (postfix_expression); - /* The POSTFIX_EXPRESSION is certainly no longer an id. */ idk = CP_ID_KIND_NONE; } @@ -6215,6 +6211,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, static tree cp_parser_binary_expression (cp_parser* parser, bool cast_p, + bool no_toplevel_fold_p, enum cp_parser_prec prec, cp_id_kind * pidk) { @@ -6297,6 +6294,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, goto get_rhs; pop: + lookahead_prec = new_prec; /* If the stack is not empty, we have parsed into LHS the right side (`4' in the example above) of an expression we had suspended. We can use the information on the stack to recover the LHS (`3') @@ -6321,8 +6319,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, pass the correct tree_code unless the unary expression was surrounded by parentheses. */ - lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type, - &overloaded_p, tf_warning_or_error); + if (no_toplevel_fold_p + && lookahead_prec <= prec + && sp == stack + && TREE_CODE_CLASS (tree_type) == tcc_comparison) + lhs = build2 (tree_type, boolean_type_node, lhs, rhs); + else + lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type, + &overloaded_p, tf_warning_or_error); lhs_type = tree_type; /* If the binary operator required the use of an overloaded operator, @@ -6408,7 +6412,8 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, else { /* Parse the binary expressions (logical-or-expression). */ - expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR, pidk); + expr = cp_parser_binary_expression (parser, cast_p, false, + PREC_NOT_OPERATOR, pidk); /* If the next token is a `?' then we're actually looking at a conditional-expression. */ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) @@ -10323,7 +10328,7 @@ cp_parser_template_name (cp_parser* parser, && !template_keyword_p && parser->scope && TYPE_P (parser->scope) && check_dependency_p - && dependent_type_p (parser->scope) + && dependent_scope_p (parser->scope) /* Do not do this for dtors (or ctors), since they never need the template keyword before their name. */ && !constructor_name_p (identifier, parser->scope)) @@ -10882,7 +10887,6 @@ cp_parser_explicit_specialization (cp_parser* parser) if (!begin_specialization ()) { end_specialization (); - cp_parser_skip_to_end_of_block_or_statement (parser); return; } @@ -11580,7 +11584,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, type = make_typename_type (parser->scope, decl, typename_type, /*complain=*/tf_error); - else + /* If the `typename' keyword is in effect and DECL is not a type + decl. Then type is non existant. */ + else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) + type = NULL_TREE; + else type = TREE_TYPE (decl); } @@ -13268,6 +13276,13 @@ cp_parser_direct_declarator (cp_parser* parser, &non_constant_p); if (!non_constant_p) bounds = fold_non_dependent_expr (bounds); + else if (processing_template_decl) + { + /* Remember this wasn't a constant-expression. */ + bounds = build_nop (TREE_TYPE (bounds), bounds); + TREE_SIDE_EFFECTS (bounds) = 1; + } + /* Normally, the array bound must be an integral constant expression. However, as an extension, we allow VLAs in function scopes. */ @@ -17023,35 +17038,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cannot look up the name if the scope is not a class type; it might, for example, be a template type parameter. */ dependent_p = (TYPE_P (parser->scope) - && !(parser->in_declarator_p - && currently_open_class (parser->scope)) - && dependent_type_p (parser->scope)); + && dependent_scope_p (parser->scope)); if ((check_dependency || !CLASS_TYPE_P (parser->scope)) - && dependent_p) - { - if (tag_type) - { - tree type; - - /* The resolution to Core Issue 180 says that `struct - A::B' should be considered a type-name, even if `A' - is dependent. */ - type = make_typename_type (parser->scope, name, tag_type, - /*complain=*/tf_error); - decl = TYPE_NAME (type); - } - else if (is_template - && (cp_parser_next_token_ends_template_argument_p (parser) - || cp_lexer_next_token_is (parser->lexer, - CPP_CLOSE_PAREN))) - decl = make_unbound_class_template (parser->scope, - name, NULL_TREE, - /*complain=*/tf_error); - else - decl = build_qualified_name (/*type=*/NULL_TREE, - parser->scope, name, - is_template); - } + && dependent_p) + /* Defer lookup. */ + decl = error_mark_node; else { tree pushed_scope = NULL_TREE; @@ -17072,14 +17063,42 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /*complain=*/true); /* If we have a single function from a using decl, pull it out. */ - if (decl - && TREE_CODE (decl) == OVERLOAD + if (TREE_CODE (decl) == OVERLOAD && !really_overloaded_fn (decl)) decl = OVL_FUNCTION (decl); if (pushed_scope) pop_scope (pushed_scope); } + + /* If the scope is a dependent type and either we deferred lookup or + we did lookup but didn't find the name, rememeber the name. */ + if (decl == error_mark_node && TYPE_P (parser->scope) + && dependent_type_p (parser->scope)) + { + if (tag_type) + { + tree type; + + /* The resolution to Core Issue 180 says that `struct + A::B' should be considered a type-name, even if `A' + is dependent. */ + type = make_typename_type (parser->scope, name, tag_type, + /*complain=*/tf_error); + decl = TYPE_NAME (type); + } + else if (is_template + && (cp_parser_next_token_ends_template_argument_p (parser) + || cp_lexer_next_token_is (parser->lexer, + CPP_CLOSE_PAREN))) + decl = make_unbound_class_template (parser->scope, + name, NULL_TREE, + /*complain=*/tf_error); + else + decl = build_qualified_name (/*type=*/NULL_TREE, + parser->scope, name, + is_template); + } parser->qualifying_scope = parser->scope; parser->object_scope = NULL_TREE; } @@ -18286,6 +18305,11 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) /* Parse the assignment-expression. */ parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); + if (parsed_arg == error_mark_node) + { + cp_parser_pop_lexer (parser); + continue; + } if (!processing_template_decl) parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg); @@ -21000,41 +21024,39 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok) static tree cp_parser_omp_for_cond (cp_parser *parser, tree decl) { - tree lhs = cp_parser_cast_expression (parser, false, false, NULL), rhs; - enum tree_code op; - cp_token *token; + tree cond = cp_parser_binary_expression (parser, false, true, + PREC_NOT_OPERATOR, NULL); + bool overloaded_p; - if (lhs != decl) + if (cond == error_mark_node + || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - token = cp_lexer_peek_token (parser->lexer); - op = binops_by_token [token->type].tree_type; - switch (op) + switch (TREE_CODE (cond)) { - case LT_EXPR: - case LE_EXPR: case GT_EXPR: case GE_EXPR: + case LT_EXPR: + case LE_EXPR: break; default: - cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_binary_expression (parser, false, - PREC_RELATIONAL_EXPRESSION, NULL); - if (rhs == error_mark_node - || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - cp_parser_skip_to_end_of_statement (parser); - return error_mark_node; - } + /* If decl is an iterator, preserve LHS and RHS of the relational + expr until finish_omp_for. */ + if (decl + && (type_dependent_expression_p (decl) + || CLASS_TYPE_P (TREE_TYPE (decl)))) + return cond; - return build2 (op, boolean_type_node, lhs, rhs); + return build_x_binary_op (TREE_CODE (cond), + TREE_OPERAND (cond, 0), ERROR_MARK, + TREE_OPERAND (cond, 1), ERROR_MARK, + &overloaded_p, tf_warning_or_error); } /* Helper function, to parse omp for increment expression. */ @@ -21083,7 +21105,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs); } - lhs = cp_parser_binary_expression (parser, false, + lhs = cp_parser_binary_expression (parser, false, false, PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); decl_first = lhs == decl; @@ -21097,7 +21119,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) { op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR; cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_binary_expression (parser, false, + rhs = cp_parser_binary_expression (parser, false, false, PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first) @@ -21406,16 +21428,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) cond = NULL; if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - /* If decl is an iterator, preserve LHS and RHS of the relational - expr until finish_omp_for. */ - if (decl - && (type_dependent_expression_p (decl) - || CLASS_TYPE_P (TREE_TYPE (decl)))) - cond = cp_parser_omp_for_cond (parser, decl); - else - cond = cp_parser_condition (parser); - } + cond = cp_parser_omp_for_cond (parser, decl); cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); incr = NULL; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dacc8689f38..5092c72b177 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -174,6 +174,7 @@ static tree tsubst (tree, tree, tsubst_flags_t, tree); static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree); +static tree tsubst_decl (tree, tree, tsubst_flags_t); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -2217,17 +2218,21 @@ check_explicit_specialization (tree declarator, the specialization of it. */ if (tsk == tsk_template) { + tree result = DECL_TEMPLATE_RESULT (tmpl); SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); - DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE; + DECL_INITIAL (result) = NULL_TREE; if (have_def) { + tree parm; DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl); - DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl)) + DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (decl); /* We want to use the argument list specified in the definition, not in the original declaration. */ - DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl)) - = DECL_ARGUMENTS (decl); + DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl); + for (parm = DECL_ARGUMENTS (result); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = result; } return tmpl; } @@ -7431,6 +7436,37 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) return r; } +/* Give a chain SPEC_PARM of PARM_DECLs, pack them into a + NONTYPE_ARGUMENT_PACK. */ + +static tree +make_fnparm_pack (tree spec_parm) +{ + /* Collect all of the extra "packed" parameters into an + argument pack. */ + tree parmvec; + tree parmtypevec; + tree argpack = make_node (NONTYPE_ARGUMENT_PACK); + tree argtypepack = make_node (TYPE_ARGUMENT_PACK); + int i, len = list_length (spec_parm); + + /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ + parmvec = make_tree_vec (len); + parmtypevec = make_tree_vec (len); + for (i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) + { + TREE_VEC_ELT (parmvec, i) = spec_parm; + TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); + } + + /* Build the argument packs. */ + SET_ARGUMENT_PACK_ARGS (argpack, parmvec); + SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); + TREE_TYPE (argpack) = argtypepack; + + return argpack; +} + /* Substitute ARGS into T, which is an pack expansion (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node @@ -7445,6 +7481,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree first_arg_pack; int i, len = -1; tree result; int incomplete = 0; + bool very_local_specializations = false; gcc_assert (PACK_EXPANSION_P (t)); pattern = PACK_EXPANSION_PATTERN (t); @@ -7461,7 +7498,18 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree orig_arg = NULL_TREE; if (TREE_CODE (parm_pack) == PARM_DECL) - arg_pack = retrieve_local_specialization (parm_pack); + { + arg_pack = retrieve_local_specialization (parm_pack); + if (arg_pack == NULL_TREE) + { + /* This can happen for a parameter name used later in a function + declaration (such as in a late-specified return type). Just + make a dummy decl, since it's only used for its type. */ + gcc_assert (skip_evaluation); + arg_pack = tsubst_decl (parm_pack, args, complain); + arg_pack = make_fnparm_pack (arg_pack); + } + } else { int level, idx, levels; @@ -7555,6 +7603,17 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) return error_mark_node; + if (!local_specializations) + { + /* We're in a late-specified return type, so we don't have a local + specializations table. Create one for doing this expansion. */ + very_local_specializations = true; + local_specializations = htab_create (37, + hash_local_specialization, + eq_local_specializations, + NULL); + } + /* For each argument in each argument pack, substitute into the pattern. */ result = make_tree_vec (len + incomplete); @@ -7616,7 +7675,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, break; } } - + /* Update ARGS to restore the substitution from parameter packs to their argument packs. */ for (pack = packs; pack; pack = TREE_CHAIN (pack)) @@ -7639,6 +7698,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } + if (very_local_specializations) + { + htab_delete (local_specializations); + local_specializations = NULL; + } + return result; } @@ -9080,8 +9145,19 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /*integral_constant_expression_p=*/false); max = fold_decl_constant_value (max); + /* If we're in a partial instantiation, preserve the magic NOP_EXPR + with TREE_SIDE_EFFECTS that indicates this is not an integral + constant expression. */ + if (processing_template_decl + && TREE_SIDE_EFFECTS (omax) && TREE_CODE (omax) == NOP_EXPR) + { + gcc_assert (TREE_CODE (max) == NOP_EXPR); + TREE_SIDE_EFFECTS (max) = 1; + } + if (TREE_CODE (max) != INTEGER_CST && !at_function_scope_p () + && !TREE_SIDE_EFFECTS (max) && !value_dependent_expression_p (max)) { if (complain & tf_error) @@ -9898,16 +9974,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (r == NULL) { /* This can happen for a parameter name used later in a function - declaration (such as in a late-specified return type). - Replace it with an arbitrary expression with the same type - (*(T*)0). This should only occur in an unevaluated context - (i.e. decltype). */ - gcc_assert (skip_evaluation); - r = non_reference (TREE_TYPE (t)); - r = tsubst (r, args, complain, in_decl); - r = build_pointer_type (r); - r = build_c_cast (r, null_node); - return cp_build_indirect_ref (r, NULL, tf_warning_or_error); + declaration (such as in a late-specified return type). Just + make a dummy decl, since it's only used for its type. */ + gcc_assert (skip_evaluation); + r = tsubst_decl (t, args, complain); + /* Give it the template pattern as its context; its true context + hasn't been instantiated yet and this is good enough for + mangling. */ + DECL_CONTEXT (r) = DECL_CONTEXT (t); } if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) @@ -15464,37 +15538,12 @@ instantiate_decl (tree d, int defer_ok, } if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { - /* Collect all of the extra "packed" parameters into an - argument pack. */ - tree parmvec; - tree parmtypevec; - tree argpack = make_node (NONTYPE_ARGUMENT_PACK); - tree argtypepack = make_node (TYPE_ARGUMENT_PACK); - int i, len = 0; - tree t; - - /* Count how many parameters remain. */ - for (t = spec_parm; t; t = TREE_CHAIN (t)) - len++; - - /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ - parmvec = make_tree_vec (len); - parmtypevec = make_tree_vec (len); - for(i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) - { - TREE_VEC_ELT (parmvec, i) = spec_parm; - TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); - } - - /* Build the argument packs. */ - SET_ARGUMENT_PACK_ARGS (argpack, parmvec); - SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); - TREE_TYPE (argpack) = argtypepack; - /* Register the (value) argument pack as a specialization of TMPL_PARM, then move on. */ + tree argpack = make_fnparm_pack (spec_parm); register_local_specialization (argpack, tmpl_parm); tmpl_parm = TREE_CHAIN (tmpl_parm); + spec_parm = NULL_TREE; } gcc_assert (!spec_parm); @@ -15970,9 +16019,9 @@ dependent_type_p_r (tree type) && !TREE_CONSTANT (TYPE_MAX_VALUE (type))) { /* If this is the TYPE_DOMAIN of an array type, consider it - dependent. */ - return (value_dependent_expression_p (TYPE_MAX_VALUE (type)) - || type_dependent_expression_p (TYPE_MAX_VALUE (type))); + dependent. We already checked for value-dependence in + compute_array_index_type. */ + return type_dependent_expression_p (TYPE_MAX_VALUE (type)); } /* -- a template-id in which either the template name is a template @@ -16067,6 +16116,16 @@ dependent_type_p (tree type) return TYPE_DEPENDENT_P (type); } +/* Returns TRUE if SCOPE is a dependent scope, in which we can't do any + lookup. In other words, a dependent type that is not the current + instantiation. */ + +bool +dependent_scope_p (tree scope) +{ + return dependent_type_p (scope) && !currently_open_class (scope); +} + /* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */ static bool @@ -16088,7 +16147,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) An id-expression is type-dependent if it contains a nested-name-specifier that contains a class-name that names a dependent type. */ - /* The suggested resolution to Core Issue 2 implies that if the + /* The suggested resolution to Core Issue 224 implies that if the qualifying type is the current class, then we must peek inside it. */ if (DECL_P (name) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 840b0e0d394..71fc43e855a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -945,8 +945,6 @@ finish_switch_cond (tree cond, tree switch_stmt) tree orig_type = NULL; if (!processing_template_decl) { - tree index; - /* Convert the condition to an integer or enumeration type. */ cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true); if (cond == NULL_TREE) @@ -963,18 +961,6 @@ finish_switch_cond (tree cond, tree switch_stmt) cond = perform_integral_promotions (cond); cond = maybe_cleanup_point_expr (cond); } - - if (cond != error_mark_node) - { - index = get_unwidened (cond, NULL_TREE); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TYPE_UNSIGNED (TREE_TYPE (cond)) - == TYPE_UNSIGNED (TREE_TYPE (index))) - cond = index; - } } if (check_for_bare_parameter_packs (cond)) cond = error_mark_node; @@ -1801,6 +1787,13 @@ perform_koenig_lookup (tree fn, tree args) { tree identifier = NULL_TREE; tree functions = NULL_TREE; + tree tmpl_args = NULL_TREE; + + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + { + tmpl_args = TREE_OPERAND (fn, 1); + fn = TREE_OPERAND (fn, 0); + } /* Find the name of the overloaded function. */ if (TREE_CODE (fn) == IDENTIFIER_NODE) @@ -1820,7 +1813,8 @@ perform_koenig_lookup (tree fn, tree args) Do Koenig lookup -- unless any of the arguments are type-dependent. */ - if (!any_type_dependent_arguments_p (args)) + if (!any_type_dependent_arguments_p (args) + && !any_dependent_template_arguments_p (tmpl_args)) { fn = lookup_arg_dependent (identifier, functions, args); if (!fn) @@ -1828,6 +1822,9 @@ perform_koenig_lookup (tree fn, tree args) fn = unqualified_fn_lookup_error (identifier); } + if (fn && tmpl_args) + fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args); + return fn; } @@ -3924,6 +3921,9 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv, case GE_EXPR: case LT_EXPR: case LE_EXPR: + if (TREE_OPERAND (cond, 1) == iter) + cond = build2 (swap_tree_comparison (TREE_CODE (cond)), + TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0)); if (TREE_OPERAND (cond, 0) != iter) cond = error_mark_node; else @@ -4588,8 +4588,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) break; } } - else - type = describable_type (expr); if (type && !type_uses_auto (type)) return type; @@ -4905,6 +4903,24 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) } } +/* Returns true if TYPE is a complete type, an array of unknown bound, + or (possibly cv-qualified) void, returns false otherwise. */ + +static bool +check_trait_type (tree type) +{ + if (COMPLETE_TYPE_P (type)) + return true; + + if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) + return true; + + if (VOID_TYPE_P (type)) + return true; + + return false; +} + /* Process a trait expression. */ tree @@ -4953,14 +4969,45 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) if (type2) complete_type (type2); - /* The only required diagnostic. */ - if (kind == CPTK_IS_BASE_OF - && NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2) - && !same_type_ignoring_top_level_qualifiers_p (type1, type2) - && !COMPLETE_TYPE_P (type2)) + switch (kind) { - error ("incomplete type %qT not allowed", type2); - return error_mark_node; + case CPTK_HAS_NOTHROW_ASSIGN: + case CPTK_HAS_TRIVIAL_ASSIGN: + case CPTK_HAS_NOTHROW_CONSTRUCTOR: + case CPTK_HAS_TRIVIAL_CONSTRUCTOR: + case CPTK_HAS_NOTHROW_COPY: + case CPTK_HAS_TRIVIAL_COPY: + case CPTK_HAS_TRIVIAL_DESTRUCTOR: + case CPTK_HAS_VIRTUAL_DESTRUCTOR: + case CPTK_IS_ABSTRACT: + case CPTK_IS_EMPTY: + case CPTK_IS_POD: + case CPTK_IS_POLYMORPHIC: + if (!check_trait_type (type1)) + { + error ("incomplete type %qT not allowed", type1); + return error_mark_node; + } + break; + + case CPTK_IS_BASE_OF: + if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2) + && !same_type_ignoring_top_level_qualifiers_p (type1, type2) + && !COMPLETE_TYPE_P (type2)) + { + error ("incomplete type %qT not allowed", type2); + return error_mark_node; + } + break; + + case CPTK_IS_CLASS: + case CPTK_IS_ENUM: + case CPTK_IS_UNION: + break; + + case CPTK_IS_CONVERTIBLE_TO: + default: + gcc_unreachable (); } return (trait_expr_value (kind, type1, type2) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 456abfc9443..2287f11f04b 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1175,8 +1175,9 @@ is_overloaded_fn (tree x) x = TREE_OPERAND (x, 1); if (BASELINK_P (x)) x = BASELINK_FUNCTIONS (x); - if (TREE_CODE (x) == TEMPLATE_ID_EXPR - || DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) + if (TREE_CODE (x) == TEMPLATE_ID_EXPR) + x = TREE_OPERAND (x, 0); + if (DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) || (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x))) return 2; return (TREE_CODE (x) == FUNCTION_DECL @@ -1202,6 +1203,8 @@ get_first_fn (tree from) from = TREE_OPERAND (from, 1); if (BASELINK_P (from)) from = BASELINK_FUNCTIONS (from); + if (TREE_CODE (from) == TEMPLATE_ID_EXPR) + from = TREE_OPERAND (from, 0); return OVL_CURRENT (from); } @@ -1878,9 +1881,8 @@ cp_tree_equal (tree t1, tree t2) case PARM_DECL: /* For comparing uses of parameters in late-specified return types with an out-of-class definition of the function. */ - if ((!DECL_CONTEXT (t1) || !DECL_CONTEXT (t2)) - && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) - && DECL_NAME (t1) == DECL_NAME (t2)) + if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) + && parm_index (t1) == parm_index (t2)) return true; else return false; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a6986f94b63..3788a7e8b9e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4031,7 +4031,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) pointer_int_sum() anyway. */ complete_type (TREE_TYPE (res_type)); - return pointer_int_sum (resultcode, ptrop, + return pointer_int_sum (input_location, resultcode, ptrop, fold_if_not_in_template (intop)); } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 637076554fb..747c964706c 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -677,18 +677,18 @@ check_narrowing (tree type, tree init) { if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype)) { - ok = false; if (TREE_CODE (init) == REAL_CST) { + /* Issue 703: Loss of precision is OK as long as the value is + within the representable range of the new type. */ + REAL_VALUE_TYPE r; d = TREE_REAL_CST (init); - if (exact_real_truncate (TYPE_MODE (type), &d) - /* FIXME: As a temporary workaround for PR 36963, don't - complain about narrowing from a floating - literal. Hopefully this will be resolved at the - September 2008 C++ meeting. */ - || !was_decl) - ok = true; + real_convert (&r, TYPE_MODE (type), &d); + if (real_isinf (&r)) + ok = false; } + else + ok = false; } } else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype) |