diff options
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/ChangeLog | 63 | ||||
-rw-r--r-- | contrib/gcc/cp/call.c | 22 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/cxx-pretty-print.c | 4 | ||||
-rw-r--r-- | contrib/gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/decl2.c | 10 | ||||
-rw-r--r-- | contrib/gcc/cp/error.c | 16 | ||||
-rw-r--r-- | contrib/gcc/cp/lex.c | 15 | ||||
-rw-r--r-- | contrib/gcc/cp/name-lookup.c | 47 | ||||
-rw-r--r-- | contrib/gcc/cp/pt.c | 13 | ||||
-rw-r--r-- | contrib/gcc/cp/semantics.c | 9 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck.c | 1 |
12 files changed, 190 insertions, 14 deletions
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index 34c036f01c17..39875472b86c 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,3 +1,66 @@ +2007-08-24 Jakub Jelinek <jakub@redhat.com> + + PR c++/31941 + * error.c (resolve_virtual_fun_from_obj_type_ref): Handle + TARGET_VTABLE_USES_DESCRIPTORS targets properly. + + PR c++/32898 + * name-lookup.c (set_decl_namespace): lookup_qualified_name failure + is error_mark_node rather than NULL_TREE. + * pt.c (check_explicit_specialization): Likewise. + +2007-08-22 Jason Merrill <jason@redhat.com> + + PR c++/29365 + * pt.c (outermost_tinst_level): New function. + * lex.c (in_main_input_context): New function. + * cp-tree.h: Declare it. + * decl2.c (constrain_class_visibility): Use it to avoid warning + about uses of the anonymous namespace in the main input file. + +2007-08-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/32992 + * typeck.c (check_return_expr): Don't NRV optimize vars in + anonymous unions. + * decl.c (finish_function): Comment fix. + +2007-08-18 Paolo Carlini <pcarlini@suse.de> + + PR c++/32112 + * error.c (dump_decl): Deal with UNBOUND_CLASS_TEMPLATE. + * cxx-pretty-print.c (pp_cxx_unqualified_id): Likewise. + +2007-08-10 Paolo Carlini <pcarlini@suse.de> + + PR c++/17763 + * error.c (dump_expr): Consistently use the *_cxx_* + variants of the pretty-print functions. + +2007-07-30 Paolo Carlini <pcarlini@suse.de> + + PR c++/32108 + * semantics.c (finish_label_stmt): Reject the __label__ + extension outside function scopes. + +2007-07-28 Simon Martin <simartin@users.sourceforge.net> + Mark Mitchell <mark@codesourcery.com> + + PR c++/30917 + * name-lookup.c (lookup_name_real): Non namespace-scope bindings can be + hidden due to friend declarations in local classes. + +2007-07-27 Mark Mitchell <mark@codesourcery.com> + + PR c++/32346 + * call.c (convert_for_arg_passing): Only widen bitfields to their + declared types if necessary. + +2007-07-24 Paolo Carlini <pcarlini@suse.de> + + PR c++/30535 + * pt.c (unify): Never pass error_mark_node to template_decl_level. + 2007-07-19 Release Manager * GCC 4.2.1 released. diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index 862c3d0ecca1..848f3c894c8e 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -4674,7 +4674,27 @@ type_passed_as (tree type) tree convert_for_arg_passing (tree type, tree val) { - val = convert_bitfield_to_declared_type (val); + tree bitfield_type; + + /* If VAL is a bitfield, then -- since it has already been converted + to TYPE -- it cannot have a precision greater than TYPE. + + If it has a smaller precision, we must widen it here. For + example, passing "int f:3;" to a function expecting an "int" will + not result in any conversion before this point. + + If the precision is the same we must not risk widening. For + example, the COMPONENT_REF for a 32-bit "long long" bitfield will + often have type "int", even though the C++ type for the field is + "long long". If the value is being passed to a function + expecting an "int", then no conversions will be required. But, + if we call convert_bitfield_to_declared_type, the bitfield will + be converted to "long long". */ + bitfield_type = is_bitfield_expr_with_lowered_type (val); + if (bitfield_type + && TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type)) + val = convert_to_integer (TYPE_MAIN_VARIANT (bitfield_type), val); + if (val == error_mark_node) ; /* Pass classes with copy ctors by invisible reference. */ diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index 9e0342a3903a..deea897c465b 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -4079,6 +4079,7 @@ extern void yyerror (const char *); extern void yyhook (int); extern bool cxx_init (void); extern void cxx_finish (void); +extern bool in_main_input_context (void); /* in method.c */ extern void init_method (void); @@ -4161,6 +4162,7 @@ extern tree build_non_dependent_args (tree); extern bool reregister_specialization (tree, tree, tree); extern tree fold_non_dependent_expr (tree); extern bool explicit_class_specialization_p (tree); +extern tree outermost_tinst_level (void); /* in repo.c */ extern void init_repo (void); diff --git a/contrib/gcc/cp/cxx-pretty-print.c b/contrib/gcc/cp/cxx-pretty-print.c index 5ceca61a4cb3..5f6150aab76a 100644 --- a/contrib/gcc/cp/cxx-pretty-print.c +++ b/contrib/gcc/cp/cxx-pretty-print.c @@ -204,6 +204,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t) pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t)); break; + case UNBOUND_CLASS_TEMPLATE: + pp_cxx_unqualified_id (pp, TYPE_NAME (t)); + break; + default: pp_unsupported_tree (pp, t); break; diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 28e653b0751e..b837b1451538 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -11273,7 +11273,7 @@ finish_function (int flags) gcc_assert (stmts_are_full_exprs_p ()); /* Set up the named return value optimization, if we can. Candidate - variables are selected in check_return_value. */ + variables are selected in check_return_expr. */ if (current_function_return_value) { tree r = current_function_return_value; diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index 00bcc16b7a5a..310dc83159dd 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -1860,9 +1860,12 @@ constrain_class_visibility (tree type) int subvis = type_visibility (ftype); if (subvis == VISIBILITY_ANON) - warning (0, "\ + { + if (!in_main_input_context ()) + warning (0, "\ %qT has a field %qD whose type uses the anonymous namespace", type, t); + } else if (IS_AGGR_TYPE (ftype) && vis < VISIBILITY_HIDDEN && subvis >= VISIBILITY_HIDDEN) @@ -1877,9 +1880,12 @@ constrain_class_visibility (tree type) int subvis = type_visibility (TREE_TYPE (t)); if (subvis == VISIBILITY_ANON) - warning (0, "\ + { + if (!in_main_input_context()) + warning (0, "\ %qT has a base %qT whose type uses the anonymous namespace", type, TREE_TYPE (t)); + } else if (vis < VISIBILITY_HIDDEN && subvis >= VISIBILITY_HIDDEN) warning (OPT_Wattributes, "\ diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 2962fe655f64..c169cabedb64 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -901,6 +901,10 @@ dump_decl (tree t, int flags) pp_type_id (cxx_pp, t); break; + case UNBOUND_CLASS_TEMPLATE: + dump_type (t, flags); + break; + default: pp_unsupported_tree (cxx_pp, t); /* Fall through to error. */ @@ -1301,10 +1305,14 @@ static tree resolve_virtual_fun_from_obj_type_ref (tree ref) { tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref)); - int index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); + HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type))); - while (index--) + while (index) + { fun = TREE_CHAIN (fun); + index -= (TARGET_VTABLE_USES_DESCRIPTORS + ? TARGET_VTABLE_USES_DESCRIPTORS : 1); + } return BV_FN (fun); } @@ -1420,13 +1428,13 @@ dump_expr (tree t, int flags) if (TREE_CODE (ob) == ADDR_EXPR) { dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); - pp_dot (cxx_pp); + pp_cxx_dot (cxx_pp); } else if (TREE_CODE (ob) != PARM_DECL || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) { dump_expr (ob, flags | TFF_EXPR_IN_PARENS); - pp_arrow (cxx_pp); + pp_cxx_arrow (cxx_pp); } args = TREE_CHAIN (args); } diff --git a/contrib/gcc/cp/lex.c b/contrib/gcc/cp/lex.c index d14a1baa926e..65dcd7d6023d 100644 --- a/contrib/gcc/cp/lex.c +++ b/contrib/gcc/cp/lex.c @@ -827,3 +827,18 @@ make_aggr_type (enum tree_code code) return t; } + +/* Returns true if we are currently in the main source file, or in a + template instantiation started from the main source file. */ + +bool +in_main_input_context (void) +{ + tree tl = outermost_tinst_level(); + + if (tl) + return strcmp (main_input_filename, + LOCATION_FILE (TINST_LOCATION (tl))) == 0; + else + return strcmp (main_input_filename, input_filename) == 0; +} diff --git a/contrib/gcc/cp/name-lookup.c b/contrib/gcc/cp/name-lookup.c index 3016bb0ad560..744dd5c489ec 100644 --- a/contrib/gcc/cp/name-lookup.c +++ b/contrib/gcc/cp/name-lookup.c @@ -2924,7 +2924,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) /* See whether this has been declared in the namespace. */ old = lookup_qualified_name (scope, DECL_NAME (decl), false, true); - if (!old) + if (old == error_mark_node) /* No old declaration at all. */ goto complain; if (!is_overloaded_fn (decl)) @@ -3996,8 +3996,49 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, if (binding) { - /* Only namespace-scope bindings can be hidden. */ - gcc_assert (!hidden_name_p (binding)); + if (hidden_name_p (binding)) + { + /* A non namespace-scope binding can only be hidden if + we are in a local class, due to friend declarations. + In particular, consider: + + void f() { + struct A { + friend struct B; + void g() { B* b; } // error: B is hidden + } + struct B {}; + } + + The standard says that "B" is a local class in "f" + (but not nested within "A") -- but that name lookup + for "B" does not find this declaration until it is + declared directly with "f". + + In particular: + + [class.friend] + + If a friend declaration appears in a local class and + the name specified is an unqualified name, a prior + declaration is looked up without considering scopes + that are outside the innermost enclosing non-class + scope. For a friend class declaration, if there is no + prior declaration, the class that is specified + belongs to the innermost enclosing non-class scope, + but if it is subsequently referenced, its name is not + found by name lookup until a matching declaration is + provided in the innermost enclosing nonclass scope. + */ + gcc_assert (current_class_type && + LOCAL_CLASS_P (current_class_type)); + + /* This binding comes from a friend declaration in the local + class. The standard (11.4.8) states that the lookup can + only succeed if there is a non-hidden declaration in the + current scope, which is not the case here. */ + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } val = binding; break; } diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 477265d49d0d..ac28afa4136f 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -1971,7 +1971,7 @@ check_explicit_specialization (tree declarator, context. */ fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, false, true); - if (!fns || !is_overloaded_fn (fns)) + if (fns == error_mark_node || !is_overloaded_fn (fns)) { error ("%qD is not a template function", dname); fns = error_mark_node; @@ -5288,6 +5288,15 @@ reopen_tinst_level (tree level) pop_tinst_level (); } +/* Returns the TINST_LEVEL which gives the original instantiation + context. */ + +tree +outermost_tinst_level (void) +{ + return tree_last (current_tinst_level); +} + /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. @@ -10453,6 +10462,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); + if (tparm == error_mark_node) + return 1; if (TEMPLATE_TYPE_LEVEL (parm) != template_decl_level (tparm)) diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index 8ad197858d0f..9c37b36cea34 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -1320,8 +1320,13 @@ finish_label_stmt (tree name) void finish_label_decl (tree name) { - tree decl = declare_local_label (name); - add_decl_expr (decl); + if (!at_function_scope_p ()) + { + error ("__label__ declarations are only allowed in function scopes"); + return; + } + + add_decl_expr (declare_local_label (name)); } /* When DECL goes out of scope, make sure that CLEANUP is executed. */ diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index 4ae2f073abde..6f0777274cef 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -6604,6 +6604,7 @@ check_return_expr (tree retval, bool *no_warning) && TREE_CODE (retval) == VAR_DECL && DECL_CONTEXT (retval) == current_function_decl && ! TREE_STATIC (retval) + && ! DECL_ANON_UNION_VAR_P (retval) && (DECL_ALIGN (retval) >= DECL_ALIGN (DECL_RESULT (current_function_decl))) && same_type_p ((TYPE_MAIN_VARIANT |