@@ -11815,7 +11815,9 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
1181511815 cp_lexer_consume_token (parser->lexer);
1181611816 first = false;
1181711817
11818- if (!(at_function_scope_p () || parsing_nsdmi ()))
11818+ if (!(at_function_scope_p ()
11819+ || parsing_nsdmi ()
11820+ || current_binding_level->kind == sk_contract))
1181911821 error ("non-local lambda expression cannot have a capture-default");
1182011822 }
1182111823
@@ -13120,16 +13122,12 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
1312013122 0);
1312113123
1312213124 /* Do we have an override for const-ification? */
13123- bool old_flag_contracts_nonattr_noconst
13124- = flag_contracts_nonattr_noconst;
13125-
1312613125 bool should_constify = !flag_contracts_nonattr_noconst;
1312713126 if (!modifier.error_p
1312813127 && (modifier.mutable_p
1312913128 || (flag_contracts_nonattr_const_keyword
1313013129 && !modifier.const_p)))
1313113130 should_constify = false;
13132- flag_contracts_nonattr_noconst = !should_constify;
1313313131
1313413132 /* If we have a current class object, see if we need to consider
1313513133 it const when processing the contract condition. */
@@ -13138,24 +13136,30 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
1313813136 current_class_ref = view_as_const (current_class_ref_copy);
1313913137
1314013138 /* Parse the condition. */
13141- ++processing_contract_condition;
13139+ tree contract = error_mark_node;
13140+ begin_scope (sk_contract, current_function_decl);
13141+ bool old_pc = processing_postcondition;
13142+ bool old_const = should_constify_contract;
13143+ processing_postcondition = false;
13144+ should_constify_contract = should_constify;
1314213145 cp_expr condition = cp_parser_conditional_expression (parser);
13143- --processing_contract_condition;
13146+ gcc_checking_assert (scope_chain && scope_chain->bindings
13147+ && scope_chain->bindings->kind == sk_contract);
13148+ /* Build the contract. */
13149+ contract
13150+ = grok_contract (cont_assert, /*mode*/NULL_TREE,
13151+ /*result*/NULL_TREE, condition, loc);
13152+ processing_postcondition = old_pc;
13153+ should_constify_contract = old_const;
13154+ pop_bindings_and_leave_scope ();
1314413155
1314513156 /* Revert (any) constification of the current class object. */
1314613157 current_class_ref = current_class_ref_copy;
1314713158
13148- flag_contracts_nonattr_noconst
13149- = old_flag_contracts_nonattr_noconst;
13150-
1315113159 parens.require_close (parser);
13152- /* Build the contract. */
13153- tree contract
13154- = grok_contract (cont_assert, /*mode*/NULL_TREE,
13155- /*result*/NULL_TREE, condition, loc);
13160+
1315613161 if (contract != error_mark_node)
1315713162 set_contract_const (contract, should_constify);
13158-
1315913163 std_attrs = finish_contract_attribute (cont_assert, contract);
1316013164
1316113165 /* If there are errors in the contract, we do not create the
@@ -31372,19 +31376,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3137231376 /* Enable location wrappers when parsing contracts. */
3137331377 auto suppression = make_temp_override (suppress_location_wrappers, 0);
3137431378
31375- /* Build a fake variable for the result identifier. */
31376- tree result = NULL_TREE;
31377- if (identifier)
31378- {
31379- begin_scope (sk_block, NULL_TREE);
31380- result = make_postcondition_variable (identifier);
31381- ++processing_template_decl;
31382- }
31383-
31384- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31385- /* The should_constify value should account for all the mixed flags. */
31386- flag_contracts_nonattr_noconst = !should_constify;
31387-
3138831379 /* If we have a current class object, see if we need to consider
3138931380 it const when processing the contract condition. */
3139031381 tree current_class_ref_copy = current_class_ref;
@@ -31393,16 +31384,31 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3139331384
3139431385 /* Parse the condition, ensuring that parameters or the return variable
3139531386 aren't flagged for use outside the body of a function. */
31396- ++processing_contract_condition;
31397- if (postcondition_p)
31398- ++processing_contract_postcondition;
31387+ begin_scope (sk_contract, current_function_decl);
31388+ bool old_pc = processing_postcondition;
31389+ bool old_const = should_constify_contract;
31390+ processing_postcondition = postcondition_p;
31391+ should_constify_contract = should_constify;
31392+ tree result = NULL_TREE;
31393+ if (identifier)
31394+ {
31395+ /* Build a fake variable for the result identifier. */
31396+ result = make_postcondition_variable (identifier);
31397+ ++processing_template_decl;
31398+ }
3139931399 cp_expr condition = cp_parser_conditional_expression (parser);
31400- if (postcondition_p)
31401- --processing_contract_postcondition;
31400+ /* Build the contract. */
31401+ contract = grok_contract (attribute, mode, result, condition, loc);
31402+ if (identifier)
31403+ --processing_template_decl;
31404+ processing_postcondition = old_pc;
31405+ should_constify_contract = old_const;
31406+ gcc_checking_assert (scope_chain && scope_chain->bindings
31407+ && scope_chain->bindings->kind == sk_contract);
31408+ pop_bindings_and_leave_scope ();
31409+
3140231410 /* Revert (any) constification of the current class object. */
3140331411 current_class_ref = current_class_ref_copy;
31404- flag_contracts_nonattr_noconst = old_flag_contracts_nonattr_noconst;
31405- --processing_contract_condition;
3140631412
3140731413 /* For natural syntax, we eat the parens here. For the attribute
3140831414 syntax, it will be done one level up, we just need to skip to it. */
@@ -31413,15 +31419,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3141331419 we need to search the condition for errors. */
3141431420 else if (contains_error_p (condition))
3141531421 cp_parser_skip_up_to_closing_square_bracket (parser);
31416-
31417- /* Build the contract. */
31418- contract = grok_contract (attribute, mode, result, condition, loc);
31419- /* Leave our temporary scope for the postcondition result. */
31420- if (result)
31421- {
31422- --processing_template_decl;
31423- pop_bindings_and_leave_scope ();
31424- }
3142531422 }
3142631423
3142731424 if (!flag_contracts)
@@ -31455,22 +31452,16 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3145531452 if (TREE_CODE (contract) == POSTCONDITION_STMT)
3145631453 identifier = POSTCONDITION_IDENTIFIER (contract);
3145731454
31458- /* Build a fake variable for the result identifier. */
31459- tree result = NULL_TREE;
31455+ tree type = TREE_TYPE (TREE_TYPE (fn));
3146031456 if (identifier)
3146131457 {
3146231458 /* TODO: Can we guarantee that the identifier has a location? */
3146331459 location_t loc = cp_expr_location (contract);
31464- tree type = TREE_TYPE (TREE_TYPE (fn));
3146531460 if (!check_postcondition_result (fn, type, loc))
3146631461 {
3146731462 invalidate_contract (contract);
3146831463 return;
3146931464 }
31470-
31471- begin_scope (sk_block, NULL_TREE);
31472- result = make_postcondition_variable (identifier, type);
31473- ++processing_template_decl;
3147431465 }
3147531466
3147631467 /* In C++20 contracts, 'this' is not allowed in preconditions of
@@ -31502,7 +31493,6 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3150231493 cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
3150331494 cp_parser_push_lexer_for_tokens (parser, tokens);
3150431495
31505- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
3150631496 bool should_constify = get_contract_const (contract);
3150731497 /* If we have a current class object, see if we need to consider
3150831498 it const when processing the contract condition. */
@@ -31512,17 +31502,32 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3151231502
3151331503 /* Parse the condition, ensuring that parameters or the return variable
3151431504 aren't flagged for use outside the body of a function. */
31515- ++processing_contract_condition;
31516- if (POSTCONDITION_P (contract))
31517- ++processing_contract_postcondition;
31505+ begin_scope (sk_contract, fn);
31506+ bool old_pc = processing_postcondition;
31507+ bool old_const = should_constify_contract;
31508+ processing_postcondition = POSTCONDITION_P (contract);
31509+ should_constify_contract = should_constify;
31510+ /* Build a fake variable for the result identifier. */
31511+ tree result = NULL_TREE;
31512+ if (identifier)
31513+ {
31514+ result = make_postcondition_variable (identifier, type);
31515+ ++processing_template_decl;
31516+ }
3151831517 condition = cp_parser_conditional_expression (parser);
31519- if (POSTCONDITION_P (contract))
31520- --processing_contract_postcondition;
31521- --processing_contract_condition;
31518+ /* Commit to changes. */
31519+ update_late_contract (contract, result, condition);
31520+ /* Leave our temporary scope for the postcondition result. */
31521+ if (identifier)
31522+ --processing_template_decl;
31523+ processing_postcondition = old_pc;
31524+ should_constify_contract = old_const;
31525+ gcc_checking_assert (scope_chain && scope_chain->bindings
31526+ && scope_chain->bindings->kind == sk_contract);
31527+ pop_bindings_and_leave_scope ();
3152231528
3152331529 if (cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
31524- error_at (input_location,
31525- "expected conditional-expression");
31530+ error_at (input_location, "expected conditional-expression");
3152631531
3152731532 /* Revert to the main lexer. */
3152831533 cp_parser_pop_lexer (parser);
@@ -31533,17 +31538,6 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3153331538 current_class_ref = saved_ccr;
3153431539 current_class_ptr = saved_ccp;
3153531540 contract_class_ptr = saved_contract_ccp;
31536-
31537- /* Commit to changes. */
31538- update_late_contract (contract, result, condition);
31539- flag_contracts_nonattr_noconst = old_flag_contracts_nonattr_noconst;
31540-
31541- /* Leave our temporary scope for the postcondition result. */
31542- if (result)
31543- {
31544- --processing_template_decl;
31545- pop_bindings_and_leave_scope ();
31546- }
3154731541}
3154831542
3154931543static contract_modifier
0 commit comments