Skip to content

Commit 0803115

Browse files
committed
adding a constification specific VCE flag
1 parent b047572 commit 0803115

File tree

5 files changed

+55
-6
lines changed

5 files changed

+55
-6
lines changed

gcc/cp/contracts.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,10 +2724,14 @@ finish_contract_condition (cp_expr condition)
27242724

27252725
tree view_as_const(tree decl)
27262726
{
2727-
tree ctype = TREE_TYPE (decl);
2728-
ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype)
2729-
| TYPE_QUAL_CONST));
2730-
decl = build1 (VIEW_CONVERT_EXPR, ctype, decl);
2727+
if (!contract_const_wrapper_p (decl))
2728+
{
2729+
tree ctype = TREE_TYPE (decl);
2730+
ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype)
2731+
| TYPE_QUAL_CONST));
2732+
decl = build1 (VIEW_CONVERT_EXPR, ctype, decl);
2733+
EXPR_CONTRACT_CONST_WRAPPER_P(decl) = true;
2734+
}
27312735
return decl;
27322736
}
27332737

gcc/cp/cp-tree.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,6 +3204,18 @@ struct GTY(()) lang_decl {
32043204
#define CONTRACT_HELPER(NODE) \
32053205
(LANG_DECL_FN_CHECK (NODE)->contract_helper)
32063206

3207+
/* In VIEW_CONVERT_EXPR, set when this node is a const wrapper. Used to
3208+
constify entities inside contract assertions. */
3209+
3210+
#define EXPR_CONTRACT_CONST_WRAPPER_P(NODE) \
3211+
(TREE_CHECK(NODE, VIEW_CONVERT_EXPR)->base.private_flag)
3212+
3213+
/* Remove any VIEW_CONVERT_EXPR that's used to constify an entity inside a
3214+
contract assertion. */
3215+
3216+
#define STRIP_ANY_CONTRACT_CONST_WRAPPER(EXP) \
3217+
(EXP) = tree_strip_any_contract_const_wrapper (CONST_CAST_TREE (EXP))
3218+
32073219
/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
32083220
declaration. Some entities (like a member function in a local
32093221
class, or a local variable) do not have linkage at all, and this
@@ -9001,6 +9013,30 @@ set_contract_const (tree t, bool constify)
90019013
TREE_LANG_FLAG_4 (CONTRACT_CHECK (t)) = constify;
90029014
}
90039015

9016+
/* Test if EXP is a contract const wrapper node. */
9017+
9018+
inline bool
9019+
contract_const_wrapper_p (const_tree exp)
9020+
{
9021+
/* A wrapper node has code VIEW_CONVERT_EXPR, and the flag
9022+
EXPR_LOCATION_WRAPPER_P is set. */
9023+
if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
9024+
&& EXPR_CONTRACT_CONST_WRAPPER_P (exp))
9025+
return true;
9026+
return false;
9027+
}
9028+
9029+
/* Implementation of STRIP_ANY_CONTRACT_CONST_WRAPPER. */
9030+
9031+
inline tree
9032+
tree_strip_any_contract_const_wrapper (tree exp)
9033+
{
9034+
if (contract_const_wrapper_p (exp))
9035+
return TREE_OPERAND (exp, 0);
9036+
else
9037+
return exp;
9038+
}
9039+
90049040
/* Inline bodies. */
90059041

90069042
inline tree

gcc/cp/semantics.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12593,7 +12593,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
1259312593
if (identifier_p (expr))
1259412594
expr = lookup_name (expr);
1259512595

12596-
while (INDIRECT_REF_P (expr)
12596+
/* If e is a constified expression inside a contract assertion,
12597+
strip the const wrapper. Per P2900R14, "For a function f with the
12598+
return type T , the result name is an lvalue of type const T , decltype(r)
12599+
is T , and decltype((r)) is const T&." */
12600+
STRIP_ANY_CONTRACT_CONST_WRAPPER (expr);
12601+
12602+
if (INDIRECT_REF_P (expr)
1259712603
|| TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1259812604
/* This can happen when the expression is, e.g., "a.b". Just
1259912605
look at the underlying operand. */

gcc/testsuite/g++.dg/contracts/cpp26/return_value_constness.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// check that the return value has correct const qualification
22
// { dg-do run }
3-
// { dg-options "-std=c++2b -fcontracts -fcontracts-nonattr -fcontract-evaluation-semantic=observe " }
3+
// { dg-options "-std=c++2b -fcontracts -fcontracts-nonattr " }
44

55

66
#include <type_traits>

gcc/tree-core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,9 @@ struct GTY(()) tree_base {
13641364
ENUM_IS_OPAQUE in
13651365
ENUMERAL_TYPE
13661366
1367+
EXPR_CONTRACT_CONST_WRAPPER_P in
1368+
VIEW_CONVERT_EXPR
1369+
13671370
protected_flag:
13681371
13691372
TREE_PROTECTED in

0 commit comments

Comments
 (0)