Skip to content

Commit d0ddc98

Browse files
Merge pull request gcc-mirror#102 from NinaRanns/contracts_ICE_github_issue_33
Fixing check of contracts on a declaration after definition
2 parents a3a3c5d + 8bff70f commit d0ddc98

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

gcc/cp/contracts.cc

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,8 +3314,8 @@ void
33143314
p2900_duplicate_contracts (tree newdecl, tree olddecl)
33153315
{
33163316
/* Aggregate the contracts and strip them from the input decls. */
3317-
tree new_contracts = extract_contract_attributes (newdecl);
3318-
tree old_contracts = extract_contract_attributes (olddecl);
3317+
tree new_contracts = DECL_CONTRACTS (newdecl);
3318+
tree old_contracts = DECL_CONTRACTS (olddecl);
33193319

33203320
if (!old_contracts && !new_contracts)
33213321
return;
@@ -3328,9 +3328,9 @@ p2900_duplicate_contracts (tree newdecl, tree olddecl)
33283328
also be needed when we process deferred contracts. */
33293329
bool existed = false;
33303330
contract_redecl& rd = redeclared_contracts.get_or_insert (olddecl, &existed);
3331-
if (!existed)
3331+
if (!existed && !contract_any_deferred_p (old_contracts))
33323332
{
3333-
rd.original_contracts = old_contracts;
3333+
rd.original_contracts = copy_contracts(olddecl);
33343334
location_t cont_end = old_loc;
33353335
if (old_contracts)
33363336
cont_end = get_contract_end_loc (old_contracts);
@@ -3351,20 +3351,13 @@ p2900_duplicate_contracts (tree newdecl, tree olddecl)
33513351
return;
33523352
}
33533353

3354-
/* If have now parsed deferred contracts for the 'first' decl, update the
3355-
saved record. */
3356-
if (rd.original_contracts
3357-
&& contract_any_deferred_p (rd.original_contracts)
3358-
&& old_contracts
3359-
&& !contract_any_deferred_p (old_contracts))
3360-
rd.original_contracts = old_contracts;
3361-
33623354
if (old_contracts && !new_contracts)
33633355
/* We allow re-declarations to omit contracts declared on the initial decl.
33643356
In fact, this is required if the conditions contain lambdas. Check if
33653357
all the parameters are correctly const qualified. */
33663358
check_param_in_redecl (olddecl, newdecl);
3367-
else if (contract_any_deferred_p (new_contracts))
3359+
else if (contract_any_deferred_p (new_contracts)
3360+
|| contract_any_deferred_p (old_contracts))
33683361
/* TODO: stash these and figure out how to process them later. */
33693362
;
33703363
else
@@ -3377,10 +3370,12 @@ p2900_duplicate_contracts (tree newdecl, tree olddecl)
33773370
}
33783371

33793372
/* We have maybe issued a diagnostic - but because the caller will smash the
3380-
attributes on the old decl with those on the new, we need to copy the old
3381-
ones onto the new. */
3373+
attributes on the old decl with those on the new, we need to remove the
3374+
contracts from the old decl and move the old contracts onto the new decl. */
3375+
remove_contract_attributes (newdecl);
33823376
DECL_ATTRIBUTES (newdecl)
3383-
= attr_chainon (DECL_ATTRIBUTES (newdecl), old_contracts);
3377+
= attr_chainon (DECL_ATTRIBUTES (newdecl),
3378+
extract_contract_attributes (olddecl));
33843379
return;
33853380
}
33863381

gcc/testsuite/g++.dg/contracts/cpp26/contracts-redecl.C

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,13 @@ struct Bar : Foo {
8686
void Bar::f10(int n) pre (n >10) {}; // { dg-error "mismatched contract" }
8787

8888

89+
struct NonTrivial{
90+
NonTrivial(){};
91+
NonTrivial(const NonTrivial&){}
92+
~NonTrivial(){};
93+
int x = 0;
94+
};
95+
96+
void f(const NonTrivial s) pre(s.x >0);
97+
void f(const NonTrivial g) {};
98+
void f(const NonTrivial t) pre(t.x >0);

0 commit comments

Comments
 (0)