[Bailout] When Inputs Detected In DepGraph Cycle

Inputs occured in depGraph cycle is dangenrous and should be treated as an 
invariant since Forget _may_ generate broken code in this case, despite that 
technically this is a stricter then what we needed for the particular case of 
#633 and #634 and there   could be case that this is safe (like many `cfg-`   
tests that I have to mark as `bailout.`) 

I expect the next diff will fix them though. 

commit-id:0b13ed02
This commit is contained in:
Xuan Huang (黄玄)
2022-10-05 18:42:10 -04:00
parent cbbfba27b4
commit 19b08e67ad
2 changed files with 27 additions and 0 deletions
+8
View File
@@ -126,6 +126,7 @@ export type ErrorCode =
| ParseCode<"E0018">
| ParseCode<"E0019">
| ParseCode<"E0020">
| ParseCode<"E0021">
;
// prettier-ignore
@@ -168,6 +169,7 @@ export type DiagnosticOpts =
| { code: "E0018"; path: NodePath; context: null }
| { code: "E0019"; path: NodePath; context: null }
| { code: "E0020"; path: NodePath; context: null }
| { code: "E0021"; path: NodePath; context: { name: Name } }
;
function getDiagnosticMessage(opts: DiagnosticOpts): DiagnosticMessage {
@@ -320,6 +322,12 @@ ${getSource(opts.path)}
body: "Forget does not support the use of the arguments object.",
suggestion: null,
};
case "E0021":
return {
level: DiagnosticLevel.Error,
body: `Input "${opts.context.name}" is detected in a DepGraph cycle. This is dangenrous since Forget may (though not always) generate broken code like accessing "c_input" before it is defined.`,
suggestion: null,
};
default:
assertExhaustive(opts, `Unhandled error code ${opts}`);
}
@@ -47,6 +47,7 @@ function run(
}
const sccGraph = valGraph.condense();
checkSCCGraph(sccGraph, context);
if (outputKinds.includes(OutputKind.SCCGraph)) {
context.outputs[OutputKind.SCCGraph].push(sccGraph.snapshot());
@@ -184,6 +185,24 @@ function checkValGraph(valGraph: DepGraph.ValGraph) {
}
}
function checkSCCGraph(sccGraph: DepGraph.SCCGraph, context: CompilerContext) {
for (const scc of sccGraph.vertices) {
if (scc.isInput()) continue;
for (const valVertex of scc.members) {
if (IR.isInputVal(valVertex.val)) {
context.bailout("InputInDepGraphCycle", {
code: "E0021",
path: valVertex.val.ast.path,
context: {
name: valVertex.val.binding.identifier.name,
},
});
}
}
}
}
export function computeCfgControlDeps(
irFunc: IR.Func,
cfg: CFG