Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- The generated C of a function whose program holds records declares `sysml_parse_rec`, so the collection runtime it instantiates over records compiles under a C compiler that rejects implicit declarations (gcc 14 and later); the compiler is now asked to reject them everywhere (`-Werror=implicit-function-declaration`).
1 change: 1 addition & 0 deletions changes/unreleased/smt-sensitivity-value-order.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- A sensitivity the SMT engine witnesses spells the output's two values in the check engine's order (`x ends as 1 or 2`), with witness A the run that ends with the first, whichever copy the solver's model put first.
2 changes: 1 addition & 1 deletion docs/project/native-compilation.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ lower.CalcBody (statements) ──┘
checked-arithmetic prelude, the calcs as functions, a `sysml_run` entry that turns an error into
a status, and a `main`.
- `build.go` — `Source`, `Build`, `Targets`; C is compiled with
`-O3 -flto -std=gnu11 -Wall -Wextra`, Go in a throwaway module.
`-O3 -flto -std=gnu11 -Werror=implicit-function-declaration -Wall -Wextra`, Go in a throwaway module.

### Function values

Expand Down
5 changes: 5 additions & 0 deletions internal/exec/smt/twocopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ func (e *Encoding) DecodePair(result *solve.Result, out Output) (*Diverging, err
if d.Values[0] == d.Values[1] {
return nil, &WitnessError{Var: out.Var.Name, Reason: fmt.Sprintf("both copies end with %s", d.Values[0])}
}
// The check engine orders a divergence's values; which copy the solver put first is noise.
if d.Values[1] < d.Values[0] {
d.Runs[0], d.Runs[1] = d.Runs[1], d.Runs[0]
d.Values[0], d.Values[1] = d.Values[1], d.Values[0]
}
return d, nil
}

Expand Down
12 changes: 9 additions & 3 deletions internal/frontend/repl/optimize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,9 @@ func TestOptimizeReportsObjectivesInDeclarationOrder(t *testing.T) {
}

// A bound no assignment attains is never reported as a value: the report says
// there is no optimum and offers only the feasible value found.
// there is no optimum and offers only the feasible value found. Whether the
// solver names the bound it approaches (z3 4.13) or reports nothing (z3 4.8)
// depends on its version; what it must never do is report the bound as a value.
func TestOptimizeReportsABoundThatIsNotAttained(t *testing.T) {
requireOptimizingSolver(t)
s := checkSession(t, optimizeModel)
Expand All @@ -231,8 +233,12 @@ func TestOptimizeReportsABoundThatIsNotAttained(t *testing.T) {
t.Fatalf("status is %s, want no-optimum: %s", report.Status, strings.Join(report.Lines, "\n"))
}
wants(t, got, "! Analysis OpenBound is satisfiable, but its optimum was not established",
"maximize widest = `margin`: no optimum reported")
rejects(t, got, "is optimized")
"maximize widest = `margin`: no ")
if !strings.Contains(got, "`margin`: no optimum reported") &&
!strings.Contains(got, "`margin`: no greatest value, approaching 10.5 without attaining it") {
t.Errorf("the open bound is neither unreported nor reported as approached:\n%s", got)
}
rejects(t, got, "is optimized", "`margin`: 10.5")
}

// Refusals need no solver: they are settled while translating.
Expand Down
2 changes: 1 addition & 1 deletion internal/translate/codegen/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func goCommand(name string) (string, error) {

// CFlags are the C compiler options; the prelude's explicit checks keep -O3 safe,
// and no contraction keeps every Real operation rounded as the interpreter rounds it.
var CFlags = []string{"-O3", "-flto", "-ffp-contract=off", "-std=gnu11", "-Wall", "-Wextra", "-Wno-unused-function", "-Wno-unused-parameter"}
var CFlags = []string{"-O3", "-flto", "-ffp-contract=off", "-std=gnu11", "-Werror=implicit-function-declaration", "-Wall", "-Wextra", "-Wno-unused-function", "-Wno-unused-parameter"}

// Source renders program for target, as a complete program with a main.
func Source(p *Program, target Target) ([]byte, error) {
Expand Down
1 change: 1 addition & 0 deletions internal/translate/codegen/emit_fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ static const char *sysml_show_rec(sysml_rec *r) {
sysml_format_rec(r, text, sizeof text);
return text;
}
static sysml_rec *sysml_parse_rec(const char *s, const char *name) { fprintf(stderr, "argument %s: %s is not an object value\n", name, s); exit(2); }
` + r.Replace(cSeqTemplate)
}

Expand Down
Loading