diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-09-01 19:18:03 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-09-01 19:18:03 +0000 |
commit | 7e99327dbcd3f1d453088f63eebe65994aded8c2 (patch) | |
tree | 3ba8f4e6715b6c18572eca713097806119e13254 /gcc/cp/decl.c | |
parent | 4b09846beff900c43203222269e235d3b6d56a47 (diff) | |
download | gcc-7e99327dbcd3f1d453088f63eebe65994aded8c2.zip gcc-7e99327dbcd3f1d453088f63eebe65994aded8c2.tar.gz gcc-7e99327dbcd3f1d453088f63eebe65994aded8c2.tar.bz2 |
re PR c++/12114 ([3.3.2] Uninitialized memory accessed in dtor)
PR c++/12114
* g++.dg/init/ref9.C: New test.
PR c++/11972
* g++.dg/template/nested4.C: New test.
PR c++/12114
* cp-tree.h (initialize_reference): Change prototype.
* call.c (initialize_reference): Add cleanup parameter.
* decl.c (grok_reference_init): Likewise.
(check_initializer): Likewise.
(cp_finish_decl): Insert a CLEANUP_STMT if necessary.
(duplicate_decls): When replacing an anticipated builtin, do not
honor TREE_NOTHROW.
* typeck.c (convert_for_initialization): Correct call to
initialize_reference.
PR c++/11972
* pt.c (dependent_type_p_r): Pass only the innermost template
arguments to any_dependent_template_arguments_p.
From-SVN: r70981
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b4eb019..4c287ea 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -68,7 +68,7 @@ static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *); static tree lookup_tag_reverse (tree, tree); static void push_local_name (tree); static void warn_extern_redeclared_static (tree, tree); -static tree grok_reference_init (tree, tree, tree); +static tree grok_reference_init (tree, tree, tree, tree *); static tree grokfndecl (tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree); @@ -117,7 +117,7 @@ static void pop_labels (tree); static void maybe_deduce_size_from_array_init (tree, tree); static void layout_var_decl (tree); static void maybe_commonize_var (tree); -static tree check_initializer (tree, tree, int); +static tree check_initializer (tree, tree, int, tree *); static void make_rtl_for_nonlocal_decl (tree, tree, const char *); static void save_function_data (tree); static void check_function_type (tree, tree); @@ -2940,9 +2940,9 @@ duplicate_decls (tree newdecl, tree olddecl) if (DECL_ANTICIPATED (olddecl)) ; /* Do nothing yet. */ else if ((DECL_EXTERN_C_P (newdecl) - && DECL_EXTERN_C_P (olddecl)) - || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), - TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) + && DECL_EXTERN_C_P (olddecl)) + || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), + TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) { /* A near match; override the builtin. */ @@ -2969,6 +2969,10 @@ duplicate_decls (tree newdecl, tree olddecl) else if (DECL_ANTICIPATED (olddecl)) TREE_TYPE (olddecl) = TREE_TYPE (newdecl); + /* Whether or not the builtin can throw exceptions has no + bearing on this declarator. */ + TREE_NOTHROW (olddecl) = 0; + if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl)) { /* If a builtin function is redeclared as `static', merge @@ -7174,14 +7178,18 @@ start_decl_1 (tree decl) DECL_INITIAL (decl) = NULL_TREE; } -/* Handle initialization of references. - These three arguments are from `cp_finish_decl', and have the - same meaning here that they do there. +/* Handle initialization of references. DECL, TYPE, and INIT have the + same meaning as in cp_finish_decl. *CLEANUP must be NULL on entry, + but will be set to a new CLEANUP_STMT if a temporary is created + that must be destroeyd subsequently. + + Returns an initializer expression to use to initialize DECL, or + NULL if the initialization can be performed statically. Quotes on semantics can be found in ARM 8.4.3. */ static tree -grok_reference_init (tree decl, tree type, tree init) +grok_reference_init (tree decl, tree type, tree init, tree *cleanup) { tree tmp; @@ -7218,7 +7226,7 @@ grok_reference_init (tree decl, tree type, tree init) DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ - tmp = initialize_reference (type, init, decl); + tmp = initialize_reference (type, init, decl, cleanup); if (tmp == error_mark_node) return NULL_TREE; @@ -7638,13 +7646,14 @@ reshape_init (tree type, tree *initp) } /* Verify INIT (the initializer for DECL), and record the - initialization in DECL_INITIAL, if appropriate. + initialization in DECL_INITIAL, if appropriate. CLEANUP is as for + grok_reference_init. If the return value is non-NULL, it is an expression that must be evaluated dynamically to initialize DECL. */ static tree -check_initializer (tree decl, tree init, int flags) +check_initializer (tree decl, tree init, int flags, tree *cleanup) { tree type = TREE_TYPE (decl); @@ -7694,7 +7703,7 @@ check_initializer (tree decl, tree init, int flags) init = NULL_TREE; } else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE) - init = grok_reference_init (decl, type, init); + init = grok_reference_init (decl, type, init, cleanup); else if (init) { if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) @@ -8001,8 +8010,9 @@ initialize_local_var (tree decl, tree init) void cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { - register tree type; + tree type; tree ttype = NULL_TREE; + tree cleanup; const char *asmspec = NULL; int was_readonly = 0; @@ -8015,6 +8025,9 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619); + /* Assume no cleanup is required. */ + cleanup = NULL_TREE; + /* If a name was specified, get the string. */ if (global_scope_p (current_binding_level)) asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); @@ -8128,7 +8141,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { - init = check_initializer (decl, init, flags); + init = check_initializer (decl, init, flags, &cleanup); /* Thread-local storage cannot be dynamically initialized. */ if (DECL_THREAD_LOCAL (decl) && init) { @@ -8244,6 +8257,11 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) } } + /* If a CLEANUP_STMT was created to destroy a temporary bound to a + reference, insert it in the statement-tree now. */ + if (cleanup) + add_stmt (cleanup); + finish_end: if (was_readonly) |