aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.6/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.6/gcc/cp/decl.c')
-rw-r--r--gcc-4.6/gcc/cp/decl.c83
1 files changed, 63 insertions, 20 deletions
diff --git a/gcc-4.6/gcc/cp/decl.c b/gcc-4.6/gcc/cp/decl.c
index aa20497b5..ff3baa54b 100644
--- a/gcc-4.6/gcc/cp/decl.c
+++ b/gcc-4.6/gcc/cp/decl.c
@@ -3519,6 +3519,7 @@ cxx_init_decl_processing (void)
{
tree void_ftype;
tree void_ftype_ptr;
+ tree void_ftype_ptr_sizetype;
build_common_tree_nodes (flag_signed_char);
@@ -3584,8 +3585,14 @@ cxx_init_decl_processing (void)
void_ftype = build_function_type_list (void_type_node, NULL_TREE);
void_ftype_ptr = build_function_type_list (void_type_node,
ptr_type_node, NULL_TREE);
+ void_ftype_ptr_sizetype = build_function_type_list (void_type_node,
+ ptr_type_node,
+ size_type_node,
+ NULL_TREE);
void_ftype_ptr
= build_exception_variant (void_ftype_ptr, empty_except_spec);
+ void_ftype_ptr_sizetype
+ = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec);
/* C++ extensions */
@@ -3635,7 +3642,7 @@ cxx_init_decl_processing (void)
current_lang_name = lang_name_cplusplus;
{
- tree newtype, deltype;
+ tree newtype, deltype, deltype2;
tree ptr_ftype_sizetype;
tree new_eh_spec;
@@ -3664,8 +3671,10 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
+ deltype2 = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec);
push_cp_library_fn (NEW_EXPR, newtype);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
+ push_cp_library_fn (DELETE_EXPR, deltype2);
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
push_cp_library_fn (VEC_DELETE_EXPR, deltype);
@@ -4877,15 +4886,16 @@ check_for_uninitialized_const_var (tree decl)
if (TREE_CODE (decl) == VAR_DECL
&& TREE_CODE (type) != REFERENCE_TYPE
&& CP_TYPE_CONST_P (type)
- && (!TYPE_NEEDS_CONSTRUCTING (type)
- || !type_has_user_provided_default_constructor (type))
&& !DECL_INITIAL (decl))
{
+ tree field = default_init_uninitialized_part (type);
+ if (!field)
+ return;
+
permerror (DECL_SOURCE_LOCATION (decl),
"uninitialized const %qD", decl);
- if (CLASS_TYPE_P (type)
- && !type_has_user_provided_default_constructor (type))
+ if (CLASS_TYPE_P (type))
{
tree defaulted_ctor;
@@ -4896,6 +4906,8 @@ check_for_uninitialized_const_var (tree decl)
inform (DECL_SOURCE_LOCATION (defaulted_ctor),
"constructor is not user-provided because it is "
"explicitly defaulted in the class body");
+ inform (0, "and the implicitly-defined constructor does not "
+ "initialize %q+#D", field);
}
}
}
@@ -7505,8 +7517,18 @@ check_static_variable_definition (tree decl, tree type)
else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
{
if (literal_type_p (type))
- error ("%<constexpr%> needed for in-class initialization of static "
- "data member %q#D of non-integral type", decl);
+ {
+ /* FIXME google: This local modification allows us to
+ transition from C++98 to C++11 without moving static
+ const floats out of the class during the transition. It
+ should not be forward-ported to a 4.7 branch, since by
+ then we should be able to just fix the code to use
+ constexpr. */
+ pedwarn (input_location, OPT_pedantic,
+ "%<constexpr%> needed for in-class initialization of "
+ "static data member %q#D of non-integral type", decl);
+ return 0;
+ }
else
error ("in-class initialization of static data member %q#D of "
"non-literal type", decl);
@@ -8796,6 +8818,10 @@ grokdeclarator (const cp_declarator *declarator,
/* Pick up the exception specifications. */
raises = declarator->u.function.exception_specification;
+ /* If the exception-specification is ill-formed, let's pretend
+ there wasn't one. */
+ if (raises == error_mark_node)
+ raises = NULL_TREE;
/* Say it's a definition only for the CALL_EXPR
closest to the identifier. */
@@ -11354,9 +11380,10 @@ xref_tag (enum tag_types tag_code, tree name,
tag_scope scope, bool template_header_p)
{
tree ret;
- timevar_start (TV_NAME_LOOKUP);
+ bool subtime;
+ subtime = timevar_cond_start (TV_NAME_LOOKUP);
ret = xref_tag_1 (tag_code, name, scope, template_header_p);
- timevar_stop (TV_NAME_LOOKUP);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
return ret;
}
@@ -11592,15 +11619,19 @@ xref_basetypes (tree ref, tree base_list)
static void
copy_type_enum (tree dst, tree src)
{
- TYPE_MIN_VALUE (dst) = TYPE_MIN_VALUE (src);
- TYPE_MAX_VALUE (dst) = TYPE_MAX_VALUE (src);
- TYPE_SIZE (dst) = TYPE_SIZE (src);
- TYPE_SIZE_UNIT (dst) = TYPE_SIZE_UNIT (src);
- SET_TYPE_MODE (dst, TYPE_MODE (src));
- TYPE_PRECISION (dst) = TYPE_PRECISION (src);
- TYPE_ALIGN (dst) = TYPE_ALIGN (src);
- TYPE_USER_ALIGN (dst) = TYPE_USER_ALIGN (src);
- TYPE_UNSIGNED (dst) = TYPE_UNSIGNED (src);
+ tree t;
+ for (t = dst; t; t = TYPE_NEXT_VARIANT (t))
+ {
+ TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (src);
+ TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (src);
+ TYPE_SIZE (t) = TYPE_SIZE (src);
+ TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (src);
+ SET_TYPE_MODE (dst, TYPE_MODE (src));
+ TYPE_PRECISION (t) = TYPE_PRECISION (src);
+ TYPE_ALIGN (t) = TYPE_ALIGN (src);
+ TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (src);
+ TYPE_UNSIGNED (t) = TYPE_UNSIGNED (src);
+ }
}
/* Begin compiling the definition of an enumeration type.
@@ -11955,9 +11986,12 @@ finish_enum (tree enumtype)
return;
}
- /* Here there should not be any variants of this type. */
+ /* If this is a forward declaration, there should not be any variants,
+ though we can get a variant in the middle of an enum-specifier with
+ wacky code like 'enum E { e = sizeof(const E*) };' */
gcc_assert (enumtype == TYPE_MAIN_VARIANT (enumtype)
- && !TYPE_NEXT_VARIANT (enumtype));
+ && (TYPE_VALUES (enumtype)
+ || !TYPE_NEXT_VARIANT (enumtype)));
}
/* Build and install a CONST_DECL for an enumeration constant of the
@@ -13408,8 +13442,17 @@ cxx_maybe_build_cleanup (tree decl)
cleanup = call;
}
+ /* build_delete sets the location of the destructor call to the
+ current location, even though the destructor is going to be
+ called later, at the end of the current scope. This can lead to
+ a "jumpy" behaviour for users of debuggers when they step around
+ the end of the block. So let's unset the location of the
+ destructor call instead. */
+ if (cleanup != NULL && EXPR_P (cleanup))
+ SET_EXPR_LOCATION (cleanup, UNKNOWN_LOCATION);
return cleanup;
}
+
/* When a stmt has been parsed, this function is called. */