diff options
author | Jason Merrill <jason@redhat.com> | 2016-01-26 16:34:10 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-01-26 16:34:10 -0500 |
commit | 2d63bc398f7221edbec3e3f1d4ecbacac87cb3a5 (patch) | |
tree | d035f1d3c7a75a68a3d60f7179cbe147b4437151 /gcc/tree.c | |
parent | 3671c99673af214992ef23e4fd9a28ab2417f33a (diff) | |
download | gcc-2d63bc398f7221edbec3e3f1d4ecbacac87cb3a5.zip gcc-2d63bc398f7221edbec3e3f1d4ecbacac87cb3a5.tar.gz gcc-2d63bc398f7221edbec3e3f1d4ecbacac87cb3a5.tar.bz2 |
re PR c++/68782 (bad reference member formed with constexpr)
PR c++/68782
gcc/
* tree.c (recompute_constructor_flags): Split out from
build_constructor.
(verify_constructor_flags): New.
* tree.h: Declare them.
gcc/cp/
* constexpr.c (cxx_eval_bare_aggregate): Update TREE_CONSTANT
and TREE_SIDE_EFFECTS.
(cxx_eval_constant_expression) [CONSTRUCTOR]: Call
verify_constructor_flags.
From-SVN: r232847
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 56 |
1 files changed, 44 insertions, 12 deletions
@@ -1790,34 +1790,66 @@ build_vector_from_val (tree vectype, tree sc) } } -/* Return a new CONSTRUCTOR node whose type is TYPE and whose values - are in the vec pointed to by VALS. */ -tree -build_constructor (tree type, vec<constructor_elt, va_gc> *vals) +/* Something has messed with the elements of CONSTRUCTOR C after it was built; + calculate TREE_CONSTANT and TREE_SIDE_EFFECTS. */ + +void +recompute_constructor_flags (tree c) { - tree c = make_node (CONSTRUCTOR); unsigned int i; - constructor_elt *elt; + tree val; bool constant_p = true; bool side_effects_p = false; + vec<constructor_elt, va_gc> *vals = CONSTRUCTOR_ELTS (c); - TREE_TYPE (c) = type; - CONSTRUCTOR_ELTS (c) = vals; - - FOR_EACH_VEC_SAFE_ELT (vals, i, elt) + FOR_EACH_CONSTRUCTOR_VALUE (vals, i, val) { /* Mostly ctors will have elts that don't have side-effects, so the usual case is to scan all the elements. Hence a single loop for both const and side effects, rather than one loop each (with early outs). */ - if (!TREE_CONSTANT (elt->value)) + if (!TREE_CONSTANT (val)) constant_p = false; - if (TREE_SIDE_EFFECTS (elt->value)) + if (TREE_SIDE_EFFECTS (val)) side_effects_p = true; } TREE_SIDE_EFFECTS (c) = side_effects_p; TREE_CONSTANT (c) = constant_p; +} + +/* Make sure that TREE_CONSTANT and TREE_SIDE_EFFECTS are correct for + CONSTRUCTOR C. */ + +void +verify_constructor_flags (tree c) +{ + unsigned int i; + tree val; + bool constant_p = TREE_CONSTANT (c); + bool side_effects_p = TREE_SIDE_EFFECTS (c); + vec<constructor_elt, va_gc> *vals = CONSTRUCTOR_ELTS (c); + + FOR_EACH_CONSTRUCTOR_VALUE (vals, i, val) + { + if (constant_p && !TREE_CONSTANT (val)) + internal_error ("non-constant element in constant CONSTRUCTOR"); + if (!side_effects_p && TREE_SIDE_EFFECTS (val)) + internal_error ("side-effects element in no-side-effects CONSTRUCTOR"); + } +} + +/* Return a new CONSTRUCTOR node whose type is TYPE and whose values + are in the vec pointed to by VALS. */ +tree +build_constructor (tree type, vec<constructor_elt, va_gc> *vals) +{ + tree c = make_node (CONSTRUCTOR); + + TREE_TYPE (c) = type; + CONSTRUCTOR_ELTS (c) = vals; + + recompute_constructor_flags (c); return c; } |