aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-10-13 23:59:57 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-10-13 23:59:57 +0000
commit6c06fbce5c77ffbb0be281d22780a919de4877fe (patch)
treea4da9de28c6912e3768cb698ed0a81ac34281fd1 /gcc
parent02f3e085c7ba33279329aae728aaf42dc922add6 (diff)
downloadgcc-6c06fbce5c77ffbb0be281d22780a919de4877fe.zip
gcc-6c06fbce5c77ffbb0be281d22780a919de4877fe.tar.gz
gcc-6c06fbce5c77ffbb0be281d22780a919de4877fe.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/init/goto2.C11
5 files changed, 39 insertions, 9 deletions
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 <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
* 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 <mark@codesourcery.com>
+ 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" }
+ ;
+}
+