@@ -146,6 +146,7 @@ along with GCC; see the file COPYING3. If not see
146
146
#include " stor-layout.h"
147
147
#include " intl.h"
148
148
#include " cgraph.h"
149
+ #include " opts.h"
149
150
150
151
const int max_custom_roles = 32 ;
151
152
static contract_role contract_build_roles[max_custom_roles] = {
@@ -761,8 +762,14 @@ grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
761
762
else
762
763
contract = build4_loc (loc, code, type, mode, NULL_TREE, NULL_TREE, result);
763
764
764
- /* Determine the concrete semantic. */
765
- set_contract_semantic (contract, compute_concrete_semantic (contract));
765
+ /* Determine the evaluation semantic:
766
+ First, apply the c++2a rules
767
+ FIXME: this is a convenience to avoid updating many tests. */
768
+ contract_semantic semantic = compute_concrete_semantic (contract);
769
+ if (flag_contracts_nonattr
770
+ && OPTION_SET_P (flag_contract_evaluation_semantic))
771
+ semantic = static_cast <contract_semantic>(flag_contract_evaluation_semantic);
772
+ set_contract_semantic (contract, semantic);
766
773
767
774
/* If the contract is deferred, don't do anything with the condition. */
768
775
if (TREE_CODE (condition) == DEFERRED_PARSE)
@@ -1881,13 +1888,22 @@ get_contract_role_name (tree contract)
1881
1888
/* Build C++20 contract_violation layout compatible object. */
1882
1889
1883
1890
static tree
1884
- build_contract_violation_cpp20 (tree contract, contract_continuation cmode )
1891
+ build_contract_violation_cpp20 (tree contract)
1885
1892
{
1886
1893
expanded_location loc = expand_location (EXPR_LOCATION (contract));
1887
1894
const char *function = fndecl_name (DECL_ORIGIN (current_function_decl));
1888
1895
const char *level = get_contract_level_name (contract);
1889
1896
const char *role = get_contract_role_name (contract);
1890
1897
1898
+ /* Get the continuation mode. */
1899
+ contract_continuation cmode;
1900
+ switch (get_contract_semantic (contract))
1901
+ {
1902
+ case CCS_NEVER: cmode = NEVER_CONTINUE; break ;
1903
+ case CCS_MAYBE: cmode = MAYBE_CONTINUE; break ;
1904
+ default : gcc_unreachable ();
1905
+ }
1906
+
1891
1907
/* Must match the type layout in get_pseudo_contract_violation_type. */
1892
1908
tree ctor = build_constructor_va
1893
1909
(init_list_type_node, 7 ,
@@ -1923,8 +1939,7 @@ get_contract_assertion_kind(tree contract)
1923
1939
gcc_unreachable ();
1924
1940
}
1925
1941
1926
- /* Get constract_evaluation_semantic of the specified contract. Used when building
1927
- P2900R7 contract_violation object. */
1942
+ /* Get contract_evaluation_semantic of the specified contract. */
1928
1943
static int
1929
1944
get_evaluation_semantic (tree contract)
1930
1945
{
@@ -1937,16 +1952,17 @@ get_evaluation_semantic(tree contract)
1937
1952
return CES_OBSERVE;
1938
1953
}
1939
1954
1955
+ /* Used when building P2900R10 contract_violation object. Note that we do not
1956
+ build such objects unless we are going to use them - so that we should not
1957
+ get asked for 'ignore' or 'quick'. */
1940
1958
switch (semantic)
1941
1959
{
1942
1960
default :
1943
1961
gcc_unreachable ();
1944
- case CCS_MAYBE :
1962
+ case CCS_OBSERVE :
1945
1963
return CES_OBSERVE;
1946
- break ;
1947
- case CCS_NEVER:
1964
+ case CCS_ENFORCE:
1948
1965
return CES_ENFORCE;
1949
- break ;
1950
1966
}
1951
1967
}
1952
1968
@@ -1979,12 +1995,12 @@ build_contract_violation_P2900 (tree contract)
1979
1995
/* Return a VAR_DECL to pass to handle_contract_violation. */
1980
1996
1981
1997
static tree
1982
- build_contract_violation (tree contract, contract_continuation cmode )
1998
+ build_contract_violation (tree contract)
1983
1999
{
1984
2000
if (flag_contracts_nonattr)
1985
2001
return build_contract_violation_P2900 (contract);
1986
2002
1987
- return build_contract_violation_cpp20 (contract, cmode );
2003
+ return build_contract_violation_cpp20 (contract);
1988
2004
}
1989
2005
1990
2006
/* Return handle_contract_violation(), declaring it if needed. */
@@ -2054,10 +2070,9 @@ declare_handle_contract_violation ()
2054
2070
/* Build the call to handle_contract_violation for CONTRACT. */
2055
2071
2056
2072
static void
2057
- build_contract_handler_call (tree contract,
2058
- contract_continuation cmode)
2073
+ build_contract_handler_call (tree contract)
2059
2074
{
2060
- tree violation = build_contract_violation (contract, cmode );
2075
+ tree violation = build_contract_violation (contract);
2061
2076
tree violation_fn = declare_handle_contract_violation ();
2062
2077
tree call = build_call_n (violation_fn, 1 , build_address (violation));
2063
2078
finish_expr_stmt (call);
@@ -2094,17 +2109,17 @@ build_contract_check (tree contract)
2094
2109
tf_warning_or_error);
2095
2110
finish_if_stmt_cond (cond, if_stmt);
2096
2111
2097
- /* Get the continuation mode. */
2098
- contract_continuation cmode;
2099
- switch (semantic)
2112
+ /* Using the P2900 names here c++24 ENFORCE=NEVER, OBSERVE=MAYBE. */
2113
+ if (semantic == CCS_ENFORCE || semantic == CCS_OBSERVE)
2114
+ build_contract_handler_call (contract);
2115
+ if (semantic == CCS_QUICK)
2100
2116
{
2101
- case CCS_NEVER: cmode = NEVER_CONTINUE; break ;
2102
- case CCS_MAYBE: cmode = MAYBE_CONTINUE; break ;
2103
- default : gcc_unreachable ();
2117
+ tree fn = builtin_decl_explicit (BUILT_IN_ABORT);
2118
+ releasing_vec vec;
2119
+ finish_expr_stmt (finish_call_expr (fn, &vec, false , false ,
2120
+ tf_warning_or_error));
2104
2121
}
2105
-
2106
- build_contract_handler_call (contract, cmode);
2107
- if (cmode == NEVER_CONTINUE)
2122
+ else if (semantic == CCS_ENFORCE)
2108
2123
finish_expr_stmt (build_call_a (terminate_fn, 0 , nullptr ));
2109
2124
2110
2125
finish_then_clause (if_stmt);
0 commit comments