Commit 6c06fbce by Mark Mitchell Committed by Mark Mitchell

re PR c++/20721 (crossing of a initialization left undetected on goto)

	PR c++/20721
	* cp-tree.h (DECL_NONTRIVIALLY_INITIALIZED_P): New macro.
	* decl.c (duplicate_decls): Merge it into new declarations.
	(decl_jump_unsafe): Use it, rather than DECL_INITIAL.
	(cp_finish_decl): Set it, when appropriate.
	PR c++/20721
	* g++.dg/init/goto2.C: New test.

From-SVN: r105380
parent 02f3e085
2005-10-13 Mark Mitchell <mark@codesourcery.com> 2005-10-13 Mark Mitchell <mark@codesourcery.com>
PR c++/20721
* cp-tree.h (DECL_NONTRIVIALLY_INITIALIZED_P): New macro.
* decl.c (duplicate_decls): Merge it into new declarations.
(decl_jump_unsafe): Use it, rather than DECL_INITIAL.
(cp_finish_decl): Set it, when appropriate.
PR c++/22180 PR c++/22180
* call.c (build_new_method_call): Correct pretty-printing of * call.c (build_new_method_call): Correct pretty-printing of
destructor names. destructor names.
......
...@@ -69,6 +69,7 @@ struct diagnostic_context; ...@@ -69,6 +69,7 @@ struct diagnostic_context;
FN_TRY_BLOCK_P (in TRY_BLOCK) FN_TRY_BLOCK_P (in TRY_BLOCK)
IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE) IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE)
BIND_EXPR_BODY_BLOCK (in BIND_EXPR) BIND_EXPR_BODY_BLOCK (in BIND_EXPR)
DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL)
4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
or FIELD_DECL). or FIELD_DECL).
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
...@@ -1784,11 +1785,17 @@ struct lang_decl GTY(()) ...@@ -1784,11 +1785,17 @@ struct lang_decl GTY(())
should be allocated. */ should be allocated. */
#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE)) #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE))
/* Nonzero for a VAR_DECL means that the variable's initialization has /* Nonzero for a VAR_DECL means that the variable's initialization (if
been processed. */ any) has been processed. (In general, DECL_INITIALIZED_P is
!DECL_EXTERN, but static data members may be initialized even if
not defined.) */
#define DECL_INITIALIZED_P(NODE) \ #define DECL_INITIALIZED_P(NODE) \
(TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE))) (TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE)))
/* Nonzero for a VAR_DECL iff an explicit initializer was provided. */
#define DECL_NONTRIVIALLY_INITIALIZED_P(NODE) \
(TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE)))
/* Nonzero for a VAR_DECL that was initialized with a /* Nonzero for a VAR_DECL that was initialized with a
constant-expression. */ constant-expression. */
#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \ #define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
......
...@@ -1542,6 +1542,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1542,6 +1542,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{ {
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
DECL_NONTRIVIALLY_INITIALIZED_P (newdecl)
|= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl);
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl) DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
|= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl); |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
} }
...@@ -2148,16 +2150,15 @@ decl_jump_unsafe (tree decl) ...@@ -2148,16 +2150,15 @@ decl_jump_unsafe (tree decl)
if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)) if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
return 0; return 0;
if (DECL_INITIAL (decl) == NULL_TREE if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
&& pod_type_p (TREE_TYPE (decl))) || DECL_NONTRIVIALLY_INITIALIZED_P (decl))
return 2;
if (pod_type_p (TREE_TYPE (decl)))
return 0; return 0;
/* This is really only important if we're crossing an initialization. /* The POD stuff is just pedantry; why should it matter if the class
The POD stuff is just pedantry; why should it matter if the class
contains a field of pointer to member type? */ contains a field of pointer to member type? */
if (DECL_INITIAL (decl)
|| (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
return 2;
return 1; return 1;
} }
...@@ -4932,6 +4933,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ...@@ -4932,6 +4933,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
is *not* defined. */ is *not* defined. */
&& (!DECL_EXTERNAL (decl) || init)) && (!DECL_EXTERNAL (decl) || init))
{ {
if (init)
DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
init = check_initializer (decl, init, flags, &cleanup); init = check_initializer (decl, init, flags, &cleanup);
/* Thread-local storage cannot be dynamically initialized. */ /* Thread-local storage cannot be dynamically initialized. */
if (DECL_THREAD_LOCAL_P (decl) && init) if (DECL_THREAD_LOCAL_P (decl) && init)
......
2005-10-13 Mark Mitchell <mark@codesourcery.com> 2005-10-13 Mark Mitchell <mark@codesourcery.com>
PR c++/20721
* g++.dg/init/goto2.C: New test.
PR c++/22464 PR c++/22464
* g++.dg/template/crash/41.C: New test. * g++.dg/template/crash/41.C: New test.
// PR c++/20721
bool f();
void g(int i)
{
if (i) goto bad; // { dg-error "from" }
bool a = f(); // { dg-error "initialization" }
bad: // { dg-error "jump" }
;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment