Skip to content

Commit

Permalink
[semantic3.d] factor contract semantic analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilsonator committed Oct 21, 2024
1 parent 7457513 commit a0b65fe
Showing 1 changed file with 24 additions and 37 deletions.
61 changes: 24 additions & 37 deletions compiler/src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -992,27 +992,17 @@ private extern(C++) final class Semantic3Visitor : Visitor
* [out] postconditions.
*/
immutable bool isNothrow = f.isNothrow && !funcdecl.nothrowInprocess;
if (freq)
{
/* frequire is composed of the [in] contracts
*/
auto sym = new ScopeDsymbol(funcdecl.loc, null);
sym.parent = sc2.scopesym;
sym.endlinnum = funcdecl.endloc.linnum;
sc2 = sc2.push(sym);
sc2.contract = Contract.require;

// BUG: need to error if accessing out parameters
// BUG: need to disallow returns
// BUG: verify that all in and ref parameters are read
freq = freq.statementSemantic(sc2);
void commonContractSem(ref Statement s, const(char*) type, CHECKENABLE use)
{
s = s.statementSemantic(sc2);

const blockExit = freq.blockExit(funcdecl, null);
const blockExit = s.blockExit(funcdecl, null);
if (blockExit & BE.throw_)
{
if (isNothrow)
error(funcdecl.loc, "`%s`: `in` contract may throw but function is marked as `nothrow`",
funcdecl.toPrettyChars());
error(funcdecl.loc, "`%s`: `%s` contract may throw but function is marked as `nothrow`",
type, funcdecl.toPrettyChars());
else if (funcdecl.nothrowInprocess)
f.isNothrow = false;
}
Expand All @@ -1021,8 +1011,23 @@ private extern(C++) final class Semantic3Visitor : Visitor

sc2 = sc2.pop();

if (global.params.useIn == CHECKENABLE.off)
freq = null;
if (use == CHECKENABLE.off)
s = null;
}
if (freq)
{
/* frequire is composed of the [in] contracts
*/
auto sym = new ScopeDsymbol(funcdecl.loc, null);
sym.parent = sc2.scopesym;
sym.endlinnum = funcdecl.endloc.linnum;
sc2 = sc2.push(sym);
sc2.contract = Contract.require;

// BUG: need to error if accessing out parameters
// BUG: need to disallow returns
// BUG: verify that all in and ref parameters are read
commonContractSem(freq, "in", global.params.useIn);
}

if (fens)
Expand All @@ -1048,25 +1053,7 @@ private extern(C++) final class Semantic3Visitor : Visitor

if (funcdecl.fensure && f.next.ty != Tvoid)
funcdecl.buildResultVar(scout, f.next);

fens = fens.statementSemantic(sc2);

const blockExit = fens.blockExit(funcdecl, null);
if (blockExit & BE.throw_)
{
if (isNothrow)
error(funcdecl.loc, "`%s`: `out` contract may throw but function is marked as `nothrow`",
funcdecl.toPrettyChars());
else if (funcdecl.nothrowInprocess)
f.isNothrow = false;
}

funcdecl.hasNoEH = false;

sc2 = sc2.pop();

if (global.params.useOut == CHECKENABLE.off)
fens = null;
commonContractSem(fens, "out", global.params.useOut);
}
if (funcdecl.fbody && funcdecl.fbody.isErrorStatement())
{
Expand Down

0 comments on commit a0b65fe

Please sign in to comment.