aboutsummaryrefslogtreecommitdiff
path: root/contrib/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r--contrib/gcc/cp/ChangeLog63
-rw-r--r--contrib/gcc/cp/call.c22
-rw-r--r--contrib/gcc/cp/cp-tree.h2
-rw-r--r--contrib/gcc/cp/cxx-pretty-print.c4
-rw-r--r--contrib/gcc/cp/decl.c2
-rw-r--r--contrib/gcc/cp/decl2.c10
-rw-r--r--contrib/gcc/cp/error.c16
-rw-r--r--contrib/gcc/cp/lex.c15
-rw-r--r--contrib/gcc/cp/name-lookup.c47
-rw-r--r--contrib/gcc/cp/pt.c13
-rw-r--r--contrib/gcc/cp/semantics.c9
-rw-r--r--contrib/gcc/cp/typeck.c1
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