From 6c06fbce5c77ffbb0be281d22780a919de4877fe Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Thu, 13 Oct 2005 23:59:57 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/cp-tree.h | 11 +++++++++-- gcc/cp/decl.c | 17 ++++++++++------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/init/goto2.C | 11 +++++++++++ 5 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/goto2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4ad7a08..ec81292 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2005-10-13 Mark Mitchell + 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 * call.c (build_new_method_call): Correct pretty-printing of destructor names. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ceaa425..42eed5f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -69,6 +69,7 @@ struct diagnostic_context; FN_TRY_BLOCK_P (in TRY_BLOCK) IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE) 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, or FIELD_DECL). IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) @@ -1784,11 +1785,17 @@ struct lang_decl GTY(()) should be allocated. */ #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE)) -/* Nonzero for a VAR_DECL means that the variable's initialization has - been processed. */ +/* Nonzero for a VAR_DECL means that the variable's initialization (if + 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) \ (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 constant-expression. */ #define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 77f3164..7cc2fde 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1542,6 +1542,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) { DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (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 (olddecl); } @@ -2148,16 +2150,15 @@ decl_jump_unsafe (tree decl) if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)) return 0; - if (DECL_INITIAL (decl) == NULL_TREE - && pod_type_p (TREE_TYPE (decl))) + if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) + || DECL_NONTRIVIALLY_INITIALIZED_P (decl)) + return 2; + + if (pod_type_p (TREE_TYPE (decl))) 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? */ - if (DECL_INITIAL (decl) - || (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))) - return 2; return 1; } @@ -4932,6 +4933,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { + if (init) + DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1; init = check_initializer (decl, init, flags, &cleanup); /* Thread-local storage cannot be dynamically initialized. */ if (DECL_THREAD_LOCAL_P (decl) && init) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1cfd961..99f49d0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-10-13 Mark Mitchell + PR c++/20721 + * g++.dg/init/goto2.C: New test. + PR c++/22464 * g++.dg/template/crash/41.C: New test. diff --git a/gcc/testsuite/g++.dg/init/goto2.C b/gcc/testsuite/g++.dg/init/goto2.C new file mode 100644 index 0000000..3f4ecc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/goto2.C @@ -0,0 +1,11 @@ +// 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" } + ; +} + -- 2.7.4