aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-01-26 16:34:10 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-01-26 16:34:10 -0500
commit2d63bc398f7221edbec3e3f1d4ecbacac87cb3a5 (patch)
treed035f1d3c7a75a68a3d60f7179cbe147b4437151 /gcc/tree.c
parent3671c99673af214992ef23e4fd9a28ab2417f33a (diff)
downloadgcc-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.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 9c67bea..fa7646b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
}