aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-06-03 23:50:50 -0400
committerJason Merrill <jason@redhat.com>2020-06-04 15:11:42 -0400
commit7ece3bd8088983289731450826c238eb2bdd2db5 (patch)
treed48b471b9169fe130e1faea914228b58853128c1 /gcc/cp/constexpr.c
parent0ddb93ce77374004c49cdfbd748ba35867620cf1 (diff)
downloadgcc-7ece3bd8088983289731450826c238eb2bdd2db5.zip
gcc-7ece3bd8088983289731450826c238eb2bdd2db5.tar.gz
gcc-7ece3bd8088983289731450826c238eb2bdd2db5.tar.bz2
c++: Fix complex constexpr virtual cases [PR93310].
The code in constexpr for looking up the actual type of the object and then getting the virtual function from there broke for both of these tests: for 16, it assumed incorrectly that the DECL_VINDEX would apply to the most derived type's vtable; for 17, it failed to consider that during construction the base subobject is treated as being of the base type. Fixed by just doing constant evaluation of the expression that looks up the function in the vtable. This means that a virtual call will involve loading the vptr, so we will reject some calls through non-constexpr variables that we previously accepted, but this seems appropriate to me. None of our testcases were affected. gcc/cp/ChangeLog: PR c++/93310 * constexpr.c (cxx_eval_constant_expression) [OBJ_TYPE_REF]: Evaluate OBJ_TYPE_REF_EXPR. gcc/testsuite/ChangeLog: PR c++/93310 * g++.dg/cpp2a/constexpr-virtual16.C: New test. * g++.dg/cpp2a/constexpr-virtual17.C: New test. * g++.dg/cpp2a/constexpr-new12.C: Adjust diagnostic.
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c44
1 files changed, 3 insertions, 41 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index c7d17e9..c01c42b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -6373,47 +6373,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break;
case OBJ_TYPE_REF:
- {
- /* Virtual function call. Let the constexpr machinery figure out
- the dynamic type. */
- int token = tree_to_shwi (OBJ_TYPE_REF_TOKEN (t));
- tree obj = OBJ_TYPE_REF_OBJECT (t);
- obj = cxx_eval_constant_expression (ctx, obj, lval, non_constant_p,
- overflow_p);
- STRIP_NOPS (obj);
- /* We expect something in the form of &x.D.2103.D.2094; get x. */
- if (TREE_CODE (obj) != ADDR_EXPR
- || !DECL_P (get_base_address (TREE_OPERAND (obj, 0))))
- {
- if (!ctx->quiet)
- error_at (loc, "expression %qE is not a constant expression", t);
- *non_constant_p = true;
- return t;
- }
- obj = TREE_OPERAND (obj, 0);
- while (TREE_CODE (obj) == COMPONENT_REF
- && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
- obj = TREE_OPERAND (obj, 0);
- tree objtype = TREE_TYPE (obj);
- if (VAR_P (obj)
- && DECL_NAME (obj) == heap_identifier
- && TREE_CODE (objtype) == ARRAY_TYPE)
- objtype = TREE_TYPE (objtype);
- if (!CLASS_TYPE_P (objtype))
- {
- if (!ctx->quiet)
- error_at (loc, "expression %qE is not a constant expression", t);
- *non_constant_p = true;
- return t;
- }
- /* Find the function decl in the virtual functions list. TOKEN is
- the DECL_VINDEX that says which function we're looking for. */
- tree virtuals = BINFO_VIRTUALS (TYPE_BINFO (objtype));
- if (TARGET_VTABLE_USES_DESCRIPTORS)
- token /= MAX (TARGET_VTABLE_USES_DESCRIPTORS, 1);
- r = TREE_VALUE (chain_index (token, virtuals));
- break;
- }
+ /* Virtual function lookup. We don't need to do anything fancy. */
+ return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t),
+ lval, non_constant_p, overflow_p);
case PLACEHOLDER_EXPR:
/* Use of the value or address of the current object. */