diff options
author | Jason Merrill <jason@redhat.com> | 2015-04-28 17:27:17 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-04-28 17:27:17 -0400 |
commit | 3f8e2835ae414fe8f6895ed7cfe7171cea506c70 (patch) | |
tree | f164f28394dd9a352b0fea7f1bd3117604375ebb | |
parent | db6113067cc3a35141c9a341aa7ffb60786e3e5b (diff) | |
download | gcc-3f8e2835ae414fe8f6895ed7cfe7171cea506c70.zip gcc-3f8e2835ae414fe8f6895ed7cfe7171cea506c70.tar.gz gcc-3f8e2835ae414fe8f6895ed7cfe7171cea506c70.tar.bz2 |
re PR c++/65896 (Erroneous uninitialized variable access error in constexpr function with temporary variables)
PR c++/65896
* constexpr.c (cxx_eval_store_expression): Don't try to actually
store an empty class.
From-SVN: r222549
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-empty9.C | 18 |
3 files changed, 36 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index acf4d49..a2d2a7c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2015-04-28 Jason Merrill <jason@redhat.com> + PR c++/65896 + * constexpr.c (cxx_eval_store_expression): Don't try to actually + store an empty class. + PR c++/65656 * constexpr.c (cxx_eval_builtin_function_call): Fix __builtin_constant_p. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 403c7cf..9ebb640 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2580,12 +2580,25 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, /* First we figure out where we're storing to. */ tree target = TREE_OPERAND (t, 0); + tree type = TREE_TYPE (target); target = cxx_eval_constant_expression (ctx, target, true, non_constant_p, overflow_p); if (*non_constant_p) return t; + if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (target), type)) + { + /* For initialization of an empty base, the original target will be + *(base*)this, which the above evaluation resolves to the object + argument, which has the derived type rather than the base type. In + this situation, just evaluate the initializer and return, since + there's no actual data to store. */ + gcc_assert (is_empty_class (type)); + return cxx_eval_constant_expression (ctx, init, false, + non_constant_p, overflow_p); + } + /* And then find the underlying variable. */ vec<tree,va_gc> *refs = make_tree_vector(); tree object = NULL_TREE; @@ -2622,7 +2635,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, *non_constant_p = true; return t; } - tree type = TREE_TYPE (object); + type = TREE_TYPE (object); while (!refs->is_empty()) { if (*valp == NULL_TREE) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty9.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty9.C new file mode 100644 index 0000000..26b4863 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty9.C @@ -0,0 +1,18 @@ +// PR c++/65896 +// { dg-do compile { target c++11 } } + +struct base {}; + +struct derived : base { + constexpr derived(): + base{}, + m_value(0) { + } + int m_value; +}; + +constexpr int by_ref(derived && value) { + return value.m_value; +} + +constexpr int value = by_ref(derived{}); |