@@ -2782,30 +2782,58 @@ constify_contract_access(tree decl)
2782
2782
return decl;
2783
2783
}
2784
2784
2785
- /* Do not allow non-const by-value params being used in postconditions. */
2785
+ /* If declaration DECL is a PARM_DECL and it appears in a postcondition, then
2786
+ check that it is not a non-const by-value param. LOCATION is where the
2787
+ expression was found and is used for diagnostic purposes. */
2786
2788
2787
- bool
2788
- maybe_reject_param_in_postcondition (tree decl)
2789
+ void
2790
+ maybe_reject_param_in_postcondition (tree decl, location_t location )
2789
2791
{
2790
2792
if (flag_contracts_nonattr
2791
- && !TREE_READONLY (decl)
2792
2793
&& TREE_CODE (decl) == PARM_DECL
2793
2794
&& should_constify_contract
2794
2795
&& processing_postcondition
2795
- && !dependent_type_p (TREE_TYPE (decl))
2796
- && !CP_TYPE_CONST_P (TREE_TYPE (decl))
2797
2796
&& !(REFERENCE_REF_P (decl)
2798
2797
&& TREE_CODE (TREE_OPERAND (decl, 0 )) == PARM_DECL)
2799
2798
/* Return value parameter has DECL_ARTIFICIAL flag set. The flag
2800
2799
* presence of the flag should be sufficient to distinguish the
2801
2800
* return value parameter in this context. */
2802
2801
&& !(DECL_ARTIFICIAL (decl)))
2803
2802
{
2804
- error_at (DECL_SOURCE_LOCATION (decl),
2805
- " a value parameter used in a postcondition must be const" );
2806
- return true ;
2803
+ set_parm_used_in_post (decl);
2804
+
2805
+ if (!CP_TYPE_CONST_P (TREE_TYPE (decl)) && !TREE_READONLY (decl))
2806
+ {
2807
+ error_at (location,
2808
+ " a value parameter used in a postcondition must be const" );
2809
+ inform (DECL_SOURCE_LOCATION (decl), " parameter declared here" );
2810
+ }
2811
+ }
2812
+ }
2813
+
2814
+ /* Check if parameters used in postconditions are const qualified on
2815
+ a redeclaration that does not specify contracts. */
2816
+
2817
+ void
2818
+ check_param_in_redecl (tree olddecl, tree newdecl)
2819
+ {
2820
+ tree t1 = FUNCTION_FIRST_USER_PARM (olddecl);
2821
+ tree t2 = FUNCTION_FIRST_USER_PARM (newdecl);
2822
+ for (; t1 && t1 != void_list_node;
2823
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
2824
+ {
2825
+ if (parm_used_in_post_p (t1))
2826
+ {
2827
+ set_parm_used_in_post (t2);
2828
+ if (!CP_TYPE_CONST_P (TREE_TYPE (t2)) && !TREE_READONLY (t2))
2829
+ {
2830
+ error_at (DECL_SOURCE_LOCATION (t2),
2831
+ " value parameter %qE used in a postcondition must be const" , t2);
2832
+ inform (DECL_SOURCE_LOCATION (olddecl),
2833
+ " previous declaration here" );
2834
+ }
2835
+ }
2807
2836
}
2808
- return false ;
2809
2837
}
2810
2838
2811
2839
void
@@ -3277,8 +3305,9 @@ p2900_duplicate_contracts (tree newdecl, tree olddecl)
3277
3305
3278
3306
if (old_contracts && !new_contracts)
3279
3307
/* We allow re-declarations to omit contracts declared on the initial decl.
3280
- In fact, this is required if the conditions contain lambdas. */
3281
- ;
3308
+ In fact, this is required if the conditions contain lambdas. Check if
3309
+ all the parameters are correctly const qualified. */
3310
+ check_param_in_redecl (olddecl, newdecl);
3282
3311
else if (contract_any_deferred_p (new_contracts))
3283
3312
/* TODO: stash these and figure out how to process them later. */
3284
3313
;
0 commit comments