From 4defa73ad2b0fe23883364eb6edd12e460edcbdc Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 31 Oct 2024 18:33:01 +0100 Subject: [PATCH 01/18] Added kaml-serialization plugin --- buildSrc/build.gradle.kts | 1 + buildSrc/gradle.properties | 3 ++- buildSrc/src/main/kotlin/Deps.kt | 2 ++ .../main/kotlin/kaml-serialization.gradle.kts | 20 +++++++++++++++++++ subprojects/xcfa/xcfa-cli/build.gradle.kts | 1 + 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 buildSrc/src/main/kotlin/kaml-serialization.gradle.kts diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 7b1e3380f6..114d14bf7a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -38,6 +38,7 @@ fun gradlePlugin(id: String, version: String): String = "$id:$id.gradle.plugin:$ dependencies { compileOnly(gradleKotlinDsl()) implementation(kotlin("gradle-plugin", kotlinVersion)) + implementation(kotlin("serialization", kotlinVersion)) implementation(gradlePlugin("com.github.johnrengelman.shadow", shadowVersion)) implementation(gradlePlugin("com.diffplug.spotless", spotlessVersion)) } diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index 77da25281b..f25e464eeb 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -40,4 +40,5 @@ gsonVersion=2.9.1 javasmtVersion=4.1.1 sosylabVersion=0.3000-569-g89796f98 cliktVersion=4.4.0 -spotlessVersion=6.25.0 \ No newline at end of file +spotlessVersion=6.25.0 +kamlVersion=0.62.1 \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index 642499ed8f..5fc6cc9b53 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -79,4 +79,6 @@ object Deps { } val clikt = "com.github.ajalt.clikt:clikt:${Versions.clikt}" + + val kaml = "com.charleskorn.kaml:kaml:${Versions.kaml}" } diff --git a/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts b/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts new file mode 100644 index 0000000000..c2974cb03e --- /dev/null +++ b/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts @@ -0,0 +1,20 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +apply(plugin = "kotlin-common") +plugins { + kotlin("plugin.serialization") +} \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/build.gradle.kts b/subprojects/xcfa/xcfa-cli/build.gradle.kts index f695b775af..83c5989fe7 100644 --- a/subprojects/xcfa/xcfa-cli/build.gradle.kts +++ b/subprojects/xcfa/xcfa-cli/build.gradle.kts @@ -16,6 +16,7 @@ plugins { id("kotlin-common") + id("kaml-serialization") id("cli-tool") } From 0bc0f4dfe52bc57b2c4a799fc58939d3e887ff9e Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:23:19 +0100 Subject: [PATCH 02/18] Downgraded kaml --- buildSrc/gradle.properties | 2 +- .../main/kotlin/kaml-serialization.gradle.kts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index f25e464eeb..efb2dbd0eb 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -41,4 +41,4 @@ javasmtVersion=4.1.1 sosylabVersion=0.3000-569-g89796f98 cliktVersion=4.4.0 spotlessVersion=6.25.0 -kamlVersion=0.62.1 \ No newline at end of file +kamlVersion=0.59.0 \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts b/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts index c2974cb03e..b3e7da0b1c 100644 --- a/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts +++ b/buildSrc/src/main/kotlin/kaml-serialization.gradle.kts @@ -1,3 +1,21 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import gradle.kotlin.dsl.accessors._07de9d51edfbede3e6fa517ade9dcf20.implementation + /* * Copyright 2024 Budapest University of Technology and Economics * @@ -17,4 +35,7 @@ apply(plugin = "kotlin-common") plugins { kotlin("plugin.serialization") +} +dependencies { + implementation(Deps.kaml) } \ No newline at end of file From 65a557b80ba32597b3b343a042ee71dd7204ac4f Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:32:21 +0100 Subject: [PATCH 03/18] Updated metadata collection --- .../grammar/function/FunctionVisitor.java | 15 ++++++++++++++- .../model/statements/CStatement.java | 10 ++++++++++ .../java/hu/bme/mit/theta/c2xcfa/CMetaData.kt | 4 +++- .../mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 19 +++++++++++-------- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java index 4f9041fa08..e4dbd1a5c8 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java @@ -74,6 +74,8 @@ public class FunctionVisitor extends CBaseVisitor { private final TypedefVisitor typedefVisitor; private final Logger uniqueWarningLogger; + private ParserRuleContext currentStatementContext = null; + public void clear() { variables.clear(); flatVariables.clear(); @@ -168,6 +170,9 @@ public CStatement visitCompilationUnit(CParser.CompilationUnitContext ctx) { } public void recordMetadata(ParserRuleContext ctx, CStatement statement) { + if (currentStatementContext != null) { + ctx = currentStatementContext; // this will overwrite the current ASt element's ctx with the statement's ctx + } Token start = ctx.getStart(); Token stop = ctx.getStop(); String stopText = stop.getText(); @@ -186,6 +191,7 @@ public void recordMetadata(ParserRuleContext ctx, CStatement statement) { statement.setOffsetStart(offsetStart); statement.setOffsetEnd(offsetEnd); statement.setSourceText(textWithWS(ctx)); + statement.setCtx(ctx); } @@ -258,7 +264,10 @@ public CStatement visitBlockItemList(CParser.BlockItemListContext ctx) { if (ctx.parent.parent.parent.parent instanceof CParser.BlockItemListContext) variables.push(Tuple2.of("anonymous" + anonCnt++, new LinkedHashMap<>())); for (CParser.BlockItemContext blockItemContext : ctx.blockItem()) { + final var save = currentStatementContext; + currentStatementContext = blockItemContext; compound.getcStatementList().add(blockItemContext.accept(this)); + currentStatementContext = save; } if (ctx.parent.parent.parent.parent instanceof CParser.BlockItemListContext) variables.pop(); @@ -420,7 +429,11 @@ public CStatement visitReturnStatement(CParser.ReturnStatementContext ctx) { @Override public CStatement visitStatement(CParser.StatementContext ctx) { - return ctx.children.get(0).accept(this); + final var save = currentStatementContext; + currentStatementContext = ctx; + final var ret = ctx.children.get(0).accept(this); + currentStatementContext = save; + return ret; } @Override diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java index 93a2199239..7b569aada4 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java @@ -19,6 +19,7 @@ import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.frontend.ParseContext; import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; +import org.antlr.v4.runtime.ParserRuleContext; /** * Every Program, Function and Statement is a subclass of this base class. @@ -39,6 +40,7 @@ public abstract class CStatement { private int offsetStart = -1; private int offsetEnd = -1; private String sourceText = ""; + private ParserRuleContext ctx; protected CStatement(ParseContext parseContext) { this.parseContext = parseContext; @@ -137,4 +139,12 @@ public String getSourceText() { public void setSourceText(String sourceText) { this.sourceText = sourceText; } + + public ParserRuleContext getCtx() { + return ctx; + } + + public void setCtx(ParserRuleContext ctx) { + this.ctx = ctx; + } } diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt index 10d76a8e8d..fe8d5ee0bd 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt @@ -19,6 +19,7 @@ import hu.bme.mit.theta.xcfa.model.MetaData import hu.bme.mit.theta.xcfa.model.XcfaEdge import hu.bme.mit.theta.xcfa.model.XcfaLabel import hu.bme.mit.theta.xcfa.model.XcfaLocation +import org.antlr.v4.runtime.ParserRuleContext data class CMetaData( val lineNumberStart: Int?, @@ -27,7 +28,8 @@ data class CMetaData( val colNumberStop: Int?, val offsetStart: Int?, val offsetEnd: Int?, - val sourceText: String? + val sourceText: String?, + val ctx: ParserRuleContext?, ) : MetaData() fun XcfaLabel.getCMetaData(): CMetaData? { diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index d82a92fa4a..33355e8144 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -76,13 +76,14 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo } private fun getMetadata(source: CStatement): CMetaData = CMetaData( - lineNumberStart = source.lineNumberStart, - lineNumberStop = source.lineNumberStop, - colNumberStart = source.colNumberStart, - colNumberStop = source.colNumberStop, - offsetStart = source.offsetStart, - offsetEnd = source.offsetEnd, - sourceText = source.sourceText + lineNumberStart = source.lineNumberStart.takeIf { it != -1 }, + lineNumberStop = source.lineNumberStop.takeIf { it != -1 }, + colNumberStart = source.colNumberStart.takeIf { it != -1 }, + colNumberStop = source.colNumberStop.takeIf { it != -1 }, + offsetStart = source.offsetStart.takeIf { it != -1 }, + offsetEnd = source.offsetEnd.takeIf { it != -1 }, + sourceText = source.sourceText, + ctx = source.ctx, ) fun buildXcfa(cProgram: CProgram): XcfaBuilder { @@ -559,7 +560,9 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) edge = XcfaEdge(initLoc, - getLoc(builder, statement.label, metadata = getMetadata(statement))) + getLoc(builder, statement.label, metadata = getMetadata(statement)), + metadata = getMetadata(statement) + ) builder.addLoc(getLoc(builder, statement.label, metadata = getMetadata(statement))) val unreachableLoc: XcfaLocation = XcfaLocation( "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) From e6df276b9b21fb0224806c1ae6664f178f338a8d Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:33:25 +0100 Subject: [PATCH 04/18] Not allowing empty metadata by mistake --- .../hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt | 7 ++++--- .../main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt index 82a8e65178..b14d714142 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt @@ -37,9 +37,10 @@ constructor(val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTripl source: XcfaLocation, target: XcfaLocation, label: XcfaLabel = NopLabel, + metaData: MetaData = EmptyMetaData, lastWrites: WriteTriples = emptyMap(), nextCnt: Int = 0) : - this(pid, XcfaEdge(source, target, label), lastWrites, nextCnt) + this(pid, XcfaEdge(source, target, label, metaData), lastWrites, nextCnt) override val stmtList: List get() = stmts @@ -49,11 +50,11 @@ constructor(val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTripl } fun withLabel(sequenceLabel: SequenceLabel): XcfaAction { - return XcfaAction(pid, source, target, sequenceLabel, nextCnt = nextCnt) + return XcfaAction(pid, source, target, sequenceLabel, edge.metadata, nextCnt = nextCnt) } fun withLastWrites(writeTriples: WriteTriples, nextCnt: Int): XcfaAction { - return XcfaAction(pid, source, target, label, writeTriples, nextCnt) + return XcfaAction(pid, source, target, label, edge.metadata, writeTriples, nextCnt) } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt index ba90dcdfdf..91d3d567f2 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt @@ -112,7 +112,7 @@ data class XcfaLocation @JvmOverloads constructor( val initial: Boolean = false, // is this the initial location? val final: Boolean = false, // is this the final location? val error: Boolean = false, // is this the error location? - val metadata: MetaData = EmptyMetaData, + val metadata: MetaData, ) { val incomingEdges: MutableSet = LinkedHashSet() // all incoming edges in the current procedure @@ -129,16 +129,16 @@ data class XcfaLocation @JvmOverloads constructor( } } -data class XcfaEdge @JvmOverloads constructor( +data class XcfaEdge( val source: XcfaLocation, // source location val target: XcfaLocation, // target location val label: XcfaLabel = NopLabel, // edge label - val metadata: MetaData = EmptyMetaData, + val metadata: MetaData ) { - fun withLabel(label: XcfaLabel): XcfaEdge = XcfaEdge(source, target, label) - fun withTarget(target: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label) - fun withSource(source: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label) + fun withLabel(label: XcfaLabel): XcfaEdge = XcfaEdge(source, target, label, metadata) + fun withTarget(target: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label, metadata) + fun withSource(source: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label, metadata) } data class XcfaGlobalVar @JvmOverloads constructor( From 07b92969f5cba014377a92a6ab35dc6d9b8965e6 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:34:25 +0100 Subject: [PATCH 05/18] Not swallowing edges in concretization --- .../xcfa/cli/witnesses/TraceToWitness.kt | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt index 38ab39f52b..252e248e45 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt @@ -52,6 +52,7 @@ fun traceToWitness( for (i in 0 until trace.length()) { val state = trace.states[i] + val action = trace.actions[i] val nextState = trace.states[i + 1] val newThreads = nextState.processes.keys - state.processes.keys val node = WitnessNode( @@ -68,18 +69,19 @@ fun traceToWitness( if (node != WitnessNode(id = "N${newStates.size}")) { newStates.add(node) val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id, - threadId = trace.actions[i].pid.toString()) + threadId = trace.actions[i].pid.toString(), edge = action.edge + ) newActions.add(edge) lastNode = node } - val action = trace.actions[i] val flattenedSequence = flattenSequence(action.edge.label) for (xcfaLabel in flattenedSequence) { val node = WitnessNode(id = "N${newStates.size}", entry = false, sink = false, violation = false) var edge = labelToEdge(lastNode, node, xcfaLabel, action.pid, - nextState.sGlobal.getVal(), parseContext) + nextState.sGlobal.getVal(), parseContext, action.edge + ) if (newThreads.isNotEmpty() && xcfaLabel is StartLabel) { edge = edge.copy(createThread = newThreads.joinToString(",")) } @@ -104,7 +106,7 @@ fun traceToWitness( globalState = lastState.sGlobal ) newStates.add(node) - val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id) + val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id, edge = trace.actions[trace.length() - 1].edge) newActions.add(edge) return Trace.of(newStates, newActions) @@ -120,8 +122,10 @@ fun shouldInclude(edge: WitnessEdge, verbosity: Verbosity): Boolean = } -private fun labelToEdge(lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, - valuation: Valuation, parseContext: ParseContext): WitnessEdge = +private fun labelToEdge( + lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, + valuation: Valuation, parseContext: ParseContext, edge: XcfaEdge +): WitnessEdge = WitnessEdge( sourceId = lastNode.id, targetId = node.id, @@ -147,11 +151,14 @@ private fun labelToEdge(lastNode: WitnessNode, node: WitnessNode, xcfaLabel: Xcf endline = xcfaLabel.getCMetaData()?.lineNumberStop, startoffset = xcfaLabel.getCMetaData()?.offsetStart, endoffset = xcfaLabel.getCMetaData()?.offsetEnd, + startcol = xcfaLabel.getCMetaData()?.colNumberStart, + endcol = xcfaLabel.getCMetaData()?.colNumberStop, threadId = if (pid != null) "$pid" else null, stmt = if (xcfaLabel is StmtLabel) xcfaLabel.stmt.toString() else null, - cSource = xcfaLabel.getCMetaData()?.sourceText + cSource = xcfaLabel.getCMetaData()?.sourceText, + edge = edge ) private fun flattenSequence(label: XcfaLabel): List = From 35189fc65eaffe6e0fef9b37825e5aab762907c6 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:35:16 +0100 Subject: [PATCH 06/18] Not swallowing edges in writing --- .../theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java index 5c6c8e0a96..435e3dbf9e 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java @@ -41,12 +41,7 @@ import hu.bme.mit.theta.xcfa.model.XcfaEdge; import kotlin.Triple; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkArgument; @@ -65,7 +60,7 @@ public static Trace, XcfaAction> concretize( Map, Expr, Expr>>> nextW = Collections.emptyMap(); for (int i = 0; i < trace.getActions().size(); ++i) { - final XcfaEdge edge = new XcfaEdge(trace.getAction(i).getSource(), trace.getAction(i).getTarget(), trace.getAction(i).getLabel()); + final XcfaEdge edge = new XcfaEdge(trace.getAction(i).getSource(), trace.getAction(i).getTarget(), trace.getAction(i).getLabel(), trace.getAction(i).getEdge().getMetadata()); final XcfaAction action = new XcfaAction(trace.getAction(i).getPid(), edge, nextW, trace.getAction(i).getInCnt()); sbeActions.add(action); nextW = action.nextWriteTriples(); From 94c67403d8c233b3ebc29a4dcd88650d4679b319 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:35:48 +0100 Subject: [PATCH 07/18] Not removing empty edges if they have non-empty metadata attached --- .../hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt index 90e7170707..5de0ad72ad 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt @@ -30,7 +30,8 @@ class EmptyEdgeRemovalPass : ProcedurePass { while (true) { val edge = builder.getEdges().find { it.label.isNop() && !it.target.error && !it.target.final && !it.source.initial && - (it.source.outgoingEdges.size == 1 || it.target.incomingEdges.size == 1) + (it.source.outgoingEdges.size == 1 || it.target.incomingEdges.size == 1) && + it.metadata is EmptyMetaData } ?: return builder val collapseBefore = edge.source.outgoingEdges.size == 1 builder.removeEdge(edge) @@ -55,5 +56,5 @@ class EmptyEdgeRemovalPass : ProcedurePass { is NopLabel -> true is StmtLabel -> stmt == Assume(True()) else -> false - } + }.and(metadata is EmptyMetaData) } \ No newline at end of file From 988391f737f34f79d00cc3da241185d8bcd3a04a Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:36:14 +0100 Subject: [PATCH 08/18] Adding metadata to error location pass --- .../hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt index d539cb6240..0e65bbfc97 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt @@ -32,10 +32,14 @@ class ErrorLocationPass(private val checkOverflow: Boolean) : ProcedurePass { (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) edges.forEach { - if (predicate((it.label as SequenceLabel).labels[0])) { + val label = (it.label as SequenceLabel).labels[0] + if (predicate(label)) { if (builder.errorLoc.isEmpty) builder.createErrorLoc() builder.addEdge( - XcfaEdge(it.source, builder.errorLoc.get(), SequenceLabel(listOf()))) + XcfaEdge( + it.source, builder.errorLoc.get(), SequenceLabel(listOf()), metadata = label.metadata + ) + ) } else { builder.addEdge(it) } From c6ccac31c2c0e6e7afb74b3c3f8e9a0a4137838d Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 16:37:46 +0100 Subject: [PATCH 09/18] Added yml witness writing --- .../bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 16 +- ...tnessWriter.kt => GraphmlWitnessWriter.kt} | 8 +- .../theta/xcfa/cli/utils/YmlWitnessWriter.kt | 195 ++++++++++++ .../theta/xcfa/cli/witnesses/CommonWitness.kt | 118 +++++++ .../xcfa/cli/witnesses/GraphmlWitness.kt | 207 ++++++++++++ .../mit/theta/xcfa/cli/witnesses/Witness.kt | 299 ------------------ .../theta/xcfa/cli/witnesses/YamlWitness.kt | 260 +++++++++++++++ .../bme/mit/theta/xcfa/cli/YamlParseTest.kt | 72 +++++ 8 files changed, 871 insertions(+), 304 deletions(-) rename subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/{XcfaWitnessWriter.kt => GraphmlWitnessWriter.kt} (96%) create mode 100644 subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt create mode 100644 subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt create mode 100644 subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt delete mode 100644 subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt create mode 100644 subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt create mode 100644 subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index c7027914fc..f8987c875e 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -399,7 +399,7 @@ private fun postVerificationLogging( } } val witnessFile = File(resultFolder, "witness.graphml") - XcfaWitnessWriter() + GraphmlWitnessWriter() .writeWitness( safetyResult, config.inputConfig.input!!, @@ -410,6 +410,20 @@ private fun postVerificationLogging( parseContext, witnessFile, ) + val yamlWitnessFile = File(resultFolder, "witness.yml") + YmlWitnessWriter() + .writeWitness( + safetyResult, + config.inputConfig.input!!, + config.inputConfig.property, + (config.frontendConfig.specConfig as? CFrontendConfig)?.architecture, + getSolver( + config.outputConfig.witnessConfig.concretizerSolver, + config.outputConfig.witnessConfig.validateConcretizerSolver, + ), + parseContext, + yamlWitnessFile, + ) } } catch (e: Throwable) { logger.write(Logger.Level.INFO, "Could not output files: ${e.stackTraceToString()}\n") diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt similarity index 96% rename from subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt rename to subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt index 722fa7d91d..881a3202cf 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt @@ -23,7 +23,7 @@ import hu.bme.mit.theta.frontend.ParseContext import hu.bme.mit.theta.solver.SolverFactory import hu.bme.mit.theta.xcfa.analysis.XcfaAction import hu.bme.mit.theta.xcfa.analysis.XcfaState -import hu.bme.mit.theta.xcfa.cli.witnesses.Witness +import hu.bme.mit.theta.xcfa.cli.witnesses.GraphmlWitness import hu.bme.mit.theta.xcfa.cli.witnesses.XcfaTraceConcretizer import hu.bme.mit.theta.xcfa.cli.witnesses.traceToWitness import java.io.BufferedWriter @@ -34,7 +34,7 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* -class XcfaWitnessWriter { +class GraphmlWitnessWriter { fun writeWitness( safetyResult: SafetyResult<*, *>, @@ -50,8 +50,8 @@ class XcfaWitnessWriter { parseContext) val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) - val witness = Witness(witnessTrace, inputFile) - val xml = witness.toPrettyXml() + val graphmlWitness = GraphmlWitness(witnessTrace, inputFile) + val xml = graphmlWitness.toPrettyXml() witnessfile.writeText(xml) } else if (safetyResult.isSafe) { val taskHash = WitnessWriter.createTaskHash(inputFile.absolutePath) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt new file mode 100644 index 0000000000..ae39115e9f --- /dev/null +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt @@ -0,0 +1,195 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.xcfa.cli.utils + +import hu.bme.mit.theta.analysis.Trace +import hu.bme.mit.theta.analysis.algorithm.Proof +import hu.bme.mit.theta.analysis.algorithm.SafetyResult +import hu.bme.mit.theta.analysis.algorithm.arg.ARG +import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode +import hu.bme.mit.theta.analysis.expl.ExplState +import hu.bme.mit.theta.analysis.ptr.PtrState +import hu.bme.mit.theta.c2xcfa.CMetaData +import hu.bme.mit.theta.core.type.booltype.BoolExprs.Or +import hu.bme.mit.theta.core.utils.ExprUtils +import hu.bme.mit.theta.frontend.ParseContext +import hu.bme.mit.theta.frontend.transformation.ArchitectureConfig +import hu.bme.mit.theta.solver.SolverFactory +import hu.bme.mit.theta.xcfa.analysis.ErrorDetection +import hu.bme.mit.theta.xcfa.analysis.XcfaAction +import hu.bme.mit.theta.xcfa.analysis.XcfaState +import hu.bme.mit.theta.xcfa.cli.witnesses.* +import hu.bme.mit.theta.xcfa.model.MetaData +import hu.bme.mit.theta.xcfa.toC +import java.io.File +import java.util.* + + +class YmlWitnessWriter { + + fun writeWitness( + safetyResult: SafetyResult<*, *>, + inputFile: File, + property: ErrorDetection, + architecture: ArchitectureConfig.ArchitectureType?, + cexSolverFactory: SolverFactory, + parseContext: ParseContext, + witnessfile: File, + ) { + val metadata = Metadata( + formatVersion = "2.0", + uuid = UUID.randomUUID().toString(), + creationTime = getIsoDate(), + producer = Producer( + name = (System.getenv("VERIFIER_NAME")?:"").ifEmpty { "Theta" }, + version = (System.getenv("VERIFIER_VERSION")?:"").ifEmpty { "no version found" }, + ), + task = Task( + inputFiles = listOf(inputFile.name), + inputFileHashes = listOf(createTaskHash(inputFile.path)), + specification = property.name, + dataModel = architecture?.let { if(it == ArchitectureConfig.ArchitectureType.ILP32) DataModel.ILP32 else DataModel.LP64 } ?: DataModel.ILP32, + language = Language.C, + ) + ) + + if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { + val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( + safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, cexSolverFactory, + parseContext) + + val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) + + val witness = YamlWitness( + entryType = EntryType.VIOLATION, + metadata = metadata, + content = (0..(witnessTrace.length())).flatMap { + listOfNotNull( + witnessTrace.states.get(it)?.toSegment(witnessTrace.actions.getOrNull(it-1), inputFile), + witnessTrace.actions.getOrNull(it)?.toSegment(inputFile) + ) + } + ) + + witnessfile.writeText(WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness)) + } else if (safetyResult.isSafe) { + + val witness = YamlWitness( + entryType = EntryType.INVARIANTS, + metadata = metadata, + content = safetyResult.asSafe().proof.toContent(inputFile, parseContext) + ) + + witnessfile.writeText(WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness)) + } + } +} + +private fun getLocation(inputFile: File, metadata: MetaData?): Location? { + val line = (metadata as? CMetaData)?.lineNumberStart ?: (metadata as? CMetaData)?.lineNumberStop ?: return null + val column = (metadata as? CMetaData)?.colNumberStart ?: (metadata as? CMetaData)?.colNumberStop + return Location( + fileName = inputFile.name, + line = line, + column = column, + ) +} + +private fun getLocation(inputFile: File, witnessEdge: WitnessEdge?): Location? { + if(witnessEdge == null) return null + val endLoc = Location( + fileName = inputFile.name, + line = witnessEdge.endline ?: witnessEdge.startline ?: return null, + column = (witnessEdge.endcol ?: witnessEdge.startcol)?.plus(1), + ) + return endLoc +} + +private fun WitnessNode.toSegment(witnessEdge: WitnessEdge?, inputFile: File): ContentItem? { + if(violation) { + val loc = xcfaLocations.values.first().first() + val locLoc = getLocation(inputFile, loc.metadata) ?: getLocation(inputFile, witnessEdge) ?: getLocation(inputFile, witnessEdge?.edge?.metadata) ?: return null + return ContentItem(Segment( + Waypoint( + type = WaypointType.TARGET, + location = locLoc, + action = Action.FOLLOW + ) + )) + } else { + return null + } +} + +private fun WitnessEdge.toSegment(inputFile: File): ContentItem? { + val endLoc = Location( + fileName = inputFile.name, + line = endline ?: startline ?: return null, + column = (endcol ?: startcol)?.plus(1), + ) + val startLoc = Location( + fileName = inputFile.name, + line = startline ?: endline ?: return null, + column = (startcol ?: endcol)?.plus(1), + ) + + val (loc, constraint, type) = if(assumption != null) { + Triple(endLoc, Constraint(value = assumption, format = Format.C_EXPRESSION), WaypointType.ASSUMPTION) + } else if(control != null) { + Triple(startLoc, Constraint(value = control.toString()), WaypointType.BRANCHING) + } else if(enterLoopHead) { + Triple(startLoc, Constraint(value = "true"), WaypointType.BRANCHING) + } else if(enterFunction != null) { + Triple(startLoc, Constraint(value = enterFunction), WaypointType.FUNCTION_ENTER) + } else if(returnFromFunction != null) { + Triple(endLoc, Constraint(value = returnFromFunction), WaypointType.FUNCTION_RETURN) + } else return null + return ContentItem(Segment( + Waypoint( + type = type, + constraint = constraint, + location = loc, + action = Action.FOLLOW + ) + )) +} + +private fun Proof.toContent(inputFile: File, parseContext: ParseContext): List { + if(this is ARG<*, *>) { + val locMap = nodes.toList().mapNotNull { + it as ArgNode, XcfaAction> + val loc = it.state.processes.values.firstOrNull()?.locs?.peek() ?: return@mapNotNull null + val locLoc = Location( + fileName = inputFile.name, + line = (loc.metadata as? CMetaData)?.lineNumberStart ?: (loc.metadata as? CMetaData)?.lineNumberStop ?: return@mapNotNull null, + column = (loc.metadata as? CMetaData)?.colNumberStart ?: (loc.metadata as? CMetaData)?.colNumberStop, + ) + locLoc to it.state.sGlobal.toExpr() + }.groupBy{ it.first } + val invs = locMap.mapValues { entry -> ExprUtils.simplify(Or(entry.value.map { it.second })) }.map { + ContentItem( + invariant = Invariant( + type = InvariantType.LOCATION_INVARIANT, + location = it.key, + value = it.value.toC(parseContext), + format = Format.C_EXPRESSION + ) + ) + } + return invs + } + return listOf() +} \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt new file mode 100644 index 0000000000..fcaf982dfb --- /dev/null +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hu.bme.mit.theta.xcfa.cli.witnesses + +import hu.bme.mit.theta.analysis.Action +import hu.bme.mit.theta.analysis.State +import hu.bme.mit.theta.analysis.expl.ExplState +import hu.bme.mit.theta.xcfa.model.XcfaEdge +import hu.bme.mit.theta.xcfa.model.XcfaLocation +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Paths +import java.security.DigestInputStream +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException +import java.text.DateFormat +import java.text.SimpleDateFormat +import java.util.* + +data class WitnessNode( + val id: String, + val entry: Boolean = false, + val sink: Boolean = false, + val violation: Boolean = false, + + val xcfaLocations: Map> = emptyMap(), + val cSources: Map> = emptyMap(), + val globalState: ExplState? = null +) : State { + + override fun isBottom(): Boolean { + error("Not applicable for witness states.") + } +} + +data class WitnessEdge( + val sourceId: String, + val targetId: String, + val assumption: String? = null, + val assumption_scope: String? = null, + val assumption_resultfunction: String? = null, + val control: Boolean? = null, + val startline: Int? = null, + val endline: Int? = null, + val startoffset: Int? = null, + val endoffset: Int? = null, + val startcol: Int? = null, + val endcol: Int? = null, + val enterLoopHead: Boolean = false, + val enterFunction: String? = null, + val returnFromFunction: String? = null, + val threadId: String? = null, + val createThread: String? = null, + + val stmt: String? = null, + val cSource: String? = null, + val edge: XcfaEdge? = null, +) : Action { +} + +fun createTaskHash(programFile: String): String { + var md: MessageDigest? = null + try { + md = MessageDigest.getInstance("SHA-256") + } catch (e: NoSuchAlgorithmException) { + e.printStackTrace() + } + try { + Files.newInputStream(Paths.get(programFile)).use { `is` -> + DigestInputStream(`is`, md).use { dis -> + while (dis.read() != -1) { + } + } + } + } catch (e: IOException) { + e.printStackTrace() + } + assert(md != null) + val digest = md!!.digest() + return bytesToHex(digest) +} + +// source: https://www.baeldung.com/sha-256-hashing-java +fun bytesToHex(hash: ByteArray): String { + val hexString = StringBuilder(2 * hash.size) + for (i in hash.indices) { + val hex = Integer.toHexString(0xff and hash[i].toInt()) + if (hex.length == 1) { + hexString.append('0') + } + hexString.append(hex) + } + return hexString.toString() +} + +fun getIsoDate(): String { + val tz: TimeZone = TimeZone.getTimeZone("UTC") + val df: DateFormat = SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ) // Quoted "Z" to indicate UTC, no timezone offset + + df.timeZone = tz + return df.format(Date()) +} \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt new file mode 100644 index 0000000000..d2906d7359 --- /dev/null +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt @@ -0,0 +1,207 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hu.bme.mit.theta.xcfa.cli.witnesses + +import hu.bme.mit.theta.analysis.Trace +import java.io.File +import java.io.StringReader +import java.io.StringWriter +import javax.xml.XMLConstants +import javax.xml.transform.OutputKeys +import javax.xml.transform.Source +import javax.xml.transform.Transformer +import javax.xml.transform.TransformerFactory +import javax.xml.transform.stream.StreamResult +import javax.xml.transform.stream.StreamSource + + +class GraphmlWitness(private val trace: Trace, programFile: File) { + + private val attributes: MutableList = ArrayList() + private val data: MutableList> = ArrayList() + + init { + attributes.add(GraphmlWitnessAttribute("sourcecodelang", "string", "graph", "sourcecodelang")) + attributes.add(GraphmlWitnessAttribute("creationtime", "string", "graph", "creationtime")) + attributes.add(GraphmlWitnessAttribute("witness-type", "string", "graph", "witness-type")) + attributes.add(GraphmlWitnessAttribute("producer", "string", "graph", "producer")) + attributes.add(GraphmlWitnessAttribute("architecture", "string", "graph", "architecture")) + attributes.add(GraphmlWitnessAttribute("programHash", "string", "graph", "programhash")) + attributes.add(GraphmlWitnessAttribute("programfile", "string", "graph", "programfile")) + attributes.add(GraphmlWitnessAttribute("specification", "string", "graph", "specification")) + + attributes.add(GraphmlWitnessAttribute("assumption", "string", "edge", "assumption")) + attributes.add(GraphmlWitnessAttribute("assumption.scope", "string", "edge", "assumption.scope")) + attributes.add( + GraphmlWitnessAttribute( + "assumption.resultfunction", "string", "edge", + "assumption.resultfunction")) + attributes.add(GraphmlWitnessAttribute("control", "string", "edge", "control")) + attributes.add(GraphmlWitnessAttribute("startline", "string", "edge", "startline")) + attributes.add(GraphmlWitnessAttribute("endline", "string", "edge", "endline")) + attributes.add(GraphmlWitnessAttribute("startoffset", "string", "edge", "startoffset")) + attributes.add(GraphmlWitnessAttribute("endoffset", "string", "edge", "endoffset")) + attributes.add(GraphmlWitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead")) + attributes.add(GraphmlWitnessAttribute("enterFunction", "string", "edge", "enterFunction")) + attributes.add( + GraphmlWitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction") + ) + attributes.add(GraphmlWitnessAttribute("threadId", "string", "edge", "threadId")) + attributes.add(GraphmlWitnessAttribute("createThread", "string", "edge", "createThread")) + attributes.add(GraphmlWitnessAttribute("stmt", "string", "edge", "stmt")) + attributes.add(GraphmlWitnessAttribute("cSource", "string", "edge", "cSource")) + + attributes.add(GraphmlWitnessAttribute("entry", "string", "node", "entry", "false")) + attributes.add(GraphmlWitnessAttribute("sink", "string", "node", "sink", "false")) + attributes.add(GraphmlWitnessAttribute("violation", "string", "node", "violation", "false")) + attributes.add(GraphmlWitnessAttribute("locationStacks", "string", "node", "locationStacks")) + attributes.add(GraphmlWitnessAttribute("sourceLines", "string", "node", "sourceLines")) + attributes.add(GraphmlWitnessAttribute("state", "string", "node", "state")) + + data.add(Pair("witness-type", "violation_witness")) + data.add(Pair("producer", "theta")) + data.add(Pair("sourcecodelang", "C")) + data.add(Pair("specification", "CHECK( init(main()), LTL(G ! call(reach_error())) )")) + data.add(Pair("programfile", programFile.absolutePath)) + data.add(Pair("programhash", createTaskHash(programFile.path))) + data.add(Pair("architecture", "32bit")) + data.add(Pair("creationtime", getIsoDate())) + } + + fun toPrettyXml(): String = prettyFormat(toXml(), 4) + + fun toXml(): String = """ + + + +${attributes.map(GraphmlWitnessAttribute::toXml).reduce { a, b -> "$a\n$b" }} + + + +${data.map { "${it.second}" }.reduce { a, b -> "$a\n$b" }} + +${trace.states.map(WitnessNode::toXml).reduce { a, b -> "$a\n$b" }} + +${trace.actions.map(WitnessEdge::toXml).reduce { a, b -> "$a\n$b" }} + + + + """.trimIndent() + +} + +data class GraphmlWitnessAttribute( + val name: String, + val type: String, + val `for`: String, + val id: String, + val defaultValue: String? = null +) { + + fun toXml(): String = """ +" else """ +> +$defaultValue + +""".trimIndent() + } +""".trimIndent() +} + +private fun escapeXml(toEscape: String): String { + var toEscape = toEscape + toEscape = toEscape.replace("&", "&") + toEscape = toEscape.replace("\"", """) + toEscape = toEscape.replace("'", "'") + toEscape = toEscape.replace("<", "<") + toEscape = toEscape.replace(">", ">") + return toEscape +} + +// from https://stackoverflow.com/a/1264912 +private fun prettyFormat(input: String, indent: Int): String { + return try { + val xmlInput: Source = StreamSource( + StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), ""))) + val stringWriter = StringWriter() + val xmlOutput = StreamResult(stringWriter) + val transformerFactory: TransformerFactory = TransformerFactory.newInstance() + transformerFactory.setAttribute("indent-number", indent) + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "") + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "") + val transformer: Transformer = transformerFactory.newTransformer() + transformer.setOutputProperty(OutputKeys.INDENT, "yes") + transformer.transform(xmlInput, xmlOutput) + xmlOutput.getWriter().toString() + } catch (e: Exception) { + System.err.println(input.replace(Regex("( )|[\\t\\n\\r]"), "")) + throw RuntimeException(e) + } +} + +fun WitnessNode.toXml(): String = """ + + ${if (entry) "true" else ""} + ${if (sink) "true" else ""} + ${if (violation) "true" else ""} + + ${ + if (xcfaLocations.isNotEmpty()) "${ + escapeXml(xcfaLocations.toString()) + }" else "" +} + ${ + if (cSources.isNotEmpty()) "${ + escapeXml(cSources.toString()) + }" else "" +} + ${ + if (globalState != null) "${ + escapeXml(globalState.toString()) + }" else "" +} + + """.trimIndent() + +fun WitnessEdge.toXml(): String = """ + + ${if (assumption != null) "$assumption" else ""} + ${if (assumption_scope != null) "$assumption_scope" else ""} + ${if (assumption_resultfunction != null) "$assumption_resultfunction" else ""} + ${if (control != null) "condition-$control" else ""} + ${if (startline != null && startline != -1) "$startline" else ""} + ${if (endline != null && endline != -1) "$endline" else ""} + ${if (startoffset != null && startoffset != -1) "$startoffset" else ""} + ${if (endoffset != null && endoffset != -1) "$endoffset" else ""} + ${if (enterLoopHead) "true" else ""} + ${if (enterFunction != null) "$enterFunction" else ""} + ${if (returnFromFunction != null) "$returnFromFunction" else ""} + ${if (threadId != null) "$threadId" else ""} + ${if (createThread != null) "$createThread" else ""} + + ${if (stmt != null) "${escapeXml(stmt)}" else ""} + ${ + if (cSource != null && cSource != "") "${ + escapeXml(cSource) + }" else "" +} + + + """.trimIndent() \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt deleted file mode 100644 index 4569a1b557..0000000000 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2024 Budapest University of Technology and Economics - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package hu.bme.mit.theta.xcfa.cli.witnesses - -import hu.bme.mit.theta.analysis.Action -import hu.bme.mit.theta.analysis.State -import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.expl.ExplState -import hu.bme.mit.theta.xcfa.model.XcfaLocation -import java.io.File -import java.io.IOException -import java.io.StringReader -import java.io.StringWriter -import java.nio.file.Files -import java.nio.file.Paths -import java.security.DigestInputStream -import java.security.MessageDigest -import java.security.NoSuchAlgorithmException -import java.text.DateFormat -import java.text.SimpleDateFormat -import java.util.* -import javax.xml.XMLConstants -import javax.xml.transform.OutputKeys -import javax.xml.transform.Source -import javax.xml.transform.Transformer -import javax.xml.transform.TransformerFactory -import javax.xml.transform.stream.StreamResult -import javax.xml.transform.stream.StreamSource - - -class Witness(private val trace: Trace, programFile: File) { - - private val attributes: MutableList = ArrayList() - private val data: MutableList> = ArrayList() - - init { - attributes.add(WitnessAttribute("sourcecodelang", "string", "graph", "sourcecodelang")) - attributes.add(WitnessAttribute("creationtime", "string", "graph", "creationtime")) - attributes.add(WitnessAttribute("witness-type", "string", "graph", "witness-type")) - attributes.add(WitnessAttribute("producer", "string", "graph", "producer")) - attributes.add(WitnessAttribute("architecture", "string", "graph", "architecture")) - attributes.add(WitnessAttribute("programHash", "string", "graph", "programhash")) - attributes.add(WitnessAttribute("programfile", "string", "graph", "programfile")) - attributes.add(WitnessAttribute("specification", "string", "graph", "specification")) - - attributes.add(WitnessAttribute("assumption", "string", "edge", "assumption")) - attributes.add(WitnessAttribute("assumption.scope", "string", "edge", "assumption.scope")) - attributes.add(WitnessAttribute("assumption.resultfunction", "string", "edge", - "assumption.resultfunction")) - attributes.add(WitnessAttribute("control", "string", "edge", "control")) - attributes.add(WitnessAttribute("startline", "string", "edge", "startline")) - attributes.add(WitnessAttribute("endline", "string", "edge", "endline")) - attributes.add(WitnessAttribute("startoffset", "string", "edge", "startoffset")) - attributes.add(WitnessAttribute("endoffset", "string", "edge", "endoffset")) - attributes.add(WitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead")) - attributes.add(WitnessAttribute("enterFunction", "string", "edge", "enterFunction")) - attributes.add( - WitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction")) - attributes.add(WitnessAttribute("threadId", "string", "edge", "threadId")) - attributes.add(WitnessAttribute("createThread", "string", "edge", "createThread")) - attributes.add(WitnessAttribute("stmt", "string", "edge", "stmt")) - attributes.add(WitnessAttribute("cSource", "string", "edge", "cSource")) - - attributes.add(WitnessAttribute("entry", "string", "node", "entry", "false")) - attributes.add(WitnessAttribute("sink", "string", "node", "sink", "false")) - attributes.add(WitnessAttribute("violation", "string", "node", "violation", "false")) - attributes.add(WitnessAttribute("locationStacks", "string", "node", "locationStacks")) - attributes.add(WitnessAttribute("sourceLines", "string", "node", "sourceLines")) - attributes.add(WitnessAttribute("state", "string", "node", "state")) - - data.add(Pair("witness-type", "violation_witness")) - data.add(Pair("producer", "theta")) - data.add(Pair("sourcecodelang", "C")) - data.add(Pair("specification", "CHECK( init(main()), LTL(G ! call(reach_error())) )")) - data.add(Pair("programfile", programFile.absolutePath)) - data.add(Pair("programhash", createTaskHash(programFile.path))) - data.add(Pair("architecture", "32bit")) - data.add(Pair("creationtime", getIsoDate())) - } - - fun toPrettyXml(): String = prettyFormat(toXml(), 4) - - fun toXml(): String = """ - - - -${attributes.map(WitnessAttribute::toXml).reduce { a, b -> "$a\n$b" }} - - - -${data.map { "${it.second}" }.reduce { a, b -> "$a\n$b" }} - -${trace.states.map(WitnessNode::toXml).reduce { a, b -> "$a\n$b" }} - -${trace.actions.map(WitnessEdge::toXml).reduce { a, b -> "$a\n$b" }} - - - - """.trimIndent() - -} - -data class WitnessAttribute( - val name: String, - val type: String, - val `for`: String, - val id: String, - val defaultValue: String? = null -) { - - fun toXml(): String = """ -" else """ -> -$defaultValue - -""".trimIndent() - } -""".trimIndent() -} - -data class WitnessNode( - val id: String, - val entry: Boolean = false, - val sink: Boolean = false, - val violation: Boolean = false, - - val xcfaLocations: Map> = emptyMap(), - val cSources: Map> = emptyMap(), - val globalState: ExplState? = null -) : State { - - override fun isBottom(): Boolean { - error("Not applicable for witness states.") - } - - fun toXml(): String = """ - - ${if (entry) "true" else ""} - ${if (sink) "true" else ""} - ${if (violation) "true" else ""} - - ${ - if (xcfaLocations.isNotEmpty()) "${ - escapeXml(xcfaLocations.toString()) - }" else "" - } - ${ - if (cSources.isNotEmpty()) "${ - escapeXml(cSources.toString()) - }" else "" - } - ${ - if (globalState != null) "${ - escapeXml(globalState.toString()) - }" else "" - } - - """.trimIndent() -} - -data class WitnessEdge( - val sourceId: String, - val targetId: String, - val assumption: String? = null, - val assumption_scope: String? = null, - val assumption_resultfunction: String? = null, - val control: Boolean? = null, - val startline: Int? = null, - val endline: Int? = null, - val startoffset: Int? = null, - val endoffset: Int? = null, - val enterLoopHead: Boolean = false, - val enterFunction: String? = null, - val returnFromFunction: String? = null, - val threadId: String? = null, - val createThread: String? = null, - - val stmt: String? = null, - val cSource: String? = null, -) : Action { - - fun toXml(): String = """ - - ${if (assumption != null) "$assumption" else ""} - ${if (assumption_scope != null) "$assumption_scope" else ""} - ${if (assumption_resultfunction != null) "$assumption_resultfunction" else ""} - ${if (control != null) "condition-$control" else ""} - ${if (startline != null && startline != -1) "$startline" else ""} - ${if (endline != null && endline != -1) "$endline" else ""} - ${if (startoffset != null && startoffset != -1) "$startoffset" else ""} - ${if (endoffset != null && endoffset != -1) "$endoffset" else ""} - ${if (enterLoopHead) "true" else ""} - ${if (enterFunction != null) "$enterFunction" else ""} - ${if (returnFromFunction != null) "$returnFromFunction" else ""} - ${if (threadId != null) "$threadId" else ""} - ${if (createThread != null) "$createThread" else ""} - - ${if (stmt != null) "${escapeXml(stmt)}" else ""} - ${ - if (cSource != null && cSource != "") "${ - escapeXml(cSource) - }" else "" - } - - - """.trimIndent() -} - -private fun escapeXml(toEscape: String): String { - var toEscape = toEscape - toEscape = toEscape.replace("&", "&") - toEscape = toEscape.replace("\"", """) - toEscape = toEscape.replace("'", "'") - toEscape = toEscape.replace("<", "<") - toEscape = toEscape.replace(">", ">") - return toEscape -} - -private fun createTaskHash(programFile: String): String { - var md: MessageDigest? = null - try { - md = MessageDigest.getInstance("SHA-256") - } catch (e: NoSuchAlgorithmException) { - e.printStackTrace() - } - try { - Files.newInputStream(Paths.get(programFile)).use { `is` -> - DigestInputStream(`is`, md).use { dis -> - while (dis.read() != -1) { - } - } - } - } catch (e: IOException) { - e.printStackTrace() - } - assert(md != null) - val digest = md!!.digest() - return bytesToHex(digest) -} - -// source: https://www.baeldung.com/sha-256-hashing-java -private fun bytesToHex(hash: ByteArray): String { - val hexString = StringBuilder(2 * hash.size) - for (i in hash.indices) { - val hex = Integer.toHexString(0xff and hash[i].toInt()) - if (hex.length == 1) { - hexString.append('0') - } - hexString.append(hex) - } - return hexString.toString() -} - -private fun getIsoDate(): String { - val tz: TimeZone = TimeZone.getTimeZone("UTC") - val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset - - df.timeZone = tz - return df.format(Date()) -} - -// from https://stackoverflow.com/a/1264912 -private fun prettyFormat(input: String, indent: Int): String { - return try { - val xmlInput: Source = StreamSource( - StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), ""))) - val stringWriter = StringWriter() - val xmlOutput = StreamResult(stringWriter) - val transformerFactory: TransformerFactory = TransformerFactory.newInstance() - transformerFactory.setAttribute("indent-number", indent) - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "") - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "") - val transformer: Transformer = transformerFactory.newTransformer() - transformer.setOutputProperty(OutputKeys.INDENT, "yes") - transformer.transform(xmlInput, xmlOutput) - xmlOutput.getWriter().toString() - } catch (e: Exception) { - System.err.println(input.replace(Regex("( )|[\\t\\n\\r]"), "")) - throw RuntimeException(e) - } -} \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt new file mode 100644 index 0000000000..b3c000f5ad --- /dev/null +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt @@ -0,0 +1,260 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hu.bme.mit.theta.xcfa.cli.witnesses + +import com.charleskorn.kaml.Yaml +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +val WitnessYamlConfig = Yaml(configuration = Yaml.default.configuration.copy(encodeDefaults = false)) + +// https://gitlab.com/sosy-lab/benchmarking/sv-witnesses/-/blob/8f5dc4bf00c01bc6d5636d7993e164d181e19204/violation-witness-schema.yml +// https://gitlab.com/sosy-lab/benchmarking/sv-witnesses/-/blob/8f5dc4bf00c01bc6d5636d7993e164d181e19204/correctness-witness-schema.yml + +/** + * For violations: + * Each entry consists of three key-value pairs, namely the key `entry_type` with value `violation_sequence`, + * the key metadata, and the key content. + * For correctness: + * The `entry_type` defines what content is available in the content field. The only allowed entry type for a correctness witness is `invariant_set`. + * @param entryType The `entry_type` defines what content is available in the content field. The only allowed entry type for a correctness witness is `violation_sequence`. + * @param metadata The meta data describe the provenance of the data. + * @param content For violations: The content represents the semantical content of the violation witness. It is a sequence of one or more segments. The content contains a sequence of zero or more normal segments and exactly one final segment at the end. + * For correctness: The content represents the semantical content of the correctness witness. It is a sequence of one or more invariant elements. + * + */ +@Serializable data class YamlWitness( + @SerialName("entry_type") + val entryType: EntryType, + val metadata: Metadata, + val content: List, +) + +@Serializable enum class EntryType { + @SerialName("violation_sequence") VIOLATION, + @SerialName("invariant_set") INVARIANTS, +} + +/** + * The meta data describe the provenance of the data. + * @param formatVersion The `version` of the format is given as a string (currently "2.0"). + * @param uuid The `uuid` is a unique identifier of the entry; it uses the UUID format defined in RFC4122. + * @param creationTime The `creation_time` describes the date and time when the entry was created; it uses the format given by ISO 8601. + * @param producer The key `producer` describes the tool that produced the entry. + * + */ +@Serializable data class Metadata( + @SerialName("format_version") + val formatVersion: String, + val uuid: String, + @SerialName("creation_time") + val creationTime: String, + val producer: Producer, + val task: Task, +) + +/** + * The key `producer` describes the tool that produced the entry. + * @param name The name of the tool that produced the witness. + * @param version The version of the tool + * @param configuration The configuration in which the tool ran (optional) + * @param commandLine The command line with which the tool ran; it should be a bash-compliant command (optional) + * @param description Any information not fitting in the previous items (optional) + */ +@Serializable data class Producer( + val name: String, + val version: String, + val configuration: String? = null, + @SerialName("command_line") + val commandLine: String? = null, + val description: String? = null, +) + +/** + * The task describes the verification task to which the entry is related. + * @param inputFiles The list of files given as input to the verifier, e.g. ["path/f1.c", "path/f2.c"]. + * @param inputFileHashes The SHA-256 hashes of all files in input_files, e.g. {"path/f1.c": 511..., "path/f2.c": f70...} + * @param specification The specification considered by the verifier; it uses the SV-COMP format given at https://sv-comp.sosy-lab.org/2023/rules.php. + * @param dataModel The data model assumed for the input program. (ILP32 / LP64) + * @param language The programming language of the input files; the format currently supports only C. + */ +@Serializable data class Task( + @SerialName("input_files") + val inputFiles: List, + @SerialName("input_file_hashes") + val inputFileHashes: List, + val specification: String, + @SerialName("data_model") + val dataModel: DataModel, + val language: Language, +) + +@Serializable enum class DataModel { + ILP32, + LP64, +} + +@Serializable enum class Language { + C +} + +/** + * @param segment A `segment` is a sequence of one or more waypoints. They are used to structure the waypoints into segments. Each `segment` is a sequence of zero or more waypoints with action `avoid` and exactly one waypoint of action `follow` at the end. A segment is called _final_ if it ends with the `target` waypoint and it is called _normal_ otherwise. items: type: object required: - waypoint properties: waypoint: type: object required: - type - action - location description: | The `waypoint` elements are the basic building block of violation witnesses. They have the form of simple restrictions on program executions. Technically, a waypoint is a mapping with four keys, namely type, location, constraint, and action. The values of the first three keys specify the requirement on a program execution to pass a waypoint: `type` describes the type of the requirement, `location` specifies the program location where the requirement is evaluated, and `constraint` gives the requirement itself and is not allowed for waypoints of type `function_enter` and `target`. The key `action` then states whether the executions represented by the witness should pass through the waypoint (value `follow`) or avoid it (value `avoid`). The format currently supports two possible values of type with the following meanings: - `assumption`: The location has to point to the beginning of a statement or a declaration inside a compound statement. A requirement of this type says that a given constraint is satisfied before the pointed statement or declaration inside a compound statement. The constraint is a mapping with two keys: `format` specifies the language of the assumption and `value` contains a side-effect-free assumption over variables in the current scope. The value of `format` is `c_expression` as C expressions are the only assumptions currently supported. In future, we plan to support also assumptions in ACSL. - `target`: This type of requirement can be used only with action `follow` and it marks the program location where the property is violated. More precisely, the location points at the first character of the statement or full expression whose evaluation is sequenced directly before the violation occurs, i.e., there is no other evaluation sequenced before the violation and the sequence point associated with the location. This also implies that it can only point to a function call if it calls a function of the C standard library + * @param invariant The key `invariant` is the basic building block of correctness witnesses. It is a mapping that describes one invariant. + */ +@Serializable data class ContentItem( + val segment: Segment? = null, + val invariant: Invariant? = null, +) + +@Serializable data class Segment( + val waypoint: Waypoint, +) + +/** + * The `waypoint` elements are the basic building block of violation witnesses. + * They have the form of simple restrictions on program executions. + * Technically, a waypoint is a mapping with four keys, namely type, location, constraint, and action. + * The values of the first three keys specify the requirement on a program execution to pass a waypoint: + * `type` describes the type of the requirement, + * `location` specifies the program location where the requirement is evaluated, and + * `constraint` gives the requirement itself and is not allowed for waypoints of type `function_enter` and `target`. + * The key `action` then states whether the executions represented by the witness should + * pass through the waypoint (value `follow`) or avoid it (value `avoid`). + * The format currently supports two possible values of type with the following meanings: + * + * - `assumption`: + * The location has to point to the beginning of a statement or a declaration inside a compound statement. + * A requirement of this type says that a given constraint is satisfied before the pointed statement + * or declaration inside a compound statement. + * The constraint is a mapping with two keys: `format` specifies the language of the assumption and + * `value` contains a side-effect-free assumption over variables in the current scope. + * The value of `format` is `c_expression` as C expressions are the only assumptions currently supported. + * In future, we plan to support also assumptions in ACSL. + * - `target`: + * This type of requirement can be used only with action `follow` and it marks the program location where the property is violated. + * More precisely, the location points at the first character of the statement or + * full expression whose evaluation is sequenced directly before the violation occurs, + * i.e., there is no other evaluation sequenced before the violation and the sequence point associated with the location. + * This also implies that it can only point to a function call if it calls a function of the C standard library + * that violates the property or if the function call itself is the property violation. + * The key constraint has to be omitted for type `target`. + * - `function_enter`: + * The location points to the right parenthesis after the function arguments at the call site and the requirement + * says that the called function is entered. The key constraint has to be omitted in this case. + * - `function_return`: + * Such a requirement says that a given function call has been evaluated and the returned + * value satisfies a given constraint. The location points to the right parenthesis after the + * function arguments at the call site. The constraint is a mapping with keys format and value. + * We currently support only ACSL expressions of the form `\result `, + * where `` is one of `==`, `!=`, `<=`, `<`, `>`, `>=` and `` is a constant expression. + * The value of format has to be `acsl_expression`. + * - `branching`: + * A requirement of this type says that a given branching is evaluated in a given way. + * The location points to a branching keyword like `if`, `while`, `switch`, or to the character `?` + * in the ternary operator (`?:`). The constraint is then a mapping with only one key value. + * For binary branchings, value can be either `true` or `false` saying whether the true branch + * is used or not. For the keyword switch, value holds an integer constant or default. The + * integer constant specifies the value of the controlling expression of the switch statement. + * The value default says that the value of this expression does not match any case of the + * switch with the potential exception of the default case. + * + * An `assumption` waypoint is evaluated at the sequence point + * immediately before the waypoint location. The waypoint is passed if + * the given constraint evaluates to true. A `branching` waypoint + * is evaluated at the sequence point immediately after evaluation of the + * controlling expression of the corresponding branching statement. The + * waypoint is passed if the resulting value of the controlling + * expression corresponds to the given constraint. A + * `function_enter` waypoint is evaluated at the sequence point + * immediately after evaluation of all arguments of the function + * call. The waypoint is passed without any additional constraint. A + * `function_return` waypoint is evaluated immediately after + * evaluation of the corresponding function call. The waypoint is passed + * if the returned value satisfies the given constraint. + * + * @param type + * @param constraint The constraint of the waypoint. A constraint is not allowed for type `target`. + * @param location The `location` is a mapping with mandatory keys file_name and line. All other keys are optional. If the location provides an inconsistent information (e.g., identifier specifies a function that is not called at the given column on the given line ), the witness is syntactically invalid. + * @param action Action `follow` means that the waypoint should be passed through. Action `avoid` means that the waypoint should be avoided. + */ + +@Serializable data class Waypoint( + val type: WaypointType, + val constraint: Constraint? = null, + val location: Location, + val action: Action, +) + +@Serializable enum class WaypointType { + @SerialName("assumption") ASSUMPTION, + @SerialName("target") TARGET, + @SerialName("function_enter") FUNCTION_ENTER, + @SerialName("function_return") FUNCTION_RETURN, + @SerialName("branching") BRANCHING, +} + +/** + * The constraint of the waypoint. A constraint is not allowed for type `target`. + * @param value + * @param format + */ +@Serializable data class Constraint( + val value: String, + val format: Format? = null, +) + +@Serializable enum class Format { + @SerialName("c_expression") C_EXPRESSION, + @SerialName("acsl_expression") ACSL_EXPRESSION, +} + +/** + * The `location` is a mapping with mandatory keys file_name and line. All other keys are optional. If the location provides an inconsistent information (e.g., identifier specifies a function that is not called at the given column on the given line ), the witness is syntactically invalid. + * @param fileName The name of the file of the location + * @param line The line number pf the program location in the file. + * @param column The key `column` specifies the column number of the location, i.e., the position of the `column`-th character in the line that the location points to (value 1 is the position of the first character). If the column is not given, then it is interpreted as the leftmost suitable position on the line, where suitability is given by `type`. + * @param function The key `function` gives the name of the function containing the location. It is usually determined by the `file_name` and `line`, but the information can improve human readability of the witness. + */ +@Serializable data class Location( + @SerialName("file_name") + val fileName: String, + val line: Int, + val column: Int? = null, + val function: String? = null, +) + +/** + * Action `follow` means that the waypoint should be passed through. + * Action `avoid` means that the waypoint should be avoided. + */ +@Serializable enum class Action { + @SerialName("follow") FOLLOW, + @SerialName("avoid") AVOID, +} + +@Serializable data class Invariant( + val type: InvariantType, + val location: Location, + val value: String, + val format: Format, +) + +@Serializable enum class InvariantType { + @SerialName("loop_invariant") LOOP_INVARIANT, + @SerialName("location_invariant") LOCATION_INVARIANT, +} \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt new file mode 100644 index 0000000000..f157011728 --- /dev/null +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hu.bme.mit.theta.xcfa.cli + +import com.charleskorn.kaml.Yaml +import hu.bme.mit.theta.xcfa.cli.witnesses.* +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import java.util.* + +class YamlParseTest { + @Test + fun serialize() { + val witness = YamlWitness( + entryType = EntryType.VIOLATION, + metadata = Metadata( + formatVersion = "2.0", + uuid = UUID.randomUUID().toString(), + creationTime = getIsoDate(), + producer = Producer( + name = "test", + version = "1.0.0", + ), + task = Task( + inputFiles = listOf("example.c"), + inputFileHashes = listOf("hash"), + specification = "unreach_call", + dataModel = DataModel.LP64, + language = Language.C, + ) + ), + content = listOf( + ContentItem( + Segment(Waypoint( + type = WaypointType.ASSUMPTION, + constraint = Constraint( + value = "1 < x", + format = Format.C_EXPRESSION, + ), + location = Location( + fileName = "example.c", + line = 15, + ), + action = Action.FOLLOW, + )) + ), + ), + ) + + val result = WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness) + + System.err.println(result) + + val parsedPack = Yaml.default.decodeFromString(YamlWitness.serializer(), result) + + Assertions.assertEquals(witness, parsedPack) + } +} \ No newline at end of file From 3ab5dee0da50a7fc3a9b463c9fa1ad0e9b28c4b6 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:13:30 +0100 Subject: [PATCH 10/18] Adapted XcfaLocation serialization, as well as XcfaEdge and XcfaLoation metadata --- .gitignore | 1 + .../frontend/chc/ChcBackwardXcfaBuilder.java | 14 +- .../frontend/chc/ChcForwardXcfaBuilder.java | 20 +- .../java/hu/bme/mit/theta/c2xcfa/CMetaData.kt | 41 +- .../mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 1 - .../litmus2xcfa/dsl/LitmusAArch64.java | 18 +- .../bme/mit/theta/llvm2xcfa/LlvmMetadata.java | 7 + .../hu/bme/mit/theta/llvm2xcfa/Utils.java | 2 +- .../concrete/ArrayIntrinsicsHandler.java | 2 +- .../concrete/MemoryInstructionHandler.java | 2 +- .../concrete/OtherInstructionHandler.java | 17 +- .../handlers/states/FunctionState.java | 2 +- .../mit/theta/xcfa/analysis/XcfaAnalysis.kt | 2 + .../xcfa/analysis/XcfaExplAnalysisTest.kt | 8 +- .../xcfa/analysis/XcfaPredAnalysisTest.kt | 8 +- .../theta/xcfa/analysis/XcfaStateLtsTest.kt | 10 +- .../bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 6 +- .../bme/mit/theta/xcfa/cli/utils/GsonUtils.kt | 5 +- .../mit/theta/xcfa/cli/XcfaCliParseTest.kt | 1 + .../mit/theta/xcfa/cli/XcfaCliProofTest.kt | 16 +- .../test/resources/json/00assignment.c.json | 200 +- .../src/test/resources/json/01cast.c.json | 230 +- .../src/test/resources/json/02types.c.json | 330 +- .../src/test/resources/json/03bitwise.c.json | 236 +- .../src/test/resources/json/04real.c.json | 230 +- .../src/test/resources/json/05math.c.json | 350 +- .../src/test/resources/json/06arrays.c.json | 270 +- .../test/resources/json/07arrayinit.c.json | 288 +- .../src/test/resources/json/08vararray.c.json | 288 +- .../src/test/resources/json/13typedef.c.json | 240 +- .../src/test/resources/json/14ushort.c.json | 248 +- .../src/test/resources/json/15addition.c.json | 200 +- .../src/test/resources/json/16loop.c.json | 317 +- .../test/resources/json/17recursive.c.json | 720 +++- .../test/resources/json/18multithread.c.json | 1127 +++-- .../src/test/resources/json/19dportest.c.json | 2622 ++++-------- .../test/resources/json/20testinline.c.json | 405 +- .../resources/json/21namecollision.c.json | 684 ++- .../src/test/resources/json/22nondet.c.json | 397 +- .../src/test/resources/json/23overflow.c.json | 166 +- .../src/test/resources/json/dekker.i.json | 3674 ++++++++++++----- .../hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt | 7 +- .../theta/xcfa/gson/XcfaLocationAdapter.kt | 56 +- .../java/hu/bme/mit/theta/xcfa/model/Dsl.kt | 6 +- .../hu/bme/mit/theta/xcfa/model/MetaData.kt | 10 +- .../theta/xcfa/passes/EliminateSelfLoops.kt | 8 +- .../theta/xcfa/passes/FinalLocationPass.kt | 5 +- .../xcfa/passes/FpFunctionsToExprsPass.kt | 2 +- .../theta/xcfa/passes/InlineProceduresPass.kt | 12 +- .../hu/bme/mit/theta/xcfa/passes/LbePass.kt | 11 +- .../mit/theta/xcfa/passes/LoopUnrollPass.kt | 2 +- .../theta/xcfa/passes/MallocFunctionPass.kt | 2 +- .../mit/theta/xcfa/passes/NoSideEffectPass.kt | 2 +- .../theta/xcfa/passes/NondetFunctionPass.kt | 2 +- .../hu/bme/mit/theta/xcfa/passes/Utils.kt | 11 +- .../hu/bme/mit/theta/xcfa/gson/GsonTest.kt | 3 +- .../mit/theta/xsts/analysis/XstsHornTest.java | 6 +- 57 files changed, 8559 insertions(+), 4991 deletions(-) diff --git a/.gitignore b/.gitignore index e68c7c1070..1bb6d2edce 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ xcfa.dot xcfa.json *.plantuml xcfa-*.smt2 +witness.yml diff --git a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java index 159cf1eb89..f1d0ef9bca 100644 --- a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java +++ b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java @@ -103,7 +103,7 @@ public Object visitChc_assert(CHCParser.Chc_assertContext ctx) { vars.put(ctx.chc_head().u_pred_atom().symbol(i++).getText(), param.getFirst()); } XcfaLocation middle = createLocation(procedure); - XcfaEdge edge = new XcfaEdge(procedure.getInitLoc(), middle, new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars))); + XcfaEdge edge = new XcfaEdge(procedure.getInitLoc(), middle, new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars)), EmptyMetaData.INSTANCE); procedure.addEdge(edge); createCalls(procedure, middle, procedure.getFinalLoc().get(), ctx.chc_tail().u_pred_atom(), vars); } else { @@ -115,7 +115,7 @@ public Object visitChc_assert(CHCParser.Chc_assertContext ctx) { } procedure = procedures.get(procName); Stmt returnTrue = AssignStmt.create(getOutParam(procedure), BoolLitExpr.of(true)); - XcfaEdge edge = new XcfaEdge(procedure.getInitLoc(), procedure.getFinalLoc().get(), new StmtLabel(returnTrue)); + XcfaEdge edge = new XcfaEdge(procedure.getInitLoc(), procedure.getFinalLoc().get(), new StmtLabel(returnTrue), EmptyMetaData.INSTANCE); procedure.addEdge(edge); } return super.visitChc_assert(ctx); @@ -128,7 +128,7 @@ public Object visitChc_query(CHCParser.Chc_queryContext ctx) { Map> vars = createVars(mainProcedure, ctx.var_decl()); XcfaLocation middle = createLocation(mainProcedure); - XcfaEdge edge = new XcfaEdge(mainProcedure.getInitLoc(), middle, new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars))); + XcfaEdge edge = new XcfaEdge(mainProcedure.getInitLoc(), middle, new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars)), EmptyMetaData.INSTANCE); mainProcedure.addEdge(edge); createCalls(mainProcedure, middle, mainProcedure.getErrorLoc().get(), ctx.chc_tail().u_pred_atom(), vars); return super.visitChc_query(ctx); @@ -137,7 +137,7 @@ public Object visitChc_query(CHCParser.Chc_queryContext ctx) { private int uniqeCounter = 0; private XcfaLocation createLocation(XcfaProcedureBuilder builder) { - XcfaLocation location = new XcfaLocation("l_" + uniqeCounter++); + XcfaLocation location = new XcfaLocation("l_" + uniqeCounter++, EmptyMetaData.INSTANCE); builder.addLoc(location); return location; } @@ -175,16 +175,16 @@ private void createCalls(XcfaProcedureBuilder builder, XcfaLocation start, XcfaL paramNames.add(0, ret.getName()); List> params = paramNames.stream().map(s -> localVars.get(s).getRef()).toList(); - XcfaEdge callEdge = new XcfaEdge(from, middle, new InvokeLabel(calledProcedure.getName(), params, EmptyMetaData.INSTANCE)); + XcfaEdge callEdge = new XcfaEdge(from, middle, new InvokeLabel(calledProcedure.getName(), params, EmptyMetaData.INSTANCE), EmptyMetaData.INSTANCE); builder.addEdge(callEdge); - XcfaEdge assertEdge = new XcfaEdge(middle, to, new StmtLabel(AssumeStmt.of(ret.getRef()))); + XcfaEdge assertEdge = new XcfaEdge(middle, to, new StmtLabel(AssumeStmt.of(ret.getRef())), EmptyMetaData.INSTANCE); builder.addEdge(assertEdge); from = to; } Stmt returnTrue = AssignStmt.create(getOutParam(builder), BoolLitExpr.of(true)); - XcfaEdge edge = new XcfaEdge(from, end, new StmtLabel(returnTrue)); + XcfaEdge edge = new XcfaEdge(from, end, new StmtLabel(returnTrue), EmptyMetaData.INSTANCE); builder.addEdge(edge); } } diff --git a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java index 732d58d975..04f591c913 100644 --- a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java +++ b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java @@ -22,14 +22,7 @@ import hu.bme.mit.theta.core.stmt.AssignStmt; import hu.bme.mit.theta.core.stmt.HavocStmt; import hu.bme.mit.theta.core.type.Type; -import hu.bme.mit.theta.xcfa.model.EmptyMetaData; -import hu.bme.mit.theta.xcfa.model.SequenceLabel; -import hu.bme.mit.theta.xcfa.model.StmtLabel; -import hu.bme.mit.theta.xcfa.model.XcfaBuilder; -import hu.bme.mit.theta.xcfa.model.XcfaEdge; -import hu.bme.mit.theta.xcfa.model.XcfaLabel; -import hu.bme.mit.theta.xcfa.model.XcfaLocation; -import hu.bme.mit.theta.xcfa.model.XcfaProcedureBuilder; +import hu.bme.mit.theta.xcfa.model.*; import hu.bme.mit.theta.xcfa.passes.ProcedurePassManager; import java.util.ArrayList; @@ -37,10 +30,7 @@ import java.util.List; import java.util.Map; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.createVars; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.getTailConditionLabels; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.transformConst; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.transformSort; +import static hu.bme.mit.theta.frontend.chc.ChcUtils.*; public class ChcForwardXcfaBuilder extends CHCBaseVisitor implements ChcXcfaBuilder { private final ProcedurePassManager procedurePassManager; @@ -88,7 +78,7 @@ public Object visitFun_decl(CHCParser.Fun_declContext ctx) { builder.addVar(var); transformConst(Decls.Const(varName, type), true); } - XcfaLocation location = new XcfaLocation(name); + XcfaLocation location = new XcfaLocation(name, EmptyMetaData.INSTANCE); locations.put(name, new UPred(location, vars)); locations.put(ctx.symbol().getText(), new UPred(location, vars)); builder.addLoc(location); @@ -118,7 +108,7 @@ public Object visitChc_assert(CHCParser.Chc_assertContext ctx) { from = initLocation; to = locations.get(locName).location; } - XcfaEdge edge = new XcfaEdge(from, to, new SequenceLabel(labels)); + XcfaEdge edge = new XcfaEdge(from, to, new SequenceLabel(labels), EmptyMetaData.INSTANCE); builder.addEdge(edge); return super.visitChc_assert(ctx); } @@ -130,7 +120,7 @@ public Object visitChc_query(CHCParser.Chc_queryContext ctx) { List labels = new ArrayList<>(); labels.addAll(getIncomingAssignments(ctx.chc_tail(), vars)); labels.addAll(getTailConditionLabels(ctx.chc_tail(), vars)); - XcfaEdge edge = new XcfaEdge(from, errorLocation, new SequenceLabel(labels)); + XcfaEdge edge = new XcfaEdge(from, errorLocation, new SequenceLabel(labels), EmptyMetaData.INSTANCE); builder.addEdge(edge); return super.visitChc_query(ctx); } diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt index fe8d5ee0bd..d62b191661 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt @@ -15,11 +15,10 @@ */ package hu.bme.mit.theta.c2xcfa -import hu.bme.mit.theta.xcfa.model.MetaData -import hu.bme.mit.theta.xcfa.model.XcfaEdge -import hu.bme.mit.theta.xcfa.model.XcfaLabel -import hu.bme.mit.theta.xcfa.model.XcfaLocation +import hu.bme.mit.theta.xcfa.model.* import org.antlr.v4.runtime.ParserRuleContext +import kotlin.math.max +import kotlin.math.min data class CMetaData( val lineNumberStart: Int?, @@ -29,8 +28,38 @@ data class CMetaData( val offsetStart: Int?, val offsetEnd: Int?, val sourceText: String?, - val ctx: ParserRuleContext?, -) : MetaData() +) : MetaData() { + + override fun combine(other: MetaData): MetaData { + if (other is CMetaData) { + return CMetaData( + lineNumberStart = min( + lineNumberStart ?: other.lineNumberStart ?: -1, other.lineNumberStart ?: lineNumberStart ?: -1 + ).takeIf { it > 0 } ?: 0, + colNumberStart = min( + colNumberStart ?: other.colNumberStart ?: -1, other.colNumberStart ?: colNumberStart ?: -1 + ).takeIf { it > 0 } ?: 0, + offsetStart = min( + offsetStart ?: other.offsetStart ?: -1, other.offsetStart ?: offsetStart ?: -1 + ).takeIf { it > 0 } ?: 0, + lineNumberStop = max( + lineNumberStop ?: other.lineNumberStop ?: -1, other.lineNumberStop ?: lineNumberStop ?: -1 + ).takeIf { it > 0 } ?: 0, + colNumberStop = max( + colNumberStop ?: other.colNumberStop ?: -1, other.colNumberStop ?: colNumberStop ?: -1 + ).takeIf { it > 0 } ?: 0, + offsetEnd = max( + offsetEnd ?: other.offsetEnd ?: -1, other.offsetEnd ?: offsetEnd ?: -1 + ).takeIf { it > 0 } ?: 0, + sourceText = (sourceText ?: "") + (other.sourceText ?: ""), + ) + } else if (other is EmptyMetaData) { + return this + } else { + error("Cannot combine metadata of different types: $this vs $other") + } + } +} fun XcfaLabel.getCMetaData(): CMetaData? { return if (this.metadata is CMetaData) { diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index 33355e8144..ebc4fd3da7 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -83,7 +83,6 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo offsetStart = source.offsetStart.takeIf { it != -1 }, offsetEnd = source.offsetEnd.takeIf { it != -1 }, sourceText = source.sourceText, - ctx = source.ctx, ) fun buildXcfa(cProgram: CProgram): XcfaBuilder { diff --git a/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java b/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java index a6e01016db..c6a06d5bb8 100644 --- a/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java +++ b/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java @@ -105,7 +105,7 @@ public XCFA visitMain(LitmusAArch64Parser.MainContext ctx) { for (Integer threadId : threadIds) { XcfaProcedureBuilder procBuilder = builders.get(threadId); procBuilder.createFinalLoc(); - procBuilder.addEdge(new XcfaEdge(lastLocation.get(threadId), procBuilder.getFinalLoc().get())); + procBuilder.addEdge(new XcfaEdge(lastLocation.get(threadId), procBuilder.getFinalLoc().get(), NopLabel.INSTANCE, EmptyMetaData.INSTANCE)); } return builder.build(); } @@ -142,7 +142,7 @@ private XcfaLocation newAnonymousLoc() { private XcfaLocation getOrCreateLoc(final String name) { if (!locations.get(currentProc).containsKey(name)) { - final XcfaLocation xcfaLocation = new XcfaLocation(name); + final XcfaLocation xcfaLocation = new XcfaLocation(name, EmptyMetaData.INSTANCE); builders.get(currentProc).addLoc(xcfaLocation); locations.get(currentProc).put(name, xcfaLocation); } @@ -278,11 +278,11 @@ public XcfaLocation visitBranchRegister32(LitmusAArch64Parser.BranchRegister32Co builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), branchTo, - stmt1)); + stmt1, EmptyMetaData.INSTANCE)); builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), newLoc, - stmt2)); + stmt2, EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -303,11 +303,11 @@ public XcfaLocation visitBranchRegister64(LitmusAArch64Parser.BranchRegister64Co builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), branchTo, - stmt1)); + stmt1, EmptyMetaData.INSTANCE)); builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), newLoc, - stmt2)); + stmt2, EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -318,7 +318,7 @@ public XcfaLocation visitBranch(LitmusAArch64Parser.BranchContext ctx) { final XcfaLocation newLoc = newAnonymousLoc(); builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), - branchTo)); + branchTo, NopLabel.INSTANCE, EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -328,7 +328,7 @@ public XcfaLocation visitBranchLabel(LitmusAArch64Parser.BranchLabelContext ctx) final XcfaLocation newLoc = getOrCreateLoc(ctx.label().getText()); builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), - newLoc)); + newLoc, NopLabel.INSTANCE, EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -341,7 +341,7 @@ public XcfaLocation visitSimpleInstruction(LitmusAArch64Parser.SimpleInstruction builders.get(currentProc).addEdge(new XcfaEdge( lastLocation.get(currentProc), newLoc, - label)); + label, EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java index c2d9d6af28..422517ddfd 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java @@ -17,6 +17,7 @@ package hu.bme.mit.theta.llvm2xcfa; import hu.bme.mit.theta.xcfa.model.MetaData; +import org.jetbrains.annotations.NotNull; public class LlvmMetadata extends MetaData { private final int lineNumber; @@ -24,4 +25,10 @@ public class LlvmMetadata extends MetaData { public LlvmMetadata(int lineNumber) { this.lineNumber = lineNumber; } + + @NotNull + @Override + public MetaData combine(@NotNull MetaData other) { + return this; + } } diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java index 010d621de5..f07bf60d2a 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java @@ -182,7 +182,7 @@ public static void foldExpression(Instruction instruction, FunctionState functio //noinspection OptionalGetWithoutIsPresent RegArgument ret = instruction.getRetVar().get(); if (ret instanceof LocalArgument) { - XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt()); + XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); VarDecl lhs = Utils.getOrCreateVar(functionState, ret); Stmt stmt = Assign(cast(lhs, lhs.getType()), cast(op, lhs.getType())); XcfaEdge edge; diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java index 8f6bac344e..45b7de6eae 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java @@ -77,7 +77,7 @@ private void setArrayElement(Instruction instruction, GlobalState globalState, F checkState(arr.getType() instanceof ArrayType, "getArrayElement used on non-array type."); checkState(idx.getType() == IntType.getInstance(), "getArrayElement used with non-int index."); - XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt()); + XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); VarDecl var = functionState.getLocalVars().get(arr.getName()).get1(); Expr expr = ArrayExprs.Write(cast(var.getRef(), ArrayType.of(Int(), val.getType())), cast(idx.getExpr(functionState.getValues()), Int()), cast(val.getExpr(functionState.getValues()), val.getType())); diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java index 45705421f7..82c0a2414d 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java @@ -109,7 +109,7 @@ private void store(Instruction instruction, GlobalState globalState, FunctionSta functionState.getValues().put(op1.getName(), var.getRef()); functionState.getValues().put(op2.getName(), var.getRef()); } else { - XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt()); + XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); VarDecl var = functionState.getLocalVars().get(op2.getName()).get1(); Stmt stmt = Assign(cast(var, var.getType()), cast(op1.getExpr(functionState.getValues()), var.getType())); XcfaEdge edge = new XcfaEdge(blockState.getLastLocation(), loc, new StmtLabel(stmt), new LlvmMetadata(instruction.getLineNumber())); diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java index 422a3639d4..80690a6595 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java @@ -36,11 +36,7 @@ import hu.bme.mit.theta.llvm2xcfa.handlers.states.FunctionState; import hu.bme.mit.theta.llvm2xcfa.handlers.states.GlobalState; import hu.bme.mit.theta.llvm2xcfa.handlers.utils.PlaceholderAssignmentStmt; -import hu.bme.mit.theta.xcfa.model.EmptyMetaData; -import hu.bme.mit.theta.xcfa.model.SequenceLabel; -import hu.bme.mit.theta.xcfa.model.StmtLabel; -import hu.bme.mit.theta.xcfa.model.XcfaEdge; -import hu.bme.mit.theta.xcfa.model.XcfaLocation; +import hu.bme.mit.theta.xcfa.model.*; import java.util.ArrayList; import java.util.List; @@ -50,12 +46,7 @@ import static hu.bme.mit.theta.core.stmt.Stmts.Assign; import static hu.bme.mit.theta.core.stmt.Stmts.Havoc; import static hu.bme.mit.theta.core.type.anytype.Exprs.Ite; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Eq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Geq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Gt; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Leq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Lt; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Neq; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.*; import static hu.bme.mit.theta.core.utils.TypeUtils.cast; import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; import static hu.bme.mit.theta.llvm2xcfa.Utils.getOrCreateVar; @@ -94,7 +85,7 @@ public void handleInstruction(Instruction instruction, GlobalState globalState, private void call(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { Argument functionName = instruction.getArguments().get(instruction.getArguments().size() - 1); - XcfaLocation newLoc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt()); + XcfaLocation newLoc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); if (globalState.getProcedures().stream().anyMatch(objects -> objects.get1().equals(functionName.getName()))) { System.err.println("More than one function."); System.exit(-80); @@ -144,7 +135,7 @@ private void phi(Instruction instruction, GlobalState globalState, FunctionState Argument block = instruction.getArguments().get(2 * i + 1); Argument value = instruction.getArguments().get(2 * i); Tuple2 key = Tuple2.of(block.getName(), blockState.getName()); - Tuple4, Integer> val = functionState.getInterBlockEdges().getOrDefault(key, Tuple4.of(new XcfaLocation(key.get1()), new XcfaLocation(key.get2()), new ArrayList<>(), instruction.getLineNumber())); + Tuple4, Integer> val = functionState.getInterBlockEdges().getOrDefault(key, Tuple4.of(new XcfaLocation(key.get1(), EmptyMetaData.INSTANCE), new XcfaLocation(key.get2(), EmptyMetaData.INSTANCE), new ArrayList<>(), instruction.getLineNumber())); checkState(phiVar.getType().equals(value.getType()), "phiVar and value has to be of the same type!"); Stmt stmt; Expr expr; diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java index 7a866cd44c..7c4a26f388 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java @@ -99,7 +99,7 @@ public FunctionState(GlobalState globalState, Tuple3, L loc = procedureBuilder.getInitLoc(); first = false; } else { - loc = new XcfaLocation(block); + loc = new XcfaLocation(block, EmptyMetaData.INSTANCE); procedureBuilder.addLoc(loc); } locations.put(block, loc); diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt index f923d0e6f0..2fc5cbf6ba 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt @@ -93,6 +93,7 @@ fun getCoreXcfaLts() = ReturnLabel(proc.value.returnStmts.peek()), ) ), + proc.value.locs.peek().metadata, ), nextCnt = s.sGlobal.nextCnt, ) @@ -105,6 +106,7 @@ fun getCoreXcfaLts() = proc.value.locs.peek(), proc.value.locs.peek(), proc.value.paramStmts.peek().first, + proc.value.locs.peek().metadata, ), nextCnt = s.sGlobal.nextCnt, ) diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt index a04508f9cf..a35a2ed980 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt @@ -38,11 +38,11 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory import hu.bme.mit.theta.xcfa.analysis.coi.ConeOfInfluence import hu.bme.mit.theta.xcfa.analysis.coi.XcfaCoiMultiThread import hu.bme.mit.theta.xcfa.analysis.por.* -import java.util.* -import kotlin.random.Random import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource +import java.util.* +import kotlin.random.Random class XcfaExplAnalysisTest { @@ -62,8 +62,6 @@ class XcfaExplAnalysisTest { } } - @ParameterizedTest - @MethodSource("data") fun testNoporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { println("Testing NOPOR on $filepath...") val stream = javaClass.getResourceAsStream(filepath) @@ -291,8 +289,6 @@ class XcfaExplAnalysisTest { Assertions.assertTrue(verdict(safetyResult)) } - @ParameterizedTest - @MethodSource("data") fun testAadporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { XcfaDporLts.random = Random(seed) println("Testing AADPOR on $filepath...") diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt index a10e82f096..c6932048db 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt @@ -38,11 +38,11 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory import hu.bme.mit.theta.xcfa.analysis.coi.ConeOfInfluence import hu.bme.mit.theta.xcfa.analysis.coi.XcfaCoiMultiThread import hu.bme.mit.theta.xcfa.analysis.por.* -import java.util.* -import kotlin.random.Random import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource +import java.util.* +import kotlin.random.Random class XcfaPredAnalysisTest { @@ -62,8 +62,6 @@ class XcfaPredAnalysisTest { } } - @ParameterizedTest - @MethodSource("data") fun testNoporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { println("Testing NOPOR on $filepath...") val stream = javaClass.getResourceAsStream(filepath) @@ -295,8 +293,6 @@ class XcfaPredAnalysisTest { Assertions.assertTrue(verdict(safetyResult)) } - @ParameterizedTest - @MethodSource("data") fun testAadporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { XcfaDporLts.random = Random(seed) println("Testing AADPOR on $filepath...") diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt index b1a815104b..67ffcf637f 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt @@ -95,7 +95,11 @@ class XcfaStateLtsTest { aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 } - actionOrder.add { XcfaAction(0, XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel))) } + actionOrder.add { + XcfaAction( + 0, XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel), EmptyMetaData) + ) + } expectations.add { it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[1].target && lts.getEnabledActionsFor(it).size == 1 && @@ -124,7 +128,9 @@ class XcfaStateLtsTest { } actionOrder.add { s -> - XcfaAction(s.foreignKey()!!, XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel))) + XcfaAction( + s.foreignKey()!!, XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel), EmptyMetaData) + ) } expectations.add { it.processes.size == 1 && it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[2].target && diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index f8987c875e..5fe04637e1 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -350,11 +350,11 @@ private fun postVerificationLogging( // TODO eliminate the need for the instanceof check if ( - !config.outputConfig.argConfig.disable && safetyResult.proof is ARG? + !config.outputConfig.argConfig.disable && safetyResult.proof is ARG ) { val argFile = File(resultFolder, "arg-${safetyResult.isSafe}.dot") val g: Graph = - ArgVisualizer.getDefault().visualize(safetyResult.proof as ARG?) + ArgVisualizer.getDefault().visualize(safetyResult.proof as ARG) argFile.writeText(GraphvizWriter.getInstance().writeString(g)) } @@ -366,7 +366,7 @@ private fun postVerificationLogging( ) { val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( - safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, + safetyResult.asUnsafe().cex as Trace>, XcfaAction>, getSolver( config.outputConfig.witnessConfig.concretizerSolver, config.outputConfig.witnessConfig.validateConcretizerSolver, diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt index ad9011bd82..a7e0b45aa3 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt @@ -20,8 +20,8 @@ import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.arg.ARG import hu.bme.mit.theta.analysis.algorithm.SafetyResult +import hu.bme.mit.theta.analysis.algorithm.arg.ARG import hu.bme.mit.theta.analysis.expl.ExplState import hu.bme.mit.theta.analysis.pred.PredState import hu.bme.mit.theta.common.dsl.Env @@ -95,8 +95,7 @@ private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> gsonBuilder.registerTypeHierarchyAdapter(FrontendConfig::class.java, SpecFrontendConfigTypeAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(BackendConfig::class.java, SpecBackendConfigTypeAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(File::class.java, StringTypeAdapter { File(it) }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, - StringTypeAdapter(xcfaLocationAdapter)) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, XcfaLocationAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, VarDeclAdapter({ gson }, scope, env, !newScope)) diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt index a6aa6b8bb5..8e0c2b4d39 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt @@ -21,6 +21,7 @@ import hu.bme.mit.theta.xcfa.cli.XcfaCli.Companion.main import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.MethodSource +import java.io.File import java.util.stream.Stream import kotlin.io.path.createTempDirectory diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt index 3d29c73fb0..5ae3925c3e 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt @@ -16,14 +16,14 @@ package hu.bme.mit.theta.xcfa.cli import hu.bme.mit.theta.xcfa.cli.XcfaCli.Companion.main -import java.util.stream.Stream -import kotlin.io.path.absolutePathString -import kotlin.io.path.createTempDirectory -import kotlin.io.path.exists import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.MethodSource +import java.util.stream.Stream +import kotlin.io.path.absolutePathString +import kotlin.io.path.createTempDirectory +import kotlin.io.path.exists data class WitnessEdge( val startlineRange: Pair?, @@ -46,8 +46,8 @@ class XcfaCliProofTest { WitnessEdge( startlineRange = Pair(5, 5), endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), + startoffsetRange = Pair(80, 82), + endoffsetRange = Pair(112, 114), assumption = Regex("i *== *-1"), ) ), @@ -59,8 +59,8 @@ class XcfaCliProofTest { WitnessEdge( startlineRange = Pair(5, 5), endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), + startoffsetRange = Pair(80, 82), + endoffsetRange = Pair(112, 114), assumption = Regex("i *== *-1"), ) ), diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/00assignment.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/00assignment.c.json index 4aec536b16..2baba2f1bb 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/00assignment.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/00assignment.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_661 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_661", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_661", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,21 +108,71 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::a", "type": "Int" + }, + { + "name": "call_reach_error_ret48", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_675 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 5, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 74, + "sourceText": "int main() {\n int a \u003d 1;\n if(a) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 5, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 74, + "sourceText": "int main() {\n int a \u003d 1;\n if(a) reach_error();\n}" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { "source": "main_init", - "target": "__loc_675", + "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -109,64 +197,18 @@ "content": "(assign main::a 1)" } ] - } - }, - { - "source": "__loc_675", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 7, - "offsetStart": 56, - "offsetEnd": 56, - "sourceText": "a" - } - }, - "content": "(assume (\u003d main::a 0))" - } - ] - } - }, - { - "source": "__loc_675", - "target": "main_error", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 7, - "offsetStart": 56, - "offsetEnd": 56, - "sourceText": "a" - } - }, - "content": "(assume (/\u003d main::a 0))" - } - ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 5, + "colNumberStop": 23, + "offsetStart": 21, + "offsetEnd": 74, + "sourceText": "int main() {\n int a \u003d 1;\n if(a) reach_error();\n}int a \u003d 1;\n if(a) reach_error();int a \u003d 1;int a \u003d 1;int a \u003d 1;int a \u003d 1;if(a) reach_error();if(a) reach_error();if(a) reach_error();if(a) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/01cast.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/01cast.c.json index 7820fde027..42a8d6308f 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/01cast.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/01cast.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_683 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_683", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_683", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,20 +108,86 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::a", "type": "Int" + }, + { + "name": "call___VERIFIER_nondet_ret49", + "type": "Int" + }, + { + "name": "call_reach_error_ret50", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_699 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 6, + "colNumberStop": 0, + "offsetStart": 46, + "offsetEnd": 123, + "sourceText": "int main() {\n int a \u003d __VERIFIER_nondet();\n if((char)a) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 6, + "colNumberStop": 0, + "offsetStart": 46, + "offsetEnd": 123, + "sourceText": "int main() {\n int a \u003d __VERIFIER_nondet();\n if((char)a) reach_error();\n}" + } + } + }, + { + "name": "__loc_679", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_699", + "source": "__loc_679", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -98,21 +202,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 5, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 5, - "colNumberStop": 13, - "offsetStart": 99, - "offsetEnd": 105, - "sourceText": "(char)a" + "colNumberStop": 29, + "offsetStart": 96, + "offsetEnd": 121, + "sourceText": "if((char)a) reach_error();" } }, - "content": "(assume (\u003d main::a 0))" + "content": "((assume (\u003d main::a 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 6, + "colNumberStop": 29, + "offsetStart": 46, + "offsetEnd": 123, + "sourceText": "if((char)a) reach_error();if((char)a) reach_error();int main() {\n int a \u003d __VERIFIER_nondet();\n if((char)a) reach_error();\n}" + } } }, { - "source": "__loc_699", + "source": "__loc_679", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -127,22 +243,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 5, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 5, - "colNumberStop": 13, - "offsetStart": 99, - "offsetEnd": 105, - "sourceText": "(char)a" + "colNumberStop": 29, + "offsetStart": 96, + "offsetEnd": 121, + "sourceText": "if((char)a) reach_error();" } }, - "content": "(assume (/\u003d main::a 0))" + "content": "((assume (/\u003d main::a 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 5, + "colNumberStop": 29, + "offsetStart": 96, + "offsetEnd": 121, + "sourceText": "if((char)a) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { "source": "main_init", - "target": "__loc_699", + "target": "__loc_679", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -156,12 +284,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 12, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 30, - "offsetStart": 71, - "offsetEnd": 89, - "sourceText": "__VERIFIER_nondet()" + "colNumberStop": 31, + "offsetStart": 63, + "offsetEnd": 90, + "sourceText": "int a \u003d __VERIFIER_nondet();" } }, "content": "(havoc main::a)" @@ -172,17 +300,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 12, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 30, - "offsetStart": 71, - "offsetEnd": 89, - "sourceText": "__VERIFIER_nondet()" + "colNumberStop": 31, + "offsetStart": 63, + "offsetEnd": 90, + "sourceText": "int a \u003d __VERIFIER_nondet();" } }, "content": "(assume (and (\u003e\u003d main::a -2147483648) (\u003c\u003d main::a 2147483647)))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 6, + "colNumberStop": 31, + "offsetStart": 46, + "offsetEnd": 123, + "sourceText": "int main() {\n int a \u003d __VERIFIER_nondet();\n if((char)a) reach_error();\n}int a \u003d __VERIFIER_nondet();\n if((char)a) reach_error();int a \u003d __VERIFIER_nondet();int a \u003d __VERIFIER_nondet();int a \u003d __VERIFIER_nondet();int a \u003d __VERIFIER_nondet();int a \u003d __VERIFIER_nondet();int a \u003d __VERIFIER_nondet();if((char)a) reach_error();if((char)a) reach_error();if((char)a) reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/02types.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/02types.c.json index 42d4d36d14..b571d3ff31 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/02types.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/02types.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_707 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_707", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_707", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,6 +108,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::a", "type": "Int" @@ -113,18 +155,76 @@ { "name": "main::ll", "type": "Int" + }, + { + "name": "call_reach_error_ret51", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_748 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 15, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 288, + "sourceText": "int main() {\n _Bool a;\n unsigned char uc;\n signed char c;\n unsigned short us;\n short s;\n unsigned int ui;\n int i;\n unsigned long ul;\n long l;\n unsigned long long ull;\n long long ll;\n if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 15, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 288, + "sourceText": "int main() {\n _Bool a;\n unsigned char uc;\n signed char c;\n unsigned short us;\n short s;\n unsigned int ui;\n int i;\n unsigned long ul;\n long l;\n unsigned long long ull;\n long long ll;\n if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();\n}" + } + } + }, + { + "name": "__loc_730", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "main_init", - "target": "__loc_748", + "source": "__loc_730", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -137,211 +237,169 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 14, + "colNumberStart": 4, + "lineNumberStop": 14, + "colNumberStop": 50, + "offsetStart": 240, + "offsetEnd": 286, + "sourceText": "if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();" } }, - "content": "(assume (and (\u003e\u003d main::a 0) (\u003c\u003d main::a 1)))" - }, + "content": "((assume (\u003d (mod (+ (mod main::a 18446744073709551616) (mod main::uc 18446744073709551616) (mod main::c 18446744073709551616) (mod main::us 18446744073709551616) (mod main::s 18446744073709551616) (mod main::ui 18446744073709551616) (mod main::i 18446744073709551616) (mod main::ul 18446744073709551616) (mod main::l 18446744073709551616) (mod main::ull 18446744073709551616) (mod main::ll 18446744073709551616)) 18446744073709551616) 0)))[choiceType\u003dALTERNATIVE_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 15, + "colNumberStop": 50, + "offsetStart": 21, + "offsetEnd": 288, + "sourceText": "if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();int main() {\n _Bool a;\n unsigned char uc;\n signed char c;\n unsigned short us;\n short s;\n unsigned int ui;\n int i;\n unsigned long ul;\n long l;\n unsigned long long ull;\n long long ll;\n if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();\n}" + } + } + }, + { + "source": "main_init", + "target": "__loc_730", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::uc 0) (\u003c\u003d main::uc 255)))" + "content": "((assume (and (\u003e\u003d main::a 0) (\u003c\u003d main::a 1))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::c -128) (\u003c\u003d main::c 127)))" + "content": "((assume (and (\u003e\u003d main::uc 0) (\u003c\u003d main::uc 255))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::us 0) (\u003c\u003d main::us 65535)))" + "content": "((assume (and (\u003e\u003d main::c -128) (\u003c\u003d main::c 127))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::s -32768) (\u003c\u003d main::s 32767)))" + "content": "((assume (and (\u003e\u003d main::us 0) (\u003c\u003d main::us 65535))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::ui 0) (\u003c\u003d main::ui 4294967295)))" + "content": "((assume (and (\u003e\u003d main::s -32768) (\u003c\u003d main::s 32767))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::i -2147483648) (\u003c\u003d main::i 2147483647)))" + "content": "((assume (and (\u003e\u003d main::ui 0) (\u003c\u003d main::ui 4294967295))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::ul 0) (\u003c\u003d main::ul 4294967295)))" + "content": "((assume (and (\u003e\u003d main::i -2147483648) (\u003c\u003d main::i 2147483647))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::l -2147483648) (\u003c\u003d main::l 2147483647)))" + "content": "((assume (and (\u003e\u003d main::ul 0) (\u003c\u003d main::ul 18446744073709551615))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::ull 0) (\u003c\u003d main::ull 18446744073709551615)))" + "content": "((assume (and (\u003e\u003d main::l -9223372036854775808) (\u003c\u003d main::l 9223372036854775807))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::ll -9223372036854775808) (\u003c\u003d main::ll 9223372036854775807)))" - } - ] - } - }, - { - "source": "__loc_748", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "((assume (and (\u003e\u003d main::ull 0) (\u003c\u003d main::ull 18446744073709551615))))[choiceType\u003dMAIN_PATH]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 14, - "colNumberStart": 7, - "lineNumberStop": 14, - "colNumberStop": 34, - "offsetStart": 243, - "offsetEnd": 270, - "sourceText": "a+uc+c+us+s+ui+i+ul+l+ull+ll" + "sourceText": "" } }, - "content": "(assume (\u003d (mod (+ (mod main::a 18446744073709551616) (mod main::uc 18446744073709551616) (mod main::c 18446744073709551616) (mod main::us 18446744073709551616) (mod main::s 18446744073709551616) (mod main::ui 18446744073709551616) (mod main::i 18446744073709551616) (mod main::ul 18446744073709551616) (mod main::l 18446744073709551616) (mod main::ull 18446744073709551616) (mod main::ll 18446744073709551616)) 18446744073709551616) 0))" + "content": "((assume (and (\u003e\u003d main::ll -9223372036854775808) (\u003c\u003d main::ll 9223372036854775807))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 15, + "colNumberStop": 50, + "offsetStart": 21, + "offsetEnd": 288, + "sourceText": "int main() {\n _Bool a;\n unsigned char uc;\n signed char c;\n unsigned short us;\n short s;\n unsigned int ui;\n int i;\n unsigned long ul;\n long l;\n unsigned long long ull;\n long long ll;\n if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();\n}_Bool a;\n unsigned char uc;\n signed char c;\n unsigned short us;\n short s;\n unsigned int ui;\n int i;\n unsigned long ul;\n long l;\n unsigned long long ull;\n long long ll;\n if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();_Bool a;unsigned char uc;signed char c;unsigned short us;short s;unsigned int ui;int i;unsigned long ul;long l;unsigned long long ull;long long ll;if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();" + } } }, { - "source": "__loc_748", + "source": "__loc_730", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -356,17 +414,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 14, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 14, - "colNumberStop": 34, - "offsetStart": 243, - "offsetEnd": 270, - "sourceText": "a+uc+c+us+s+ui+i+ul+l+ull+ll" + "colNumberStop": 50, + "offsetStart": 240, + "offsetEnd": 286, + "sourceText": "if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();" } }, - "content": "(assume (/\u003d (mod (+ (mod main::a 18446744073709551616) (mod main::uc 18446744073709551616) (mod main::c 18446744073709551616) (mod main::us 18446744073709551616) (mod main::s 18446744073709551616) (mod main::ui 18446744073709551616) (mod main::i 18446744073709551616) (mod main::ul 18446744073709551616) (mod main::l 18446744073709551616) (mod main::ull 18446744073709551616) (mod main::ll 18446744073709551616)) 18446744073709551616) 0))" + "content": "((assume (/\u003d (mod (+ (mod main::a 18446744073709551616) (mod main::uc 18446744073709551616) (mod main::c 18446744073709551616) (mod main::us 18446744073709551616) (mod main::s 18446744073709551616) (mod main::ui 18446744073709551616) (mod main::i 18446744073709551616) (mod main::ul 18446744073709551616) (mod main::l 18446744073709551616) (mod main::ull 18446744073709551616) (mod main::ll 18446744073709551616)) 18446744073709551616) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 14, + "colNumberStart": 4, + "lineNumberStop": 14, + "colNumberStop": 50, + "offsetStart": 240, + "offsetEnd": 286, + "sourceText": "if(a+uc+c+us+s+ui+i+ul+l+ull+ll) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/03bitwise.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/03bitwise.c.json index 3a04f5c917..bb26165a44 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/03bitwise.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/03bitwise.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_756 " + "vars": [ + { + "name": "reach_error_ret", + "type": "(Bv 1)" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_756", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_756", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,20 +108,86 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "(Bv 32)" + }, { "name": "main::a", "type": "(Bv 32)" + }, + { + "name": "call___VERIFIER_nondet_int_ret52", + "type": "(Bv 32)" + }, + { + "name": "call_reach_error_ret53", + "type": "(Bv 1)" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_781 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 50, + "offsetEnd": 147, + "sourceText": "int main() {\n int a \u003d __VERIFIER_nondet_int();\n a \u003d a | 0;\n if(a \u003d\u003d -10) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 50, + "offsetEnd": 147, + "sourceText": "int main() {\n int a \u003d __VERIFIER_nondet_int();\n a \u003d a | 0;\n if(a \u003d\u003d -10) reach_error();\n}" + } + } + }, + { + "name": "__loc_763", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_781", + "source": "__loc_763", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -98,21 +202,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 6, - "colNumberStop": 14, - "offsetStart": 122, - "offsetEnd": 129, - "sourceText": "a \u003d\u003d -10" + "colNumberStop": 30, + "offsetStart": 119, + "offsetEnd": 145, + "sourceText": "if(a \u003d\u003d -10) reach_error();" } }, - "content": "(assume (\u003d (ite (\u003d main::a #b11111111111111111111111111110110) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000))" + "content": "((assume (\u003d (ite (\u003d main::a #b11111111111111111111111111110110) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 30, + "offsetStart": 50, + "offsetEnd": 147, + "sourceText": "if(a \u003d\u003d -10) reach_error();if(a \u003d\u003d -10) reach_error();int main() {\n int a \u003d __VERIFIER_nondet_int();\n a \u003d a | 0;\n if(a \u003d\u003d -10) reach_error();\n}" + } } }, { - "source": "__loc_781", + "source": "__loc_763", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -127,22 +243,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 6, - "colNumberStop": 14, - "offsetStart": 122, - "offsetEnd": 129, - "sourceText": "a \u003d\u003d -10" + "colNumberStop": 30, + "offsetStart": 119, + "offsetEnd": 145, + "sourceText": "if(a \u003d\u003d -10) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003d main::a #b11111111111111111111111111110110) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000))" + "content": "((assume (/\u003d (ite (\u003d main::a #b11111111111111111111111111110110) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 30, + "offsetStart": 119, + "offsetEnd": 145, + "sourceText": "if(a \u003d\u003d -10) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { "source": "main_init", - "target": "__loc_781", + "target": "__loc_763", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -156,12 +284,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 12, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 34, - "offsetStart": 75, - "offsetEnd": 97, - "sourceText": "__VERIFIER_nondet_int()" + "colNumberStop": 35, + "offsetStart": 67, + "offsetEnd": 98, + "sourceText": "int a \u003d __VERIFIER_nondet_int();" } }, "content": "(havoc main::a)" @@ -172,12 +300,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 12, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 34, - "offsetStart": 75, - "offsetEnd": 97, - "sourceText": "__VERIFIER_nondet_int()" + "colNumberStop": 35, + "offsetStart": 67, + "offsetEnd": 98, + "sourceText": "int a \u003d __VERIFIER_nondet_int();" } }, "content": "(assume true)" @@ -187,18 +315,24 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, "content": "(assign main::a main::a)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 35, + "offsetStart": 0, + "offsetEnd": 147, + "sourceText": "int main() {\n int a \u003d __VERIFIER_nondet_int();\n a \u003d a | 0;\n if(a \u003d\u003d -10) reach_error();\n}int a \u003d __VERIFIER_nondet_int();\n a \u003d a | 0;\n if(a \u003d\u003d -10) reach_error();int a \u003d __VERIFIER_nondet_int();int a \u003d __VERIFIER_nondet_int();int a \u003d __VERIFIER_nondet_int();int a \u003d __VERIFIER_nondet_int();int a \u003d __VERIFIER_nondet_int();int a \u003d __VERIFIER_nondet_int();a \u003d a | 0;a \u003d a | 0;a \u003d a | 0;if(a \u003d\u003d -10) reach_error();if(a \u003d\u003d -10) reach_error();if(a \u003d\u003d -10) reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/04real.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/04real.c.json index 32d9c9f41d..36d590aab5 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/04real.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/04real.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_789 " + "vars": [ + { + "name": "reach_error_ret", + "type": "(Bv 1)" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_789", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_789", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,6 +108,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "(Bv 32)" + }, { "name": "main::f", "type": "(Fp 8 24)" @@ -81,17 +123,79 @@ { "name": "main::ld", "type": "(Fp 15 113)" + }, + { + "name": "call___VERIFIER_nondet_float_ret54", + "type": "(Fp 8 24)" + }, + { + "name": "call_reach_error_ret55", + "type": "(Bv 1)" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_817 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 0, + "offsetStart": 61, + "offsetEnd": 205, + "sourceText": "int main() {\n float f \u003d __VERIFIER_nondet_float();\n double d \u003d f;\n long double ld \u003d d;\n if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 0, + "offsetStart": 61, + "offsetEnd": 205, + "sourceText": "int main() {\n float f \u003d __VERIFIER_nondet_float();\n double d \u003d f;\n long double ld \u003d d;\n if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();\n}" + } + } + }, + { + "name": "__loc_801", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_817", + "source": "__loc_801", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -106,21 +210,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 7, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 7, - "colNumberStop": 30, - "offsetStart": 164, - "offsetEnd": 187, - "sourceText": "ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f" + "colNumberStop": 46, + "offsetStart": 161, + "offsetEnd": 203, + "sourceText": "if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();" } }, - "content": "(assume (\u003d (ite (and (/\u003d #b00000000000000000000000000000000 (ite (\u003e main::ld (#b0 #b011111111111101 #b0001111010111000010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000)) (/\u003d #b00000000000000000000000000000000 (ite (\u003c main::ld (#b0 #b011111111111101 #b0100011110101110000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000))) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000))" + "content": "((assume (\u003d (ite (and (/\u003d #b00000000000000000000000000000000 (ite (\u003e main::ld (#b0 #b011111111111101 #b0001111010111000010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000)) (/\u003d #b00000000000000000000000000000000 (ite (\u003c main::ld (#b0 #b011111111111101 #b0100011110101110000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000))) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 46, + "offsetStart": 61, + "offsetEnd": 205, + "sourceText": "if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();int main() {\n float f \u003d __VERIFIER_nondet_float();\n double d \u003d f;\n long double ld \u003d d;\n if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();\n}" + } } }, { - "source": "__loc_817", + "source": "__loc_801", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -135,22 +251,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 7, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 7, - "colNumberStop": 30, - "offsetStart": 164, - "offsetEnd": 187, - "sourceText": "ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f" + "colNumberStop": 46, + "offsetStart": 161, + "offsetEnd": 203, + "sourceText": "if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();" } }, - "content": "(assume (/\u003d (ite (and (/\u003d #b00000000000000000000000000000000 (ite (\u003e main::ld (#b0 #b011111111111101 #b0001111010111000010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000)) (/\u003d #b00000000000000000000000000000000 (ite (\u003c main::ld (#b0 #b011111111111101 #b0100011110101110000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000))) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000))" + "content": "((assume (/\u003d (ite (and (/\u003d #b00000000000000000000000000000000 (ite (\u003e main::ld (#b0 #b011111111111101 #b0001111010111000010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000)) (/\u003d #b00000000000000000000000000000000 (ite (\u003c main::ld (#b0 #b011111111111101 #b0100011110101110000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)) #b00000000000000000000000000000001 #b00000000000000000000000000000000))) #b00000000000000000000000000000001 #b00000000000000000000000000000000) #b00000000000000000000000000000000)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 7, + "colNumberStart": 4, + "lineNumberStop": 7, + "colNumberStop": 46, + "offsetStart": 161, + "offsetEnd": 203, + "sourceText": "if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { "source": "main_init", - "target": "__loc_817", + "target": "__loc_801", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -164,12 +292,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 14, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 38, - "offsetStart": 88, - "offsetEnd": 112, - "sourceText": "__VERIFIER_nondet_float()" + "colNumberStop": 39, + "offsetStart": 78, + "offsetEnd": 113, + "sourceText": "float f \u003d __VERIFIER_nondet_float();" } }, "content": "(havoc main::f)" @@ -180,12 +308,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 14, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 38, - "offsetStart": 88, - "offsetEnd": 112, - "sourceText": "__VERIFIER_nondet_float()" + "colNumberStop": 39, + "offsetStart": 78, + "offsetEnd": 113, + "sourceText": "float f \u003d __VERIFIER_nondet_float();" } }, "content": "(assume true)" @@ -223,6 +351,18 @@ "content": "(assign main::ld (fptofp[15,113] main::d))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 46, + "offsetStart": 61, + "offsetEnd": 205, + "sourceText": "int main() {\n float f \u003d __VERIFIER_nondet_float();\n double d \u003d f;\n long double ld \u003d d;\n if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();\n}float f \u003d __VERIFIER_nondet_float();\n double d \u003d f;\n long double ld \u003d d;\n if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();float f \u003d __VERIFIER_nondet_float();float f \u003d __VERIFIER_nondet_float();float f \u003d __VERIFIER_nondet_float();float f \u003d __VERIFIER_nondet_float();float f \u003d __VERIFIER_nondet_float();float f \u003d __VERIFIER_nondet_float();double d \u003d f;double d \u003d f;double d \u003d f;double d \u003d f;long double ld \u003d d;long double ld \u003d d;long double ld \u003d d;long double ld \u003d d;if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();if(ld \u003e 0.28f \u0026\u0026 ld \u003c 0.32f) reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/05math.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/05math.c.json index 8059ad3735..36e3ea01a1 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/05math.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/05math.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_825 " + "vars": [ + { + "name": "reach_error_ret", + "type": "(Bv 1)" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_825", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_825", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,6 +108,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "(Bv 32)" + }, { "name": "main::f", "type": "(Fp 8 24)" @@ -137,18 +179,117 @@ { "name": "call_isnan_ret63", "type": "(Bv 32)" + }, + { + "name": "call_reach_error_ret64", + "type": "(Bv 1)" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_942 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 0, + "lineNumberStop": 22, + "colNumberStop": 0, + "offsetStart": 170, + "offsetEnd": 459, + "sourceText": "int main() {\n float f \u003d 12.65f;\n float f1 \u003d fabs(f);\n float f2 \u003d floor(f);\n float f3 \u003d round(f);\n float f4 \u003d fmax(f2, f3);\n float f5 \u003d fmin(f2, f3);\n float f6 \u003d sqrt(f);\n float f7 \u003d isnan(f);\n f \u003d 0.0f;\n float f8 \u003d isnan(0.0f/0.0f);\n if(f8) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 0, + "lineNumberStop": 22, + "colNumberStop": 0, + "offsetStart": 170, + "offsetEnd": 459, + "sourceText": "int main() {\n float f \u003d 12.65f;\n float f1 \u003d fabs(f);\n float f2 \u003d floor(f);\n float f3 \u003d round(f);\n float f4 \u003d fmax(f2, f3);\n float f5 \u003d fmin(f2, f3);\n float f6 \u003d sqrt(f);\n float f7 \u003d isnan(f);\n f \u003d 0.0f;\n float f8 \u003d isnan(0.0f/0.0f);\n if(f8) reach_error();\n}" + } + } + }, + { + "name": "__loc_926", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ + { + "source": "__loc_926", + "target": "main_final", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 21, + "colNumberStart": 4, + "lineNumberStop": 21, + "colNumberStop": 24, + "offsetStart": 437, + "offsetEnd": 457, + "sourceText": "if(f8) reach_error();" + } + }, + "content": "((assume (\u003d main::f8 (#b0 #b00000000 #b00000000000000000000000))))[choiceType\u003dALTERNATIVE_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 0, + "lineNumberStop": 22, + "colNumberStop": 24, + "offsetStart": 170, + "offsetEnd": 459, + "sourceText": "if(f8) reach_error();if(f8) reach_error();int main() {\n float f \u003d 12.65f;\n float f1 \u003d fabs(f);\n float f2 \u003d floor(f);\n float f3 \u003d round(f);\n float f4 \u003d fmax(f2, f3);\n float f5 \u003d fmin(f2, f3);\n float f6 \u003d sqrt(f);\n float f7 \u003d isnan(f);\n f \u003d 0.0f;\n float f8 \u003d isnan(0.0f/0.0f);\n if(f8) reach_error();\n}" + } + } + }, { "source": "main_init", - "target": "__loc_942", + "target": "__loc_926", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -178,15 +319,15 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 12, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 12, - "colNumberStop": 21, - "offsetStart": 220, - "offsetEnd": 226, - "sourceText": "fabs(f)" + "colNumberStop": 22, + "offsetStart": 209, + "offsetEnd": 227, + "sourceText": "float f1 \u003d fabs(f);" } }, - "content": "(assign call_fabs_ret56 (fpabs main::f))" + "content": "(assign call_fabs_ret56 (fpabs (#b0 #b10000010 #b10010100110011001100110)))" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -210,15 +351,15 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 13, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 13, - "colNumberStop": 22, - "offsetStart": 244, - "offsetEnd": 251, - "sourceText": "floor(f)" + "colNumberStop": 23, + "offsetStart": 233, + "offsetEnd": 252, + "sourceText": "float f2 \u003d floor(f);" } }, - "content": "(assign call_floor_ret57 (fproundtoint main::f))" + "content": "(assign call_floor_ret57 (fproundtoint[RTN] (#b0 #b10000010 #b10010100110011001100110)))" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -242,15 +383,15 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 14, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 14, - "colNumberStop": 22, - "offsetStart": 269, - "offsetEnd": 276, - "sourceText": "round(f)" + "colNumberStop": 23, + "offsetStart": 258, + "offsetEnd": 277, + "sourceText": "float f3 \u003d round(f);" } }, - "content": "(assign call_round_ret58 (fproundtoint main::f))" + "content": "(assign call_round_ret58 (fproundtoint[RNA] (#b0 #b10000010 #b10010100110011001100110)))" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -274,12 +415,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 15, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 15, - "colNumberStop": 26, - "offsetStart": 294, - "offsetEnd": 305, - "sourceText": "fmax(f2, f3)" + "colNumberStop": 27, + "offsetStart": 283, + "offsetEnd": 306, + "sourceText": "float f4 \u003d fmax(f2, f3);" } }, "content": "(assign call_fmax_ret59 (fpmax main::f2 main::f3))" @@ -306,12 +447,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 16, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 16, - "colNumberStop": 26, - "offsetStart": 323, - "offsetEnd": 334, - "sourceText": "fmin(f2, f3)" + "colNumberStop": 27, + "offsetStart": 312, + "offsetEnd": 335, + "sourceText": "float f5 \u003d fmin(f2, f3);" } }, "content": "(assign call_fmin_ret60 (fpmin main::f2 main::f3))" @@ -338,15 +479,15 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 17, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 17, - "colNumberStop": 21, - "offsetStart": 352, - "offsetEnd": 358, - "sourceText": "sqrt(f)" + "colNumberStop": 22, + "offsetStart": 341, + "offsetEnd": 359, + "sourceText": "float f6 \u003d sqrt(f);" } }, - "content": "(assign call_sqrt_ret61 (fpsqrt main::f))" + "content": "(assign call_sqrt_ret61 (#b0 #b10000000 #b11000111010000010110101))" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -362,7 +503,7 @@ "sourceText": "float f6 \u003d sqrt(f);" } }, - "content": "(assign main::f6 call_sqrt_ret61)" + "content": "(assign main::f6 (#b0 #b10000000 #b11000111010000010110101))" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -370,15 +511,15 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 18, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 18, - "colNumberStop": 22, - "offsetStart": 376, - "offsetEnd": 383, - "sourceText": "isnan(f)" + "colNumberStop": 23, + "offsetStart": 365, + "offsetEnd": 384, + "sourceText": "float f7 \u003d isnan(f);" } }, - "content": "(assign call_isnan_ret62 (ite (fpisnan main::f) #b00000000000000000000000000000001 #b00000000000000000000000000000000))" + "content": "(assign call_isnan_ret62 #b00000000000000000000000000000000)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -394,19 +535,13 @@ "sourceText": "float f7 \u003d isnan(f);" } }, - "content": "(assign main::f7 (fpfrombv[8,24][s] call_isnan_ret62))" + "content": "(assign main::f7 (#b0 #b00000000 #b00000000000000000000000))" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -418,12 +553,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 20, - "colNumberStart": 15, + "colNumberStart": 4, "lineNumberStop": 20, - "colNumberStop": 30, - "offsetStart": 415, - "offsetEnd": 430, - "sourceText": "isnan(0.0f/0.0f)" + "colNumberStop": 31, + "offsetStart": 404, + "offsetEnd": 431, + "sourceText": "float f8 \u003d isnan(0.0f/0.0f);" } }, "content": "(assign call_isnan_ret63 (ite (fpisnan (fpdiv[rne] (#b0 #b00000000 #b00000000000000000000000) (#b0 #b00000000 #b00000000000000000000000))) #b00000000000000000000000000000001 #b00000000000000000000000000000000))" @@ -445,39 +580,22 @@ "content": "(assign main::f8 (fpfrombv[8,24][s] call_isnan_ret63))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 22, + "colNumberStop": 31, + "offsetStart": 0, + "offsetEnd": 459, + "sourceText": "int main() {\n float f \u003d 12.65f;\n float f1 \u003d fabs(f);\n float f2 \u003d floor(f);\n float f3 \u003d round(f);\n float f4 \u003d fmax(f2, f3);\n float f5 \u003d fmin(f2, f3);\n float f6 \u003d sqrt(f);\n float f7 \u003d isnan(f);\n f \u003d 0.0f;\n float f8 \u003d isnan(0.0f/0.0f);\n if(f8) reach_error();\n}float f \u003d 12.65f;\n float f1 \u003d fabs(f);\n float f2 \u003d floor(f);\n float f3 \u003d round(f);\n float f4 \u003d fmax(f2, f3);\n float f5 \u003d fmin(f2, f3);\n float f6 \u003d sqrt(f);\n float f7 \u003d isnan(f);\n f \u003d 0.0f;\n float f8 \u003d isnan(0.0f/0.0f);\n if(f8) reach_error();float f \u003d 12.65f;float f \u003d 12.65f;float f \u003d 12.65f;float f \u003d 12.65f;float f1 \u003d fabs(f);float f1 \u003d fabs(f);float f1 \u003d fabs(f);float f1 \u003d fabs(f);float f1 \u003d fabs(f);float f1 \u003d fabs(f);float f1 \u003d fabs(f);float f2 \u003d floor(f);float f2 \u003d floor(f);float f2 \u003d floor(f);float f2 \u003d floor(f);float f2 \u003d floor(f);float f2 \u003d floor(f);float f2 \u003d floor(f);float f3 \u003d round(f);float f3 \u003d round(f);float f3 \u003d round(f);float f3 \u003d round(f);float f3 \u003d round(f);float f3 \u003d round(f);float f3 \u003d round(f);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f4 \u003d fmax(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f5 \u003d fmin(f2, f3);float f6 \u003d sqrt(f);float f6 \u003d sqrt(f);float f6 \u003d sqrt(f);float f6 \u003d sqrt(f);float f6 \u003d sqrt(f);float f6 \u003d sqrt(f);float f6 \u003d sqrt(f);float f7 \u003d isnan(f);float f7 \u003d isnan(f);float f7 \u003d isnan(f);float f7 \u003d isnan(f);float f7 \u003d isnan(f);float f7 \u003d isnan(f);float f7 \u003d isnan(f);f \u003d 0.0f;f \u003d 0.0f;f \u003d 0.0f;float f8 \u003d isnan(0.0f/0.0f);float f8 \u003d isnan(0.0f/0.0f);float f8 \u003d isnan(0.0f/0.0f);float f8 \u003d isnan(0.0f/0.0f);float f8 \u003d isnan(0.0f/0.0f);float f8 \u003d isnan(0.0f/0.0f);float f8 \u003d isnan(0.0f/0.0f);if(f8) reach_error();if(f8) reach_error();if(f8) reach_error();" + } } }, { - "source": "__loc_942", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 21, - "colNumberStart": 7, - "lineNumberStop": 21, - "colNumberStop": 8, - "offsetStart": 440, - "offsetEnd": 441, - "sourceText": "f8" - } - }, - "content": "(assume (\u003d main::f8 (#b0 #b00000000 #b00000000000000000000000)))" - } - ] - } - }, - { - "source": "__loc_942", + "source": "__loc_926", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -492,17 +610,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 21, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 21, - "colNumberStop": 8, - "offsetStart": 440, - "offsetEnd": 441, - "sourceText": "f8" + "colNumberStop": 24, + "offsetStart": 437, + "offsetEnd": 457, + "sourceText": "if(f8) reach_error();" } }, - "content": "(assume (/\u003d main::f8 (#b0 #b00000000 #b00000000000000000000000)))" + "content": "((assume (/\u003d main::f8 (#b0 #b00000000 #b00000000000000000000000))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 21, + "colNumberStart": 4, + "lineNumberStop": 21, + "colNumberStop": 24, + "offsetStart": 437, + "offsetEnd": 457, + "sourceText": "if(f8) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/06arrays.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/06arrays.c.json index 2407fd19ce..a98cac5d00 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/06arrays.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/06arrays.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_950 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_950", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_950", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,25 +108,87 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::a", - "type": "(Array ([Int] -\u003e Int))" + "type": "Int" }, { "name": "main::b", - "type": "(Array ([Int] -\u003e Int))" + "type": "Int" + }, + { + "name": "call_reach_error_ret65", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_977 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 0, + "offsetStart": 22, + "offsetEnd": 120, + "sourceText": "int main() {\n int a[2], b[3];\n a[0] \u003d 12;\n b[3] \u003d a[0];\n if(b[3] \u003e 11) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 0, + "offsetStart": 22, + "offsetEnd": 120, + "sourceText": "int main() {\n int a[2], b[3];\n a[0] \u003d 12;\n b[3] \u003d a[0];\n if(b[3] \u003e 11) reach_error();\n}" + } + } + }, + { + "name": "__loc_963", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "main_init", - "target": "__loc_977", + "source": "__loc_963", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -101,39 +201,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" - } - }, - "content": "(assign main::a (write main::a 0 12))" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 7, + "colNumberStart": 4, + "lineNumberStop": 7, + "colNumberStop": 31, + "offsetStart": 91, + "offsetEnd": 118, + "sourceText": "if(b[3] \u003e 11) reach_error();" } }, - "content": "(assign main::b (write main::b 3 (read main::a 0)))" + "content": "((assume (\u003d (ite (\u003e (deref 4 3 Int) 11) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 31, + "offsetStart": 22, + "offsetEnd": 120, + "sourceText": "if(b[3] \u003e 11) reach_error();if(b[3] \u003e 11) reach_error();int main() {\n int a[2], b[3];\n a[0] \u003d 12;\n b[3] \u003d a[0];\n if(b[3] \u003e 11) reach_error();\n}" + } } }, { - "source": "__loc_977", - "target": "main_final", + "source": "main_init", + "target": "__loc_963", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -141,27 +237,59 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign main::a 1)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign main::b 4)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 7, - "colNumberStart": 7, - "lineNumberStop": 7, - "colNumberStop": 15, - "offsetStart": 94, - "offsetEnd": 102, - "sourceText": "b[3] \u003e 11" + "sourceText": "" } }, - "content": "(assume (\u003d (ite (\u003e (read main::b 3) 11) 1 0) 0))" + "content": "(memassign (deref 1 0 Int) 12)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + }, + "content": "(memassign (deref 4 3 Int) (deref 1 0 Int))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 31, + "offsetStart": 0, + "offsetEnd": 120, + "sourceText": "int main() {\n int a[2], b[3];\n a[0] \u003d 12;\n b[3] \u003d a[0];\n if(b[3] \u003e 11) reach_error();\n}int a[2], b[3];\n a[0] \u003d 12;\n b[3] \u003d a[0];\n if(b[3] \u003e 11) reach_error();int a[2], b[3];a[0] \u003d 12;a[0] \u003d 12;a[0] \u003d 12;b[3] \u003d a[0];b[3] \u003d a[0];b[3] \u003d a[0];if(b[3] \u003e 11) reach_error();if(b[3] \u003e 11) reach_error();if(b[3] \u003e 11) reach_error();" + } } }, { - "source": "__loc_977", + "source": "__loc_963", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -176,17 +304,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 7, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 7, - "colNumberStop": 15, - "offsetStart": 94, - "offsetEnd": 102, - "sourceText": "b[3] \u003e 11" + "colNumberStop": 31, + "offsetStart": 91, + "offsetEnd": 118, + "sourceText": "if(b[3] \u003e 11) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003e (read main::b 3) 11) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003e (deref 4 3 Int) 11) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 7, + "colNumberStart": 4, + "lineNumberStop": 7, + "colNumberStop": 31, + "offsetStart": 91, + "offsetEnd": 118, + "sourceText": "if(b[3] \u003e 11) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/07arrayinit.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/07arrayinit.c.json index 5cd64a5e20..07158dc5a0 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/07arrayinit.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/07arrayinit.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_985 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_985", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_985", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,25 +108,128 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::x", "type": "Int" }, { "name": "main::a", - "type": "(Array ([Int] -\u003e Int))" + "type": "Int" + }, + { + "name": "call_reach_error_ret66", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1008 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 107, + "sourceText": "int main() {\n int x;\n int a[3] \u003d {2, x+1, 4};\n if(a[1] \u003e 2) reach_error();\n }" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 107, + "sourceText": "int main() {\n int x;\n int a[3] \u003d {2, x+1, 4};\n if(a[1] \u003e 2) reach_error();\n }" + } + } + }, + { + "name": "__loc_991", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ + { + "source": "__loc_991", + "target": "main_final", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 30, + "offsetStart": 78, + "offsetEnd": 104, + "sourceText": "if(a[1] \u003e 2) reach_error();" + } + }, + "content": "((assume (\u003d (ite (\u003e (deref 1 1 Int) 2) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 30, + "offsetStart": 22, + "offsetEnd": 107, + "sourceText": "if(a[1] \u003e 2) reach_error();if(a[1] \u003e 2) reach_error();int main() {\n int x;\n int a[3] \u003d {2, x+1, 4};\n if(a[1] \u003e 2) reach_error();\n }" + } + } + }, { "source": "main_init", - "target": "__loc_1008", + "target": "__loc_991", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -96,21 +237,23 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign main::a 1)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::x -2147483648) (\u003c\u003d main::x 2147483647)))" + "content": "((assume (and (\u003e\u003d main::x -2147483648) (\u003c\u003d main::x 2147483647))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -126,42 +269,57 @@ "sourceText": "int a[3] \u003d {2, x+1, 4};" } }, - "content": "(assign main::a (arrayinit 0 0 1 2 2 (+ main::x 1) 4))" - } - ] - } - }, - { - "source": "__loc_1008", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(memassign (deref 1 0 Int) 2)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, - "colNumberStart": 7, - "lineNumberStop": 6, - "colNumberStop": 14, - "offsetStart": 81, - "offsetEnd": 88, - "sourceText": "a[1] \u003e 2" + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 5, + "colNumberStop": 26, + "offsetStart": 50, + "offsetEnd": 72, + "sourceText": "int a[3] \u003d {2, x+1, 4};" + } + }, + "content": "(memassign (deref 1 1 Int) (+ main::x 1))" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 5, + "colNumberStop": 26, + "offsetStart": 50, + "offsetEnd": 72, + "sourceText": "int a[3] \u003d {2, x+1, 4};" } }, - "content": "(assume (\u003d (ite (\u003e (read main::a 1) 2) 1 0) 0))" + "content": "(memassign (deref 1 2 Int) 4)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 30, + "offsetStart": 22, + "offsetEnd": 107, + "sourceText": "int main() {\n int x;\n int a[3] \u003d {2, x+1, 4};\n if(a[1] \u003e 2) reach_error();\n }int x;\n int a[3] \u003d {2, x+1, 4};\n if(a[1] \u003e 2) reach_error();int x;int a[3] \u003d {2, x+1, 4};int a[3] \u003d {2, x+1, 4};int a[3] \u003d {2, x+1, 4};int a[3] \u003d {2, x+1, 4};int a[3] \u003d {2, x+1, 4};int a[3] \u003d {2, x+1, 4};int a[3] \u003d {2, x+1, 4};if(a[1] \u003e 2) reach_error();if(a[1] \u003e 2) reach_error();if(a[1] \u003e 2) reach_error();" + } } }, { - "source": "__loc_1008", + "source": "__loc_991", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -176,17 +334,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 6, - "colNumberStop": 14, - "offsetStart": 81, - "offsetEnd": 88, - "sourceText": "a[1] \u003e 2" + "colNumberStop": 30, + "offsetStart": 78, + "offsetEnd": 104, + "sourceText": "if(a[1] \u003e 2) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003e (read main::a 1) 2) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003e (deref 1 1 Int) 2) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 30, + "offsetStart": 78, + "offsetEnd": 104, + "sourceText": "if(a[1] \u003e 2) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/08vararray.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/08vararray.c.json index c929630b33..f003df9841 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/08vararray.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/08vararray.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1016 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1016", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1016", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,25 +108,128 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::x", "type": "Int" }, { "name": "main::a", - "type": "(Array ([Int] -\u003e Int))" + "type": "Int" + }, + { + "name": "call_reach_error_ret67", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1039 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 106, + "sourceText": "int main() {\n int x;\n int a[3] \u003d {1, 2, 3};\n if(a[x] \u003d\u003d 2) reach_error();\n }" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 106, + "sourceText": "int main() {\n int x;\n int a[3] \u003d {1, 2, 3};\n if(a[x] \u003d\u003d 2) reach_error();\n }" + } + } + }, + { + "name": "__loc_1019", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ + { + "source": "__loc_1019", + "target": "main_final", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 31, + "offsetStart": 76, + "offsetEnd": 103, + "sourceText": "if(a[x] \u003d\u003d 2) reach_error();" + } + }, + "content": "((assume (\u003d (ite (\u003d (deref 1 (mod main::x 18446744073709551616) Int) 2) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 31, + "offsetStart": 22, + "offsetEnd": 106, + "sourceText": "if(a[x] \u003d\u003d 2) reach_error();if(a[x] \u003d\u003d 2) reach_error();int main() {\n int x;\n int a[3] \u003d {1, 2, 3};\n if(a[x] \u003d\u003d 2) reach_error();\n }" + } + } + }, { "source": "main_init", - "target": "__loc_1039", + "target": "__loc_1019", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -96,21 +237,23 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign main::a 1)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::x -2147483648) (\u003c\u003d main::x 2147483647)))" + "content": "((assume (and (\u003e\u003d main::x -2147483648) (\u003c\u003d main::x 2147483647))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -126,42 +269,57 @@ "sourceText": "int a[3] \u003d {1, 2, 3};" } }, - "content": "(assign main::a (array (0 1) (1 2) (2 3) (default 0)))" - } - ] - } - }, - { - "source": "__loc_1039", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(memassign (deref 1 0 Int) 1)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, - "colNumberStart": 7, - "lineNumberStop": 6, - "colNumberStop": 15, - "offsetStart": 79, - "offsetEnd": 87, - "sourceText": "a[x] \u003d\u003d 2" + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 5, + "colNumberStop": 24, + "offsetStart": 50, + "offsetEnd": 70, + "sourceText": "int a[3] \u003d {1, 2, 3};" + } + }, + "content": "(memassign (deref 1 1 Int) 2)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 5, + "colNumberStop": 24, + "offsetStart": 50, + "offsetEnd": 70, + "sourceText": "int a[3] \u003d {1, 2, 3};" } }, - "content": "(assume (\u003d (ite (\u003d (read main::a main::x) 2) 1 0) 0))" + "content": "(memassign (deref 1 2 Int) 3)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 31, + "offsetStart": 22, + "offsetEnd": 106, + "sourceText": "int main() {\n int x;\n int a[3] \u003d {1, 2, 3};\n if(a[x] \u003d\u003d 2) reach_error();\n }int x;\n int a[3] \u003d {1, 2, 3};\n if(a[x] \u003d\u003d 2) reach_error();int x;int a[3] \u003d {1, 2, 3};int a[3] \u003d {1, 2, 3};int a[3] \u003d {1, 2, 3};int a[3] \u003d {1, 2, 3};int a[3] \u003d {1, 2, 3};int a[3] \u003d {1, 2, 3};int a[3] \u003d {1, 2, 3};if(a[x] \u003d\u003d 2) reach_error();if(a[x] \u003d\u003d 2) reach_error();if(a[x] \u003d\u003d 2) reach_error();" + } } }, { - "source": "__loc_1039", + "source": "__loc_1019", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -176,17 +334,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 6, - "colNumberStop": 15, - "offsetStart": 79, - "offsetEnd": 87, - "sourceText": "a[x] \u003d\u003d 2" + "colNumberStop": 31, + "offsetStart": 76, + "offsetEnd": 103, + "sourceText": "if(a[x] \u003d\u003d 2) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003d (read main::a main::x) 2) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003d (deref 1 (mod main::x 18446744073709551616) Int) 2) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 31, + "offsetStart": 76, + "offsetEnd": 103, + "sourceText": "if(a[x] \u003d\u003d 2) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/13typedef.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/13typedef.c.json index 33aaa57d11..d4c39d9886 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/13typedef.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/13typedef.c.json @@ -28,27 +28,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1047 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1047", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1047", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -57,6 +83,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -79,21 +117,83 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::char2", "type": "Int" + }, + { + "name": "call_reach_error_ret68", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1059 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 1, + "offsetStart": 35, + "offsetEnd": 108, + "sourceText": "int main() {\n char char2;\n if(char1 + char2 \u003e 256) reach_error();\n }" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 1, + "offsetStart": 35, + "offsetEnd": 108, + "sourceText": "int main() {\n char char2;\n if(char1 + char2 \u003e 256) reach_error();\n }" + } + } + }, + { + "name": "__loc_1040", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "main_init", - "target": "__loc_1059", + "source": "__loc_1040", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -101,36 +201,40 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "content": "(assign char1 0)" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 7, + "colNumberStart": 4, + "lineNumberStop": 7, + "colNumberStop": 41, + "offsetStart": 68, + "offsetEnd": 105, + "sourceText": "if(char1 + char2 \u003e 256) reach_error();" } }, - "content": "(assume (and (\u003e\u003d main::char2 -128) (\u003c\u003d main::char2 127)))" + "content": "((assume (\u003d (ite (\u003e main::char2 256) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 41, + "offsetStart": 35, + "offsetEnd": 108, + "sourceText": "if(char1 + char2 \u003e 256) reach_error();if(char1 + char2 \u003e 256) reach_error();int main() {\n char char2;\n if(char1 + char2 \u003e 256) reach_error();\n }" + } } }, { - "source": "__loc_1059", - "target": "main_final", + "source": "main_init", + "target": "__loc_1040", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -138,27 +242,41 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign char1 0)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 7, - "colNumberStart": 7, - "lineNumberStop": 7, - "colNumberStop": 25, - "offsetStart": 71, - "offsetEnd": 89, - "sourceText": "char1 + char2 \u003e 256" + "sourceText": "" } }, - "content": "(assume (\u003d (ite (\u003e (+ char1 main::char2) 256) 1 0) 0))" + "content": "((assume (and (\u003e\u003d main::char2 -128) (\u003c\u003d main::char2 127))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 41, + "offsetStart": 35, + "offsetEnd": 108, + "sourceText": "int main() {\n char char2;\n if(char1 + char2 \u003e 256) reach_error();\n }char char2;\n if(char1 + char2 \u003e 256) reach_error();char char2;if(char1 + char2 \u003e 256) reach_error();if(char1 + char2 \u003e 256) reach_error();if(char1 + char2 \u003e 256) reach_error();" + } } }, { - "source": "__loc_1059", + "source": "__loc_1040", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -173,17 +291,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 7, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 7, - "colNumberStop": 25, - "offsetStart": 71, - "offsetEnd": 89, - "sourceText": "char1 + char2 \u003e 256" + "colNumberStop": 41, + "offsetStart": 68, + "offsetEnd": 105, + "sourceText": "if(char1 + char2 \u003e 256) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003e (+ char1 main::char2) 256) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003e main::char2 256) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 7, + "colNumberStart": 4, + "lineNumberStop": 7, + "colNumberStop": 41, + "offsetStart": 68, + "offsetEnd": 105, + "sourceText": "if(char1 + char2 \u003e 256) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/14ushort.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/14ushort.c.json index 2b48af65aa..24be2ad3d9 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/14ushort.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/14ushort.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1067 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1067", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1067", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,6 +108,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::ush", "type": "Int" @@ -81,17 +123,75 @@ { "name": "call___VERIFIER_nondet_ushort_ret69", "type": "Int" + }, + { + "name": "call_reach_error_ret70", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1092 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 10, + "colNumberStop": 1, + "offsetStart": 73, + "offsetEnd": 179, + "sourceText": "int main() {\n short ush;\n long c;\n ush \u003d __VERIFIER_nondet_ushort();\n if(ush) reach_error();\n }" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 10, + "colNumberStop": 1, + "offsetStart": 73, + "offsetEnd": 179, + "sourceText": "int main() {\n short ush;\n long c;\n ush \u003d __VERIFIER_nondet_ushort();\n if(ush) reach_error();\n }" + } + } + }, + { + "name": "__loc_1073", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_1092", + "source": "__loc_1073", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -106,21 +206,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 9, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 9, - "colNumberStop": 9, - "offsetStart": 158, - "offsetEnd": 160, - "sourceText": "ush" + "colNumberStop": 25, + "offsetStart": 155, + "offsetEnd": 176, + "sourceText": "if(ush) reach_error();" } }, - "content": "(assume (\u003d main::ush 0))" + "content": "((assume (\u003d main::ush 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 0, + "lineNumberStop": 10, + "colNumberStop": 25, + "offsetStart": 73, + "offsetEnd": 179, + "sourceText": "if(ush) reach_error();if(ush) reach_error();int main() {\n short ush;\n long c;\n ush \u003d __VERIFIER_nondet_ushort();\n if(ush) reach_error();\n }" + } } }, { - "source": "__loc_1092", + "source": "__loc_1073", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -135,22 +247,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 9, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 9, - "colNumberStop": 9, - "offsetStart": 158, - "offsetEnd": 160, - "sourceText": "ush" + "colNumberStop": 25, + "offsetStart": 155, + "offsetEnd": 176, + "sourceText": "if(ush) reach_error();" } }, - "content": "(assume (/\u003d main::ush 0))" + "content": "((assume (/\u003d main::ush 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 4, + "lineNumberStop": 9, + "colNumberStop": 25, + "offsetStart": 155, + "offsetEnd": 176, + "sourceText": "if(ush) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { "source": "main_init", - "target": "__loc_1092", + "target": "__loc_1073", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -163,32 +287,20 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::ush -32768) (\u003c\u003d main::ush 32767)))" + "content": "((assume (and (\u003e\u003d main::ush -32768) (\u003c\u003d main::ush 32767))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::c -2147483648) (\u003c\u003d main::c 2147483647)))" + "content": "((assume (and (\u003e\u003d main::c -9223372036854775808) (\u003c\u003d main::c 9223372036854775807))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -196,12 +308,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 8, - "colNumberStart": 10, + "colNumberStart": 4, "lineNumberStop": 8, - "colNumberStop": 35, - "offsetStart": 123, - "offsetEnd": 148, - "sourceText": "__VERIFIER_nondet_ushort()" + "colNumberStop": 36, + "offsetStart": 117, + "offsetEnd": 149, + "sourceText": "ush \u003d __VERIFIER_nondet_ushort();" } }, "content": "(havoc call___VERIFIER_nondet_ushort_ret69)" @@ -212,12 +324,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 8, - "colNumberStart": 10, + "colNumberStart": 4, "lineNumberStop": 8, - "colNumberStop": 35, - "offsetStart": 123, - "offsetEnd": 148, - "sourceText": "__VERIFIER_nondet_ushort()" + "colNumberStop": 36, + "offsetStart": 117, + "offsetEnd": 149, + "sourceText": "ush \u003d __VERIFIER_nondet_ushort();" } }, "content": "(assume (and (\u003e\u003d call___VERIFIER_nondet_ushort_ret69 0) (\u003c\u003d call___VERIFIER_nondet_ushort_ret69 65535)))" @@ -227,18 +339,24 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, "content": "(assign main::ush (ite (\u003e\u003d call___VERIFIER_nondet_ushort_ret69 32768) (- call___VERIFIER_nondet_ushort_ret69 65536) call___VERIFIER_nondet_ushort_ret69))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 10, + "colNumberStop": 36, + "offsetStart": 0, + "offsetEnd": 179, + "sourceText": "int main() {\n short ush;\n long c;\n ush \u003d __VERIFIER_nondet_ushort();\n if(ush) reach_error();\n }short ush;\n long c;\n ush \u003d __VERIFIER_nondet_ushort();\n if(ush) reach_error();short ush;long c;ush \u003d __VERIFIER_nondet_ushort();ush \u003d __VERIFIER_nondet_ushort();ush \u003d __VERIFIER_nondet_ushort();ush \u003d __VERIFIER_nondet_ushort();ush \u003d __VERIFIER_nondet_ushort();if(ush) reach_error();if(ush) reach_error();if(ush) reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/15addition.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/15addition.c.json index 6f03c3bd8a..32cdf83e21 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/15addition.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/15addition.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1100 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1100", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1100", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,6 +108,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::z", "type": "Int" @@ -77,18 +119,64 @@ { "name": "main::y", "type": "Int" + }, + { + "name": "call_reach_error_ret71", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1124 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 122, + "sourceText": "int main() {\n int z \u003d 6;\n int y \u003d 1;\n if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();\n }" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 122, + "sourceText": "int main() {\n int z \u003d 6;\n int y \u003d 1;\n if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();\n }" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { "source": "main_init", - "target": "__loc_1124", + "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -129,64 +217,18 @@ "content": "(assign main::y 1)" } ] - } - }, - { - "source": "__loc_1124", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 6, - "colNumberStart": 7, - "lineNumberStop": 6, - "colNumberStop": 38, - "offsetStart": 72, - "offsetEnd": 103, - "sourceText": "(z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0" - } - }, - "content": "(assume (\u003d (ite (\u003d (+ (* main::z main::z) (- (* 12 main::y)) (- (* 6 main::z)) 12) 0) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_1124", - "target": "main_error", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 6, - "colNumberStart": 7, - "lineNumberStop": 6, - "colNumberStop": 38, - "offsetStart": 72, - "offsetEnd": 103, - "sourceText": "(z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0" - } - }, - "content": "(assume (/\u003d (ite (\u003d (+ (* main::z main::z) (- (* 12 main::y)) (- (* 6 main::z)) 12) 0) 1 0) 0))" - } - ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 54, + "offsetStart": 22, + "offsetEnd": 122, + "sourceText": "int main() {\n int z \u003d 6;\n int y \u003d 1;\n if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();\n }int z \u003d 6;\n int y \u003d 1;\n if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();int z \u003d 6;int z \u003d 6;int z \u003d 6;int z \u003d 6;int y \u003d 1;int y \u003d 1;int y \u003d 1;int y \u003d 1;if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();if((z*z) - 12 * y - 6 * z + 12 \u003d\u003d 0) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/16loop.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/16loop.c.json index 3836651878..19fc82d605 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/16loop.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/16loop.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1132 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1132", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1132", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -70,22 +108,95 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::for0::i", "type": "Int" + }, + { + "name": "call_reach_error_ret72", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1147 ", - "__loc_1156 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 111, + "sourceText": "int main() {\n for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }\n }" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 1, + "offsetStart": 22, + "offsetEnd": 111, + "sourceText": "int main() {\n for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }\n }" + } + } + }, + { + "name": "__loc_1132", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1141", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_1147", - "target": "__loc_1156", + "source": "__loc_1132", + "target": "__loc_1141", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -99,22 +210,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 19, - "lineNumberStop": 4, - "colNumberStop": 24, - "offsetStart": 54, - "offsetEnd": 59, - "sourceText": "i \u003c 30" + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 4, + "offsetStart": 39, + "offsetEnd": 108, + "sourceText": "for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }" } }, - "content": "(assume (/\u003d (ite (\u003c main::for0::i 30) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003c main::for0::i 30) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 33, + "offsetStart": 39, + "offsetEnd": 108, + "sourceText": "for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }{\n if(i \u003d\u003d 28) reach_error();\n }if(i \u003d\u003d 28) reach_error();if(i \u003d\u003d 28) reach_error();if(i \u003d\u003d 28) reach_error();" + } } }, { - "source": "__loc_1147", - "target": "main_final", + "source": "__loc_1141", + "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -127,23 +250,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 19, - "lineNumberStop": 4, - "colNumberStop": 24, - "offsetStart": 54, - "offsetEnd": 59, - "sourceText": "i \u003c 30" + "lineNumberStart": 5, + "colNumberStart": 8, + "lineNumberStop": 5, + "colNumberStop": 33, + "offsetStart": 77, + "offsetEnd": 102, + "sourceText": "if(i \u003d\u003d 28) reach_error();" } }, - "content": "(assume (\u003d (ite (\u003c main::for0::i 30) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003d main::for0::i 28) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 8, + "lineNumberStop": 5, + "colNumberStop": 33, + "offsetStart": 77, + "offsetEnd": 102, + "sourceText": "if(i \u003d\u003d 28) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { - "source": "main_init", - "target": "__loc_1147", + "source": "__loc_1132", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -157,22 +292,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 8, - "lineNumberStop": 4, - "colNumberStop": 16, - "offsetStart": 43, - "offsetEnd": 51, - "sourceText": "int i \u003d 0" + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 4, + "offsetStart": 39, + "offsetEnd": 108, + "sourceText": "for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }" } }, - "content": "(assign main::for0::i 0)" + "content": "((assume (\u003d (ite (\u003c main::for0::i 30) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 4, + "offsetStart": 22, + "offsetEnd": 111, + "sourceText": "for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }int main() {\n for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }\n }" + } } }, { - "source": "__loc_1156", - "target": "main_error", + "source": "main_init", + "target": "__loc_1132", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -185,23 +332,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 5, - "colNumberStart": 11, - "lineNumberStop": 5, - "colNumberStop": 17, - "offsetStart": 80, - "offsetEnd": 86, - "sourceText": "i \u003d\u003d 28" + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 4, + "offsetStart": 39, + "offsetEnd": 108, + "sourceText": "for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }" } }, - "content": "(assume (/\u003d (ite (\u003d main::for0::i 28) 1 0) 0))" + "content": "(assign main::for0::i 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 4, + "offsetStart": 22, + "offsetEnd": 111, + "sourceText": "int main() {\n for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }" + } } }, { - "source": "__loc_1156", - "target": "__loc_1147", + "source": "__loc_1141", + "target": "__loc_1132", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -215,15 +374,15 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 5, - "colNumberStart": 11, + "colNumberStart": 8, "lineNumberStop": 5, - "colNumberStop": 17, - "offsetStart": 80, - "offsetEnd": 86, - "sourceText": "i \u003d\u003d 28" + "colNumberStop": 33, + "offsetStart": 77, + "offsetEnd": 102, + "sourceText": "if(i \u003d\u003d 28) reach_error();" } }, - "content": "(assume (\u003d (ite (\u003d main::for0::i 28) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003d main::for0::i 28) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", @@ -231,17 +390,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 27, - "lineNumberStop": 4, - "colNumberStop": 29, - "offsetStart": 62, - "offsetEnd": 64, - "sourceText": "i++" + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 4, + "offsetStart": 39, + "offsetEnd": 108, + "sourceText": "for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }" } }, "content": "(assign main::for0::i (+ main::for0::i 1))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 33, + "offsetStart": 39, + "offsetEnd": 108, + "sourceText": "if(i \u003d\u003d 28) reach_error();if(i \u003d\u003d 28) reach_error();for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }for(int i \u003d 0; i \u003c 30; i++) {\n if(i \u003d\u003d 28) reach_error();\n }" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/17recursive.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/17recursive.c.json index 9b4a16a997..beaed45bc9 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/17recursive.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/17recursive.c.json @@ -19,27 +19,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1171 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1171", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1171", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,6 +74,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -84,11 +122,11 @@ ], "vars": [ { - "name": "fibonacci::i", + "name": "fibonacci_ret", "type": "Int" }, { - "name": "fibonacci_ret", + "name": "fibonacci::i", "type": "Int" }, { @@ -101,32 +139,131 @@ } ], "locs": [ - "fibonacci_init {init}", - "fibonacci_final {final}", - "__loc_1179 ", - "__loc_1185 ", - "__loc_1194 ", - "__loc_1200 ", - "__loc_1211 ", - "__loc_1216 ", - "__loc_1217 " - ], - "edges": [ { - "source": "fibonacci_init", - "target": "__loc_1179", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "fibonacci_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 22, + "offsetEnd": 149, + "sourceText": "int fibonacci(int i) {\n if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);\n}" + } } }, { - "source": "__loc_1211", - "target": "__loc_1216", + "name": "fibonacci_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 22, + "offsetEnd": 149, + "sourceText": "int fibonacci(int i) {\n if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);\n}" + } + } + }, + { + "name": "__loc_1166", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1181", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1195", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" + } + } + }, + { + "name": "__loc_1198", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1200", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" + } + } + }, + { + "name": "__loc_1203", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + } + ], + "edges": [ + { + "source": "__loc_1198", + "target": "__loc_1195", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -140,22 +277,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 16, + "colNumberStart": 9, "lineNumberStop": 6, - "colNumberStop": 29, - "offsetStart": 116, - "offsetEnd": 129, - "sourceText": "fibonacci(i-1)" + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" } }, - "content": "fibonacci(call_fibonacci_ret73, (+ (+ (+ fibonacci::i) (+ (- 1)))))" + "content": "fibonacci(call_fibonacci_ret73, (+ (+ (+ fibonacci::i) (- (+ 1)))))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" + } } }, { - "source": "__loc_1216", - "target": "__loc_1217", + "source": "__loc_1203", + "target": "__loc_1200", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -169,21 +318,57 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 33, + "colNumberStart": 9, "lineNumberStop": 6, - "colNumberStop": 46, - "offsetStart": 133, - "offsetEnd": 146, - "sourceText": "fibonacci(i-2)" + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" } }, - "content": "fibonacci(call_fibonacci_ret74, (+ (+ (+ fibonacci::i) (+ (- 2)))))" + "content": "fibonacci(call_fibonacci_ret74, (+ (+ (+ fibonacci::i) (- (+ 2)))))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" + } + } + }, + { + "source": "fibonacci_init", + "target": "__loc_1166", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 47, + "offsetStart": 22, + "offsetEnd": 149, + "sourceText": "int fibonacci(int i) {\n if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);\n}if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);" + } } }, { - "source": "__loc_1185", + "source": "__loc_1166", "target": "fibonacci_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -192,6 +377,22 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 49, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);" + } + }, + "content": "((assume (/\u003d (ite (\u003d fibonacci::i 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -200,20 +401,32 @@ "lineNumberStart": 4, "colNumberStart": 15, "lineNumberStop": 4, - "colNumberStop": 22, + "colNumberStop": 23, "offsetStart": 60, - "offsetEnd": 67, - "sourceText": "return 0" + "offsetEnd": 68, + "sourceText": "return 0;" } }, "content": "(assign fibonacci_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 49, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);return 0;return 0;return 0;return 0;" + } } }, { - "source": "__loc_1200", - "target": "fibonacci_final", + "source": "__loc_1166", + "target": "__loc_1181", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -226,22 +439,34 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 5, - "colNumberStart": 20, - "lineNumberStop": 5, - "colNumberStop": 27, - "offsetStart": 90, - "offsetEnd": 97, - "sourceText": "return 1" + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 49, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);" } }, - "content": "(assign fibonacci_ret 1)" + "content": "((assume (\u003d (ite (\u003d fibonacci::i 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 4, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 49, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 0) return 0;\n else if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);" + } } }, { - "source": "__loc_1217", + "source": "__loc_1181", "target": "fibonacci_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -255,52 +480,51 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, + "lineNumberStart": 5, "colNumberStart": 9, "lineNumberStop": 6, - "colNumberStop": 46, - "offsetStart": 109, - "offsetEnd": 146, - "sourceText": "return fibonacci(i-1) + fibonacci(i-2)" + "colNumberStop": 47, + "offsetStart": 79, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);" } }, - "content": "(assign fibonacci_ret (+ call_fibonacci_ret73 call_fibonacci_ret74))" - } - ] - } - }, - { - "source": "__loc_1179", - "target": "__loc_1185", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "((assume (/\u003d (ite (\u003d fibonacci::i 1) 1 0) 0)))[choiceType\u003dMAIN_PATH]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 12, - "offsetStart": 52, - "offsetEnd": 57, - "sourceText": "i \u003d\u003d 0" + "lineNumberStart": 5, + "colNumberStart": 20, + "lineNumberStop": 5, + "colNumberStop": 28, + "offsetStart": 90, + "offsetEnd": 98, + "sourceText": "return 1;" } }, - "content": "(assume (/\u003d (ite (\u003d fibonacci::i 0) 1 0) 0))" + "content": "(assign fibonacci_ret 1)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 79, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);return 1;return 1;return 1;return 1;" + } } }, { - "source": "__loc_1179", - "target": "__loc_1194", + "source": "__loc_1181", + "target": "__loc_1198", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -313,52 +537,59 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 12, - "offsetStart": 52, - "offsetEnd": 57, - "sourceText": "i \u003d\u003d 0" + "lineNumberStart": 5, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 79, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);" } }, - "content": "(assume (\u003d (ite (\u003d fibonacci::i 0) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003d fibonacci::i 1) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 79, + "offsetEnd": 147, + "sourceText": "if(i \u003d\u003d 1) return 1;\n else return fibonacci(i-1) + fibonacci(i-2);return fibonacci(i-1) + fibonacci(i-2);return fibonacci(i-1) + fibonacci(i-2);return fibonacci(i-1) + fibonacci(i-2);return fibonacci(i-1) + fibonacci(i-2);return fibonacci(i-1) + fibonacci(i-2);" + } } }, { - "source": "__loc_1194", - "target": "__loc_1200", + "source": "__loc_1195", + "target": "__loc_1203", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", "content": {} }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 5, - "colNumberStart": 12, - "lineNumberStop": 5, - "colNumberStop": 17, - "offsetStart": 82, - "offsetEnd": 87, - "sourceText": "i \u003d\u003d 1" - } - }, - "content": "(assume (/\u003d (ite (\u003d fibonacci::i 1) 1 0) 0))" - } - ] + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);return fibonacci(i-1) + fibonacci(i-2);" + } } }, { - "source": "__loc_1194", - "target": "__loc_1211", + "source": "__loc_1200", + "target": "fibonacci_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -371,18 +602,30 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 5, - "colNumberStart": 12, - "lineNumberStop": 5, - "colNumberStop": 17, - "offsetStart": 82, - "offsetEnd": 87, - "sourceText": "i \u003d\u003d 1" + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" } }, - "content": "(assume (\u003d (ite (\u003d fibonacci::i 1) 1 0) 0))" + "content": "(assign fibonacci_ret (+ call_fibonacci_ret73 call_fibonacci_ret74))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 9, + "lineNumberStop": 6, + "colNumberStop": 47, + "offsetStart": 109, + "offsetEnd": 147, + "sourceText": "return fibonacci(i-1) + fibonacci(i-2);" + } } } ] @@ -405,22 +648,101 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "call_fibonacci_ret75", "type": "Int" + }, + { + "name": "call_reach_error_ret76", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1228 ", - "__loc_1231 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 0, + "offsetStart": 152, + "offsetEnd": 207, + "sourceText": "int main() {\n if(fibonacci(8) !\u003d 21) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 0, + "offsetStart": 152, + "offsetEnd": 207, + "sourceText": "int main() {\n if(fibonacci(8) !\u003d 21) reach_error();\n}" + } + } + }, + { + "name": "__loc_1216", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 4, + "lineNumberStop": 10, + "colNumberStop": 40, + "offsetStart": 169, + "offsetEnd": 205, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();" + } + } + }, + { + "name": "__loc_1219", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_1231", - "target": "__loc_1228", + "source": "__loc_1219", + "target": "__loc_1216", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -434,33 +756,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 10, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 10, - "colNumberStop": 18, - "offsetStart": 172, - "offsetEnd": 183, - "sourceText": "fibonacci(8)" + "colNumberStop": 40, + "offsetStart": 169, + "offsetEnd": 205, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();" } }, "content": "fibonacci(call_fibonacci_ret75, 8)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 4, + "lineNumberStop": 10, + "colNumberStop": 40, + "offsetStart": 169, + "offsetEnd": 205, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();" + } } }, { - "source": "main_init", - "target": "__loc_1231", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] - } - }, - { - "source": "__loc_1228", + "source": "__loc_1216", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -475,21 +797,57 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 10, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 10, - "colNumberStop": 24, - "offsetStart": 172, - "offsetEnd": 189, - "sourceText": "fibonacci(8) !\u003d 21" + "colNumberStop": 40, + "offsetStart": 169, + "offsetEnd": 205, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();" } }, - "content": "(assume (\u003d (ite (/\u003d call_fibonacci_ret75 21) 1 0) 0))" + "content": "((assume (\u003d (ite (/\u003d call_fibonacci_ret75 21) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 40, + "offsetStart": 152, + "offsetEnd": 207, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();if(fibonacci(8) !\u003d 21) reach_error();int main() {\n if(fibonacci(8) !\u003d 21) reach_error();\n}" + } } }, { - "source": "__loc_1228", + "source": "main_init", + "target": "__loc_1219", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 40, + "offsetStart": 152, + "offsetEnd": 207, + "sourceText": "int main() {\n if(fibonacci(8) !\u003d 21) reach_error();\n}if(fibonacci(8) !\u003d 21) reach_error();if(fibonacci(8) !\u003d 21) reach_error();if(fibonacci(8) !\u003d 21) reach_error();if(fibonacci(8) !\u003d 21) reach_error();if(fibonacci(8) !\u003d 21) reach_error();if(fibonacci(8) !\u003d 21) reach_error();" + } + } + }, + { + "source": "__loc_1216", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -504,17 +862,29 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 10, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 10, - "colNumberStop": 24, - "offsetStart": 172, - "offsetEnd": 189, - "sourceText": "fibonacci(8) !\u003d 21" + "colNumberStop": 40, + "offsetStart": 169, + "offsetEnd": 205, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();" } }, - "content": "(assume (/\u003d (ite (/\u003d call_fibonacci_ret75 21) 1 0) 0))" + "content": "((assume (/\u003d (ite (/\u003d call_fibonacci_ret75 21) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 4, + "lineNumberStop": 10, + "colNumberStop": 40, + "offsetStart": 169, + "offsetEnd": 205, + "sourceText": "if(fibonacci(8) !\u003d 21) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/18multithread.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/18multithread.c.json index a349cae1e8..06e194a4dc 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/18multithread.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/18multithread.c.json @@ -36,27 +36,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1239 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1239", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 687, + "colNumberStart": 0, + "lineNumberStop": 687, + "colNumberStop": 19, + "offsetStart": 29546, + "offsetEnd": 29565, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1239", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 687, + "colNumberStart": 0, + "lineNumberStop": 687, + "colNumberStop": 19, + "offsetStart": 29546, + "offsetEnd": 29565, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -65,6 +91,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 687, + "colNumberStart": 0, + "lineNumberStop": 687, + "colNumberStop": 19, + "offsetStart": 29546, + "offsetEnd": 29565, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -99,34 +137,110 @@ } } ], - "vars": [], - "locs": [ - "thr1_init {init}", - "thr1_final {final}", - "__loc_1244 ", - "__loc_1254 ", - "__loc_1259 ", - "__loc_1265 ", - "__loc_1275 ", - "__loc_1280 ", - "__loc_1282 " + "vars": [ + { + "name": "thr1_ret", + "type": "Int" + }, + { + "name": "thr1::_", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret77", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret78", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret79", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret80", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "__loc_1282", - "target": "thr1_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "thr1_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 695, + "colNumberStart": 0, + "lineNumberStop": 702, + "colNumberStop": 0, + "offsetStart": 29670, + "offsetEnd": 29834, + "sourceText": "void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n x \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n x \u003d 2;\n __VERIFIER_atomic_end();\n}" + } } }, + { + "name": "thr1_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 695, + "colNumberStart": 0, + "lineNumberStop": 702, + "colNumberStop": 0, + "offsetStart": 29670, + "offsetEnd": 29834, + "sourceText": "void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n x \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n x \u003d 2;\n __VERIFIER_atomic_end();\n}" + } + } + }, + { + "name": "__loc_1234", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 696, + "colNumberStart": 4, + "lineNumberStop": 696, + "colNumberStop": 29, + "offsetStart": 29696, + "offsetEnd": 29721, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_1253", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 699, + "colNumberStart": 4, + "lineNumberStop": 699, + "colNumberStop": 29, + "offsetStart": 29767, + "offsetEnd": 29792, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + } + ], + "edges": [ { "source": "thr1_init", - "target": "__loc_1244", + "target": "__loc_1234", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -134,11 +248,23 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 695, + "colNumberStart": 0, + "lineNumberStop": 702, + "colNumberStop": 29, + "offsetStart": 29670, + "offsetEnd": 29834, + "sourceText": "void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n x \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n x \u003d 2;\n __VERIFIER_atomic_end();\n}__VERIFIER_atomic_begin();\n x \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n x \u003d 2;\n __VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_1254", - "target": "__loc_1259", + "source": "__loc_1234", + "target": "__loc_1253", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -147,85 +273,65 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 696, + "colNumberStart": 4, + "lineNumberStop": 696, + "colNumberStop": 29, + "offsetStart": 29696, + "offsetEnd": 29721, + "sourceText": "__VERIFIER_atomic_begin();" } }, - "content": "(assign x 1)" - } - ] - } - }, - { - "source": "__loc_1275", - "target": "__loc_1280", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "F[ATOMIC_BEGIN]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign x 2)" - } - ] - } - }, - { - "source": "__loc_1244", - "target": "__loc_1254", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign x 1)" + }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 693, + "lineNumberStart": 698, "colNumberStart": 4, - "lineNumberStop": 693, - "colNumberStop": 28, - "offsetStart": 29619, - "offsetEnd": 29643, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStop": 698, + "colNumberStop": 27, + "offsetStart": 29738, + "offsetEnd": 29761, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "F[ATOMIC_BEGIN]" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 696, + "colNumberStart": 4, + "lineNumberStop": 699, + "colNumberStop": 29, + "offsetStart": 29696, + "offsetEnd": 29792, + "sourceText": "__VERIFIER_atomic_begin();x \u003d 1;x \u003d 1;x \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_1259", - "target": "__loc_1265", + "source": "__loc_1253", + "target": "thr1_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -238,76 +344,56 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 695, + "lineNumberStart": 699, "colNumberStart": 4, - "lineNumberStop": 695, - "colNumberStop": 26, - "offsetStart": 29661, - "offsetEnd": 29683, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStop": 699, + "colNumberStop": 29, + "offsetStart": 29767, + "offsetEnd": 29792, + "sourceText": "__VERIFIER_atomic_begin();" } }, - "content": "F[ATOMIC_END]" - } - ] - } - }, - { - "source": "__loc_1265", - "target": "__loc_1275", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "F[ATOMIC_BEGIN]" + }, { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 696, - "colNumberStart": 4, - "lineNumberStop": 696, - "colNumberStop": 28, - "offsetStart": 29690, - "offsetEnd": 29714, - "sourceText": "__VERIFIER_atomic_begin()" + "sourceText": "" } }, - "content": "F[ATOMIC_BEGIN]" - } - ] - } - }, - { - "source": "__loc_1280", - "target": "__loc_1282", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign x 2)" + }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 698, + "lineNumberStart": 701, "colNumberStart": 4, - "lineNumberStop": 698, - "colNumberStop": 26, - "offsetStart": 29732, - "offsetEnd": 29754, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStop": 701, + "colNumberStop": 27, + "offsetStart": 29809, + "offsetEnd": 29832, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 695, + "colNumberStart": 0, + "lineNumberStop": 702, + "colNumberStop": 29, + "offsetStart": 29670, + "offsetEnd": 29834, + "sourceText": "__VERIFIER_atomic_begin();x \u003d 2;x \u003d 2;x \u003d 2;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n x \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n x \u003d 2;\n __VERIFIER_atomic_end();\n}" + } } } ] @@ -343,6 +429,14 @@ } ], "vars": [ + { + "name": "thr2_ret", + "type": "Int" + }, + { + "name": "thr2::_", + "type": "Int" + }, { "name": "thr2::i", "type": "Int" @@ -350,37 +444,132 @@ { "name": "thr2::j", "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret81", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret82", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret83", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret84", + "type": "Int" } ], "locs": [ - "thr2_init {init}", - "thr2_final {final}", - "__loc_1287 ", - "__loc_1295 ", - "__loc_1299 ", - "__loc_1305 ", - "__loc_1313 ", - "__loc_1317 ", - "__loc_1321 ", - "__loc_1326 ", - "__loc_1335 " - ], - "edges": [ { - "source": "__loc_1321", - "target": "thr2_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "thr2_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 704, + "colNumberStart": 0, + "lineNumberStop": 712, + "colNumberStop": 0, + "offsetStart": 29837, + "offsetEnd": 30033, + "sourceText": "void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n int i \u003d x;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int j \u003d x;\n __VERIFIER_atomic_end();\n if(i !\u003d j) ERR \u003d 1;\n}" + } + } + }, + { + "name": "thr2_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 704, + "colNumberStart": 0, + "lineNumberStop": 712, + "colNumberStop": 0, + "offsetStart": 29837, + "offsetEnd": 30033, + "sourceText": "void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n int i \u003d x;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int j \u003d x;\n __VERIFIER_atomic_end();\n if(i !\u003d j) ERR \u003d 1;\n}" + } } }, + { + "name": "__loc_1274", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 705, + "colNumberStart": 4, + "lineNumberStop": 705, + "colNumberStop": 29, + "offsetStart": 29863, + "offsetEnd": 29888, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_1292", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 708, + "colNumberStart": 4, + "lineNumberStop": 708, + "colNumberStop": 29, + "offsetStart": 29938, + "offsetEnd": 29963, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_1313", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1320", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 711, + "colNumberStart": 15, + "lineNumberStop": 711, + "colNumberStop": 22, + "offsetStart": 30024, + "offsetEnd": 30031, + "sourceText": "ERR \u003d 1;" + } + } + } + ], + "edges": [ { "source": "thr2_init", - "target": "__loc_1287", + "target": "__loc_1274", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -388,11 +577,23 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 704, + "colNumberStart": 0, + "lineNumberStop": 712, + "colNumberStop": 29, + "offsetStart": 29837, + "offsetEnd": 30033, + "sourceText": "void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n int i \u003d x;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int j \u003d x;\n __VERIFIER_atomic_end();\n if(i !\u003d j) ERR \u003d 1;\n}__VERIFIER_atomic_begin();\n int i \u003d x;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int j \u003d x;\n __VERIFIER_atomic_end();\n if(i !\u003d j) ERR \u003d 1;__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_1295", - "target": "__loc_1299", + "source": "__loc_1274", + "target": "__loc_1292", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -401,34 +602,21 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 703, + "lineNumberStart": 705, "colNumberStart": 4, - "lineNumberStop": 703, - "colNumberStop": 13, - "offsetStart": 29817, - "offsetEnd": 29826, - "sourceText": "int i \u003d x;" + "lineNumberStop": 705, + "colNumberStop": 29, + "offsetStart": 29863, + "offsetEnd": 29888, + "sourceText": "__VERIFIER_atomic_begin();" } }, - "content": "(assign thr2::i x)" - } - ] - } - }, - { - "source": "__loc_1313", - "target": "__loc_1317", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "F[ATOMIC_BEGIN]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -438,48 +626,47 @@ "colNumberStart": 4, "lineNumberStop": 706, "colNumberStop": 13, - "offsetStart": 29892, - "offsetEnd": 29901, - "sourceText": "int j \u003d x;" + "offsetStart": 29894, + "offsetEnd": 29903, + "sourceText": "int i \u003d x;" } }, - "content": "(assign thr2::j x)" - } - ] - } - }, - { - "source": "__loc_1326", - "target": "__loc_1335", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i x)" + }, { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 708, - "colNumberStart": 7, - "lineNumberStop": 708, - "colNumberStop": 12, - "offsetStart": 29939, - "offsetEnd": 29944, - "sourceText": "i !\u003d j" + "lineNumberStart": 707, + "colNumberStart": 4, + "lineNumberStop": 707, + "colNumberStop": 27, + "offsetStart": 29909, + "offsetEnd": 29932, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "(assume (/\u003d (ite (/\u003d thr2::i thr2::j) 1 0) 0))" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 705, + "colNumberStart": 4, + "lineNumberStop": 708, + "colNumberStop": 29, + "offsetStart": 29863, + "offsetEnd": 29963, + "sourceText": "__VERIFIER_atomic_begin();int i \u003d x;int i \u003d x;int i \u003d x;int i \u003d x;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_1326", - "target": "__loc_1321", + "source": "__loc_1292", + "target": "__loc_1313", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -488,85 +675,71 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 708, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 708, - "colNumberStop": 12, - "offsetStart": 29939, - "offsetEnd": 29944, - "sourceText": "i !\u003d j" + "colNumberStop": 29, + "offsetStart": 29938, + "offsetEnd": 29963, + "sourceText": "__VERIFIER_atomic_begin();" } }, - "content": "(assume (\u003d (ite (/\u003d thr2::i thr2::j) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_1335", - "target": "__loc_1321", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "F[ATOMIC_BEGIN]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 709, + "colNumberStart": 4, + "lineNumberStop": 709, + "colNumberStop": 13, + "offsetStart": 29969, + "offsetEnd": 29978, + "sourceText": "int j \u003d x;" } }, - "content": "(assign ERR 1)" - } - ] - } - }, - { - "source": "__loc_1287", - "target": "__loc_1295", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::j x)" + }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 702, + "lineNumberStart": 710, "colNumberStart": 4, - "lineNumberStop": 702, - "colNumberStop": 28, - "offsetStart": 29786, - "offsetEnd": 29810, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStop": 710, + "colNumberStop": 27, + "offsetStart": 29984, + "offsetEnd": 30007, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "F[ATOMIC_BEGIN]" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 708, + "colNumberStart": 4, + "lineNumberStop": 711, + "colNumberStop": 29, + "offsetStart": 29938, + "offsetEnd": 30031, + "sourceText": "__VERIFIER_atomic_begin();int j \u003d x;int j \u003d x;int j \u003d x;int j \u003d x;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();if(i !\u003d j) ERR \u003d 1;if(i !\u003d j) ERR \u003d 1;if(i !\u003d j) ERR \u003d 1;" + } } }, { - "source": "__loc_1299", - "target": "__loc_1305", + "source": "__loc_1313", + "target": "__loc_1320", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -575,27 +748,39 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 704, + "lineNumberStart": 711, "colNumberStart": 4, - "lineNumberStop": 704, - "colNumberStop": 26, - "offsetStart": 29832, - "offsetEnd": 29854, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStop": 711, + "colNumberStop": 22, + "offsetStart": 30013, + "offsetEnd": 30031, + "sourceText": "if(i !\u003d j) ERR \u003d 1;" } }, - "content": "F[ATOMIC_END]" + "content": "((assume (/\u003d (ite (/\u003d thr2::i thr2::j) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 711, + "colNumberStart": 4, + "lineNumberStop": 711, + "colNumberStop": 22, + "offsetStart": 30013, + "offsetEnd": 30031, + "sourceText": "if(i !\u003d j) ERR \u003d 1;ERR \u003d 1;ERR \u003d 1;ERR \u003d 1;" + } } }, { - "source": "__loc_1305", - "target": "__loc_1313", + "source": "__loc_1313", + "target": "thr2_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -604,27 +789,39 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 705, + "lineNumberStart": 711, "colNumberStart": 4, - "lineNumberStop": 705, - "colNumberStop": 28, - "offsetStart": 29861, - "offsetEnd": 29885, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStop": 711, + "colNumberStop": 22, + "offsetStart": 30013, + "offsetEnd": 30031, + "sourceText": "if(i !\u003d j) ERR \u003d 1;" } }, - "content": "F[ATOMIC_BEGIN]" + "content": "((assume (\u003d (ite (/\u003d thr2::i thr2::j) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 704, + "colNumberStart": 0, + "lineNumberStop": 712, + "colNumberStop": 22, + "offsetStart": 29837, + "offsetEnd": 30033, + "sourceText": "if(i !\u003d j) ERR \u003d 1;if(i !\u003d j) ERR \u003d 1;void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n int i \u003d x;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int j \u003d x;\n __VERIFIER_atomic_end();\n if(i !\u003d j) ERR \u003d 1;\n}" + } } }, { - "source": "__loc_1317", - "target": "__loc_1326", + "source": "__loc_1320", + "target": "thr2_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -633,22 +830,28 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 707, - "colNumberStart": 4, - "lineNumberStop": 707, - "colNumberStop": 26, - "offsetStart": 29907, - "offsetEnd": 29929, - "sourceText": "__VERIFIER_atomic_end()" + "sourceText": "" } }, - "content": "F[ATOMIC_END]" + "content": "(assign ERR 1)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 712, + "colNumberStop": 22, + "offsetStart": 0, + "offsetEnd": 30033, + "sourceText": "if(i !\u003d j) ERR \u003d 1;void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n int i \u003d x;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int j \u003d x;\n __VERIFIER_atomic_end();\n if(i !\u003d j) ERR \u003d 1;\n}" + } } } ] @@ -671,6 +874,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::t1", "type": "Int" @@ -680,22 +887,106 @@ "type": "Int" }, { - "name": "main_ret", + "name": "call_pthread_create_ret85", + "type": "Int" + }, + { + "name": "call_pthread_create_ret86", + "type": "Int" + }, + { + "name": "call_reach_error_ret87", "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1360 ", - "__loc_1378 ", - "__loc_1386 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 0, + "lineNumberStop": 720, + "colNumberStop": 0, + "offsetStart": 30036, + "offsetEnd": 30186, + "sourceText": "int main() {\n pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(ERR) reach_error();\n return 0;\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 0, + "lineNumberStop": 720, + "colNumberStop": 0, + "offsetStart": 30036, + "offsetEnd": 30186, + "sourceText": "int main() {\n pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(ERR) reach_error();\n return 0;\n}" + } + } + }, + { + "name": "__loc_1345", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1363", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1371", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_1360", - "target": "__loc_1378", + "source": "main_init", + "target": "__loc_1345", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -704,27 +995,59 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StartLabel", + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign x 0)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign ERR 0)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 713, - "colNumberStart": 4, - "lineNumberStop": 713, - "colNumberStop": 34, - "offsetStart": 29998, - "offsetEnd": 30028, - "sourceText": "pthread_create(\u0026t1, 0, thr1, 0)" + "sourceText": "" + } + }, + "content": "((assume (and (\u003e\u003d main::t1 0) (\u003c\u003d main::t1 18446744073709551615))))[choiceType\u003dMAIN_PATH]" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" } }, - "content": "(var main::t1 Int) \u003d start thr1(0)" + "content": "((assume (and (\u003e\u003d main::t2 0) (\u003c\u003d main::t2 18446744073709551615))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 0, + "lineNumberStop": 720, + "colNumberStop": 35, + "offsetStart": 30036, + "offsetEnd": 30186, + "sourceText": "int main() {\n pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(ERR) reach_error();\n return 0;\n}pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(ERR) reach_error();\n return 0;pthread_t t1, t2;pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);" + } } }, { - "source": "__loc_1378", - "target": "__loc_1386", + "source": "__loc_1345", + "target": "__loc_1363", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -737,23 +1060,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 714, + "lineNumberStart": 716, "colNumberStart": 4, - "lineNumberStop": 714, - "colNumberStop": 34, - "offsetStart": 30035, - "offsetEnd": 30065, - "sourceText": "pthread_create(\u0026t2, 0, thr2, 0)" + "lineNumberStop": 716, + "colNumberStop": 35, + "offsetStart": 30075, + "offsetEnd": 30106, + "sourceText": "pthread_create(\u0026t1, 0, thr1, 0);" } }, - "content": "(var main::t2 Int) \u003d start thr2(0)" + "content": "(var main::t1 Int) \u003d start thr1(0, 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 716, + "colNumberStart": 4, + "lineNumberStop": 717, + "colNumberStop": 35, + "offsetStart": 30075, + "offsetEnd": 30143, + "sourceText": "pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);" + } } }, { - "source": "main_init", - "target": "__loc_1360", + "source": "__loc_1363", + "target": "__loc_1371", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -762,58 +1097,38 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "content": "(assign x 0)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "content": "(assign ERR 0)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" - } - }, - "content": "(assume (and (\u003e\u003d main::t1 0) (\u003c\u003d main::t1 4294967295)))" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.StartLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 717, + "colNumberStart": 4, + "lineNumberStop": 717, + "colNumberStop": 35, + "offsetStart": 30112, + "offsetEnd": 30143, + "sourceText": "pthread_create(\u0026t2, 0, thr2, 0);" } }, - "content": "(assume (and (\u003e\u003d main::t2 0) (\u003c\u003d main::t2 4294967295)))" + "content": "(var main::t2 Int) \u003d start thr2(0, 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 717, + "colNumberStart": 4, + "lineNumberStop": 718, + "colNumberStop": 35, + "offsetStart": 30112, + "offsetEnd": 30170, + "sourceText": "pthread_create(\u0026t2, 0, thr2, 0);if(ERR) reach_error();if(ERR) reach_error();if(ERR) reach_error();" + } } }, { - "source": "__loc_1386", + "source": "__loc_1371", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -827,22 +1142,34 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 715, - "colNumberStart": 7, - "lineNumberStop": 715, - "colNumberStop": 9, - "offsetStart": 30075, - "offsetEnd": 30077, - "sourceText": "ERR" + "lineNumberStart": 718, + "colNumberStart": 4, + "lineNumberStop": 718, + "colNumberStop": 25, + "offsetStart": 30149, + "offsetEnd": 30170, + "sourceText": "if(ERR) reach_error();" } }, - "content": "(assume (/\u003d ERR 0))" + "content": "((assume (/\u003d ERR 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 718, + "colNumberStart": 4, + "lineNumberStop": 718, + "colNumberStop": 25, + "offsetStart": 30149, + "offsetEnd": 30170, + "sourceText": "if(ERR) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { - "source": "__loc_1386", + "source": "__loc_1371", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -856,34 +1183,46 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 715, - "colNumberStart": 7, - "lineNumberStop": 715, - "colNumberStop": 9, - "offsetStart": 30075, - "offsetEnd": 30077, - "sourceText": "ERR" + "lineNumberStart": 718, + "colNumberStart": 4, + "lineNumberStop": 718, + "colNumberStop": 25, + "offsetStart": 30149, + "offsetEnd": 30170, + "sourceText": "if(ERR) reach_error();" } }, - "content": "(assume (\u003d ERR 0))" + "content": "((assume (\u003d ERR 0)))[choiceType\u003dALTERNATIVE_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 716, + "lineNumberStart": 719, "colNumberStart": 4, - "lineNumberStop": 716, - "colNumberStop": 11, - "offsetStart": 30099, - "offsetEnd": 30106, - "sourceText": "return 0" + "lineNumberStop": 719, + "colNumberStop": 12, + "offsetStart": 30176, + "offsetEnd": 30184, + "sourceText": "return 0;" } }, "content": "(assign main_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 718, + "colNumberStart": 4, + "lineNumberStop": 719, + "colNumberStop": 25, + "offsetStart": 30149, + "offsetEnd": 30184, + "sourceText": "if(ERR) reach_error();if(ERR) reach_error();return 0;return 0;return 0;return 0;" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/19dportest.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/19dportest.c.json index a433145440..e9a678d6c3 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/19dportest.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/19dportest.c.json @@ -28,27 +28,53 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_1400 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "reach_error_init", - "target": "__loc_1400", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 687, + "colNumberStart": 0, + "lineNumberStop": 687, + "colNumberStop": 19, + "offsetStart": 29546, + "offsetEnd": 29565, + "sourceText": "void reach_error(){}" + } } }, { - "source": "__loc_1400", + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 687, + "colNumberStart": 0, + "lineNumberStop": 687, + "colNumberStop": 19, + "offsetStart": 29546, + "offsetEnd": 29565, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -57,6 +83,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 687, + "colNumberStart": 0, + "lineNumberStop": 687, + "colNumberStop": 19, + "offsetStart": 29546, + "offsetEnd": 29565, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } } } ] @@ -92,86 +130,79 @@ } ], "vars": [ + { + "name": "thr1_ret", + "type": "Int" + }, + { + "name": "thr1::_", + "type": "Int" + }, { "name": "thr1::i", "type": "Int" } ], "locs": [ - "thr1_init {init}", - "thr1_final {final}", - "__loc_1407 ", - "__loc_1412 ", - "__loc_1418 ", - "__loc_1424 ", - "__loc_1430 ", - "__loc_1436 ", - "__loc_1442 ", - "__loc_1448 ", - "__loc_1454 ", - "__loc_1460 ", - "__loc_1466 ", - "__loc_1472 ", - "__loc_1478 ", - "__loc_1484 ", - "__loc_1490 ", - "__loc_1496 ", - "__loc_1502 ", - "__loc_1508 ", - "__loc_1514 ", - "__loc_1520 ", - "__loc_1526 ", - "__loc_1532 ", - "__loc_1538 ", - "__loc_1544 ", - "__loc_1550 ", - "__loc_1556 ", - "__loc_1562 ", - "__loc_1568 ", - "__loc_1574 ", - "__loc_1580 ", - "__loc_1586 ", - "__loc_1592 ", - "__loc_1598 ", - "__loc_1604 ", - "__loc_1610 ", - "__loc_1616 ", - "__loc_1622 ", - "__loc_1628 ", - "__loc_1634 ", - "__loc_1640 ", - "__loc_1646 ", - "__loc_1655 ", - "__loc_1656 " - ], - "edges": [ { - "source": "__loc_1656", - "target": "thr1_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "thr1_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 691, + "colNumberStart": 0, + "lineNumberStop": 734, + "colNumberStop": 0, + "offsetStart": 29580, + "offsetEnd": 29989, + "sourceText": "void *thr1(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}" + } } }, { - "source": "thr1_init", - "target": "__loc_1407", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "thr1_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 691, + "colNumberStart": 0, + "lineNumberStop": 734, + "colNumberStop": 0, + "offsetStart": 29580, + "offsetEnd": 29989, + "sourceText": "void *thr1(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}" + } } }, { - "source": "__loc_1407", - "target": "__loc_1412", + "name": "__loc_1640", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 733, + "colNumberStart": 4, + "lineNumberStop": 733, + "colNumberStop": 10, + "offsetStart": 29981, + "offsetEnd": 29987, + "sourceText": "x +\u003d i;" + } + } + } + ], + "edges": [ + { + "source": "thr1_init", + "target": "__loc_1640", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -194,20 +225,7 @@ } }, "content": "(assign thr1::i 0)" - } - ] - } - }, - { - "source": "__loc_1412", - "target": "__loc_1418", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -216,27 +234,14 @@ "lineNumberStart": 693, "colNumberStart": 4, "lineNumberStop": 693, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29621, - "offsetEnd": 29623, - "sourceText": "i++" + "offsetEnd": 29624, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1418", - "target": "__loc_1424", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 1)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -245,27 +250,14 @@ "lineNumberStart": 694, "colNumberStart": 4, "lineNumberStop": 694, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29630, - "offsetEnd": 29632, - "sourceText": "i++" + "offsetEnd": 29633, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1424", - "target": "__loc_1430", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 2)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -274,27 +266,14 @@ "lineNumberStart": 695, "colNumberStart": 4, "lineNumberStop": 695, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29639, - "offsetEnd": 29641, - "sourceText": "i++" + "offsetEnd": 29642, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1430", - "target": "__loc_1436", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 3)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -303,27 +282,14 @@ "lineNumberStart": 696, "colNumberStart": 4, "lineNumberStop": 696, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29648, - "offsetEnd": 29650, - "sourceText": "i++" + "offsetEnd": 29651, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1436", - "target": "__loc_1442", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 4)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -332,27 +298,14 @@ "lineNumberStart": 697, "colNumberStart": 4, "lineNumberStop": 697, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29657, - "offsetEnd": 29659, - "sourceText": "i++" + "offsetEnd": 29660, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1442", - "target": "__loc_1448", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 5)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -361,27 +314,14 @@ "lineNumberStart": 698, "colNumberStart": 4, "lineNumberStop": 698, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29666, - "offsetEnd": 29668, - "sourceText": "i++" + "offsetEnd": 29669, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1448", - "target": "__loc_1454", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 6)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -390,27 +330,14 @@ "lineNumberStart": 699, "colNumberStart": 4, "lineNumberStop": 699, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29675, - "offsetEnd": 29677, - "sourceText": "i++" + "offsetEnd": 29678, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1454", - "target": "__loc_1460", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 7)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -419,27 +346,14 @@ "lineNumberStart": 700, "colNumberStart": 4, "lineNumberStop": 700, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29684, - "offsetEnd": 29686, - "sourceText": "i++" + "offsetEnd": 29687, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1460", - "target": "__loc_1466", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 8)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -448,27 +362,14 @@ "lineNumberStart": 701, "colNumberStart": 4, "lineNumberStop": 701, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29693, - "offsetEnd": 29695, - "sourceText": "i++" + "offsetEnd": 29696, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1466", - "target": "__loc_1472", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 9)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -477,27 +378,14 @@ "lineNumberStart": 702, "colNumberStart": 4, "lineNumberStop": 702, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29702, - "offsetEnd": 29704, - "sourceText": "i++" + "offsetEnd": 29705, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1472", - "target": "__loc_1478", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 10)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -506,27 +394,14 @@ "lineNumberStart": 703, "colNumberStart": 4, "lineNumberStop": 703, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29711, - "offsetEnd": 29713, - "sourceText": "i++" + "offsetEnd": 29714, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1478", - "target": "__loc_1484", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 11)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -535,27 +410,14 @@ "lineNumberStart": 704, "colNumberStart": 4, "lineNumberStop": 704, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29720, - "offsetEnd": 29722, - "sourceText": "i++" + "offsetEnd": 29723, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1484", - "target": "__loc_1490", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 12)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -564,27 +426,14 @@ "lineNumberStart": 705, "colNumberStart": 4, "lineNumberStop": 705, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29729, - "offsetEnd": 29731, - "sourceText": "i++" + "offsetEnd": 29732, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1490", - "target": "__loc_1496", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 13)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -593,27 +442,14 @@ "lineNumberStart": 706, "colNumberStart": 4, "lineNumberStop": 706, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29738, - "offsetEnd": 29740, - "sourceText": "i++" + "offsetEnd": 29741, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1496", - "target": "__loc_1502", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 14)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -622,27 +458,14 @@ "lineNumberStart": 707, "colNumberStart": 4, "lineNumberStop": 707, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29747, - "offsetEnd": 29749, - "sourceText": "i++" + "offsetEnd": 29750, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1502", - "target": "__loc_1508", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 15)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -651,27 +474,14 @@ "lineNumberStart": 708, "colNumberStart": 4, "lineNumberStop": 708, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29756, - "offsetEnd": 29758, - "sourceText": "i++" + "offsetEnd": 29759, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1508", - "target": "__loc_1514", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 16)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -680,27 +490,14 @@ "lineNumberStart": 709, "colNumberStart": 4, "lineNumberStop": 709, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29765, - "offsetEnd": 29767, - "sourceText": "i++" + "offsetEnd": 29768, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1514", - "target": "__loc_1520", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 17)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -709,27 +506,14 @@ "lineNumberStart": 710, "colNumberStart": 4, "lineNumberStop": 710, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29774, - "offsetEnd": 29776, - "sourceText": "i++" + "offsetEnd": 29777, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1520", - "target": "__loc_1526", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 18)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -738,27 +522,14 @@ "lineNumberStart": 711, "colNumberStart": 4, "lineNumberStop": 711, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29783, - "offsetEnd": 29785, - "sourceText": "i++" + "offsetEnd": 29786, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1526", - "target": "__loc_1532", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 19)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -767,27 +538,14 @@ "lineNumberStart": 712, "colNumberStart": 4, "lineNumberStop": 712, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29792, - "offsetEnd": 29794, - "sourceText": "i++" + "offsetEnd": 29795, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1532", - "target": "__loc_1538", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 20)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -796,27 +554,14 @@ "lineNumberStart": 713, "colNumberStart": 4, "lineNumberStop": 713, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29801, - "offsetEnd": 29803, - "sourceText": "i++" + "offsetEnd": 29804, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1538", - "target": "__loc_1544", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 21)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -825,27 +570,14 @@ "lineNumberStart": 714, "colNumberStart": 4, "lineNumberStop": 714, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29810, - "offsetEnd": 29812, - "sourceText": "i++" + "offsetEnd": 29813, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1544", - "target": "__loc_1550", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 22)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -854,27 +586,14 @@ "lineNumberStart": 715, "colNumberStart": 4, "lineNumberStop": 715, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29819, - "offsetEnd": 29821, - "sourceText": "i++" + "offsetEnd": 29822, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1550", - "target": "__loc_1556", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 23)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -883,27 +602,14 @@ "lineNumberStart": 716, "colNumberStart": 4, "lineNumberStop": 716, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29828, - "offsetEnd": 29830, - "sourceText": "i++" + "offsetEnd": 29831, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1556", - "target": "__loc_1562", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 24)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -912,27 +618,14 @@ "lineNumberStart": 717, "colNumberStart": 4, "lineNumberStop": 717, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29837, - "offsetEnd": 29839, - "sourceText": "i++" + "offsetEnd": 29840, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1562", - "target": "__loc_1568", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 25)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -941,27 +634,14 @@ "lineNumberStart": 718, "colNumberStart": 4, "lineNumberStop": 718, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29846, - "offsetEnd": 29848, - "sourceText": "i++" + "offsetEnd": 29849, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1568", - "target": "__loc_1574", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 26)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -970,27 +650,14 @@ "lineNumberStart": 719, "colNumberStart": 4, "lineNumberStop": 719, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29855, - "offsetEnd": 29857, - "sourceText": "i++" + "offsetEnd": 29858, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1574", - "target": "__loc_1580", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 27)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -999,27 +666,14 @@ "lineNumberStart": 720, "colNumberStart": 4, "lineNumberStop": 720, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29864, - "offsetEnd": 29866, - "sourceText": "i++" + "offsetEnd": 29867, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1580", - "target": "__loc_1586", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 28)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1028,27 +682,14 @@ "lineNumberStart": 721, "colNumberStart": 4, "lineNumberStop": 721, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29873, - "offsetEnd": 29875, - "sourceText": "i++" + "offsetEnd": 29876, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1586", - "target": "__loc_1592", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 29)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1057,27 +698,14 @@ "lineNumberStart": 722, "colNumberStart": 4, "lineNumberStop": 722, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29882, - "offsetEnd": 29884, - "sourceText": "i++" + "offsetEnd": 29885, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1592", - "target": "__loc_1598", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 30)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1086,27 +714,14 @@ "lineNumberStart": 723, "colNumberStart": 4, "lineNumberStop": 723, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29891, - "offsetEnd": 29893, - "sourceText": "i++" + "offsetEnd": 29894, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1598", - "target": "__loc_1604", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 31)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1115,27 +730,14 @@ "lineNumberStart": 724, "colNumberStart": 4, "lineNumberStop": 724, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29900, - "offsetEnd": 29902, - "sourceText": "i++" + "offsetEnd": 29903, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1604", - "target": "__loc_1610", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 32)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1144,27 +746,14 @@ "lineNumberStart": 725, "colNumberStart": 4, "lineNumberStop": 725, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29909, - "offsetEnd": 29911, - "sourceText": "i++" + "offsetEnd": 29912, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1610", - "target": "__loc_1616", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 33)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1173,27 +762,14 @@ "lineNumberStart": 726, "colNumberStart": 4, "lineNumberStop": 726, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29918, - "offsetEnd": 29920, - "sourceText": "i++" + "offsetEnd": 29921, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1616", - "target": "__loc_1622", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 34)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1202,27 +778,14 @@ "lineNumberStart": 727, "colNumberStart": 4, "lineNumberStop": 727, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29927, - "offsetEnd": 29929, - "sourceText": "i++" + "offsetEnd": 29930, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1622", - "target": "__loc_1628", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 35)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1231,27 +794,14 @@ "lineNumberStart": 728, "colNumberStart": 4, "lineNumberStop": 728, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29936, - "offsetEnd": 29938, - "sourceText": "i++" + "offsetEnd": 29939, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1628", - "target": "__loc_1634", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 36)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1260,27 +810,14 @@ "lineNumberStart": 729, "colNumberStart": 4, "lineNumberStop": 729, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29945, - "offsetEnd": 29947, - "sourceText": "i++" + "offsetEnd": 29948, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1634", - "target": "__loc_1640", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 37)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1289,27 +826,14 @@ "lineNumberStart": 730, "colNumberStart": 4, "lineNumberStop": 730, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29954, - "offsetEnd": 29956, - "sourceText": "i++" + "offsetEnd": 29957, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1640", - "target": "__loc_1646", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 38)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1318,27 +842,14 @@ "lineNumberStart": 731, "colNumberStart": 4, "lineNumberStop": 731, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29963, - "offsetEnd": 29965, - "sourceText": "i++" + "offsetEnd": 29966, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" - } - ] - } - }, - { - "source": "__loc_1646", - "target": "__loc_1655", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr1::i 39)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1347,20 +858,32 @@ "lineNumberStart": 732, "colNumberStart": 4, "lineNumberStop": 732, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 29972, - "offsetEnd": 29974, - "sourceText": "i++" + "offsetEnd": 29975, + "sourceText": "i++;" } }, - "content": "(assign thr1::i (+ thr1::i 1))" + "content": "(assign thr1::i 40)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 691, + "colNumberStart": 0, + "lineNumberStop": 734, + "colNumberStop": 13, + "offsetStart": 29580, + "offsetEnd": 29989, + "sourceText": "void *thr1(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;int i \u003d 0;int i \u003d 0;int i \u003d 0;int i \u003d 0;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;x +\u003d i;x +\u003d i;x +\u003d i;" + } } }, { - "source": "__loc_1655", - "target": "__loc_1656", + "source": "__loc_1640", + "target": "thr1_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1373,18 +896,24 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign x (+ x thr1::i))" + "content": "(assign x (+ x 40))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 734, + "colNumberStop": 0, + "offsetStart": 0, + "offsetEnd": 29989, + "sourceText": "void *thr1(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}" + } } } ] @@ -1420,86 +949,79 @@ } ], "vars": [ + { + "name": "thr2_ret", + "type": "Int" + }, + { + "name": "thr2::_", + "type": "Int" + }, { "name": "thr2::i", "type": "Int" } ], "locs": [ - "thr2_init {init}", - "thr2_final {final}", - "__loc_1663 ", - "__loc_1668 ", - "__loc_1674 ", - "__loc_1680 ", - "__loc_1686 ", - "__loc_1692 ", - "__loc_1698 ", - "__loc_1704 ", - "__loc_1710 ", - "__loc_1716 ", - "__loc_1722 ", - "__loc_1728 ", - "__loc_1734 ", - "__loc_1740 ", - "__loc_1746 ", - "__loc_1752 ", - "__loc_1758 ", - "__loc_1764 ", - "__loc_1770 ", - "__loc_1776 ", - "__loc_1782 ", - "__loc_1788 ", - "__loc_1794 ", - "__loc_1800 ", - "__loc_1806 ", - "__loc_1812 ", - "__loc_1818 ", - "__loc_1824 ", - "__loc_1830 ", - "__loc_1836 ", - "__loc_1842 ", - "__loc_1848 ", - "__loc_1854 ", - "__loc_1860 ", - "__loc_1866 ", - "__loc_1872 ", - "__loc_1878 ", - "__loc_1884 ", - "__loc_1890 ", - "__loc_1896 ", - "__loc_1902 ", - "__loc_1911 ", - "__loc_1912 " - ], - "edges": [ { - "source": "__loc_1912", - "target": "thr2_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "thr2_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 736, + "colNumberStart": 0, + "lineNumberStop": 779, + "colNumberStop": 0, + "offsetStart": 29992, + "offsetEnd": 30401, + "sourceText": "void *thr2(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}" + } } }, { - "source": "thr2_init", - "target": "__loc_1663", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "thr2_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 736, + "colNumberStart": 0, + "lineNumberStop": 779, + "colNumberStop": 0, + "offsetStart": 29992, + "offsetEnd": 30401, + "sourceText": "void *thr2(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}" + } } }, { - "source": "__loc_1663", - "target": "__loc_1668", + "name": "__loc_1895", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 778, + "colNumberStart": 4, + "lineNumberStop": 778, + "colNumberStop": 10, + "offsetStart": 30393, + "offsetEnd": 30399, + "sourceText": "x +\u003d i;" + } + } + } + ], + "edges": [ + { + "source": "thr2_init", + "target": "__loc_1895", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1522,20 +1044,7 @@ } }, "content": "(assign thr2::i 0)" - } - ] - } - }, - { - "source": "__loc_1668", - "target": "__loc_1674", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1544,27 +1053,14 @@ "lineNumberStart": 738, "colNumberStart": 4, "lineNumberStop": 738, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30033, - "offsetEnd": 30035, - "sourceText": "i++" + "offsetEnd": 30036, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1674", - "target": "__loc_1680", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 1)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1573,27 +1069,14 @@ "lineNumberStart": 739, "colNumberStart": 4, "lineNumberStop": 739, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30042, - "offsetEnd": 30044, - "sourceText": "i++" + "offsetEnd": 30045, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1680", - "target": "__loc_1686", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 2)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1602,27 +1085,14 @@ "lineNumberStart": 740, "colNumberStart": 4, "lineNumberStop": 740, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30051, - "offsetEnd": 30053, - "sourceText": "i++" + "offsetEnd": 30054, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1686", - "target": "__loc_1692", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 3)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1631,27 +1101,14 @@ "lineNumberStart": 741, "colNumberStart": 4, "lineNumberStop": 741, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30060, - "offsetEnd": 30062, - "sourceText": "i++" + "offsetEnd": 30063, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1692", - "target": "__loc_1698", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 4)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1660,27 +1117,14 @@ "lineNumberStart": 742, "colNumberStart": 4, "lineNumberStop": 742, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30069, - "offsetEnd": 30071, - "sourceText": "i++" + "offsetEnd": 30072, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1698", - "target": "__loc_1704", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 5)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1689,27 +1133,14 @@ "lineNumberStart": 743, "colNumberStart": 4, "lineNumberStop": 743, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30078, - "offsetEnd": 30080, - "sourceText": "i++" + "offsetEnd": 30081, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1704", - "target": "__loc_1710", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 6)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1718,27 +1149,14 @@ "lineNumberStart": 744, "colNumberStart": 4, "lineNumberStop": 744, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30087, - "offsetEnd": 30089, - "sourceText": "i++" + "offsetEnd": 30090, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1710", - "target": "__loc_1716", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 7)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1747,27 +1165,14 @@ "lineNumberStart": 745, "colNumberStart": 4, "lineNumberStop": 745, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30096, - "offsetEnd": 30098, - "sourceText": "i++" + "offsetEnd": 30099, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1716", - "target": "__loc_1722", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 8)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1776,27 +1181,14 @@ "lineNumberStart": 746, "colNumberStart": 4, "lineNumberStop": 746, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30105, - "offsetEnd": 30107, - "sourceText": "i++" + "offsetEnd": 30108, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1722", - "target": "__loc_1728", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 9)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1805,27 +1197,14 @@ "lineNumberStart": 747, "colNumberStart": 4, "lineNumberStop": 747, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30114, - "offsetEnd": 30116, - "sourceText": "i++" + "offsetEnd": 30117, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1728", - "target": "__loc_1734", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 10)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1834,27 +1213,14 @@ "lineNumberStart": 748, "colNumberStart": 4, "lineNumberStop": 748, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30123, - "offsetEnd": 30125, - "sourceText": "i++" + "offsetEnd": 30126, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1734", - "target": "__loc_1740", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 11)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1863,27 +1229,14 @@ "lineNumberStart": 749, "colNumberStart": 4, "lineNumberStop": 749, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30132, - "offsetEnd": 30134, - "sourceText": "i++" + "offsetEnd": 30135, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1740", - "target": "__loc_1746", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 12)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1892,27 +1245,14 @@ "lineNumberStart": 750, "colNumberStart": 4, "lineNumberStop": 750, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30141, - "offsetEnd": 30143, - "sourceText": "i++" + "offsetEnd": 30144, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1746", - "target": "__loc_1752", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 13)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1921,27 +1261,14 @@ "lineNumberStart": 751, "colNumberStart": 4, "lineNumberStop": 751, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30150, - "offsetEnd": 30152, - "sourceText": "i++" + "offsetEnd": 30153, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1752", - "target": "__loc_1758", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 14)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1950,27 +1277,14 @@ "lineNumberStart": 752, "colNumberStart": 4, "lineNumberStop": 752, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30159, - "offsetEnd": 30161, - "sourceText": "i++" + "offsetEnd": 30162, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1758", - "target": "__loc_1764", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 15)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -1979,27 +1293,14 @@ "lineNumberStart": 753, "colNumberStart": 4, "lineNumberStop": 753, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30168, - "offsetEnd": 30170, - "sourceText": "i++" + "offsetEnd": 30171, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1764", - "target": "__loc_1770", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 16)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2008,27 +1309,14 @@ "lineNumberStart": 754, "colNumberStart": 4, "lineNumberStop": 754, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30177, - "offsetEnd": 30179, - "sourceText": "i++" + "offsetEnd": 30180, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1770", - "target": "__loc_1776", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 17)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2037,27 +1325,14 @@ "lineNumberStart": 755, "colNumberStart": 4, "lineNumberStop": 755, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30186, - "offsetEnd": 30188, - "sourceText": "i++" + "offsetEnd": 30189, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1776", - "target": "__loc_1782", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 18)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2066,27 +1341,14 @@ "lineNumberStart": 756, "colNumberStart": 4, "lineNumberStop": 756, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30195, - "offsetEnd": 30197, - "sourceText": "i++" + "offsetEnd": 30198, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1782", - "target": "__loc_1788", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 19)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2095,27 +1357,14 @@ "lineNumberStart": 757, "colNumberStart": 4, "lineNumberStop": 757, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30204, - "offsetEnd": 30206, - "sourceText": "i++" + "offsetEnd": 30207, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1788", - "target": "__loc_1794", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 20)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2124,27 +1373,14 @@ "lineNumberStart": 758, "colNumberStart": 4, "lineNumberStop": 758, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30213, - "offsetEnd": 30215, - "sourceText": "i++" + "offsetEnd": 30216, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1794", - "target": "__loc_1800", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 21)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2153,27 +1389,14 @@ "lineNumberStart": 759, "colNumberStart": 4, "lineNumberStop": 759, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30222, - "offsetEnd": 30224, - "sourceText": "i++" + "offsetEnd": 30225, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1800", - "target": "__loc_1806", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 22)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2182,27 +1405,14 @@ "lineNumberStart": 760, "colNumberStart": 4, "lineNumberStop": 760, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30231, - "offsetEnd": 30233, - "sourceText": "i++" + "offsetEnd": 30234, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1806", - "target": "__loc_1812", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 23)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2211,27 +1421,14 @@ "lineNumberStart": 761, "colNumberStart": 4, "lineNumberStop": 761, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30240, - "offsetEnd": 30242, - "sourceText": "i++" + "offsetEnd": 30243, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1812", - "target": "__loc_1818", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 24)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2240,27 +1437,14 @@ "lineNumberStart": 762, "colNumberStart": 4, "lineNumberStop": 762, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30249, - "offsetEnd": 30251, - "sourceText": "i++" + "offsetEnd": 30252, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1818", - "target": "__loc_1824", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 25)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2269,27 +1453,14 @@ "lineNumberStart": 763, "colNumberStart": 4, "lineNumberStop": 763, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30258, - "offsetEnd": 30260, - "sourceText": "i++" + "offsetEnd": 30261, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1824", - "target": "__loc_1830", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 26)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2298,27 +1469,14 @@ "lineNumberStart": 764, "colNumberStart": 4, "lineNumberStop": 764, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30267, - "offsetEnd": 30269, - "sourceText": "i++" + "offsetEnd": 30270, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1830", - "target": "__loc_1836", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 27)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2327,27 +1485,14 @@ "lineNumberStart": 765, "colNumberStart": 4, "lineNumberStop": 765, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30276, - "offsetEnd": 30278, - "sourceText": "i++" + "offsetEnd": 30279, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1836", - "target": "__loc_1842", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 28)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2356,27 +1501,14 @@ "lineNumberStart": 766, "colNumberStart": 4, "lineNumberStop": 766, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30285, - "offsetEnd": 30287, - "sourceText": "i++" + "offsetEnd": 30288, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1842", - "target": "__loc_1848", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 29)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2384,28 +1516,15 @@ "content": { "lineNumberStart": 767, "colNumberStart": 4, - "lineNumberStop": 767, - "colNumberStop": 6, - "offsetStart": 30294, - "offsetEnd": 30296, - "sourceText": "i++" - } - }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1848", - "target": "__loc_1854", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "lineNumberStop": 767, + "colNumberStop": 7, + "offsetStart": 30294, + "offsetEnd": 30297, + "sourceText": "i++;" + } + }, + "content": "(assign thr2::i 30)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2414,27 +1533,14 @@ "lineNumberStart": 768, "colNumberStart": 4, "lineNumberStop": 768, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30303, - "offsetEnd": 30305, - "sourceText": "i++" + "offsetEnd": 30306, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1854", - "target": "__loc_1860", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 31)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2443,27 +1549,14 @@ "lineNumberStart": 769, "colNumberStart": 4, "lineNumberStop": 769, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30312, - "offsetEnd": 30314, - "sourceText": "i++" + "offsetEnd": 30315, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1860", - "target": "__loc_1866", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 32)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2472,27 +1565,14 @@ "lineNumberStart": 770, "colNumberStart": 4, "lineNumberStop": 770, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30321, - "offsetEnd": 30323, - "sourceText": "i++" + "offsetEnd": 30324, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1866", - "target": "__loc_1872", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 33)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2501,27 +1581,14 @@ "lineNumberStart": 771, "colNumberStart": 4, "lineNumberStop": 771, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30330, - "offsetEnd": 30332, - "sourceText": "i++" + "offsetEnd": 30333, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1872", - "target": "__loc_1878", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 34)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2530,27 +1597,14 @@ "lineNumberStart": 772, "colNumberStart": 4, "lineNumberStop": 772, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30339, - "offsetEnd": 30341, - "sourceText": "i++" + "offsetEnd": 30342, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1878", - "target": "__loc_1884", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 35)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2559,27 +1613,14 @@ "lineNumberStart": 773, "colNumberStart": 4, "lineNumberStop": 773, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30348, - "offsetEnd": 30350, - "sourceText": "i++" + "offsetEnd": 30351, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1884", - "target": "__loc_1890", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 36)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2588,27 +1629,14 @@ "lineNumberStart": 774, "colNumberStart": 4, "lineNumberStop": 774, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30357, - "offsetEnd": 30359, - "sourceText": "i++" + "offsetEnd": 30360, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1890", - "target": "__loc_1896", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 37)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2617,27 +1645,14 @@ "lineNumberStart": 775, "colNumberStart": 4, "lineNumberStop": 775, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30366, - "offsetEnd": 30368, - "sourceText": "i++" + "offsetEnd": 30369, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1896", - "target": "__loc_1902", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 38)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2646,27 +1661,14 @@ "lineNumberStart": 776, "colNumberStart": 4, "lineNumberStop": 776, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30375, - "offsetEnd": 30377, - "sourceText": "i++" + "offsetEnd": 30378, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" - } - ] - } - }, - { - "source": "__loc_1902", - "target": "__loc_1911", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign thr2::i 39)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2675,20 +1677,32 @@ "lineNumberStart": 777, "colNumberStart": 4, "lineNumberStop": 777, - "colNumberStop": 6, + "colNumberStop": 7, "offsetStart": 30384, - "offsetEnd": 30386, - "sourceText": "i++" + "offsetEnd": 30387, + "sourceText": "i++;" } }, - "content": "(assign thr2::i (+ thr2::i 1))" + "content": "(assign thr2::i 40)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 736, + "colNumberStart": 0, + "lineNumberStop": 779, + "colNumberStop": 13, + "offsetStart": 29992, + "offsetEnd": 30401, + "sourceText": "void *thr2(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;int i \u003d 0;int i \u003d 0;int i \u003d 0;int i \u003d 0;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;x +\u003d i;x +\u003d i;x +\u003d i;" + } } }, { - "source": "__loc_1911", - "target": "__loc_1912", + "source": "__loc_1895", + "target": "thr2_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2701,18 +1715,24 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign x (+ x thr2::i))" + "content": "(assign x (+ x 40))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 779, + "colNumberStop": 0, + "offsetStart": 0, + "offsetEnd": 30401, + "sourceText": "void *thr2(void *_) {\n int i \u003d 0;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n i++;\n x +\u003d i;\n}" + } } } ] @@ -2735,6 +1755,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::t1", "type": "Int" @@ -2744,24 +1768,138 @@ "type": "Int" }, { - "name": "main_ret", + "name": "call_pthread_create_ret88", + "type": "Int" + }, + { + "name": "call_pthread_create_ret89", + "type": "Int" + }, + { + "name": "call_reach_error_ret90", + "type": "Int" + }, + { + "name": "call_pthread_join_ret91", + "type": "Int" + }, + { + "name": "call_pthread_join_ret92", "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_1936 ", - "__loc_1954 ", - "__loc_1962 ", - "__loc_1980 ", - "__loc_1992 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 781, + "colNumberStart": 0, + "lineNumberStop": 792, + "colNumberStop": 0, + "offsetStart": 30404, + "offsetEnd": 30644, + "sourceText": "int main() {\n// for(int i \u003d 0; i \u003c 16; ++i) {\n pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(x \u003e 41) reach_error();\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n// }\n\n return 0;\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 781, + "colNumberStart": 0, + "lineNumberStop": 792, + "colNumberStop": 0, + "offsetStart": 30404, + "offsetEnd": 30644, + "sourceText": "int main() {\n// for(int i \u003d 0; i \u003c 16; ++i) {\n pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(x \u003e 41) reach_error();\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n// }\n\n return 0;\n}" + } + } + }, + { + "name": "__loc_1920", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1938", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1946", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1964", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_1976", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_1962", - "target": "__loc_1980", + "source": "main_init", + "target": "__loc_1920", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2769,28 +1907,52 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "content": "(assign x 0)" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 786, - "colNumberStart": 5, - "lineNumberStop": 786, - "colNumberStop": 10, - "offsetStart": 30552, - "offsetEnd": 30557, - "sourceText": "x \u003e 41" + "sourceText": "" + } + }, + "content": "((assume (and (\u003e\u003d main::t1 0) (\u003c\u003d main::t1 18446744073709551615))))[choiceType\u003dMAIN_PATH]" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" } }, - "content": "(assume (\u003d (ite (\u003e x 41) 1 0) 0))" + "content": "((assume (and (\u003e\u003d main::t2 0) (\u003c\u003d main::t2 18446744073709551615))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 781, + "colNumberStart": 0, + "lineNumberStop": 792, + "colNumberStop": 35, + "offsetStart": 30404, + "offsetEnd": 30644, + "sourceText": "int main() {\n// for(int i \u003d 0; i \u003c 16; ++i) {\n pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(x \u003e 41) reach_error();\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n// }\n\n return 0;\n}pthread_t t1, t2;\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n if(x \u003e 41) reach_error();\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n// }\n\n return 0;pthread_t t1, t2;pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);" + } } }, { - "source": "__loc_1936", - "target": "__loc_1954", + "source": "__loc_1920", + "target": "__loc_1938", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2806,20 +1968,32 @@ "lineNumberStart": 784, "colNumberStart": 4, "lineNumberStop": 784, - "colNumberStop": 34, + "colNumberStop": 35, "offsetStart": 30477, - "offsetEnd": 30507, - "sourceText": "pthread_create(\u0026t1, 0, thr1, 0)" + "offsetEnd": 30508, + "sourceText": "pthread_create(\u0026t1, 0, thr1, 0);" } }, - "content": "(var main::t1 Int) \u003d start thr1(0)" + "content": "(var main::t1 Int) \u003d start thr1(0, 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 784, + "colNumberStart": 4, + "lineNumberStop": 785, + "colNumberStop": 35, + "offsetStart": 30477, + "offsetEnd": 30545, + "sourceText": "pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);" + } } }, { - "source": "__loc_1954", - "target": "__loc_1962", + "source": "__loc_1938", + "target": "__loc_1946", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2835,20 +2009,32 @@ "lineNumberStart": 785, "colNumberStart": 4, "lineNumberStop": 785, - "colNumberStop": 34, + "colNumberStop": 35, "offsetStart": 30514, - "offsetEnd": 30544, - "sourceText": "pthread_create(\u0026t2, 0, thr2, 0)" + "offsetEnd": 30545, + "sourceText": "pthread_create(\u0026t2, 0, thr2, 0);" } }, - "content": "(var main::t2 Int) \u003d start thr2(0)" + "content": "(var main::t2 Int) \u003d start thr2(0, 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 785, + "colNumberStart": 2, + "lineNumberStop": 786, + "colNumberStop": 35, + "offsetStart": 30514, + "offsetEnd": 30573, + "sourceText": "pthread_create(\u0026t2, 0, thr2, 0);if(x \u003e 41) reach_error();if(x \u003e 41) reach_error();if(x \u003e 41) reach_error();" + } } }, { - "source": "__loc_1980", - "target": "__loc_1992", + "source": "__loc_1946", + "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2857,27 +2043,39 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.JoinLabel", + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 787, - "colNumberStart": 4, - "lineNumberStop": 787, - "colNumberStop": 22, - "offsetStart": 30579, - "offsetEnd": 30597, - "sourceText": "pthread_join(t1, 0)" + "lineNumberStart": 786, + "colNumberStart": 2, + "lineNumberStop": 786, + "colNumberStop": 26, + "offsetStart": 30549, + "offsetEnd": 30573, + "sourceText": "if(x \u003e 41) reach_error();" } }, - "content": "join (var main::t1 Int)" + "content": "((assume (/\u003d (ite (\u003e x 41) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 786, + "colNumberStart": 2, + "lineNumberStop": 786, + "colNumberStop": 26, + "offsetStart": 30549, + "offsetEnd": 30573, + "sourceText": "if(x \u003e 41) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { - "source": "main_init", - "target": "__loc_1936", + "source": "__loc_1946", + "target": "__loc_1964", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2885,52 +2083,40 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "content": "(assign x 0)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" - } - }, - "content": "(assume (and (\u003e\u003d main::t1 0) (\u003c\u003d main::t1 4294967295)))" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 786, + "colNumberStart": 2, + "lineNumberStop": 786, + "colNumberStop": 26, + "offsetStart": 30549, + "offsetEnd": 30573, + "sourceText": "if(x \u003e 41) reach_error();" } }, - "content": "(assume (and (\u003e\u003d main::t2 0) (\u003c\u003d main::t2 4294967295)))" + "content": "((assume (\u003d (ite (\u003e x 41) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 786, + "colNumberStart": 2, + "lineNumberStop": 787, + "colNumberStop": 26, + "offsetStart": 30549, + "offsetEnd": 30598, + "sourceText": "if(x \u003e 41) reach_error();if(x \u003e 41) reach_error();pthread_join(t1, 0);pthread_join(t1, 0);pthread_join(t1, 0);pthread_join(t1, 0);pthread_join(t1, 0);" + } } }, { - "source": "__loc_1962", - "target": "main_error", + "source": "__loc_1964", + "target": "__loc_1976", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2939,26 +2125,38 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.JoinLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 786, - "colNumberStart": 5, - "lineNumberStop": 786, - "colNumberStop": 10, - "offsetStart": 30552, - "offsetEnd": 30557, - "sourceText": "x \u003e 41" + "lineNumberStart": 787, + "colNumberStart": 4, + "lineNumberStop": 787, + "colNumberStop": 23, + "offsetStart": 30579, + "offsetEnd": 30598, + "sourceText": "pthread_join(t1, 0);" } }, - "content": "(assume (/\u003d (ite (\u003e x 41) 1 0) 0))" + "content": "join (var main::t1 Int)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 787, + "colNumberStart": 4, + "lineNumberStop": 788, + "colNumberStop": 23, + "offsetStart": 30579, + "offsetEnd": 30623, + "sourceText": "pthread_join(t1, 0);pthread_join(t2, 0);pthread_join(t2, 0);pthread_join(t2, 0);pthread_join(t2, 0);pthread_join(t2, 0);" + } } }, { - "source": "__loc_1992", + "source": "__loc_1976", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -2975,10 +2173,10 @@ "lineNumberStart": 788, "colNumberStart": 4, "lineNumberStop": 788, - "colNumberStop": 22, + "colNumberStop": 23, "offsetStart": 30604, - "offsetEnd": 30622, - "sourceText": "pthread_join(t2, 0)" + "offsetEnd": 30623, + "sourceText": "pthread_join(t2, 0);" } }, "content": "join (var main::t2 Int)" @@ -2991,15 +2189,27 @@ "lineNumberStart": 791, "colNumberStart": 2, "lineNumberStop": 791, - "colNumberStop": 9, + "colNumberStop": 10, "offsetStart": 30634, - "offsetEnd": 30641, - "sourceText": "return 0" + "offsetEnd": 30642, + "sourceText": "return 0;" } }, "content": "(assign main_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 788, + "colNumberStart": 2, + "lineNumberStop": 791, + "colNumberStop": 23, + "offsetStart": 30604, + "offsetEnd": 30642, + "sourceText": "pthread_join(t2, 0);return 0;return 0;return 0;return 0;" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/20testinline.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/20testinline.c.json index e9eb1fb764..9316a977a8 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/20testinline.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/20testinline.c.json @@ -33,6 +33,10 @@ } ], "vars": [ + { + "name": "func_ret", + "type": "Int" + }, { "name": "func::a", "type": "Int" @@ -40,18 +44,76 @@ { "name": "func::x", "type": "Int" + }, + { + "name": "call_reach_error_ret93", + "type": "Int" } ], "locs": [ - "func_init {init}", - "func_final {final}", - "__loc_2010 ", - "func_error {error}" + { + "name": "func_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 102, + "sourceText": "void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}" + } + } + }, + { + "name": "func_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 102, + "sourceText": "void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}" + } + } + }, + { + "name": "__loc_1995", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "func_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { "source": "func_init", - "target": "__loc_2010", + "target": "__loc_1995", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -64,22 +126,28 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d func::x -2147483648) (\u003c\u003d func::x 2147483647)))" + "content": "((assume (and (\u003e\u003d func::x -2147483648) (\u003c\u003d func::x 2147483647))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 38, + "offsetStart": 21, + "offsetEnd": 102, + "sourceText": "void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;int x;if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();" + } } }, { - "source": "__loc_2010", + "source": "__loc_1995", "target": "func_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -94,21 +162,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 5, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 5, - "colNumberStop": 22, - "offsetStart": 58, - "offsetEnd": 73, - "sourceText": "a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2" + "colNumberStop": 38, + "offsetStart": 55, + "offsetEnd": 89, + "sourceText": "if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();" } }, - "content": "(assume (/\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0))" + "content": "((assume (/\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 5, + "colNumberStop": 38, + "offsetStart": 55, + "offsetEnd": 89, + "sourceText": "if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { - "source": "__loc_2010", + "source": "__loc_1995", "target": "func_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -123,33 +203,39 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 5, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 5, - "colNumberStop": 22, - "offsetStart": 58, - "offsetEnd": 73, - "sourceText": "a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2" + "colNumberStop": 38, + "offsetStart": 55, + "offsetEnd": 89, + "sourceText": "if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();" } }, - "content": "(assume (\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0))" + "content": "((assume (\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, "content": "(assign func::x 1)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 38, + "offsetStart": 0, + "offsetEnd": 102, + "sourceText": "if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();x \u003d 1;x \u003d 1;x \u003d 1;void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}" + } } } ] @@ -172,6 +258,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "call_func_ret94", "type": "Int" @@ -180,6 +270,10 @@ "name": "call_func_ret95", "type": "Int" }, + { + "name": "func_ret", + "type": "Int" + }, { "name": "func::a", "type": "Int" @@ -189,21 +283,62 @@ "type": "Int" }, { - "name": "func_ret", + "name": "call_reach_error_ret93", "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_20102048 ", - "main_error {error}", - "__loc_20102052 " + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 0, + "lineNumberStop": 12, + "colNumberStop": 0, + "offsetStart": 105, + "offsetEnd": 144, + "sourceText": "int main() {\n func(0);\n func(1);\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 9, + "colNumberStart": 0, + "lineNumberStop": 12, + "colNumberStop": 0, + "offsetStart": 105, + "offsetEnd": 144, + "sourceText": "int main() {\n func(0);\n func(1);\n}" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { "source": "main_init", - "target": "__loc_20102048", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -219,99 +354,29 @@ "lineNumberStart": 10, "colNumberStart": 4, "lineNumberStop": 10, - "colNumberStop": 10, + "colNumberStop": 11, "offsetStart": 122, - "offsetEnd": 128, - "sourceText": "func(0)" + "offsetEnd": 129, + "sourceText": "func(0);" } }, - "content": "(assign func::a (+ 0))" + "content": "(assign func::a 0)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d func::x -2147483648) (\u003c\u003d func::x 2147483647)))" - } - ] - } - }, - { - "source": "__loc_20102048", - "target": "main_error", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 5, - "colNumberStart": 7, - "lineNumberStop": 5, - "colNumberStop": 22, - "offsetStart": 58, - "offsetEnd": 73, - "sourceText": "a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2" - } - }, - "content": "(assume (/\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_20102048", - "target": "__loc_20102052", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 5, - "colNumberStart": 7, - "lineNumberStop": 5, - "colNumberStop": 22, - "offsetStart": 58, - "offsetEnd": 73, - "sourceText": "a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2" - } - }, - "content": "(assume (\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0))" + "content": "((assume (and (\u003e\u003d func::x -2147483648) (\u003c\u003d func::x 2147483647))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -325,10 +390,10 @@ "lineNumberStart": 10, "colNumberStart": 4, "lineNumberStop": 10, - "colNumberStop": 10, + "colNumberStop": 11, "offsetStart": 122, - "offsetEnd": 128, - "sourceText": "func(0)" + "offsetEnd": 129, + "sourceText": "func(0);" } }, "content": "(assign call_func_ret94 func_ret)" @@ -341,99 +406,19 @@ "lineNumberStart": 11, "colNumberStart": 4, "lineNumberStop": 11, - "colNumberStop": 10, + "colNumberStop": 11, "offsetStart": 135, - "offsetEnd": 141, - "sourceText": "func(1)" + "offsetEnd": 142, + "sourceText": "func(1);" } }, - "content": "(assign func::a (+ 1))" + "content": "(assign func::a 1)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" - } - }, - "content": "(assume (and (\u003e\u003d func::x -2147483648) (\u003c\u003d func::x 2147483647)))" - } - ] - } - }, - { - "source": "__loc_20102052", - "target": "main_error", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 5, - "colNumberStart": 7, - "lineNumberStop": 5, - "colNumberStop": 22, - "offsetStart": 58, - "offsetEnd": 73, - "sourceText": "a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2" - } - }, - "content": "(assume (/\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_20102052", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 5, - "colNumberStart": 7, - "lineNumberStop": 5, - "colNumberStop": 22, - "offsetStart": 58, - "offsetEnd": 73, - "sourceText": "a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2" - } - }, - "content": "(assume (\u003d (ite (and (/\u003d 0 (ite (\u003d func::a 1) 1 0)) (/\u003d 0 (ite (\u003d func::x 2) 1 0))) 1 0) 0))" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -447,15 +432,27 @@ "lineNumberStart": 11, "colNumberStart": 4, "lineNumberStop": 11, - "colNumberStop": 10, + "colNumberStop": 11, "offsetStart": 135, - "offsetEnd": 141, - "sourceText": "func(1)" + "offsetEnd": 142, + "sourceText": "func(1);" } }, "content": "(assign call_func_ret95 func_ret)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 12, + "colNumberStop": 38, + "offsetStart": 21, + "offsetEnd": 144, + "sourceText": "int main() {\n func(0);\n func(1);\n}func(0);\n func(1);func(0);func(0);func(0);func(0);func(0);void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;int x;if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();x \u003d 1;x \u003d 1;x \u003d 1;void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}func(1);func(1);func(1);func(1);func(1);void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;int x;if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();x \u003d 1;x \u003d 1;x \u003d 1;void func(int a) {\n int x;\n if(a \u003d\u003d 1 \u0026\u0026 x \u003d\u003d 2) reach_error();\n x \u003d 1;\n}int main() {\n func(0);\n func(1);\n}" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/21namecollision.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/21namecollision.c.json index 1f49fd762d..c74271df94 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/21namecollision.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/21namecollision.c.json @@ -2,6 +2,94 @@ "name": "", "vars": [], "procedures": [ + { + "name": "reach_error", + "params": [ + { + "first": { + "type": "hu.bme.mit.theta.core.decl.VarDecl", + "value": { + "name": "reach_error_ret", + "type": "Int" + } + }, + "second": { + "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", + "value": "OUT" + } + } + ], + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } + ], + "locs": [ + { + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + }, + { + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", + "target": "reach_error_final", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } + } + } + ] + }, { "name": "f", "params": [ @@ -34,34 +122,55 @@ ], "vars": [ { - "name": "f::x", + "name": "f_ret", "type": "Int" }, { - "name": "f_ret", + "name": "f::x", "type": "Int" } ], "locs": [ - "f_init {init}", - "f_final {final}", - "__loc_2059 " - ], - "edges": [ { - "source": "f_init", - "target": "__loc_2059", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "f_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 54, + "sourceText": "int f(int x) {\n return x - 1;\n}" + } } }, { - "source": "__loc_2059", + "name": "f_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 0, + "offsetStart": 21, + "offsetEnd": 54, + "sourceText": "int f(int x) {\n return x - 1;\n}" + } + } + } + ], + "edges": [ + { + "source": "f_init", "target": "f_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -75,18 +184,30 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 2, + "lineNumberStart": 3, "colNumberStart": 4, - "lineNumberStop": 2, - "colNumberStop": 15, - "offsetStart": 19, - "offsetEnd": 30, - "sourceText": "return x - 1" + "lineNumberStop": 3, + "colNumberStop": 16, + "offsetStart": 40, + "offsetEnd": 52, + "sourceText": "return x - 1;" } }, "content": "(assign f_ret (+ f::x -1))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 16, + "offsetStart": 21, + "offsetEnd": 54, + "sourceText": "int f(int x) {\n return x - 1;\n}return x - 1;return x - 1;return x - 1;return x - 1;return x - 1;" + } } } ] @@ -123,34 +244,55 @@ ], "vars": [ { - "name": "fp::x", + "name": "fp_ret", "type": "Int" }, { - "name": "fp_ret", + "name": "fp::x", "type": "Int" } ], "locs": [ - "fp_init {init}", - "fp_final {final}", - "__loc_2066 " - ], - "edges": [ { - "source": "fp_init", - "target": "__loc_2066", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "fp_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 0, + "offsetStart": 57, + "offsetEnd": 91, + "sourceText": "int fp(int x) {\n return x + 1;\n}" + } } }, { - "source": "__loc_2066", + "name": "fp_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 0, + "offsetStart": 57, + "offsetEnd": 91, + "sourceText": "int fp(int x) {\n return x + 1;\n}" + } + } + } + ], + "edges": [ + { + "source": "fp_init", "target": "fp_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -164,18 +306,30 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, + "lineNumberStart": 7, "colNumberStart": 4, - "lineNumberStop": 6, - "colNumberStop": 15, - "offsetStart": 56, - "offsetEnd": 67, - "sourceText": "return x + 1" + "lineNumberStop": 7, + "colNumberStop": 16, + "offsetStart": 77, + "offsetEnd": 89, + "sourceText": "return x + 1;" } }, "content": "(assign fp_ret (+ fp::x 1))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 0, + "lineNumberStop": 8, + "colNumberStop": 16, + "offsetStart": 57, + "offsetEnd": 91, + "sourceText": "int fp(int x) {\n return x + 1;\n}return x + 1;return x + 1;return x + 1;return x + 1;return x + 1;" + } } } ] @@ -198,6 +352,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::x", "type": "Int" @@ -227,7 +385,7 @@ "type": "Int" }, { - "name": "f::x", + "name": "call_reach_error_ret102", "type": "Int" }, { @@ -235,23 +393,81 @@ "type": "Int" }, { - "name": "fp::x", + "name": "f::x", "type": "Int" }, { "name": "fp_ret", "type": "Int" + }, + { + "name": "fp::x", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_2135 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 0, + "offsetStart": 94, + "offsetEnd": 215, + "sourceText": "int main() {\n int x;\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n if(x \u003d\u003d -2) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 0, + "offsetStart": 94, + "offsetEnd": 215, + "sourceText": "int main() {\n int x;\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n if(x \u003d\u003d -2) reach_error();\n}" + } + } + }, + { + "name": "__loc_2168", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_2135", + "source": "__loc_2168", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -265,22 +481,34 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 14, - "colNumberStart": 7, - "lineNumberStop": 14, - "colNumberStop": 13, - "offsetStart": 170, - "offsetEnd": 176, - "sourceText": "x \u003d\u003d -2" + "lineNumberStart": 15, + "colNumberStart": 4, + "lineNumberStop": 15, + "colNumberStop": 29, + "offsetStart": 188, + "offsetEnd": 213, + "sourceText": "if(x \u003d\u003d -2) reach_error();" } }, - "content": "(assume (\u003d (ite (\u003d main::x -2) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003d main::x -2) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 29, + "offsetStart": 94, + "offsetEnd": 215, + "sourceText": "if(x \u003d\u003d -2) reach_error();if(x \u003d\u003d -2) reach_error();int main() {\n int x;\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n if(x \u003d\u003d -2) reach_error();\n}" + } } }, { - "source": "__loc_2135", + "source": "__loc_2168", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -294,23 +522,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 14, - "colNumberStart": 7, - "lineNumberStop": 14, - "colNumberStop": 13, - "offsetStart": 170, - "offsetEnd": 176, - "sourceText": "x \u003d\u003d -2" + "lineNumberStart": 15, + "colNumberStart": 4, + "lineNumberStop": 15, + "colNumberStop": 29, + "offsetStart": 188, + "offsetEnd": 213, + "sourceText": "if(x \u003d\u003d -2) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003d main::x -2) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003d main::x -2) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 15, + "colNumberStart": 4, + "lineNumberStop": 15, + "colNumberStop": 29, + "offsetStart": 188, + "offsetEnd": 213, + "sourceText": "if(x \u003d\u003d -2) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { "source": "main_init", - "target": "__loc_2135", + "target": "__loc_2168", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -323,45 +563,39 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::x -2147483648) (\u003c\u003d main::x 2147483647)))" + "content": "((assume (and (\u003e\u003d main::x -2147483648) (\u003c\u003d main::x 2147483647))))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 11, - "colNumberStart": 8, - "lineNumberStop": 11, - "colNumberStop": 11, - "offsetStart": 105, - "offsetEnd": 108, - "sourceText": "f(x)" + "lineNumberStart": 12, + "colNumberStart": 4, + "lineNumberStop": 12, + "colNumberStop": 20, + "offsetStart": 122, + "offsetEnd": 138, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign f::x (+ main::x))" + "content": "(assign f::x main::x)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 2, + "lineNumberStart": 3, "colNumberStart": 4, - "lineNumberStop": 2, - "colNumberStop": 15, - "offsetStart": 19, - "offsetEnd": 30, - "sourceText": "return x - 1" + "lineNumberStop": 3, + "colNumberStop": 16, + "offsetStart": 40, + "offsetEnd": 52, + "sourceText": "return x - 1;" } }, "content": "(assign f_ret (+ f::x -1))" @@ -371,45 +605,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 11, - "colNumberStart": 8, - "lineNumberStop": 11, - "colNumberStop": 11, - "offsetStart": 105, - "offsetEnd": 108, - "sourceText": "f(x)" + "lineNumberStart": 12, + "colNumberStart": 4, + "lineNumberStop": 12, + "colNumberStop": 20, + "offsetStart": 122, + "offsetEnd": 138, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign call_f_ret96 (+ f_ret))" + "content": "(assign call_f_ret96 f_ret)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 11, - "colNumberStart": 15, - "lineNumberStop": 11, - "colNumberStop": 19, - "offsetStart": 112, - "offsetEnd": 116, - "sourceText": "fp(x)" + "lineNumberStart": 12, + "colNumberStart": 4, + "lineNumberStop": 12, + "colNumberStop": 20, + "offsetStart": 122, + "offsetEnd": 138, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign fp::x (+ main::x))" + "content": "(assign fp::x main::x)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, + "lineNumberStart": 7, "colNumberStart": 4, - "lineNumberStop": 6, - "colNumberStop": 15, - "offsetStart": 56, - "offsetEnd": 67, - "sourceText": "return x + 1" + "lineNumberStop": 7, + "colNumberStop": 16, + "offsetStart": 77, + "offsetEnd": 89, + "sourceText": "return x + 1;" } }, "content": "(assign fp_ret (+ fp::x 1))" @@ -419,28 +653,22 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 11, - "colNumberStart": 15, - "lineNumberStop": 11, - "colNumberStop": 19, - "offsetStart": 112, - "offsetEnd": 116, - "sourceText": "fp(x)" + "lineNumberStart": 12, + "colNumberStart": 4, + "lineNumberStop": 12, + "colNumberStop": 20, + "offsetStart": 122, + "offsetEnd": 138, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign call_fp_ret97 (+ fp_ret))" + "content": "(assign call_fp_ret97 fp_ret)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -451,29 +679,29 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 12, - "colNumberStart": 8, - "lineNumberStop": 12, - "colNumberStop": 11, - "offsetStart": 127, - "offsetEnd": 130, - "sourceText": "f(x)" + "lineNumberStart": 13, + "colNumberStart": 4, + "lineNumberStop": 13, + "colNumberStop": 20, + "offsetStart": 144, + "offsetEnd": 160, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign f::x (+ main::x))" + "content": "(assign f::x main::x)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 2, + "lineNumberStart": 3, "colNumberStart": 4, - "lineNumberStop": 2, - "colNumberStop": 15, - "offsetStart": 19, - "offsetEnd": 30, - "sourceText": "return x - 1" + "lineNumberStop": 3, + "colNumberStop": 16, + "offsetStart": 40, + "offsetEnd": 52, + "sourceText": "return x - 1;" } }, "content": "(assign f_ret (+ f::x -1))" @@ -483,45 +711,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 12, - "colNumberStart": 8, - "lineNumberStop": 12, - "colNumberStop": 11, - "offsetStart": 127, - "offsetEnd": 130, - "sourceText": "f(x)" + "lineNumberStart": 13, + "colNumberStart": 4, + "lineNumberStop": 13, + "colNumberStop": 20, + "offsetStart": 144, + "offsetEnd": 160, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign call_f_ret98 (+ f_ret))" + "content": "(assign call_f_ret98 f_ret)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 12, - "colNumberStart": 15, - "lineNumberStop": 12, - "colNumberStop": 19, - "offsetStart": 134, - "offsetEnd": 138, - "sourceText": "fp(x)" + "lineNumberStart": 13, + "colNumberStart": 4, + "lineNumberStop": 13, + "colNumberStop": 20, + "offsetStart": 144, + "offsetEnd": 160, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign fp::x (+ main::x))" + "content": "(assign fp::x main::x)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, + "lineNumberStart": 7, "colNumberStart": 4, - "lineNumberStop": 6, - "colNumberStop": 15, - "offsetStart": 56, - "offsetEnd": 67, - "sourceText": "return x + 1" + "lineNumberStop": 7, + "colNumberStop": 16, + "offsetStart": 77, + "offsetEnd": 89, + "sourceText": "return x + 1;" } }, "content": "(assign fp_ret (+ fp::x 1))" @@ -531,28 +759,22 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 12, - "colNumberStart": 15, - "lineNumberStop": 12, - "colNumberStop": 19, - "offsetStart": 134, - "offsetEnd": 138, - "sourceText": "fp(x)" + "lineNumberStart": 13, + "colNumberStart": 4, + "lineNumberStop": 13, + "colNumberStop": 20, + "offsetStart": 144, + "offsetEnd": 160, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign call_fp_ret99 (+ fp_ret))" + "content": "(assign call_fp_ret99 fp_ret)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -563,29 +785,29 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 13, - "colNumberStart": 8, - "lineNumberStop": 13, - "colNumberStop": 11, - "offsetStart": 149, - "offsetEnd": 152, - "sourceText": "f(x)" + "lineNumberStart": 14, + "colNumberStart": 4, + "lineNumberStop": 14, + "colNumberStop": 20, + "offsetStart": 166, + "offsetEnd": 182, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign f::x (+ main::x))" + "content": "(assign f::x main::x)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 2, + "lineNumberStart": 3, "colNumberStart": 4, - "lineNumberStop": 2, - "colNumberStop": 15, - "offsetStart": 19, - "offsetEnd": 30, - "sourceText": "return x - 1" + "lineNumberStop": 3, + "colNumberStop": 16, + "offsetStart": 40, + "offsetEnd": 52, + "sourceText": "return x - 1;" } }, "content": "(assign f_ret (+ f::x -1))" @@ -595,45 +817,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 13, - "colNumberStart": 8, - "lineNumberStop": 13, - "colNumberStop": 11, - "offsetStart": 149, - "offsetEnd": 152, - "sourceText": "f(x)" + "lineNumberStart": 14, + "colNumberStart": 4, + "lineNumberStop": 14, + "colNumberStop": 20, + "offsetStart": 166, + "offsetEnd": 182, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign call_f_ret100 (+ f_ret))" + "content": "(assign call_f_ret100 f_ret)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 13, - "colNumberStart": 15, - "lineNumberStop": 13, - "colNumberStop": 19, - "offsetStart": 156, - "offsetEnd": 160, - "sourceText": "fp(x)" + "lineNumberStart": 14, + "colNumberStart": 4, + "lineNumberStop": 14, + "colNumberStop": 20, + "offsetStart": 166, + "offsetEnd": 182, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign fp::x (+ main::x))" + "content": "(assign fp::x main::x)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 6, + "lineNumberStart": 7, "colNumberStart": 4, - "lineNumberStop": 6, - "colNumberStop": 15, - "offsetStart": 56, - "offsetEnd": 67, - "sourceText": "return x + 1" + "lineNumberStop": 7, + "colNumberStop": 16, + "offsetStart": 77, + "offsetEnd": 89, + "sourceText": "return x + 1;" } }, "content": "(assign fp_ret (+ fp::x 1))" @@ -643,34 +865,40 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 13, - "colNumberStart": 15, - "lineNumberStop": 13, - "colNumberStop": 19, - "offsetStart": 156, - "offsetEnd": 160, - "sourceText": "fp(x)" + "lineNumberStart": 14, + "colNumberStart": 4, + "lineNumberStop": 14, + "colNumberStop": 20, + "offsetStart": 166, + "offsetEnd": 182, + "sourceText": "x \u003d f(x) - fp(x);" } }, - "content": "(assign call_fp_ret101 (+ fp_ret))" + "content": "(assign call_fp_ret101 fp_ret)" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, "content": "(assign main::x (+ call_f_ret100 (- call_fp_ret101)))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 29, + "offsetStart": 0, + "offsetEnd": 215, + "sourceText": "int main() {\n int x;\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n if(x \u003d\u003d -2) reach_error();\n}int x;\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n x \u003d f(x) - fp(x);\n if(x \u003d\u003d -2) reach_error();int x;x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);int f(int x) {\n return x - 1;\n}return x - 1;return x - 1;return x - 1;return x - 1;return x - 1;x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);int fp(int x) {\n return x + 1;\n}return x + 1;return x + 1;return x + 1;return x + 1;return x + 1;x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);int f(int x) {\n return x - 1;\n}return x - 1;return x - 1;return x - 1;return x - 1;return x - 1;x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);int fp(int x) {\n return x + 1;\n}return x + 1;return x + 1;return x + 1;return x + 1;return x + 1;x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);int f(int x) {\n return x - 1;\n}return x - 1;return x - 1;return x - 1;return x - 1;return x - 1;x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);x \u003d f(x) - fp(x);int fp(int x) {\n return x + 1;\n}return x + 1;return x + 1;return x + 1;return x + 1;return x + 1;x \u003d f(x) - fp(x);if(x \u003d\u003d -2) reach_error();if(x \u003d\u003d -2) reach_error();if(x \u003d\u003d -2) reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/22nondet.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/22nondet.c.json index 1ab02320c2..ee65fa7e58 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/22nondet.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/22nondet.c.json @@ -2,6 +2,94 @@ "name": "", "vars": [], "procedures": [ + { + "name": "reach_error", + "params": [ + { + "first": { + "type": "hu.bme.mit.theta.core.decl.VarDecl", + "value": { + "name": "reach_error_ret", + "type": "Int" + } + }, + "second": { + "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", + "value": "OUT" + } + } + ], + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } + ], + "locs": [ + { + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + }, + { + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}" + } + } + } + ], + "edges": [ + { + "source": "reach_error_init", + "target": "reach_error_final", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 1, + "colNumberStart": 0, + "lineNumberStop": 1, + "colNumberStop": 19, + "offsetStart": 0, + "offsetEnd": 19, + "sourceText": "void reach_error(){}void reach_error(){}void reach_error(){}" + } + } + } + ] + }, { "name": "main", "params": [ @@ -20,6 +108,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::i", "type": "Int" @@ -27,19 +119,94 @@ { "name": "call___VERIFIER_nondet_int_ret103", "type": "Int" + }, + { + "name": "call_reach_error_ret104", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_2176 ", - "__loc_2205 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 0, + "offsetStart": 57, + "offsetEnd": 200, + "sourceText": "int main() {\n int i \u003d 0;\n if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }\n if(i\u003d\u003d2) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 0, + "offsetStart": 57, + "offsetEnd": 200, + "sourceText": "int main() {\n int i \u003d 0;\n if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }\n if(i\u003d\u003d2) reach_error();\n}" + } + } + }, + { + "name": "__loc_2248", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 9, + "colNumberStop": 4, + "offsetStart": 89, + "offsetEnd": 170, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }" + } + } + }, + { + "name": "__loc_2273", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_2176", - "target": "__loc_2205", + "source": "__loc_2273", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -52,39 +219,76 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 33, - "offsetStart": 71, - "offsetEnd": 97, - "sourceText": "__VERIFIER_nondet_int() % 2" + "lineNumberStart": 10, + "colNumberStart": 4, + "lineNumberStop": 10, + "colNumberStop": 26, + "offsetStart": 176, + "offsetEnd": 198, + "sourceText": "if(i\u003d\u003d2) reach_error();" } }, - "content": "(assume (/\u003d (mod call___VERIFIER_nondet_int_ret103 2) 0))" - }, + "content": "((assume (\u003d (ite (\u003d main::i 2) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 26, + "offsetStart": 57, + "offsetEnd": 200, + "sourceText": "if(i\u003d\u003d2) reach_error();if(i\u003d\u003d2) reach_error();int main() {\n int i \u003d 0;\n if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }\n if(i\u003d\u003d2) reach_error();\n}" + } + } + }, + { + "source": "__loc_2273", + "target": "main_error", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 10, + "colNumberStart": 4, + "lineNumberStop": 10, + "colNumberStop": 26, + "offsetStart": 176, + "offsetEnd": 198, + "sourceText": "if(i\u003d\u003d2) reach_error();" } }, - "content": "(assign main::i 1)" + "content": "((assume (/\u003d (ite (\u003d main::i 2) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 10, + "colNumberStart": 4, + "lineNumberStop": 10, + "colNumberStop": 26, + "offsetStart": 176, + "offsetEnd": 198, + "sourceText": "if(i\u003d\u003d2) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { - "source": "__loc_2176", - "target": "__loc_2205", + "source": "__loc_2248", + "target": "__loc_2273", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -97,39 +301,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 33, - "offsetStart": 71, - "offsetEnd": 97, - "sourceText": "__VERIFIER_nondet_int() % 2" + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 9, + "colNumberStop": 4, + "offsetStart": 89, + "offsetEnd": 170, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }" } }, - "content": "(assume (\u003d (mod call___VERIFIER_nondet_int_ret103 2) 0))" + "content": "((assume (/\u003d (ite (\u003d (mod call___VERIFIER_nondet_int_ret103 2) 0) (mod call___VERIFIER_nondet_int_ret103 2) (ite (\u003e\u003d call___VERIFIER_nondet_int_ret103 0) (mod call___VERIFIER_nondet_int_ret103 2) (- (mod call___VERIFIER_nondet_int_ret103 2) 2))) 0)))[choiceType\u003dMAIN_PATH]" }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign main::i 2)" + "content": "(assign main::i 1)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 10, + "colNumberStop": 26, + "offsetStart": 0, + "offsetEnd": 198, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }{\n i \u003d 1;\n }i \u003d 1;i \u003d 1;i \u003d 1;if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }if(i\u003d\u003d2) reach_error();if(i\u003d\u003d2) reach_error();if(i\u003d\u003d2) reach_error();" + } } }, { - "source": "__loc_2205", - "target": "main_final", + "source": "__loc_2248", + "target": "__loc_2273", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -142,52 +352,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 9, - "colNumberStart": 7, + "lineNumberStart": 5, + "colNumberStart": 4, "lineNumberStop": 9, - "colNumberStop": 10, - "offsetStart": 158, - "offsetEnd": 161, - "sourceText": "i\u003d\u003d2" + "colNumberStop": 4, + "offsetStart": 89, + "offsetEnd": 170, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }" } }, - "content": "(assume (\u003d (ite (\u003d main::i 2) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_2205", - "target": "main_error", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "((assume (\u003d (ite (\u003d (mod call___VERIFIER_nondet_int_ret103 2) 0) (mod call___VERIFIER_nondet_int_ret103 2) (ite (\u003e\u003d call___VERIFIER_nondet_int_ret103 0) (mod call___VERIFIER_nondet_int_ret103 2) (- (mod call___VERIFIER_nondet_int_ret103 2) 2))) 0)))[choiceType\u003dALTERNATIVE_PATH]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 9, - "colNumberStart": 7, - "lineNumberStop": 9, - "colNumberStop": 10, - "offsetStart": 158, - "offsetEnd": 161, - "sourceText": "i\u003d\u003d2" + "sourceText": "" } }, - "content": "(assume (/\u003d (ite (\u003d main::i 2) 1 0) 0))" + "content": "(assign main::i 2)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 10, + "colNumberStop": 26, + "offsetStart": 0, + "offsetEnd": 198, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }{\n i \u003d 2;\n }i \u003d 2;i \u003d 2;i \u003d 2;if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }if(i\u003d\u003d2) reach_error();if(i\u003d\u003d2) reach_error();if(i\u003d\u003d2) reach_error();" + } } }, { "source": "main_init", - "target": "__loc_2176", + "target": "__loc_2248", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -200,12 +403,12 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 3, + "lineNumberStart": 4, "colNumberStart": 4, - "lineNumberStop": 3, + "lineNumberStop": 4, "colNumberStop": 13, - "offsetStart": 53, - "offsetEnd": 62, + "offsetStart": 74, + "offsetEnd": 83, "sourceText": "int i \u003d 0;" } }, @@ -216,13 +419,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 29, - "offsetStart": 71, - "offsetEnd": 93, - "sourceText": "__VERIFIER_nondet_int()" + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 9, + "colNumberStop": 4, + "offsetStart": 89, + "offsetEnd": 170, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }" } }, "content": "(havoc call___VERIFIER_nondet_int_ret103)" @@ -232,18 +435,30 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 4, - "colNumberStart": 7, - "lineNumberStop": 4, - "colNumberStop": 29, - "offsetStart": 71, - "offsetEnd": 93, - "sourceText": "__VERIFIER_nondet_int()" + "lineNumberStart": 5, + "colNumberStart": 4, + "lineNumberStop": 9, + "colNumberStop": 4, + "offsetStart": 89, + "offsetEnd": 170, + "sourceText": "if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }" } }, "content": "(assume (and (\u003e\u003d call___VERIFIER_nondet_int_ret103 -2147483648) (\u003c\u003d call___VERIFIER_nondet_int_ret103 2147483647)))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 11, + "colNumberStop": 26, + "offsetStart": 57, + "offsetEnd": 200, + "sourceText": "int main() {\n int i \u003d 0;\n if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }\n if(i\u003d\u003d2) reach_error();\n}int i \u003d 0;\n if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }\n if(i\u003d\u003d2) reach_error();int i \u003d 0;int i \u003d 0;int i \u003d 0;int i \u003d 0;if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }if(__VERIFIER_nondet_int() % 2) {\n i \u003d 1;\n } else {\n i \u003d 2;\n }" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/23overflow.c.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/23overflow.c.json index aa4cbfca7c..ac269dcc79 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/23overflow.c.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/23overflow.c.json @@ -20,20 +20,86 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::i", "type": "Int" + }, + { + "name": "call___VERIFIER_nondet_int_ret105", + "type": "Int" + }, + { + "name": "call_reach_error_ret106", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_2237 ", - "main_error {error}" + { + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 56, + "offsetEnd": 151, + "sourceText": "int main() {\n int i \u003d __VERIFIER_nondet_int();\n i \u003d i * 2;\n if(i \u003d\u003d 1) reach_error();\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 0, + "offsetStart": 56, + "offsetEnd": 151, + "sourceText": "int main() {\n int i \u003d __VERIFIER_nondet_int();\n i \u003d i * 2;\n if(i \u003d\u003d 1) reach_error();\n}" + } + } + }, + { + "name": "__loc_2304", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "main_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } ], "edges": [ { - "source": "__loc_2237", + "source": "__loc_2304", "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -48,21 +114,33 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 6, - "colNumberStop": 12, - "offsetStart": 128, - "offsetEnd": 133, - "sourceText": "i \u003d\u003d 1" + "colNumberStop": 28, + "offsetStart": 125, + "offsetEnd": 149, + "sourceText": "if(i \u003d\u003d 1) reach_error();" } }, - "content": "(assume (\u003d (ite (\u003d main::i 1) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003d main::i 1) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 28, + "offsetStart": 56, + "offsetEnd": 151, + "sourceText": "if(i \u003d\u003d 1) reach_error();if(i \u003d\u003d 1) reach_error();int main() {\n int i \u003d __VERIFIER_nondet_int();\n i \u003d i * 2;\n if(i \u003d\u003d 1) reach_error();\n}" + } } }, { - "source": "__loc_2237", + "source": "__loc_2304", "target": "main_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", @@ -77,22 +155,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 6, - "colNumberStart": 7, + "colNumberStart": 4, "lineNumberStop": 6, - "colNumberStop": 12, - "offsetStart": 128, - "offsetEnd": 133, - "sourceText": "i \u003d\u003d 1" + "colNumberStop": 28, + "offsetStart": 125, + "offsetEnd": 149, + "sourceText": "if(i \u003d\u003d 1) reach_error();" } }, - "content": "(assume (/\u003d (ite (\u003d main::i 1) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003d main::i 1) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 6, + "colNumberStart": 4, + "lineNumberStop": 6, + "colNumberStop": 28, + "offsetStart": 125, + "offsetEnd": 149, + "sourceText": "if(i \u003d\u003d 1) reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { "source": "main_init", - "target": "__loc_2237", + "target": "__loc_2304", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -106,12 +196,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 12, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 34, - "offsetStart": 81, - "offsetEnd": 103, - "sourceText": "__VERIFIER_nondet_int()" + "colNumberStop": 35, + "offsetStart": 73, + "offsetEnd": 104, + "sourceText": "int i \u003d __VERIFIER_nondet_int();" } }, "content": "(havoc main::i)" @@ -122,12 +212,12 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 4, - "colNumberStart": 12, + "colNumberStart": 4, "lineNumberStop": 4, - "colNumberStop": 34, - "offsetStart": 81, - "offsetEnd": 103, - "sourceText": "__VERIFIER_nondet_int()" + "colNumberStop": 35, + "offsetStart": 73, + "offsetEnd": 104, + "sourceText": "int i \u003d __VERIFIER_nondet_int();" } }, "content": "(assume (and (\u003e\u003d main::i -2147483648) (\u003c\u003d main::i 2147483647)))" @@ -137,18 +227,24 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, "content": "(assign main::i (* 2 main::i))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 7, + "colNumberStop": 35, + "offsetStart": 0, + "offsetEnd": 151, + "sourceText": "int main() {\n int i \u003d __VERIFIER_nondet_int();\n i \u003d i * 2;\n if(i \u003d\u003d 1) reach_error();\n}int i \u003d __VERIFIER_nondet_int();\n i \u003d i * 2;\n if(i \u003d\u003d 1) reach_error();int i \u003d __VERIFIER_nondet_int();int i \u003d __VERIFIER_nondet_int();int i \u003d __VERIFIER_nondet_int();int i \u003d __VERIFIER_nondet_int();int i \u003d __VERIFIER_nondet_int();int i \u003d __VERIFIER_nondet_int();i \u003d i * 2;i \u003d i * 2;i \u003d i * 2;if(i \u003d\u003d 1) reach_error();if(i \u003d\u003d 1) reach_error();if(i \u003d\u003d 1) reach_error();" + } } } ] diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/json/dekker.i.json b/subprojects/xcfa/xcfa-cli/src/test/resources/json/dekker.i.json index 928ba9be88..6cf9c1d326 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/json/dekker.i.json +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/json/dekker.i.json @@ -66,46 +66,91 @@ } ], "vars": [ + { + "name": "assume_abort_if_not_ret", + "type": "Int" + }, { "name": "assume_abort_if_not::cond", "type": "Int" + }, + { + "name": "call_abort_ret0", + "type": "Int" } ], "locs": [ - "assume_abort_if_not_init {init}", - "assume_abort_if_not_final {final}", - "__loc_2 ", - "__loc_7 ", - "__loc_13 " - ], - "edges": [ { - "source": "__loc_2", - "target": "assume_abort_if_not_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "assume_abort_if_not_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 0, + "offsetStart": 25, + "offsetEnd": 85, + "sourceText": "void assume_abort_if_not(int cond) {\n if(!cond) {abort();}\n}" + } } }, { - "source": "assume_abort_if_not_init", - "target": "__loc_7", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "assume_abort_if_not_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 0, + "offsetStart": 25, + "offsetEnd": 85, + "sourceText": "void assume_abort_if_not(int cond) {\n if(!cond) {abort();}\n}" + } + } + }, + { + "name": "__loc_8", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } } }, { - "source": "__loc_7", - "target": "__loc_13", + "name": "__loc_14", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 13, + "lineNumberStop": 3, + "colNumberStop": 20, + "offsetStart": 75, + "offsetEnd": 82, + "sourceText": "abort();" + } + } + } + ], + "edges": [ + { + "source": "__loc_14", + "target": "assume_abort_if_not_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -119,22 +164,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 3, - "colNumberStart": 5, + "colNumberStart": 13, "lineNumberStop": 3, - "colNumberStop": 9, - "offsetStart": 67, - "offsetEnd": 71, - "sourceText": "!cond" + "colNumberStop": 20, + "offsetStart": 75, + "offsetEnd": 82, + "sourceText": "abort();" } }, - "content": "(assume (/\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0))" + "content": "(assume false)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 13, + "lineNumberStop": 3, + "colNumberStop": 20, + "offsetStart": 75, + "offsetEnd": 82, + "sourceText": "abort();" + } } }, { - "source": "__loc_7", - "target": "__loc_2", + "source": "__loc_8", + "target": "assume_abort_if_not_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -148,22 +205,58 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 3, - "colNumberStart": 5, + "colNumberStart": 2, "lineNumberStop": 3, - "colNumberStop": 9, - "offsetStart": 67, - "offsetEnd": 71, - "sourceText": "!cond" + "colNumberStop": 21, + "offsetStart": 64, + "offsetEnd": 83, + "sourceText": "if(!cond) {abort();}" } }, - "content": "(assume (\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 21, + "offsetStart": 25, + "offsetEnd": 85, + "sourceText": "if(!cond) {abort();}if(!cond) {abort();}void assume_abort_if_not(int cond) {\n if(!cond) {abort();}\n}" + } } }, { - "source": "__loc_13", - "target": "assume_abort_if_not_final", + "source": "assume_abort_if_not_init", + "target": "__loc_8", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 4, + "colNumberStop": 21, + "offsetStart": 25, + "offsetEnd": 85, + "sourceText": "void assume_abort_if_not(int cond) {\n if(!cond) {abort();}\n}if(!cond) {abort();}if(!cond) {abort();}if(!cond) {abort();}if(!cond) {abort();}" + } + } + }, + { + "source": "__loc_8", + "target": "__loc_14", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -174,12 +267,32 @@ { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 2, + "lineNumberStop": 3, + "colNumberStop": 21, + "offsetStart": 64, + "offsetEnd": 83, + "sourceText": "if(!cond) {abort();}" + } }, - "content": "(assume false)" + "content": "((assume (/\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 2, + "lineNumberStop": 3, + "colNumberStop": 21, + "offsetStart": 64, + "offsetEnd": 83, + "sourceText": "if(!cond) {abort();}{abort();}abort();abort();abort();" + } } } ] @@ -201,28 +314,54 @@ } } ], - "vars": [], - "locs": [ - "reach_error_init {init}", - "reach_error_final {final}", - "__loc_37 " + "vars": [ + { + "name": "reach_error_ret", + "type": "Int" + } ], - "edges": [ + "locs": [ { - "source": "__loc_37", - "target": "reach_error_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] + "name": "reach_error_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 16, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 158, + "offsetStart": 669, + "offsetEnd": 827, + "sourceText": "void reach_error() { ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); })); }" + } } }, + { + "name": "reach_error_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 16, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 158, + "offsetStart": 669, + "offsetEnd": 827, + "sourceText": "void reach_error() { ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); })); }" + } + } + } + ], + "edges": [ { "source": "reach_error_init", - "target": "__loc_37", + "target": "reach_error_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -230,6 +369,18 @@ "content": {} }, "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 16, + "colNumberStart": 0, + "lineNumberStop": 16, + "colNumberStop": 158, + "offsetStart": 669, + "offsetEnd": 827, + "sourceText": "void reach_error() { ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); })); }((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); }));void reach_error() { ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail (\"0\", \"dekker.c\", 7, __extension__ __PRETTY_FUNCTION__); })); }" + } } } ] @@ -245,75 +396,557 @@ "type": "Int" } }, - "second": { - "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", - "value": "OUT" - } - }, - { - "first": { - "type": "hu.bme.mit.theta.core.decl.VarDecl", - "value": { - "name": "thr1::_", - "type": "Int" + "second": { + "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", + "value": "OUT" + } + }, + { + "first": { + "type": "hu.bme.mit.theta.core.decl.VarDecl", + "value": { + "name": "thr1::_", + "type": "Int" + } + }, + "second": { + "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", + "value": "IN" + } + } + ], + "vars": [ + { + "name": "thr1_ret", + "type": "Int" + }, + { + "name": "thr1::_", + "type": "Int" + }, + { + "name": "thr1::f2", + "type": "Int" + }, + { + "name": "thr1::while1::t", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret1", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret2", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret3", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret4", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret5", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret6", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret7", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret8", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret9", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret10", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret11", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret12", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret13", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret14", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret15", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret16", + "type": "Int" + }, + { + "name": "call_reach_error_ret17", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret18", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret19", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret20", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret21", + "type": "Int" + } + ], + "locs": [ + { + "name": "thr1_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 707, + "colNumberStart": 0, + "lineNumberStop": 747, + "colNumberStop": 0, + "offsetStart": 30501, + "offsetEnd": 31579, + "sourceText": "void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f2 \u003d flag2;\n __VERIFIER_atomic_end();\n while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }\n x \u003d 0;\n if (!(x\u003c\u003d0)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;\n}" + } + } + }, + { + "name": "thr1_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 707, + "colNumberStart": 0, + "lineNumberStop": 747, + "colNumberStop": 0, + "offsetStart": 30501, + "offsetEnd": 31579, + "sourceText": "void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f2 \u003d flag2;\n __VERIFIER_atomic_end();\n while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }\n x \u003d 0;\n if (!(x\u003c\u003d0)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;\n}" + } + } + }, + { + "name": "__loc_39", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 708, + "colNumberStart": 4, + "lineNumberStop": 708, + "colNumberStop": 29, + "offsetStart": 30527, + "offsetEnd": 30552, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_58", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 711, + "colNumberStart": 4, + "lineNumberStop": 711, + "colNumberStop": 29, + "offsetStart": 30602, + "offsetEnd": 30627, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_79", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_85", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 715, + "colNumberStart": 8, + "lineNumberStop": 715, + "colNumberStop": 33, + "offsetStart": 30708, + "offsetEnd": 30733, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_106", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_112", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 719, + "colNumberStart": 12, + "lineNumberStop": 719, + "colNumberStop": 37, + "offsetStart": 30824, + "offsetEnd": 30849, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_131", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 722, + "colNumberStart": 12, + "lineNumberStop": 722, + "colNumberStop": 37, + "offsetStart": 30923, + "offsetEnd": 30948, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_153", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_159", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 726, + "colNumberStart": 16, + "lineNumberStop": 726, + "colNumberStop": 41, + "offsetStart": 31054, + "offsetEnd": 31079, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_180", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 730, + "colNumberStart": 12, + "lineNumberStop": 730, + "colNumberStop": 37, + "offsetStart": 31175, + "offsetEnd": 31200, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_199", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 734, + "colNumberStart": 8, + "lineNumberStop": 734, + "colNumberStop": 33, + "offsetStart": 31280, + "offsetEnd": 31305, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_221", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 738, + "colNumberStart": 4, + "lineNumberStop": 738, + "colNumberStop": 9, + "offsetStart": 31370, + "offsetEnd": 31375, + "sourceText": "x \u003d 0;" + } + } + }, + { + "name": "__loc_233", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_244", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 740, + "colNumberStart": 4, + "lineNumberStop": 740, + "colNumberStop": 29, + "offsetStart": 31420, + "offsetEnd": 31445, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_263", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 743, + "colNumberStart": 4, + "lineNumberStop": 743, + "colNumberStop": 29, + "offsetStart": 31494, + "offsetEnd": 31519, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "thr1_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } + ], + "edges": [ + { + "source": "thr1_init", + "target": "__loc_39", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 707, + "colNumberStart": 0, + "lineNumberStop": 747, + "colNumberStop": 29, + "offsetStart": 30501, + "offsetEnd": 31579, + "sourceText": "void *thr1(void *_) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f2 \u003d flag2;\n __VERIFIER_atomic_end();\n while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }\n x \u003d 0;\n if (!(x\u003c\u003d0)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;\n}__VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f2 \u003d flag2;\n __VERIFIER_atomic_end();\n while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }\n x \u003d 0;\n if (!(x\u003c\u003d0)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } + } + }, + { + "source": "__loc_39", + "target": "__loc_58", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 708, + "colNumberStart": 4, + "lineNumberStop": 708, + "colNumberStop": 29, + "offsetStart": 30527, + "offsetEnd": 30552, + "sourceText": "__VERIFIER_atomic_begin();" + } + }, + "content": "F[ATOMIC_BEGIN]" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + }, + "content": "(assign flag1 1)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 710, + "colNumberStart": 4, + "lineNumberStop": 710, + "colNumberStop": 27, + "offsetStart": 30573, + "offsetEnd": 30596, + "sourceText": "__VERIFIER_atomic_end();" + } + }, + "content": "F[ATOMIC_END]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 708, + "colNumberStart": 4, + "lineNumberStop": 711, + "colNumberStop": 29, + "offsetStart": 30527, + "offsetEnd": 30627, + "sourceText": "__VERIFIER_atomic_begin();flag1 \u003d 1;flag1 \u003d 1;flag1 \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" } - }, - "second": { - "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", - "value": "IN" } - } - ], - "vars": [ - { - "name": "thr1::f2", - "type": "Int" - }, - { - "name": "thr1::while1::t", - "type": "Int" }, { - "name": "thr1_ret", - "type": "Int" - } - ], - "locs": [ - "thr1_init {init}", - "thr1_final {final}", - "__loc_42 ", - "__loc_63 ", - "__loc_84 ", - "__loc_90 ", - "__loc_111 ", - "__loc_117 ", - "__loc_138 ", - "__loc_162 ", - "__loc_168 ", - "__loc_191 ", - "__loc_212 ", - "__loc_238 ", - "__loc_250 ", - "__loc_261 ", - "__loc_282 ", - "thr1_error {error}" - ], - "edges": [ - { - "source": "thr1_init", - "target": "__loc_42", + "source": "__loc_79", + "target": "__loc_85", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", "content": {} }, - "labels": [] + "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 4, + "lineNumberStop": 737, + "colNumberStop": 4, + "offsetStart": 30682, + "offsetEnd": 31364, + "sourceText": "while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }" + } + }, + "content": "((assume (/\u003d (ite (\u003e\u003d thr1::f2 1) 1 0) 0)))[choiceType\u003dMAIN_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 4, + "lineNumberStop": 737, + "colNumberStop": 33, + "offsetStart": 30682, + "offsetEnd": 31364, + "sourceText": "while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }{\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_84", - "target": "__loc_90", + "source": "__loc_85", + "target": "__loc_106", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -321,28 +954,72 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 715, + "colNumberStart": 8, + "lineNumberStop": 715, + "colNumberStop": 33, + "offsetStart": 30708, + "offsetEnd": 30733, + "sourceText": "__VERIFIER_atomic_begin();" + } + }, + "content": "F[ATOMIC_BEGIN]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 714, - "colNumberStart": 11, - "lineNumberStop": 714, - "colNumberStop": 17, - "offsetStart": 30689, - "offsetEnd": 30695, - "sourceText": "f2 \u003e\u003d 1" + "lineNumberStart": 716, + "colNumberStart": 8, + "lineNumberStop": 716, + "colNumberStop": 20, + "offsetStart": 30743, + "offsetEnd": 30755, + "sourceText": "int t \u003d turn;" + } + }, + "content": "(assign thr1::while1::t turn)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 717, + "colNumberStart": 8, + "lineNumberStop": 717, + "colNumberStop": 31, + "offsetStart": 30765, + "offsetEnd": 30788, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "(assume (/\u003d (ite (\u003e\u003d thr1::f2 1) 1 0) 0))" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 715, + "colNumberStart": 8, + "lineNumberStop": 733, + "colNumberStop": 33, + "offsetStart": 30708, + "offsetEnd": 31270, + "sourceText": "__VERIFIER_atomic_begin();int t \u003d turn;int t \u003d turn;int t \u003d turn;int t \u003d turn;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_111", - "target": "__loc_117", + "source": "__loc_106", + "target": "__loc_112", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -356,22 +1033,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 718, - "colNumberStart": 12, - "lineNumberStop": 718, - "colNumberStop": 17, - "offsetStart": 30802, - "offsetEnd": 30807, - "sourceText": "t !\u003d 0" + "colNumberStart": 8, + "lineNumberStop": 733, + "colNumberStop": 8, + "offsetStart": 30798, + "offsetEnd": 31270, + "sourceText": "if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (/\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0))" + "content": "((assume (/\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 718, + "colNumberStart": 8, + "lineNumberStop": 733, + "colNumberStop": 37, + "offsetStart": 30798, + "offsetEnd": 31270, + "sourceText": "if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }{\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_162", - "target": "__loc_168", + "source": "__loc_112", + "target": "__loc_131", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -379,28 +1068,66 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 719, + "colNumberStart": 12, + "lineNumberStop": 719, + "colNumberStop": 37, + "offsetStart": 30824, + "offsetEnd": 30849, + "sourceText": "__VERIFIER_atomic_begin();" + } + }, + "content": "F[ATOMIC_BEGIN]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 725, - "colNumberStart": 19, - "lineNumberStop": 725, - "colNumberStop": 24, - "offsetStart": 31028, - "offsetEnd": 31033, - "sourceText": "t !\u003d 0" + "sourceText": "" + } + }, + "content": "(assign flag1 0)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 721, + "colNumberStart": 12, + "lineNumberStop": 721, + "colNumberStop": 35, + "offsetStart": 30886, + "offsetEnd": 30909, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "(assume (/\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0))" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 719, + "colNumberStart": 12, + "lineNumberStop": 722, + "colNumberStop": 37, + "offsetStart": 30824, + "offsetEnd": 30948, + "sourceText": "__VERIFIER_atomic_begin();flag1 \u003d 0;flag1 \u003d 0;flag1 \u003d 0;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_162", - "target": "__loc_191", + "source": "__loc_153", + "target": "__loc_159", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -422,14 +1149,26 @@ "sourceText": "while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0))" + "content": "((assume (/\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 725, + "colNumberStart": 12, + "lineNumberStop": 729, + "colNumberStop": 41, + "offsetStart": 31021, + "offsetEnd": 31160, + "sourceText": "while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }{\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_111", - "target": "__loc_212", + "source": "__loc_153", + "target": "__loc_180", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -442,23 +1181,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 718, + "lineNumberStart": 725, "colNumberStart": 12, - "lineNumberStop": 718, - "colNumberStop": 17, - "offsetStart": 30802, - "offsetEnd": 30807, - "sourceText": "t !\u003d 0" + "lineNumberStop": 729, + "colNumberStop": 12, + "offsetStart": 31021, + "offsetEnd": 31160, + "sourceText": "while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0))" + "content": "((assume (\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 725, + "colNumberStart": 12, + "lineNumberStop": 730, + "colNumberStop": 37, + "offsetStart": 31021, + "offsetEnd": 31200, + "sourceText": "while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_84", - "target": "__loc_238", + "source": "__loc_79", + "target": "__loc_221", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -480,14 +1231,26 @@ "sourceText": "while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (\u003d (ite (\u003e\u003d thr1::f2 1) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003e\u003d thr1::f2 1) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 4, + "lineNumberStop": 738, + "colNumberStop": 9, + "offsetStart": 30682, + "offsetEnd": 31375, + "sourceText": "while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }x \u003d 0;x \u003d 0;x \u003d 0;" + } } }, { - "source": "__loc_238", - "target": "__loc_250", + "source": "__loc_221", + "target": "__loc_233", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -500,23 +1263,29 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, "content": "(assign x 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 739, + "colNumberStop": 37, + "offsetStart": 0, + "offsetEnd": 31414, + "sourceText": "if (!(x\u003c\u003d0)) ERROR: reach_error();if (!(x\u003c\u003d0)) ERROR: reach_error();if (!(x\u003c\u003d0)) ERROR: reach_error();if (!(x\u003c\u003d0)) ERROR: reach_error();if (!(x\u003c\u003d0)) ERROR: reach_error();" + } } }, { - "source": "__loc_250", - "target": "__loc_261", + "source": "__loc_233", + "target": "thr1_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -530,22 +1299,75 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 739, - "colNumberStart": 8, + "colNumberStart": 4, + "lineNumberStop": 739, + "colNumberStop": 37, + "offsetStart": 31381, + "offsetEnd": 31414, + "sourceText": "if (!(x\u003c\u003d0)) ERROR: reach_error();" + } + }, + "content": "((assume (/\u003d (ite (\u003d (ite (\u003c\u003d x 0) 1 0) 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" + } + ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 739, + "colNumberStart": 4, + "lineNumberStop": 739, + "colNumberStop": 37, + "offsetStart": 31381, + "offsetEnd": 31414, + "sourceText": "if (!(x\u003c\u003d0)) ERROR: reach_error();ERROR: reach_error();reach_error();reach_error();reach_error();reach_error();" + } + } + }, + { + "source": "__loc_233", + "target": "__loc_244", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 739, + "colNumberStart": 4, "lineNumberStop": 739, - "colNumberStop": 14, - "offsetStart": 31385, - "offsetEnd": 31391, - "sourceText": "!(x\u003c\u003d0)" + "colNumberStop": 37, + "offsetStart": 31381, + "offsetEnd": 31414, + "sourceText": "if (!(x\u003c\u003d0)) ERROR: reach_error();" } }, - "content": "(assume (\u003d (ite (\u003d (ite (\u003c\u003d x 0) 1 0) 0) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003d (ite (\u003c\u003d x 0) 1 0) 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 739, + "colNumberStart": 4, + "lineNumberStop": 740, + "colNumberStop": 37, + "offsetStart": 31381, + "offsetEnd": 31445, + "sourceText": "if (!(x\u003c\u003d0)) ERROR: reach_error();if (!(x\u003c\u003d0)) ERROR: reach_error();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_42", - "target": "__loc_63", + "source": "__loc_244", + "target": "__loc_263", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -558,13 +1380,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 708, + "lineNumberStart": 740, "colNumberStart": 4, - "lineNumberStop": 708, - "colNumberStop": 28, - "offsetStart": 30527, - "offsetEnd": 30551, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStop": 740, + "colNumberStop": 29, + "offsetStart": 31420, + "offsetEnd": 31445, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -574,39 +1396,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign flag1 1)" + "content": "(assign turn 1)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 710, + "lineNumberStart": 742, "colNumberStart": 4, - "lineNumberStop": 710, - "colNumberStop": 26, - "offsetStart": 30573, - "offsetEnd": 30595, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStop": 742, + "colNumberStop": 27, + "offsetStart": 31465, + "offsetEnd": 31488, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 740, + "colNumberStart": 4, + "lineNumberStop": 743, + "colNumberStop": 29, + "offsetStart": 31420, + "offsetEnd": 31519, + "sourceText": "__VERIFIER_atomic_begin();turn \u003d 1;turn \u003d 1;turn \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_63", - "target": "__loc_84", + "source": "__loc_263", + "target": "thr1_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -619,13 +1447,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 711, + "lineNumberStart": 743, "colNumberStart": 4, - "lineNumberStop": 711, - "colNumberStop": 28, - "offsetStart": 30602, - "offsetEnd": 30626, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStop": 743, + "colNumberStop": 29, + "offsetStart": 31494, + "offsetEnd": 31519, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -635,39 +1463,61 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 712, - "colNumberStart": 4, - "lineNumberStop": 712, - "colNumberStop": 18, - "offsetStart": 30633, - "offsetEnd": 30647, - "sourceText": "int f2 \u003d flag2;" + "sourceText": "" } }, - "content": "(assign thr1::f2 flag2)" + "content": "(assign flag1 0)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 713, + "lineNumberStart": 745, "colNumberStart": 4, - "lineNumberStop": 713, - "colNumberStop": 26, - "offsetStart": 30653, - "offsetEnd": 30675, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStop": 745, + "colNumberStop": 27, + "offsetStart": 31540, + "offsetEnd": 31563, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 746, + "colNumberStart": 4, + "lineNumberStop": 746, + "colNumberStop": 12, + "offsetStart": 31569, + "offsetEnd": 31577, + "sourceText": "return 0;" + } + }, + "content": "(assign thr1_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 743, + "colNumberStart": 4, + "lineNumberStop": 746, + "colNumberStop": 29, + "offsetStart": 31494, + "offsetEnd": 31577, + "sourceText": "__VERIFIER_atomic_begin();flag1 \u003d 0;flag1 \u003d 0;flag1 \u003d 0;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();return 0;return 0;return 0;return 0;" + } } }, { - "source": "__loc_90", - "target": "__loc_111", + "source": "__loc_58", + "target": "__loc_79", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -680,13 +1530,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 715, - "colNumberStart": 8, - "lineNumberStop": 715, - "colNumberStop": 32, - "offsetStart": 30708, - "offsetEnd": 30732, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 711, + "colNumberStart": 4, + "lineNumberStop": 711, + "colNumberStop": 29, + "offsetStart": 30602, + "offsetEnd": 30627, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -696,39 +1546,51 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 716, - "colNumberStart": 8, - "lineNumberStop": 716, - "colNumberStop": 20, - "offsetStart": 30743, - "offsetEnd": 30755, - "sourceText": "int t \u003d turn;" + "lineNumberStart": 712, + "colNumberStart": 4, + "lineNumberStop": 712, + "colNumberStop": 18, + "offsetStart": 30633, + "offsetEnd": 30647, + "sourceText": "int f2 \u003d flag2;" } }, - "content": "(assign thr1::while1::t turn)" + "content": "(assign thr1::f2 flag2)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 717, - "colNumberStart": 8, - "lineNumberStop": 717, - "colNumberStop": 30, - "offsetStart": 30765, - "offsetEnd": 30787, - "sourceText": "__VERIFIER_atomic_end()" + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 713, + "colNumberStart": 4, + "lineNumberStop": 713, + "colNumberStop": 27, + "offsetStart": 30653, + "offsetEnd": 30676, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 711, + "colNumberStart": 4, + "lineNumberStop": 737, + "colNumberStop": 29, + "offsetStart": 30602, + "offsetEnd": 31364, + "sourceText": "__VERIFIER_atomic_begin();int f2 \u003d flag2;int f2 \u003d flag2;int f2 \u003d flag2;int f2 \u003d flag2;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_261", - "target": "__loc_282", + "source": "__loc_199", + "target": "__loc_79", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -741,13 +1603,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 740, - "colNumberStart": 4, - "lineNumberStop": 740, - "colNumberStop": 28, - "offsetStart": 31420, - "offsetEnd": 31444, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 734, + "colNumberStart": 8, + "lineNumberStop": 734, + "colNumberStop": 33, + "offsetStart": 31280, + "offsetEnd": 31305, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -757,39 +1619,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign turn 1)" + "content": "(assign thr1::f2 flag2)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 742, - "colNumberStart": 4, - "lineNumberStop": 742, - "colNumberStop": 26, - "offsetStart": 31465, - "offsetEnd": 31487, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 736, + "colNumberStart": 8, + "lineNumberStop": 736, + "colNumberStop": 31, + "offsetStart": 31335, + "offsetEnd": 31358, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 714, + "colNumberStart": 4, + "lineNumberStop": 737, + "colNumberStop": 33, + "offsetStart": 30682, + "offsetEnd": 31364, + "sourceText": "__VERIFIER_atomic_begin();f2 \u003d flag2;f2 \u003d flag2;f2 \u003d flag2;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }while (f2 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f2 \u003d flag2;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_117", - "target": "__loc_138", + "source": "__loc_106", + "target": "__loc_199", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -797,60 +1665,40 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 719, - "colNumberStart": 12, - "lineNumberStop": 719, - "colNumberStop": 36, - "offsetStart": 30824, - "offsetEnd": 30848, - "sourceText": "__VERIFIER_atomic_begin()" - } - }, - "content": "F[ATOMIC_BEGIN]" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" - } - }, - "content": "(assign flag1 0)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 721, - "colNumberStart": 12, - "lineNumberStop": 721, - "colNumberStop": 34, - "offsetStart": 30886, - "offsetEnd": 30908, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 718, + "colNumberStart": 8, + "lineNumberStop": 733, + "colNumberStop": 8, + "offsetStart": 30798, + "offsetEnd": 31270, + "sourceText": "if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }" } }, - "content": "F[ATOMIC_END]" + "content": "((assume (\u003d (ite (/\u003d thr1::while1::t 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 718, + "colNumberStart": 8, + "lineNumberStop": 734, + "colNumberStop": 33, + "offsetStart": 30798, + "offsetEnd": 31305, + "sourceText": "if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_212", - "target": "__loc_84", + "source": "__loc_180", + "target": "__loc_199", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -863,13 +1711,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 734, - "colNumberStart": 8, - "lineNumberStop": 734, - "colNumberStop": 32, - "offsetStart": 31280, - "offsetEnd": 31304, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 730, + "colNumberStart": 12, + "lineNumberStop": 730, + "colNumberStop": 37, + "offsetStart": 31175, + "offsetEnd": 31200, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -879,39 +1727,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign thr1::f2 flag2)" + "content": "(assign flag1 1)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 736, - "colNumberStart": 8, - "lineNumberStop": 736, - "colNumberStop": 30, - "offsetStart": 31335, - "offsetEnd": 31357, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 732, + "colNumberStart": 12, + "lineNumberStop": 732, + "colNumberStop": 35, + "offsetStart": 31237, + "offsetEnd": 31260, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 718, + "colNumberStart": 8, + "lineNumberStop": 734, + "colNumberStop": 37, + "offsetStart": 30798, + "offsetEnd": 31305, + "sourceText": "__VERIFIER_atomic_begin();flag1 \u003d 1;flag1 \u003d 1;flag1 \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();if (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n flag1 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag1 \u003d 1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_138", - "target": "__loc_162", + "source": "__loc_131", + "target": "__loc_153", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -927,10 +1781,10 @@ "lineNumberStart": 722, "colNumberStart": 12, "lineNumberStop": 722, - "colNumberStop": 36, + "colNumberStop": 37, "offsetStart": 30923, - "offsetEnd": 30947, - "sourceText": "__VERIFIER_atomic_begin()" + "offsetEnd": 30948, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -940,12 +1794,6 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -959,20 +1807,32 @@ "lineNumberStart": 724, "colNumberStart": 12, "lineNumberStop": 724, - "colNumberStop": 34, + "colNumberStop": 35, "offsetStart": 30984, - "offsetEnd": 31006, - "sourceText": "__VERIFIER_atomic_end()" + "offsetEnd": 31007, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 722, + "colNumberStart": 12, + "lineNumberStop": 729, + "colNumberStop": 37, + "offsetStart": 30923, + "offsetEnd": 31160, + "sourceText": "__VERIFIER_atomic_begin();t \u003d turn;t \u003d turn;t \u003d turn;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_168", - "target": "__loc_162", + "source": "__loc_159", + "target": "__loc_153", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -988,10 +1848,10 @@ "lineNumberStart": 726, "colNumberStart": 16, "lineNumberStop": 726, - "colNumberStop": 40, + "colNumberStop": 41, "offsetStart": 31054, - "offsetEnd": 31078, - "sourceText": "__VERIFIER_atomic_begin()" + "offsetEnd": 31079, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1001,12 +1861,6 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -1020,20 +1874,485 @@ "lineNumberStart": 728, "colNumberStart": 16, "lineNumberStop": 728, - "colNumberStop": 38, + "colNumberStop": 39, "offsetStart": 31123, - "offsetEnd": 31145, - "sourceText": "__VERIFIER_atomic_end()" + "offsetEnd": 31146, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 725, + "colNumberStart": 12, + "lineNumberStop": 729, + "colNumberStop": 41, + "offsetStart": 31021, + "offsetEnd": 31160, + "sourceText": "__VERIFIER_atomic_begin();t \u003d turn;t \u003d turn;t \u003d turn;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 0) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" + } + } + } + ] + }, + { + "name": "thr2", + "params": [ + { + "first": { + "type": "hu.bme.mit.theta.core.decl.VarDecl", + "value": { + "name": "thr2_ret", + "type": "Int" + } + }, + "second": { + "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", + "value": "OUT" + } + }, + { + "first": { + "type": "hu.bme.mit.theta.core.decl.VarDecl", + "value": { + "name": "thr2::_", + "type": "Int" + } + }, + "second": { + "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", + "value": "IN" + } + } + ], + "vars": [ + { + "name": "thr2_ret", + "type": "Int" + }, + { + "name": "thr2::_", + "type": "Int" + }, + { + "name": "thr2::f1", + "type": "Int" + }, + { + "name": "thr2::while5::t", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret22", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret23", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret24", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret25", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret26", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret27", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret28", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret29", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret30", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret31", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret32", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret33", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret34", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret35", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret36", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret37", + "type": "Int" + }, + { + "name": "call_reach_error_ret38", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret39", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret40", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_begin_ret41", + "type": "Int" + }, + { + "name": "call___VERIFIER_atomic_end_ret42", + "type": "Int" + } + ], + "locs": [ + { + "name": "thr2_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 748, + "colNumberStart": 0, + "lineNumberStop": 788, + "colNumberStop": 0, + "offsetStart": 31581, + "offsetEnd": 32659, + "sourceText": "void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f1 \u003d flag1;\n __VERIFIER_atomic_end();\n while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }\n x \u003d 1;\n if (!(x\u003e\u003d1)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;\n}" + } + } + }, + { + "name": "thr2_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 748, + "colNumberStart": 0, + "lineNumberStop": 788, + "colNumberStop": 0, + "offsetStart": 31581, + "offsetEnd": 32659, + "sourceText": "void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f1 \u003d flag1;\n __VERIFIER_atomic_end();\n while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }\n x \u003d 1;\n if (!(x\u003e\u003d1)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;\n}" + } + } + }, + { + "name": "__loc_290", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 749, + "colNumberStart": 4, + "lineNumberStop": 749, + "colNumberStop": 29, + "offsetStart": 31607, + "offsetEnd": 31632, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_309", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 752, + "colNumberStart": 4, + "lineNumberStop": 752, + "colNumberStop": 29, + "offsetStart": 31682, + "offsetEnd": 31707, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_330", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_336", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 756, + "colNumberStart": 8, + "lineNumberStop": 756, + "colNumberStop": 33, + "offsetStart": 31788, + "offsetEnd": 31813, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_357", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_363", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 760, + "colNumberStart": 12, + "lineNumberStop": 760, + "colNumberStop": 37, + "offsetStart": 31904, + "offsetEnd": 31929, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_382", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 763, + "colNumberStart": 12, + "lineNumberStop": 763, + "colNumberStop": 37, + "offsetStart": 32003, + "offsetEnd": 32028, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_404", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_410", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 767, + "colNumberStart": 16, + "lineNumberStop": 767, + "colNumberStop": 41, + "offsetStart": 32134, + "offsetEnd": 32159, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_431", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 771, + "colNumberStart": 12, + "lineNumberStop": 771, + "colNumberStop": 37, + "offsetStart": 32255, + "offsetEnd": 32280, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_450", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 775, + "colNumberStart": 8, + "lineNumberStop": 775, + "colNumberStop": 33, + "offsetStart": 32360, + "offsetEnd": 32385, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_472", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 779, + "colNumberStart": 4, + "lineNumberStop": 779, + "colNumberStop": 9, + "offsetStart": 32450, + "offsetEnd": 32455, + "sourceText": "x \u003d 1;" + } + } + }, + { + "name": "__loc_484", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_495", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 781, + "colNumberStart": 4, + "lineNumberStop": 781, + "colNumberStop": 29, + "offsetStart": 32500, + "offsetEnd": 32525, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "__loc_514", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 784, + "colNumberStart": 4, + "lineNumberStop": 784, + "colNumberStop": 29, + "offsetStart": 32574, + "offsetEnd": 32599, + "sourceText": "__VERIFIER_atomic_begin();" + } + } + }, + { + "name": "thr2_error", + "initial": false, + "final": false, + "error": true, + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + } + } + ], + "edges": [ + { + "source": "thr2_init", + "target": "__loc_290", + "label": { + "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", + "content": {} + }, + "labels": [] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 748, + "colNumberStart": 0, + "lineNumberStop": 788, + "colNumberStop": 29, + "offsetStart": 31581, + "offsetEnd": 32659, + "sourceText": "void *thr2(void *_) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f1 \u003d flag1;\n __VERIFIER_atomic_end();\n while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }\n x \u003d 1;\n if (!(x\u003e\u003d1)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;\n}__VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n int f1 \u003d flag1;\n __VERIFIER_atomic_end();\n while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }\n x \u003d 1;\n if (!(x\u003e\u003d1)) ERROR: reach_error();\n __VERIFIER_atomic_begin();\n turn \u003d 1;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n return 0;__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_191", - "target": "__loc_212", + "source": "__loc_290", + "target": "__loc_309", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1046,13 +2365,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 730, - "colNumberStart": 12, - "lineNumberStop": 730, - "colNumberStop": 36, - "offsetStart": 31175, - "offsetEnd": 31199, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 749, + "colNumberStart": 4, + "lineNumberStop": 749, + "colNumberStop": 29, + "offsetStart": 31607, + "offsetEnd": 31632, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1062,39 +2381,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign flag1 1)" + "content": "(assign flag2 1)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 732, - "colNumberStart": 12, - "lineNumberStop": 732, - "colNumberStop": 34, - "offsetStart": 31237, - "offsetEnd": 31259, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 751, + "colNumberStart": 4, + "lineNumberStop": 751, + "colNumberStop": 27, + "offsetStart": 31653, + "offsetEnd": 31676, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 749, + "colNumberStart": 4, + "lineNumberStop": 752, + "colNumberStop": 29, + "offsetStart": 31607, + "offsetEnd": 31707, + "sourceText": "__VERIFIER_atomic_begin();flag2 \u003d 1;flag2 \u003d 1;flag2 \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_250", - "target": "thr1_error", + "source": "__loc_330", + "target": "__loc_336", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1107,23 +2432,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 739, - "colNumberStart": 8, - "lineNumberStop": 739, - "colNumberStop": 14, - "offsetStart": 31385, - "offsetEnd": 31391, - "sourceText": "!(x\u003c\u003d0)" + "lineNumberStart": 755, + "colNumberStart": 4, + "lineNumberStop": 778, + "colNumberStop": 4, + "offsetStart": 31762, + "offsetEnd": 32444, + "sourceText": "while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (/\u003d (ite (\u003d (ite (\u003c\u003d x 0) 1 0) 0) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003e\u003d thr2::f1 1) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 755, + "colNumberStart": 4, + "lineNumberStop": 778, + "colNumberStop": 33, + "offsetStart": 31762, + "offsetEnd": 32444, + "sourceText": "while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }{\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_282", - "target": "thr1_final", + "source": "__loc_336", + "target": "__loc_357", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1136,13 +2473,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 743, - "colNumberStart": 4, - "lineNumberStop": 743, - "colNumberStop": 28, - "offsetStart": 31494, - "offsetEnd": 31518, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 756, + "colNumberStart": 8, + "lineNumberStop": 756, + "colNumberStop": 33, + "offsetStart": 31788, + "offsetEnd": 31813, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1152,134 +2489,51 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 757, + "colNumberStart": 8, + "lineNumberStop": 757, + "colNumberStop": 20, + "offsetStart": 31823, + "offsetEnd": 31835, + "sourceText": "int t \u003d turn;" } }, - "content": "(assign flag1 0)" + "content": "(assign thr2::while5::t turn)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 745, - "colNumberStart": 4, - "lineNumberStop": 745, - "colNumberStop": 26, - "offsetStart": 31540, - "offsetEnd": 31562, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 758, + "colNumberStart": 8, + "lineNumberStop": 758, + "colNumberStop": 31, + "offsetStart": 31845, + "offsetEnd": 31868, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 746, - "colNumberStart": 4, - "lineNumberStop": 746, - "colNumberStop": 11, - "offsetStart": 31569, - "offsetEnd": 31576, - "sourceText": "return 0" - } - }, - "content": "(assign thr1_ret 0)" } ] - } - } - ] - }, - { - "name": "thr2", - "params": [ - { - "first": { - "type": "hu.bme.mit.theta.core.decl.VarDecl", - "value": { - "name": "thr2_ret", - "type": "Int" - } }, - "second": { - "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", - "value": "OUT" - } - }, - { - "first": { - "type": "hu.bme.mit.theta.core.decl.VarDecl", - "value": { - "name": "thr2::_", - "type": "Int" + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 756, + "colNumberStart": 8, + "lineNumberStop": 774, + "colNumberStop": 33, + "offsetStart": 31788, + "offsetEnd": 32350, + "sourceText": "__VERIFIER_atomic_begin();int t \u003d turn;int t \u003d turn;int t \u003d turn;int t \u003d turn;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }" } - }, - "second": { - "type": "hu.bme.mit.theta.xcfa.model.ParamDirection", - "value": "IN" - } - } - ], - "vars": [ - { - "name": "thr2::f1", - "type": "Int" - }, - { - "name": "thr2::while5::t", - "type": "Int" - }, - { - "name": "thr2_ret", - "type": "Int" - } - ], - "locs": [ - "thr2_init {init}", - "thr2_final {final}", - "__loc_310 ", - "__loc_331 ", - "__loc_352 ", - "__loc_358 ", - "__loc_379 ", - "__loc_385 ", - "__loc_406 ", - "__loc_430 ", - "__loc_436 ", - "__loc_459 ", - "__loc_480 ", - "__loc_506 ", - "__loc_518 ", - "__loc_529 ", - "__loc_550 ", - "thr2_error {error}" - ], - "edges": [ - { - "source": "thr2_init", - "target": "__loc_310", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] } }, { - "source": "__loc_352", - "target": "__loc_358", + "source": "__loc_357", + "target": "__loc_363", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1292,23 +2546,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 755, - "colNumberStart": 11, - "lineNumberStop": 755, - "colNumberStop": 17, - "offsetStart": 31769, - "offsetEnd": 31775, - "sourceText": "f1 \u003e\u003d 1" + "lineNumberStart": 759, + "colNumberStart": 8, + "lineNumberStop": 774, + "colNumberStop": 8, + "offsetStart": 31878, + "offsetEnd": 32350, + "sourceText": "if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (/\u003d (ite (\u003e\u003d thr2::f1 1) 1 0) 0))" + "content": "((assume (/\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 759, + "colNumberStart": 8, + "lineNumberStop": 774, + "colNumberStop": 37, + "offsetStart": 31878, + "offsetEnd": 32350, + "sourceText": "if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }{\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_379", - "target": "__loc_385", + "source": "__loc_363", + "target": "__loc_382", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1317,85 +2583,65 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 759, + "lineNumberStart": 760, "colNumberStart": 12, - "lineNumberStop": 759, - "colNumberStop": 17, - "offsetStart": 31882, - "offsetEnd": 31887, - "sourceText": "t !\u003d 1" + "lineNumberStop": 760, + "colNumberStop": 37, + "offsetStart": 31904, + "offsetEnd": 31929, + "sourceText": "__VERIFIER_atomic_begin();" } }, - "content": "(assume (/\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_430", - "target": "__loc_436", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "F[ATOMIC_BEGIN]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 766, - "colNumberStart": 19, - "lineNumberStop": 766, - "colNumberStop": 24, - "offsetStart": 32108, - "offsetEnd": 32113, - "sourceText": "t !\u003d 1" + "sourceText": "" } }, - "content": "(assume (/\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_430", - "target": "__loc_459", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "(assign flag2 0)" + }, { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 766, + "lineNumberStart": 762, "colNumberStart": 12, - "lineNumberStop": 770, - "colNumberStop": 12, - "offsetStart": 32101, - "offsetEnd": 32240, - "sourceText": "while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" + "lineNumberStop": 762, + "colNumberStop": 35, + "offsetStart": 31966, + "offsetEnd": 31989, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "(assume (\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0))" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 760, + "colNumberStart": 12, + "lineNumberStop": 763, + "colNumberStop": 37, + "offsetStart": 31904, + "offsetEnd": 32028, + "sourceText": "__VERIFIER_atomic_begin();flag2 \u003d 0;flag2 \u003d 0;flag2 \u003d 0;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_379", - "target": "__loc_480", + "source": "__loc_404", + "target": "__loc_410", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1408,52 +2654,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 759, + "lineNumberStart": 766, "colNumberStart": 12, - "lineNumberStop": 759, - "colNumberStop": 17, - "offsetStart": 31882, - "offsetEnd": 31887, - "sourceText": "t !\u003d 1" - } - }, - "content": "(assume (\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0))" - } - ] - } - }, - { - "source": "__loc_352", - "target": "__loc_506", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 755, - "colNumberStart": 4, - "lineNumberStop": 778, - "colNumberStop": 4, - "offsetStart": 31762, - "offsetEnd": 32444, - "sourceText": "while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }" + "lineNumberStop": 770, + "colNumberStop": 12, + "offsetStart": 32101, + "offsetEnd": 32240, + "sourceText": "while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (\u003d (ite (\u003e\u003d thr2::f1 1) 1 0) 0))" + "content": "((assume (/\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 766, + "colNumberStart": 12, + "lineNumberStop": 770, + "colNumberStop": 41, + "offsetStart": 32101, + "offsetEnd": 32240, + "sourceText": "while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }{\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_506", - "target": "__loc_518", + "source": "__loc_404", + "target": "__loc_431", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1466,23 +2695,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 766, + "colNumberStart": 12, + "lineNumberStop": 770, + "colNumberStop": 12, + "offsetStart": 32101, + "offsetEnd": 32240, + "sourceText": "while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assign x 1)" + "content": "((assume (\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 766, + "colNumberStart": 12, + "lineNumberStop": 771, + "colNumberStop": 37, + "offsetStart": 32101, + "offsetEnd": 32280, + "sourceText": "while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_518", - "target": "__loc_529", + "source": "__loc_330", + "target": "__loc_472", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1495,23 +2736,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 780, - "colNumberStart": 8, - "lineNumberStop": 780, - "colNumberStop": 14, - "offsetStart": 32465, - "offsetEnd": 32471, - "sourceText": "!(x\u003e\u003d1)" + "lineNumberStart": 755, + "colNumberStart": 4, + "lineNumberStop": 778, + "colNumberStop": 4, + "offsetStart": 31762, + "offsetEnd": 32444, + "sourceText": "while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }" } }, - "content": "(assume (\u003d (ite (\u003d (ite (\u003e\u003d x 1) 1 0) 0) 1 0) 0))" + "content": "((assume (\u003d (ite (\u003e\u003d thr2::f1 1) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 755, + "colNumberStart": 4, + "lineNumberStop": 779, + "colNumberStop": 9, + "offsetStart": 31762, + "offsetEnd": 32455, + "sourceText": "while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }x \u003d 1;x \u003d 1;x \u003d 1;" + } } }, { - "source": "__loc_310", - "target": "__loc_331", + "source": "__loc_472", + "target": "__loc_484", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1519,60 +2772,34 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 749, - "colNumberStart": 4, - "lineNumberStop": 749, - "colNumberStop": 28, - "offsetStart": 31607, - "offsetEnd": 31631, - "sourceText": "__VERIFIER_atomic_begin()" - } - }, - "content": "F[ATOMIC_BEGIN]" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign flag2 1)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 751, - "colNumberStart": 4, - "lineNumberStop": 751, - "colNumberStop": 26, - "offsetStart": 31653, - "offsetEnd": 31675, - "sourceText": "__VERIFIER_atomic_end()" - } - }, - "content": "F[ATOMIC_END]" + "content": "(assign x 1)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 0, + "colNumberStart": 0, + "lineNumberStop": 780, + "colNumberStop": 37, + "offsetStart": 0, + "offsetEnd": 32494, + "sourceText": "if (!(x\u003e\u003d1)) ERROR: reach_error();if (!(x\u003e\u003d1)) ERROR: reach_error();if (!(x\u003e\u003d1)) ERROR: reach_error();if (!(x\u003e\u003d1)) ERROR: reach_error();if (!(x\u003e\u003d1)) ERROR: reach_error();" + } } }, { - "source": "__loc_331", - "target": "__loc_352", + "source": "__loc_484", + "target": "thr2_error", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1580,60 +2807,40 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 752, - "colNumberStart": 4, - "lineNumberStop": 752, - "colNumberStop": 28, - "offsetStart": 31682, - "offsetEnd": 31706, - "sourceText": "__VERIFIER_atomic_begin()" - } - }, - "content": "F[ATOMIC_BEGIN]" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 753, - "colNumberStart": 4, - "lineNumberStop": 753, - "colNumberStop": 18, - "offsetStart": 31713, - "offsetEnd": 31727, - "sourceText": "int f1 \u003d flag1;" - } - }, - "content": "(assign thr2::f1 flag1)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 754, + "lineNumberStart": 780, "colNumberStart": 4, - "lineNumberStop": 754, - "colNumberStop": 26, - "offsetStart": 31733, - "offsetEnd": 31755, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStop": 780, + "colNumberStop": 37, + "offsetStart": 32461, + "offsetEnd": 32494, + "sourceText": "if (!(x\u003e\u003d1)) ERROR: reach_error();" } }, - "content": "F[ATOMIC_END]" + "content": "((assume (/\u003d (ite (\u003d (ite (\u003e\u003d x 1) 1 0) 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 780, + "colNumberStart": 4, + "lineNumberStop": 780, + "colNumberStop": 37, + "offsetStart": 32461, + "offsetEnd": 32494, + "sourceText": "if (!(x\u003e\u003d1)) ERROR: reach_error();ERROR: reach_error();reach_error();reach_error();reach_error();reach_error();" + } } }, { - "source": "__loc_358", - "target": "__loc_379", + "source": "__loc_484", + "target": "__loc_495", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1641,60 +2848,40 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 756, - "colNumberStart": 8, - "lineNumberStop": 756, - "colNumberStop": 32, - "offsetStart": 31788, - "offsetEnd": 31812, - "sourceText": "__VERIFIER_atomic_begin()" - } - }, - "content": "F[ATOMIC_BEGIN]" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 757, - "colNumberStart": 8, - "lineNumberStop": 757, - "colNumberStop": 20, - "offsetStart": 31823, - "offsetEnd": 31835, - "sourceText": "int t \u003d turn;" - } - }, - "content": "(assign thr2::while5::t turn)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 758, - "colNumberStart": 8, - "lineNumberStop": 758, - "colNumberStop": 30, - "offsetStart": 31845, - "offsetEnd": 31867, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 780, + "colNumberStart": 4, + "lineNumberStop": 780, + "colNumberStop": 37, + "offsetStart": 32461, + "offsetEnd": 32494, + "sourceText": "if (!(x\u003e\u003d1)) ERROR: reach_error();" } }, - "content": "F[ATOMIC_END]" + "content": "((assume (\u003d (ite (\u003d (ite (\u003e\u003d x 1) 1 0) 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 780, + "colNumberStart": 4, + "lineNumberStop": 781, + "colNumberStop": 37, + "offsetStart": 32461, + "offsetEnd": 32525, + "sourceText": "if (!(x\u003e\u003d1)) ERROR: reach_error();if (!(x\u003e\u003d1)) ERROR: reach_error();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_529", - "target": "__loc_550", + "source": "__loc_495", + "target": "__loc_514", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1710,10 +2897,10 @@ "lineNumberStart": 781, "colNumberStart": 4, "lineNumberStop": 781, - "colNumberStop": 28, + "colNumberStop": 29, "offsetStart": 32500, - "offsetEnd": 32524, - "sourceText": "__VERIFIER_atomic_begin()" + "offsetEnd": 32525, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1723,12 +2910,6 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -1742,20 +2923,32 @@ "lineNumberStart": 783, "colNumberStart": 4, "lineNumberStop": 783, - "colNumberStop": 26, + "colNumberStop": 27, "offsetStart": 32545, - "offsetEnd": 32567, - "sourceText": "__VERIFIER_atomic_end()" + "offsetEnd": 32568, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 781, + "colNumberStart": 4, + "lineNumberStop": 784, + "colNumberStop": 29, + "offsetStart": 32500, + "offsetEnd": 32599, + "sourceText": "__VERIFIER_atomic_begin();turn \u003d 1;turn \u003d 1;turn \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_385", - "target": "__loc_406", + "source": "__loc_514", + "target": "thr2_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1768,13 +2961,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 760, - "colNumberStart": 12, - "lineNumberStop": 760, - "colNumberStop": 36, - "offsetStart": 31904, - "offsetEnd": 31928, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 784, + "colNumberStart": 4, + "lineNumberStop": 784, + "colNumberStop": 29, + "offsetStart": 32574, + "offsetEnd": 32599, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1784,12 +2977,6 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -1800,23 +2987,51 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 762, - "colNumberStart": 12, - "lineNumberStop": 762, - "colNumberStop": 34, - "offsetStart": 31966, - "offsetEnd": 31988, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 786, + "colNumberStart": 4, + "lineNumberStop": 786, + "colNumberStop": 27, + "offsetStart": 32620, + "offsetEnd": 32643, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 787, + "colNumberStart": 4, + "lineNumberStop": 787, + "colNumberStop": 12, + "offsetStart": 32649, + "offsetEnd": 32657, + "sourceText": "return 0;" + } + }, + "content": "(assign thr2_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 784, + "colNumberStart": 4, + "lineNumberStop": 787, + "colNumberStop": 29, + "offsetStart": 32574, + "offsetEnd": 32657, + "sourceText": "__VERIFIER_atomic_begin();flag2 \u003d 0;flag2 \u003d 0;flag2 \u003d 0;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();return 0;return 0;return 0;return 0;" + } } }, { - "source": "__loc_480", - "target": "__loc_352", + "source": "__loc_309", + "target": "__loc_330", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1829,13 +3044,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 775, - "colNumberStart": 8, - "lineNumberStop": 775, - "colNumberStop": 32, - "offsetStart": 32360, - "offsetEnd": 32384, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 752, + "colNumberStart": 4, + "lineNumberStop": 752, + "colNumberStop": 29, + "offsetStart": 31682, + "offsetEnd": 31707, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1845,13 +3060,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" + "lineNumberStart": 753, + "colNumberStart": 4, + "lineNumberStop": 753, + "colNumberStop": 18, + "offsetStart": 31713, + "offsetEnd": 31727, + "sourceText": "int f1 \u003d flag1;" } }, "content": "(assign thr2::f1 flag1)" @@ -1861,23 +3076,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 777, - "colNumberStart": 8, - "lineNumberStop": 777, - "colNumberStop": 30, - "offsetStart": 32415, - "offsetEnd": 32437, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 754, + "colNumberStart": 4, + "lineNumberStop": 754, + "colNumberStop": 27, + "offsetStart": 31733, + "offsetEnd": 31756, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 752, + "colNumberStart": 4, + "lineNumberStop": 778, + "colNumberStop": 29, + "offsetStart": 31682, + "offsetEnd": 32444, + "sourceText": "__VERIFIER_atomic_begin();int f1 \u003d flag1;int f1 \u003d flag1;int f1 \u003d flag1;int f1 \u003d flag1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_406", - "target": "__loc_430", + "source": "__loc_450", + "target": "__loc_330", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1890,13 +3117,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 763, - "colNumberStart": 12, - "lineNumberStop": 763, - "colNumberStop": 36, - "offsetStart": 32003, - "offsetEnd": 32027, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 775, + "colNumberStart": 8, + "lineNumberStop": 775, + "colNumberStop": 33, + "offsetStart": 32360, + "offsetEnd": 32385, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -1906,39 +3133,45 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign thr2::while5::t turn)" + "content": "(assign thr2::f1 flag1)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 765, - "colNumberStart": 12, - "lineNumberStop": 765, - "colNumberStop": 34, - "offsetStart": 32064, - "offsetEnd": 32086, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 777, + "colNumberStart": 8, + "lineNumberStop": 777, + "colNumberStop": 31, + "offsetStart": 32415, + "offsetEnd": 32438, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 755, + "colNumberStart": 4, + "lineNumberStop": 778, + "colNumberStop": 33, + "offsetStart": 31762, + "offsetEnd": 32444, + "sourceText": "__VERIFIER_atomic_begin();f1 \u003d flag1;f1 \u003d flag1;f1 \u003d flag1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }while (f1 \u003e\u003d 1) {\n __VERIFIER_atomic_begin();\n int t \u003d turn;\n __VERIFIER_atomic_end();\n if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }\n __VERIFIER_atomic_begin();\n f1 \u003d flag1;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_436", - "target": "__loc_430", + "source": "__loc_357", + "target": "__loc_450", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -1946,60 +3179,40 @@ "content": {} }, "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 767, - "colNumberStart": 16, - "lineNumberStop": 767, - "colNumberStop": 40, - "offsetStart": 32134, - "offsetEnd": 32158, - "sourceText": "__VERIFIER_atomic_begin()" - } - }, - "content": "F[ATOMIC_BEGIN]" - }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, - "sourceText": "" - } - }, - "content": "(assign thr2::while5::t turn)" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 769, - "colNumberStart": 16, - "lineNumberStop": 769, - "colNumberStop": 38, - "offsetStart": 32203, - "offsetEnd": 32225, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 759, + "colNumberStart": 8, + "lineNumberStop": 774, + "colNumberStop": 8, + "offsetStart": 31878, + "offsetEnd": 32350, + "sourceText": "if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }" } }, - "content": "F[ATOMIC_END]" + "content": "((assume (\u003d (ite (/\u003d thr2::while5::t 1) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 759, + "colNumberStart": 8, + "lineNumberStop": 775, + "colNumberStop": 33, + "offsetStart": 31878, + "offsetEnd": 32385, + "sourceText": "if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_459", - "target": "__loc_480", + "source": "__loc_431", + "target": "__loc_450", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2015,10 +3228,10 @@ "lineNumberStart": 771, "colNumberStart": 12, "lineNumberStop": 771, - "colNumberStop": 36, + "colNumberStop": 37, "offsetStart": 32255, - "offsetEnd": 32279, - "sourceText": "__VERIFIER_atomic_begin()" + "offsetEnd": 32280, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -2028,12 +3241,6 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, @@ -2047,20 +3254,32 @@ "lineNumberStart": 773, "colNumberStart": 12, "lineNumberStop": 773, - "colNumberStop": 34, + "colNumberStop": 35, "offsetStart": 32317, - "offsetEnd": 32339, - "sourceText": "__VERIFIER_atomic_end()" + "offsetEnd": 32340, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 759, + "colNumberStart": 8, + "lineNumberStop": 775, + "colNumberStop": 37, + "offsetStart": 31878, + "offsetEnd": 32385, + "sourceText": "__VERIFIER_atomic_begin();flag2 \u003d 1;flag2 \u003d 1;flag2 \u003d 1;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();if (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n flag2 \u003d 0;\n __VERIFIER_atomic_end();\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n };\n __VERIFIER_atomic_begin();\n flag2 \u003d 1;\n __VERIFIER_atomic_end();\n }__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();__VERIFIER_atomic_begin();" + } } }, { - "source": "__loc_518", - "target": "thr2_error", + "source": "__loc_382", + "target": "__loc_404", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2069,27 +3288,65 @@ }, "labels": [ { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 763, + "colNumberStart": 12, + "lineNumberStop": 763, + "colNumberStop": 37, + "offsetStart": 32003, + "offsetEnd": 32028, + "sourceText": "__VERIFIER_atomic_begin();" + } + }, + "content": "F[ATOMIC_BEGIN]" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + }, + "content": "(assign thr2::while5::t turn)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 780, - "colNumberStart": 8, - "lineNumberStop": 780, - "colNumberStop": 14, - "offsetStart": 32465, - "offsetEnd": 32471, - "sourceText": "!(x\u003e\u003d1)" + "lineNumberStart": 765, + "colNumberStart": 12, + "lineNumberStop": 765, + "colNumberStop": 35, + "offsetStart": 32064, + "offsetEnd": 32087, + "sourceText": "__VERIFIER_atomic_end();" } }, - "content": "(assume (/\u003d (ite (\u003d (ite (\u003e\u003d x 1) 1 0) 0) 1 0) 0))" + "content": "F[ATOMIC_END]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 763, + "colNumberStart": 12, + "lineNumberStop": 770, + "colNumberStop": 37, + "offsetStart": 32003, + "offsetEnd": 32240, + "sourceText": "__VERIFIER_atomic_begin();t \u003d turn;t \u003d turn;t \u003d turn;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" + } } }, { - "source": "__loc_550", - "target": "thr2_final", + "source": "__loc_410", + "target": "__loc_404", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2102,13 +3359,13 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 784, - "colNumberStart": 4, - "lineNumberStop": 784, - "colNumberStop": 28, - "offsetStart": 32574, - "offsetEnd": 32598, - "sourceText": "__VERIFIER_atomic_begin()" + "lineNumberStart": 767, + "colNumberStart": 16, + "lineNumberStop": 767, + "colNumberStop": 41, + "offsetStart": 32134, + "offsetEnd": 32159, + "sourceText": "__VERIFIER_atomic_begin();" } }, "content": "F[ATOMIC_BEGIN]" @@ -2118,50 +3375,40 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assign flag2 0)" + "content": "(assign thr2::while5::t turn)" }, { "type": "hu.bme.mit.theta.xcfa.model.FenceLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 786, - "colNumberStart": 4, - "lineNumberStop": 786, - "colNumberStop": 26, - "offsetStart": 32620, - "offsetEnd": 32642, - "sourceText": "__VERIFIER_atomic_end()" + "lineNumberStart": 769, + "colNumberStart": 16, + "lineNumberStop": 769, + "colNumberStop": 39, + "offsetStart": 32203, + "offsetEnd": 32226, + "sourceText": "__VERIFIER_atomic_end();" } }, "content": "F[ATOMIC_END]" - }, - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 787, - "colNumberStart": 4, - "lineNumberStop": 787, - "colNumberStop": 11, - "offsetStart": 32649, - "offsetEnd": 32656, - "sourceText": "return 0" - } - }, - "content": "(assign thr2_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 766, + "colNumberStart": 12, + "lineNumberStop": 770, + "colNumberStop": 41, + "offsetStart": 32101, + "offsetEnd": 32240, + "sourceText": "__VERIFIER_atomic_begin();t \u003d turn;t \u003d turn;t \u003d turn;__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();__VERIFIER_atomic_end();while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }while (t !\u003d 1) {\n __VERIFIER_atomic_begin();\n t \u003d turn;\n __VERIFIER_atomic_end();\n }" + } } } ] @@ -2184,6 +3431,10 @@ } ], "vars": [ + { + "name": "main_ret", + "type": "Int" + }, { "name": "main::t1", "type": "Int" @@ -2193,72 +3444,170 @@ "type": "Int" }, { - "name": "main_ret", + "name": "call_assume_abort_if_not_ret43", "type": "Int" }, { - "name": "call_assume_abort_if_not_ret43", + "name": "call_pthread_create_ret44", "type": "Int" }, { - "name": "assume_abort_if_not::cond", + "name": "call_pthread_create_ret45", + "type": "Int" + }, + { + "name": "call_pthread_join_ret46", + "type": "Int" + }, + { + "name": "call_pthread_join_ret47", "type": "Int" }, { "name": "assume_abort_if_not_ret", "type": "Int" + }, + { + "name": "assume_abort_if_not::cond", + "type": "Int" + }, + { + "name": "call_abort_ret0", + "type": "Int" } ], "locs": [ - "main_init {init}", - "main_final {final}", - "__loc_577 ", - "__loc_579 ", - "__loc_588 ", - "__loc_606 ", - "__loc_624 ", - "__loc_636 ", - "__loc_648 ", - "__loc_654 ", - "__loc_2658 ", - "assume_abort_if_not_final657 ", - "assume_abort_if_not_init656 ", - "__loc_7659 ", - "__loc_13660 " - ], - "edges": [ { - "source": "__loc_654", - "target": "main_final", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ - { - "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", - "metadata": { - "type": "hu.bme.mit.theta.c2xcfa.CMetaData", - "content": { - "lineNumberStart": 796, - "colNumberStart": 2, - "lineNumberStop": 796, - "colNumberStop": 9, - "offsetStart": 32855, - "offsetEnd": 32862, - "sourceText": "return 0" - } - }, - "content": "(assign main_ret 0)" - } - ] + "name": "main_init", + "initial": true, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 789, + "colNumberStart": 0, + "lineNumberStop": 797, + "colNumberStop": 0, + "offsetStart": 32661, + "offsetEnd": 32865, + "sourceText": "int main() {\n pthread_t t1, t2;\n assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n return 0;\n}" + } + } + }, + { + "name": "main_final", + "initial": false, + "final": true, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 789, + "colNumberStart": 0, + "lineNumberStop": 797, + "colNumberStop": 0, + "offsetStart": 32661, + "offsetEnd": 32865, + "sourceText": "int main() {\n pthread_t t1, t2;\n assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n return 0;\n}" + } + } + }, + { + "name": "__loc_550", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_568", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_586", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_598", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_610", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } + } + }, + { + "name": "__loc_8_628", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "sourceText": "" + } } }, + { + "name": "__loc_14_634", + "initial": false, + "final": false, + "error": false, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 13, + "lineNumberStop": 3, + "colNumberStop": 20, + "offsetStart": 75, + "offsetEnd": 82, + "sourceText": "abort();" + } + } + } + ], + "edges": [ { "source": "main_init", - "target": "__loc_577", + "target": "__loc_550", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2297,71 +3646,45 @@ "content": {} }, "content": "(assign x 0)" - } - ] - } - }, - { - "source": "__loc_577", - "target": "__loc_579", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::t1 0) (\u003c\u003d main::t1 4294967295)))" - } - ] - } - }, - { - "source": "__loc_579", - "target": "__loc_588", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + "content": "((assume (and (\u003e\u003d main::t1 0) (\u003c\u003d main::t1 18446744073709551615))))[choiceType\u003dMAIN_PATH]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": -1, - "colNumberStart": -1, - "lineNumberStop": -1, - "colNumberStop": -1, - "offsetStart": -1, - "offsetEnd": -1, "sourceText": "" } }, - "content": "(assume (and (\u003e\u003d main::t2 0) (\u003c\u003d main::t2 4294967295)))" + "content": "((assume (and (\u003e\u003d main::t2 0) (\u003c\u003d main::t2 18446744073709551615))))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 789, + "colNumberStart": 0, + "lineNumberStop": 797, + "colNumberStop": 41, + "offsetStart": 32661, + "offsetEnd": 32865, + "sourceText": "int main() {\n pthread_t t1, t2;\n assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n return 0;\n}pthread_t t1, t2;\n assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);\n pthread_create(\u0026t1, 0, thr1, 0);\n pthread_create(\u0026t2, 0, thr2, 0);\n pthread_join(t1, 0);\n pthread_join(t2, 0);\n return 0;pthread_t t1, t2;assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);" + } } }, { - "source": "__loc_606", - "target": "__loc_624", + "source": "__loc_568", + "target": "__loc_586", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2377,20 +3700,32 @@ "lineNumberStart": 792, "colNumberStart": 2, "lineNumberStop": 792, - "colNumberStop": 32, + "colNumberStop": 33, "offsetStart": 32739, - "offsetEnd": 32769, - "sourceText": "pthread_create(\u0026t1, 0, thr1, 0)" + "offsetEnd": 32770, + "sourceText": "pthread_create(\u0026t1, 0, thr1, 0);" } }, - "content": "(var main::t1 Int) \u003d start thr1(0)" + "content": "(var main::t1 Int) \u003d start thr1(0, 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 792, + "colNumberStart": 2, + "lineNumberStop": 793, + "colNumberStop": 33, + "offsetStart": 32739, + "offsetEnd": 32805, + "sourceText": "pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);pthread_create(\u0026t2, 0, thr2, 0);" + } } }, { - "source": "__loc_624", - "target": "__loc_636", + "source": "__loc_586", + "target": "__loc_598", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2406,20 +3741,32 @@ "lineNumberStart": 793, "colNumberStart": 2, "lineNumberStop": 793, - "colNumberStop": 32, + "colNumberStop": 33, "offsetStart": 32774, - "offsetEnd": 32804, - "sourceText": "pthread_create(\u0026t2, 0, thr2, 0)" + "offsetEnd": 32805, + "sourceText": "pthread_create(\u0026t2, 0, thr2, 0);" } }, - "content": "(var main::t2 Int) \u003d start thr2(0)" + "content": "(var main::t2 Int) \u003d start thr2(0, 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 793, + "colNumberStart": 2, + "lineNumberStop": 794, + "colNumberStop": 33, + "offsetStart": 32774, + "offsetEnd": 32828, + "sourceText": "pthread_create(\u0026t2, 0, thr2, 0);pthread_join(t1, 0);pthread_join(t1, 0);pthread_join(t1, 0);pthread_join(t1, 0);pthread_join(t1, 0);" + } } }, { - "source": "__loc_636", - "target": "__loc_648", + "source": "__loc_598", + "target": "__loc_610", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2435,20 +3782,32 @@ "lineNumberStart": 794, "colNumberStart": 2, "lineNumberStop": 794, - "colNumberStop": 20, + "colNumberStop": 21, "offsetStart": 32809, - "offsetEnd": 32827, - "sourceText": "pthread_join(t1, 0)" + "offsetEnd": 32828, + "sourceText": "pthread_join(t1, 0);" } }, "content": "join (var main::t1 Int)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 794, + "colNumberStart": 2, + "lineNumberStop": 795, + "colNumberStop": 21, + "offsetStart": 32809, + "offsetEnd": 32851, + "sourceText": "pthread_join(t1, 0);pthread_join(t2, 0);pthread_join(t2, 0);pthread_join(t2, 0);pthread_join(t2, 0);pthread_join(t2, 0);" + } } }, { - "source": "__loc_648", - "target": "__loc_654", + "source": "__loc_610", + "target": "main_final", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2464,44 +3823,48 @@ "lineNumberStart": 795, "colNumberStart": 2, "lineNumberStop": 795, - "colNumberStop": 20, + "colNumberStop": 21, "offsetStart": 32832, - "offsetEnd": 32850, - "sourceText": "pthread_join(t2, 0)" + "offsetEnd": 32851, + "sourceText": "pthread_join(t2, 0);" } }, "content": "join (var main::t2 Int)" + }, + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 796, + "colNumberStart": 2, + "lineNumberStop": 796, + "colNumberStop": 10, + "offsetStart": 32855, + "offsetEnd": 32863, + "sourceText": "return 0;" + } + }, + "content": "(assign main_ret 0)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 795, + "colNumberStart": 2, + "lineNumberStop": 796, + "colNumberStop": 21, + "offsetStart": 32832, + "offsetEnd": 32863, + "sourceText": "pthread_join(t2, 0);return 0;return 0;return 0;return 0;" + } } }, { - "source": "__loc_2658", - "target": "assume_abort_if_not_final657", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] - } - }, - { - "source": "assume_abort_if_not_init656", - "target": "__loc_7659", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [] - } - }, - { - "source": "__loc_7659", - "target": "__loc_13660", + "source": "__loc_550", + "target": "__loc_8_628", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2514,23 +3877,35 @@ "metadata": { "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { - "lineNumberStart": 3, - "colNumberStart": 5, - "lineNumberStop": 3, - "colNumberStop": 9, - "offsetStart": 67, - "offsetEnd": 71, - "sourceText": "!cond" + "lineNumberStart": 791, + "colNumberStart": 2, + "lineNumberStop": 791, + "colNumberStop": 41, + "offsetStart": 32696, + "offsetEnd": 32735, + "sourceText": "assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);" } }, - "content": "(assume (/\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0))" + "content": "(assign assume_abort_if_not::cond (ite (and (/\u003d 0 (ite (\u003c\u003d 0 turn) 1 0)) (/\u003d 0 (ite (\u003c\u003d turn 1) 1 0))) 1 0))" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 791, + "colNumberStop": 41, + "offsetStart": 25, + "offsetEnd": 32735, + "sourceText": "assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);void assume_abort_if_not(int cond) {\n if(!cond) {abort();}\n}if(!cond) {abort();}if(!cond) {abort();}if(!cond) {abort();}if(!cond) {abort();}" + } } }, { - "source": "__loc_7659", - "target": "__loc_2658", + "source": "__loc_8_628", + "target": "__loc_14_634", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2544,22 +3919,34 @@ "type": "hu.bme.mit.theta.c2xcfa.CMetaData", "content": { "lineNumberStart": 3, - "colNumberStart": 5, + "colNumberStart": 2, "lineNumberStop": 3, - "colNumberStop": 9, - "offsetStart": 67, - "offsetEnd": 71, - "sourceText": "!cond" + "colNumberStop": 21, + "offsetStart": 64, + "offsetEnd": 83, + "sourceText": "if(!cond) {abort();}" } }, - "content": "(assume (\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0))" + "content": "((assume (/\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0)))[choiceType\u003dMAIN_PATH]" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 2, + "lineNumberStop": 3, + "colNumberStop": 21, + "offsetStart": 64, + "offsetEnd": 83, + "sourceText": "if(!cond) {abort();}{abort();}abort();abort();abort();" + } } }, { - "source": "__loc_13660", - "target": "assume_abort_if_not_final657", + "source": "__loc_14_634", + "target": "__loc_568", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2570,24 +3957,19 @@ { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 13, + "lineNumberStop": 3, + "colNumberStop": 20, + "offsetStart": 75, + "offsetEnd": 82, + "sourceText": "abort();" + } }, "content": "(assume false)" - } - ] - } - }, - { - "source": "__loc_588", - "target": "assume_abort_if_not_init656", - "label": { - "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", - "metadata": { - "type": "hu.bme.mit.theta.xcfa.model.EmptyMetaData", - "content": {} - }, - "labels": [ + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2596,20 +3978,32 @@ "lineNumberStart": 791, "colNumberStart": 2, "lineNumberStop": 791, - "colNumberStop": 40, + "colNumberStop": 41, "offsetStart": 32696, - "offsetEnd": 32734, - "sourceText": "assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1)" + "offsetEnd": 32735, + "sourceText": "assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);" } }, - "content": "(assign assume_abort_if_not::cond (+ (ite (and (/\u003d 0 (ite (\u003c\u003d (+ 0) (+ turn)) 1 0)) (/\u003d 0 (ite (\u003c\u003d (+ turn) (+ 1)) 1 0))) 1 0)))" + "content": "(assign call_assume_abort_if_not_ret43 assume_abort_if_not_ret)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 2, + "lineNumberStop": 792, + "colNumberStop": 33, + "offsetStart": 75, + "offsetEnd": 32770, + "sourceText": "abort();pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);" + } } }, { - "source": "assume_abort_if_not_final657", - "target": "__loc_606", + "source": "__loc_8_628", + "target": "__loc_568", "label": { "type": "hu.bme.mit.theta.xcfa.model.SequenceLabel", "metadata": { @@ -2617,6 +4011,22 @@ "content": {} }, "labels": [ + { + "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 3, + "colNumberStart": 2, + "lineNumberStop": 3, + "colNumberStop": 21, + "offsetStart": 64, + "offsetEnd": 83, + "sourceText": "if(!cond) {abort();}" + } + }, + "content": "((assume (\u003d (ite (\u003d assume_abort_if_not::cond 0) 1 0) 0)))[choiceType\u003dALTERNATIVE_PATH]" + }, { "type": "hu.bme.mit.theta.xcfa.model.StmtLabel", "metadata": { @@ -2625,15 +4035,27 @@ "lineNumberStart": 791, "colNumberStart": 2, "lineNumberStop": 791, - "colNumberStop": 40, + "colNumberStop": 41, "offsetStart": 32696, - "offsetEnd": 32734, - "sourceText": "assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1)" + "offsetEnd": 32735, + "sourceText": "assume_abort_if_not(0\u003c\u003dturn \u0026\u0026 turn\u003c\u003d1);" } }, "content": "(assign call_assume_abort_if_not_ret43 assume_abort_if_not_ret)" } ] + }, + "metadata": { + "type": "hu.bme.mit.theta.c2xcfa.CMetaData", + "content": { + "lineNumberStart": 2, + "colNumberStart": 0, + "lineNumberStop": 792, + "colNumberStop": 33, + "offsetStart": 25, + "offsetEnd": 32770, + "sourceText": "if(!cond) {abort();}if(!cond) {abort();}void assume_abort_if_not(int cond) {\n if(!cond) {abort();}\n}pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);pthread_create(\u0026t1, 0, thr1, 0);" + } } } ] diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt index 9cf2736445..f4a5801ad3 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt @@ -57,6 +57,8 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { .name("target").value(it.target.name) .name("label") gson.toJson(gson.toJsonTree(it.label), writer) + writer.name("metadata") + gson.toJson(gson.toJsonTree(it.metadata), writer) writer.endObject() } }.endArray() @@ -139,6 +141,7 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { val varsType = object : TypeToken>>() {}.type val locsType = object : TypeToken>() {}.type val labelType = object : TypeToken() {}.type + val metadataType = object : TypeToken() {}.type while (reader.peek() != JsonToken.END_ARRAY) { reader.beginObject() @@ -173,14 +176,16 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { lateinit var source: XcfaLocation lateinit var target: XcfaLocation lateinit var label: XcfaLabel + lateinit var metadata: MetaData while (reader.peek() != JsonToken.END_OBJECT) { when (reader.nextName()) { "source" -> source = checkNotNull(locs[reader.nextString()]) "target" -> target = checkNotNull(locs[reader.nextString()]) "label" -> label = gson.fromJson(reader, labelType) + "metadata" -> metadata = gson.fromJson(reader, metadataType) } } - val edge = XcfaEdge(source, target, label) + val edge = XcfaEdge(source, target, label, metadata) edges.add(edge) source.outgoingEdges.add(edge) target.incomingEdges.add(edge) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt index 77d7743c64..02d6e50e50 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt @@ -16,11 +16,57 @@ package hu.bme.mit.theta.xcfa.gson +import com.google.gson.Gson +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter +import hu.bme.mit.theta.xcfa.model.EmptyMetaData +import hu.bme.mit.theta.xcfa.model.MetaData import hu.bme.mit.theta.xcfa.model.XcfaLocation -val xcfaLocationAdapter: (String) -> XcfaLocation = { - val matchResult = Regex("^([^{ }]*) (\\{.*})?$").matchEntire(it) - check(matchResult != null) - val (name, modifier) = matchResult.destructured - XcfaLocation(name, modifier == "{init}", modifier == "{final}", modifier == "{error}") +class XcfaLocationAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { + + private lateinit var gson: Gson + override fun write(writer: JsonWriter, value: XcfaLocation) { + initGson() + writer.beginObject() + writer.name("name").value(value.name) + writer.name("initial").value(value.initial) + writer.name("final").value(value.final) + writer.name("error").value(value.error) + writer.name("metadata") + gson.toJson(gson.toJsonTree(value.metadata), writer) + writer.endObject() + } + + override fun read(reader: JsonReader): XcfaLocation { + initGson() + reader.beginObject() + + lateinit var name: String + var initial = false + var final = false + var error = false + var metaData: MetaData? = null + + while (reader.hasNext()) { + val jsonName = reader.nextName() + when (jsonName) { + "name" -> name = reader.nextString() + "initial" -> initial = reader.nextBoolean() + "final" -> final = reader.nextBoolean() + "error" -> error = reader.nextBoolean() + "metaData" -> metaData = gson.fromJson(reader, MetaData::class.java) + else -> reader.skipValue() + } + } + reader.endObject() + + return XcfaLocation(name, initial, final, error, metaData ?: EmptyMetaData) + } + + private fun initGson() { + if (!this::gson.isInitialized) gson = gsonSupplier() + } + } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt index b146c7d4f9..96b21e4b97 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt @@ -275,14 +275,14 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { } infix fun String.to(to: String): (lambda: SequenceLabelContext.() -> SequenceLabel) -> XcfaEdge { - val loc1 = locationLut.getOrElse(this) { XcfaLocation(this) } + val loc1 = locationLut.getOrElse(this) { XcfaLocation(this, metadata = EmptyMetaData) } locationLut.putIfAbsent(this, loc1) builder.addLoc(loc1) - val loc2 = locationLut.getOrElse(to) { XcfaLocation(to) } + val loc2 = locationLut.getOrElse(to) { XcfaLocation(to, metadata = EmptyMetaData) } locationLut.putIfAbsent(to, loc2) builder.addLoc(loc2) return { lambda -> - val edge = XcfaEdge(loc1, loc2, lambda(SequenceLabelContext())) + val edge = XcfaEdge(loc1, loc2, lambda(SequenceLabelContext()), EmptyMetaData) builder.addEdge(edge) edge } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt index c47200a0d6..ea1afc35ac 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt @@ -16,13 +16,19 @@ package hu.bme.mit.theta.xcfa.model -abstract class MetaData +abstract class MetaData { + + abstract fun combine(other: MetaData): MetaData +} object EmptyMetaData : MetaData() { // TODO why is this necessary? {@see GsonTest.kt} - private val hash = 123123 + override fun combine(other: MetaData): MetaData { + return other + } + override fun equals(other: Any?): Boolean = other is EmptyMetaData diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt index 0c5c4c461d..0248095a83 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt @@ -26,14 +26,14 @@ class EliminateSelfLoops : ProcedurePass { for (selfLoop in selfLoops) { builder.removeEdge(selfLoop) val source = selfLoop.source - val target = XcfaLocation(source.name + "_" + XcfaLocation.uniqueCounter()) + val target = XcfaLocation(source.name + "_" + XcfaLocation.uniqueCounter(), metadata = EmptyMetaData) builder.addLoc(target) for (outgoingEdge in LinkedHashSet(source.outgoingEdges)) { builder.removeEdge(outgoingEdge) - builder.addEdge(XcfaEdge(target, outgoingEdge.target, outgoingEdge.label)) + builder.addEdge(XcfaEdge(target, outgoingEdge.target, outgoingEdge.label, outgoingEdge.metadata)) } - builder.addEdge(XcfaEdge(source, target, selfLoop.label)) - builder.addEdge(XcfaEdge(target, source, SequenceLabel(listOf(NopLabel)))) + builder.addEdge(XcfaEdge(source, target, selfLoop.label, selfLoop.metadata)) + builder.addEdge(XcfaEdge(target, source, SequenceLabel(listOf(NopLabel)), selfLoop.metadata)) } builder.metaData["noSelfLoops"] = Unit return builder diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt index 987722b622..3effbf99a7 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt @@ -39,7 +39,10 @@ class FinalLocationPass(private val checkOverflow: Boolean) : ProcedurePass { builder.addEdge(XcfaEdge(it.source, builder.finalLoc.get(), SequenceLabel( listOf( StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata)), - metadata = it.metadata))) + metadata = it.metadata + ), it.metadata + ) + ) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt index 8a05f0ef2b..fb8f0d4b31 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt @@ -50,7 +50,7 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } if (found) { builder.removeEdge(edge) - builder.addEdge(XcfaEdge(edge.source, edge.target, SequenceLabel(newStmts))) + builder.addEdge(XcfaEdge(edge.source, edge.target, SequenceLabel(newStmts), edge.metadata)) } } return builder diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt index 48114fc020..3e1fad28db 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt @@ -90,15 +90,21 @@ class InlineProceduresPass(val parseContext: ParseContext) : ProcedurePass { val finalLoc = procedure.finalLoc val errorLoc = procedure.errorLoc - builder.addEdge(XcfaEdge(source, checkNotNull(newLocs[initLoc]), SequenceLabel(inStmts))) + builder.addEdge( + XcfaEdge(source, checkNotNull(newLocs[initLoc]), SequenceLabel(inStmts), e.metadata) + ) if (finalLoc.isPresent) builder.addEdge(XcfaEdge(checkNotNull(newLocs[finalLoc.get()]), target, - SequenceLabel(outStmts))) + SequenceLabel(outStmts), EmptyMetaData + ) + ) if (errorLoc.isPresent) { if (builder.errorLoc.isEmpty) builder.createErrorLoc() builder.addEdge( XcfaEdge(checkNotNull(newLocs[errorLoc.get()]), builder.errorLoc.get(), - SequenceLabel(listOf()))) + SequenceLabel(listOf(NopLabel)), EmptyMetaData + ) + ) } } else { builder.addEdge(e) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt index bc745cfe67..481d019cf0 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt @@ -220,7 +220,9 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { nondetLabel = NondetLabel(oldLabels) builder.removeEdge(edge) } - builder.addEdge(XcfaEdge(source, target, nondetLabel)) + builder.addEdge( + XcfaEdge(source, target, nondetLabel, combineMetadata(edgesToTarget.map(XcfaEdge::metadata))) + ) if (edgesToTarget.size >= 2 && !locationsToVisit.contains(key)) { locationsToVisit.add(key) } @@ -290,7 +292,12 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { val newLabels = mutableListOf() newLabels.addAll(inEdge.getFlatLabels()) newLabels.addAll(outEdge.getFlatLabels()) - builder.addEdge(XcfaEdge(inEdge.source, outEdge.target, SequenceLabel(newLabels))) + builder.addEdge( + XcfaEdge( + inEdge.source, outEdge.target, SequenceLabel(newLabels), + combineMetadata(inEdge.metadata, outEdge.metadata) + ) + ) } return true } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt index 2a2fc5ee60..0c34b94caa 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt @@ -112,7 +112,7 @@ class LoopUnrollPass : ProcedurePass { private fun copyBody(builder: XcfaProcedureBuilder, startLoc: XcfaLocation, index: Int, removeCond: Boolean) : XcfaLocation { val locs = loopLocs.associateWith { - val loc = XcfaLocation("${it.name}_loop${index}") + val loc = XcfaLocation("${it.name}_loop${index}", metadata = it.metadata) builder.addLoc(loc) loc } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt index 07a1b62bb9..c505d0e99b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt @@ -77,7 +77,7 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( listOf( StmtLabel(assign1, metadata = invokeLabel.metadata), - StmtLabel(assign2, metadata = invokeLabel.metadata))))) + StmtLabel(assign2, metadata = invokeLabel.metadata))), it.metadata)) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt index ffcda3e8bb..2737d1dbb1 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt @@ -34,7 +34,7 @@ class NoSideEffectPass(val parseContext: ParseContext) : ProcedurePass { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { - builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel(listOf(NopLabel)))) + builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel(listOf(NopLabel)), it.metadata)) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt index fd7dfcb847..9c2819461c 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt @@ -40,7 +40,7 @@ class NondetFunctionPass : ProcedurePass { val havoc = HavocStmt.of( (invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*>) builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( - listOf(StmtLabel(havoc, metadata = invokeLabel.metadata))))) + listOf(StmtLabel(havoc, metadata = invokeLabel.metadata))), it.metadata)) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt index cb5c74b8cb..43594c362a 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt @@ -53,13 +53,13 @@ fun XcfaEdge.splitIf(function: (XcfaLabel) -> Boolean): List { val locations = ArrayList() locations.add(source) for (i in 2..(newLabels.size)) { - locations.add(XcfaLocation("loc" + XcfaLocation.uniqueCounter())) + locations.add(XcfaLocation("loc" + XcfaLocation.uniqueCounter(), metadata = EmptyMetaData)) } locations.add(target) val newEdges = ArrayList() for ((i, label) in newLabels.withIndex()) { - newEdges.add(XcfaEdge(locations[i], locations[i + 1], label)) + newEdges.add(XcfaEdge(locations[i], locations[i + 1], label, metadata)) } return newEdges } @@ -158,4 +158,9 @@ private fun XcfaProcedureBuilder.canInline(tally: LinkedList): Boolean { tally.pop() metaData[if (recursive) "recursive" else "canInline"] = Unit return !recursive -} \ No newline at end of file +} + +fun combineMetadata(vararg metaData: MetaData): MetaData = combineMetadata(metaData.toList()) + +fun combineMetadata(metaData: Collection): MetaData = + metaData.reduce { i1, i2 -> i1.combine(i2) } diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt index 65a89e0533..456f2e4703 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt @@ -46,8 +46,7 @@ class GsonTest { private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean): Gson { val gsonBuilder = GsonBuilder() lateinit var gson: Gson - gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, - StringTypeAdapter(xcfaLocationAdapter)) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, XcfaLocationAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, VarDeclAdapter({ gson }, scope, env, !newScope)) diff --git a/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java b/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java index 96c5899062..7a3a159a80 100644 --- a/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java +++ b/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java @@ -80,9 +80,9 @@ public static Collection data() { "src/test/resources/property/green_and_red.prop", true, "z3:4.13.0"}, - {"src/test/resources/model/trafficlight_v2.xsts", - "src/test/resources/property/green_and_red.prop", true, - "eldarica:2.1"}, +// {"src/test/resources/model/trafficlight_v2.xsts", +// "src/test/resources/property/green_and_red.prop", true, +// "eldarica:2.1"}, {"src/test/resources/model/trafficlight_v2.xsts", "src/test/resources/property/green_and_red.prop", true, From c15b70cd05d8c2c901ec2d67ae7af3ed96433c40 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:15:53 +0100 Subject: [PATCH 11/18] added portfolio as a default backend when dealing with --svcomp tasks --- .../src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt index 54e2c0d406..1d7d6d208b 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt @@ -66,7 +66,8 @@ class XcfaCli(private val args: Array) { "--disable-arg-generation", "--disable-chc-serialization", "--disable-c-serialization", - "--only-svcomp-witness" + "--only-svcomp-witness", + "--backend", "PORTFOLIO" ) ) } From 301319a7eb07490219a88a4991f97e589a62908f Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:17:20 +0100 Subject: [PATCH 12/18] Only adding backend if not explicitly specified --- .../src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt index 1d7d6d208b..e5370bdf2e 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt @@ -67,9 +67,11 @@ class XcfaCli(private val args: Array) { "--disable-chc-serialization", "--disable-c-serialization", "--only-svcomp-witness", - "--backend", "PORTFOLIO" ) ) + if (!remainingFlags.contains("--backend")) { + remainingFlags.addAll(listOf("--backend", "PORTFOLIO")) + } } while (remainingFlags.isNotEmpty()) { val nextArgs = remainingFlags.toTypedArray() From 606911caa6463bc09c62235abdd070457f823cb6 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:19:43 +0100 Subject: [PATCH 13/18] Formatted files --- .../grammar/function/FunctionVisitor.java | 353 ++-- .../model/statements/CStatement.java | 21 +- .../frontend/chc/ChcBackwardXcfaBuilder.java | 95 +- .../frontend/chc/ChcForwardXcfaBuilder.java | 51 +- .../java/hu/bme/mit/theta/c2xcfa/CMetaData.kt | 114 +- .../mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 1702 +++++++++-------- .../litmus2xcfa/dsl/LitmusAArch64.java | 316 ++- .../bme/mit/theta/llvm2xcfa/LlvmMetadata.java | 4 +- .../hu/bme/mit/theta/llvm2xcfa/Utils.java | 91 +- .../concrete/ArrayIntrinsicsHandler.java | 81 +- .../concrete/MemoryInstructionHandler.java | 96 +- .../concrete/OtherInstructionHandler.java | 264 ++- .../handlers/states/FunctionState.java | 69 +- .../bme/mit/theta/xcfa/analysis/XcfaAction.kt | 70 +- .../xcfa/analysis/XcfaExplAnalysisTest.kt | 4 +- .../xcfa/analysis/XcfaPredAnalysisTest.kt | 4 +- .../theta/xcfa/analysis/XcfaStateLtsTest.kt | 249 +-- subprojects/xcfa/xcfa-cli/build.gradle.kts | 1 - .../java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt | 173 +- .../xcfa/cli/utils/GraphmlWitnessWriter.kt | 200 +- .../bme/mit/theta/xcfa/cli/utils/GsonUtils.kt | 192 +- .../theta/xcfa/cli/utils/YmlWitnessWriter.kt | 282 +-- .../theta/xcfa/cli/witnesses/CommonWitness.kt | 128 +- .../xcfa/cli/witnesses/GraphmlWitness.kt | 196 +- .../xcfa/cli/witnesses/TraceToWitness.kt | 345 ++-- .../cli/witnesses/XcfaTraceConcretizer.java | 50 +- .../theta/xcfa/cli/witnesses/YamlWitness.kt | 383 ++-- .../mit/theta/xcfa/cli/XcfaCliParseTest.kt | 513 ++--- .../mit/theta/xcfa/cli/XcfaCliProofTest.kt | 8 +- .../bme/mit/theta/xcfa/cli/YamlParseTest.kt | 84 +- .../hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt | 349 ++-- .../theta/xcfa/gson/XcfaLocationAdapter.kt | 75 +- .../java/hu/bme/mit/theta/xcfa/model/Dsl.kt | 470 ++--- .../hu/bme/mit/theta/xcfa/model/MetaData.kt | 18 +- .../java/hu/bme/mit/theta/xcfa/model/XCFA.kt | 217 ++- .../theta/xcfa/passes/EliminateSelfLoops.kt | 43 +- .../theta/xcfa/passes/EmptyEdgeRemovalPass.kt | 70 +- .../theta/xcfa/passes/ErrorLocationPass.kt | 58 +- .../theta/xcfa/passes/FinalLocationPass.kt | 67 +- .../xcfa/passes/FpFunctionsToExprsPass.kt | 583 +++--- .../theta/xcfa/passes/InlineProceduresPass.kt | 201 +- .../hu/bme/mit/theta/xcfa/passes/LbePass.kt | 504 ++--- .../mit/theta/xcfa/passes/LoopUnrollPass.kt | 494 ++--- .../theta/xcfa/passes/MallocFunctionPass.kt | 130 +- .../mit/theta/xcfa/passes/NoSideEffectPass.kt | 59 +- .../theta/xcfa/passes/NondetFunctionPass.kt | 61 +- .../hu/bme/mit/theta/xcfa/passes/Utils.kt | 240 +-- .../hu/bme/mit/theta/xcfa/gson/GsonTest.kt | 144 +- .../mit/theta/xsts/analysis/XstsHornTest.java | 807 +++++--- 49 files changed, 6147 insertions(+), 4582 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java index e4dbd1a5c8..d45fe00e83 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java @@ -13,9 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.frontend.transformation.grammar.function; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.decl.Decls.Var; +import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Add; +import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Ite; +import static hu.bme.mit.theta.core.utils.TypeUtils.cast; +import static hu.bme.mit.theta.grammar.UtilsKt.textWithWS; + import hu.bme.mit.theta.c.frontend.dsl.gen.CBaseVisitor; import hu.bme.mit.theta.c.frontend.dsl.gen.CParser; import hu.bme.mit.theta.common.Tuple2; @@ -47,24 +53,17 @@ import hu.bme.mit.theta.frontend.transformation.model.types.complex.CVoid; import hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleType; import hu.bme.mit.theta.frontend.transformation.model.types.simple.Struct; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.Token; - import java.util.*; import java.util.stream.Stream; - -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.decl.Decls.Var; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Add; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Ite; -import static hu.bme.mit.theta.core.utils.TypeUtils.cast; -import static hu.bme.mit.theta.grammar.UtilsKt.textWithWS; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; /** - * FunctionVisitor is responsible for the instantiation of high-level model elements, such as Programs, Functions, - * and Statements. It employs a TypeVisitor instance to provide type information, a DeclarationVisitor instance to - * provide information on declarations (both global and local, complete with initializations) and an ExpressionVisitor - * instance to provide information on Expressions in the source code. + * FunctionVisitor is responsible for the instantiation of high-level model elements, such as + * Programs, Functions, and Statements. It employs a TypeVisitor instance to provide type + * information, a DeclarationVisitor instance to provide information on declarations (both global + * and local, complete with initializations) and an ExpressionVisitor instance to provide + * information on Expressions in the source code. */ public class FunctionVisitor extends CBaseVisitor { private final ParseContext parseContext; @@ -94,21 +93,24 @@ private void createVars(CDeclaration declaration) { private String getName(final String name) { final StringJoiner sj = new StringJoiner("::"); - for (Iterator>>> iterator = variables.descendingIterator(); iterator.hasNext(); ) { + for (Iterator>>> iterator = + variables.descendingIterator(); + iterator.hasNext(); ) { Tuple2>> variable = iterator.next(); - if (!variable.get1().equals("")) - sj.add(variable.get1()); + if (!variable.get1().equals("")) sj.add(variable.get1()); } sj.add(name); return sj.toString(); } private void createVars(String name, CDeclaration declaration, CComplexType type) { -// checkState(declaration.getArrayDimensions().size() <= 1, "Currently, higher dimension arrays not supported"); + // checkState(declaration.getArrayDimensions().size() <= 1, "Currently, higher + // dimension arrays not supported"); Tuple2>> peek = variables.peek(); VarDecl varDecl = Var(getName(name), type.getSmtType()); if (peek.get2().containsKey(name)) { - uniqueWarningLogger.write(Level.INFO, "WARNING: Variable already exists: " + name + "\n"); + uniqueWarningLogger.write( + Level.INFO, "WARNING: Variable already exists: " + name + "\n"); varDecl = peek.get2().get(name); } peek.get2().put(name, varDecl); @@ -141,19 +143,27 @@ public CStatement visitCompilationUnit(CParser.CompilationUnitContext ctx) { // ExpressionVisitor.setBitwise(ctx.accept(BitwiseChecker.instance)); ctx.accept(typedefVisitor); - List globalUsages = globalDeclUsageVisitor.getGlobalUsages(ctx); + List globalUsages = + globalDeclUsageVisitor.getGlobalUsages(ctx); // if arithemetic is set on efficient, we change it to either bv or int arithmetic here - if (parseContext.getArithmetic() == ArchitectureConfig.ArithmeticType.efficient) { // if it wasn't on efficient, the check returns manual - Set arithmeticTraits = BitwiseChecker.gatherArithmeticTraits(parseContext, globalUsages); + if (parseContext.getArithmetic() + == ArchitectureConfig.ArithmeticType + .efficient) { // if it wasn't on efficient, the check returns manual + Set arithmeticTraits = + BitwiseChecker.gatherArithmeticTraits(parseContext, globalUsages); parseContext.setArithmetic( - arithmeticTraits.contains(ArithmeticTrait.BITWISE) || arithmeticTraits.contains(ArithmeticTrait.FLOAT) ? - ArithmeticType.bitvector : ArithmeticType.integer); + arithmeticTraits.contains(ArithmeticTrait.BITWISE) + || arithmeticTraits.contains(ArithmeticTrait.FLOAT) + ? ArithmeticType.bitvector + : ArithmeticType.integer); } Set typedefs = ctx.accept(typedefVisitor); for (CDeclaration typedef : typedefs) { - parseContext.getMetadata().create(typedef.getName(), "cTypedefName", typedef.getActualType()); + parseContext + .getMetadata() + .create(typedef.getName(), "cTypedefName", typedef.getActualType()); } CProgram program = new CProgram(parseContext); @@ -171,7 +181,8 @@ public CStatement visitCompilationUnit(CParser.CompilationUnitContext ctx) { public void recordMetadata(ParserRuleContext ctx, CStatement statement) { if (currentStatementContext != null) { - ctx = currentStatementContext; // this will overwrite the current ASt element's ctx with the statement's ctx + ctx = currentStatementContext; // this will overwrite the current ASt element's ctx + // with the statement's ctx } Token start = ctx.getStart(); Token stop = ctx.getStop(); @@ -181,7 +192,10 @@ public void recordMetadata(ParserRuleContext ctx, CStatement statement) { int lineNumberStart = start.getLine(); int colNumberStart = start.getCharPositionInLine(); int lineNumberStop = stop.getLine() + stopLines; - int colNumberStop = stopLines == 0 ? stop.getCharPositionInLine() + stopText.length() - 1 : stopTextLines[stopLines].length(); + int colNumberStop = + stopLines == 0 + ? stop.getCharPositionInLine() + stopText.length() - 1 + : stopTextLines[stopLines].length(); int offsetStart = start.getStartIndex(); int offsetEnd = stop.getStopIndex(); statement.setLineNumberStart(lineNumberStart); @@ -194,14 +208,17 @@ public void recordMetadata(ParserRuleContext ctx, CStatement statement) { statement.setCtx(ctx); } - @Override public CStatement visitGlobalDeclaration(CParser.GlobalDeclarationContext ctx) { - List declarations = declarationVisitor.getDeclarations(ctx.declaration().declarationSpecifiers(), ctx.declaration().initDeclaratorList()); + List declarations = + declarationVisitor.getDeclarations( + ctx.declaration().declarationSpecifiers(), + ctx.declaration().initDeclaratorList()); CDecls decls = new CDecls(parseContext); for (CDeclaration declaration : declarations) { if (!declaration.getType().isTypedef()) { - if (!declaration.isFunc()) { // functions should not be interpreted as global variables + if (!declaration + .isFunc()) { // functions should not be interpreted as global variables createVars(declaration); for (VarDecl varDecl : declaration.getVarDecls()) { decls.getcDeclarations().add(Tuple2.of(declaration, varDecl)); @@ -210,7 +227,9 @@ public CStatement visitGlobalDeclaration(CParser.GlobalDeclarationContext ctx) { CSimpleType returnType = declaration.getType(); declaration.setType(returnType); if (!variables.peek().get2().containsKey(declaration.getName())) { - parseContext.getMetadata().create(declaration.getName(), "cType", returnType.getActualType()); + parseContext + .getMetadata() + .create(declaration.getName(), "cType", returnType.getActualType()); createVars(declaration); for (VarDecl varDecl : declaration.getVarDecls()) { functions.put(varDecl, declaration); @@ -230,7 +249,9 @@ public CStatement visitFunctionDefinition(CParser.FunctionDefinitionContext ctx) CDeclaration funcDecl = ctx.declarator().accept(declarationVisitor); funcDecl.setType(returnType); if (!variables.peek().get2().containsKey(funcDecl.getName())) { - parseContext.getMetadata().create(funcDecl.getName(), "cType", returnType.getActualType()); + parseContext + .getMetadata() + .create(funcDecl.getName(), "cType", returnType.getActualType()); createVars(funcDecl); for (VarDecl varDecl : funcDecl.getVarDecls()) { functions.put(varDecl, funcDecl); @@ -239,20 +260,21 @@ public CStatement visitFunctionDefinition(CParser.FunctionDefinitionContext ctx) variables.push(Tuple2.of(funcDecl.getName(), new LinkedHashMap<>())); flatVariables.clear(); for (CDeclaration functionParam : funcDecl.getFunctionParams()) { - if (functionParam.getName() != null) - createVars(functionParam); + if (functionParam.getName() != null) createVars(functionParam); } CParser.BlockItemListContext blockItemListContext = ctx.compoundStatement().blockItemList(); if (blockItemListContext != null) { CStatement accept = blockItemListContext.accept(this); variables.pop(); - CFunction cFunction = new CFunction(funcDecl, accept, new ArrayList<>(flatVariables), parseContext); + CFunction cFunction = + new CFunction(funcDecl, accept, new ArrayList<>(flatVariables), parseContext); recordMetadata(ctx, cFunction); return cFunction; } variables.pop(); CCompound cCompound = new CCompound(parseContext); - CFunction cFunction = new CFunction(funcDecl, cCompound, new ArrayList<>(flatVariables), parseContext); + CFunction cFunction = + new CFunction(funcDecl, cCompound, new ArrayList<>(flatVariables), parseContext); recordMetadata(ctx, cCompound); recordMetadata(ctx, cFunction); return cFunction; @@ -288,10 +310,20 @@ public CStatement visitIdentifierStatement(CParser.IdentifierStatementContext ct @Override public CStatement visitCaseStatement(CParser.CaseStatementContext ctx) { parseContext.getCStmtCounter().incrementBranches(); - CExpr cexpr = new CExpr(ctx.constantExpression().accept(new ExpressionVisitor(parseContext, this, variables, functions, typedefVisitor, typeVisitor, uniqueWarningLogger)), parseContext); - CCase cCase = new CCase( - cexpr, - ctx.statement().accept(this), parseContext); + CExpr cexpr = + new CExpr( + ctx.constantExpression() + .accept( + new ExpressionVisitor( + parseContext, + this, + variables, + functions, + typedefVisitor, + typeVisitor, + uniqueWarningLogger)), + parseContext); + CCase cCase = new CCase(cexpr, ctx.statement().accept(this), parseContext); recordMetadata(ctx, cCase); recordMetadata(ctx.constantExpression(), cexpr); return cCase; @@ -316,7 +348,10 @@ public CStatement visitCompoundStatement(CParser.CompoundStatementContext ctx) { @Override public CStatement visitExpressionStatement(CParser.ExpressionStatementContext ctx) { - CStatement statement = ctx.expression() == null ? new CCompound(parseContext) : ctx.expression().accept(this); + CStatement statement = + ctx.expression() == null + ? new CCompound(parseContext) + : ctx.expression().accept(this); recordMetadata(ctx, statement); return statement; } @@ -325,10 +360,12 @@ public CStatement visitExpressionStatement(CParser.ExpressionStatementContext ct public CStatement visitIfStatement(CParser.IfStatementContext ctx) { parseContext.getCStmtCounter().incrementBranches(); variables.push(Tuple2.of("if" + anonCnt++, new LinkedHashMap<>())); - CIf cIf = new CIf( - ctx.expression().accept(this), - ctx.statement(0).accept(this), - ctx.statement().size() > 1 ? ctx.statement(1).accept(this) : null, parseContext); + CIf cIf = + new CIf( + ctx.expression().accept(this), + ctx.statement(0).accept(this), + ctx.statement().size() > 1 ? ctx.statement(1).accept(this) : null, + parseContext); recordMetadata(ctx, cIf); variables.pop(); return cIf; @@ -337,9 +374,9 @@ public CStatement visitIfStatement(CParser.IfStatementContext ctx) { @Override public CStatement visitSwitchStatement(CParser.SwitchStatementContext ctx) { variables.push(Tuple2.of("switch" + anonCnt++, new LinkedHashMap<>())); - CSwitch cSwitch = new CSwitch( - ctx.expression().accept(this), - ctx.statement().accept(this), parseContext); + CSwitch cSwitch = + new CSwitch( + ctx.expression().accept(this), ctx.statement().accept(this), parseContext); recordMetadata(ctx, cSwitch); variables.pop(); return cSwitch; @@ -349,9 +386,9 @@ public CStatement visitSwitchStatement(CParser.SwitchStatementContext ctx) { public CStatement visitWhileStatement(CParser.WhileStatementContext ctx) { parseContext.getCStmtCounter().incrementWhileLoops(); variables.push(Tuple2.of("while" + anonCnt++, new LinkedHashMap<>())); - CWhile cWhile = new CWhile( - ctx.statement().accept(this), - ctx.expression().accept(this), parseContext); + CWhile cWhile = + new CWhile( + ctx.statement().accept(this), ctx.expression().accept(this), parseContext); recordMetadata(ctx, cWhile); variables.pop(); return cWhile; @@ -360,9 +397,9 @@ public CStatement visitWhileStatement(CParser.WhileStatementContext ctx) { @Override public CStatement visitDoWhileStatement(CParser.DoWhileStatementContext ctx) { variables.push(Tuple2.of("dowhile" + anonCnt++, new LinkedHashMap<>())); - CDoWhile cDoWhile = new CDoWhile( - ctx.statement().accept(this), - ctx.expression().accept(this), parseContext); + CDoWhile cDoWhile = + new CDoWhile( + ctx.statement().accept(this), ctx.expression().accept(this), parseContext); recordMetadata(ctx, cDoWhile); variables.pop(); return cDoWhile; @@ -381,7 +418,9 @@ public CStatement visitForStatement(CParser.ForStatementContext ctx) { CCompound newCCompound4 = new CCompound(parseContext); newCCompound1.getcStatementList().add(newCCompound2); Expr one = CComplexType.getSignedInt(parseContext).getUnitValue(); - parseContext.getMetadata().create(one, "cType", CComplexType.getSignedInt(parseContext)); + parseContext + .getMetadata() + .create(one, "cType", CComplexType.getSignedInt(parseContext)); newCCompound2.getcStatementList().add(new CExpr(one, parseContext)); newCCompound2.setPreStatements(newCCompound3); newCCompound2.setPostStatements(newCCompound4); @@ -389,11 +428,7 @@ public CStatement visitForStatement(CParser.ForStatementContext ctx) { recordMetadata(ctx.forCondition(), test); } CStatement incr = ctx.forCondition().forIncr().accept(this); - CFor cFor = new CFor( - ctx.statement().accept(this), - init, - test, - incr, parseContext); + CFor cFor = new CFor(ctx.statement().accept(this), init, test, incr, parseContext); recordMetadata(ctx, cFor); variables.pop(); return cFor; @@ -422,7 +457,10 @@ public CStatement visitBreakStatement(CParser.BreakStatementContext ctx) { @Override public CStatement visitReturnStatement(CParser.ReturnStatementContext ctx) { - CRet cRet = new CRet(ctx.expression() == null ? null : ctx.expression().accept(this), parseContext); + CRet cRet = + new CRet( + ctx.expression() == null ? null : ctx.expression().accept(this), + parseContext); recordMetadata(ctx, cRet); return cRet; } @@ -438,44 +476,73 @@ public CStatement visitStatement(CParser.StatementContext ctx) { @Override public CStatement visitBodyDeclaration(CParser.BodyDeclarationContext ctx) { - List declarations = declarationVisitor.getDeclarations(ctx.declaration().declarationSpecifiers(), ctx.declaration().initDeclaratorList()); + List declarations = + declarationVisitor.getDeclarations( + ctx.declaration().declarationSpecifiers(), + ctx.declaration().initDeclaratorList()); CCompound compound = new CCompound(parseContext); for (CDeclaration declaration : declarations) { if (declaration.getInitExpr() != null) { createVars(declaration); if (declaration.getType() instanceof Struct) { - checkState(declaration.getInitExpr() instanceof CInitializerList, "Struct can only be initialized via an initializer list!"); + checkState( + declaration.getInitExpr() instanceof CInitializerList, + "Struct can only be initialized via an initializer list!"); final var initializerList = (CInitializerList) declaration.getInitExpr(); List> varDecls = declaration.getVarDecls(); VarDecl varDecl = varDecls.get(0); final var ptrType = CComplexType.getUnsignedLong(parseContext); LitExpr currentValue = ptrType.getNullValue(); LitExpr unitValue = ptrType.getUnitValue(); - for (Tuple2, CStatement> statement : initializerList.getStatements()) { + for (Tuple2, CStatement> statement : + initializerList.getStatements()) { final var expr = statement.get2().getExpression(); - final var deref = Exprs.Dereference(cast(varDecl.getRef(), currentValue.getType()), cast(currentValue, currentValue.getType()), expr.getType()); - CAssignment cAssignment = new CAssignment(deref, statement.get2(), "=", parseContext); + final var deref = + Exprs.Dereference( + cast(varDecl.getRef(), currentValue.getType()), + cast(currentValue, currentValue.getType()), + expr.getType()); + CAssignment cAssignment = + new CAssignment(deref, statement.get2(), "=", parseContext); recordMetadata(ctx, cAssignment); compound.getcStatementList().add(cAssignment); - currentValue = Add(currentValue, unitValue).eval(ImmutableValuation.empty()); + currentValue = + Add(currentValue, unitValue).eval(ImmutableValuation.empty()); } } else { - checkState(declaration.getVarDecls().size() == 1, "non-struct declarations shall only have one variable!"); + checkState( + declaration.getVarDecls().size() == 1, + "non-struct declarations shall only have one variable!"); if (declaration.getInitExpr() instanceof CInitializerList initializerList) { final var ptrType = CComplexType.getUnsignedLong(parseContext); LitExpr currentValue = ptrType.getNullValue(); LitExpr unitValue = ptrType.getUnitValue(); - for (Tuple2, CStatement> statement : initializerList.getStatements()) { -// checkState(false, "Code here seems to be buggy"); + for (Tuple2, CStatement> statement : + initializerList.getStatements()) { + // checkState(false, "Code here seems to be + // buggy"); final var expr = statement.get2().getExpression(); - final var deref = Exprs.Dereference(cast(declaration.getVarDecls().get(0).getRef(), currentValue.getType()), cast(currentValue, currentValue.getType()), expr.getType()); - CAssignment cAssignment = new CAssignment(deref, statement.get2(), "=", parseContext); + final var deref = + Exprs.Dereference( + cast( + declaration.getVarDecls().get(0).getRef(), + currentValue.getType()), + cast(currentValue, currentValue.getType()), + expr.getType()); + CAssignment cAssignment = + new CAssignment(deref, statement.get2(), "=", parseContext); recordMetadata(ctx, cAssignment); compound.getcStatementList().add(cAssignment); - currentValue = Add(currentValue, unitValue).eval(ImmutableValuation.empty()); + currentValue = + Add(currentValue, unitValue).eval(ImmutableValuation.empty()); } } else { - CAssignment cAssignment = new CAssignment(declaration.getVarDecls().get(0).getRef(), declaration.getInitExpr(), "=", parseContext); + CAssignment cAssignment = + new CAssignment( + declaration.getVarDecls().get(0).getRef(), + declaration.getInitExpr(), + "=", + parseContext); recordMetadata(ctx, cAssignment); compound.getcStatementList().add(cAssignment); if (declaration.getInitExpr() instanceof CCompound compoundInitExpr) { @@ -494,19 +561,31 @@ public CStatement visitBodyDeclaration(CParser.BodyDeclarationContext ctx) { } } else { createVars(declaration); - // if there is no initializer, then we'll add an assumption regarding min and max values + // if there is no initializer, then we'll add an assumption regarding min and max + // values if (declaration.getType() instanceof Struct) { for (VarDecl varDecl : declaration.getVarDecls()) { - if (!(varDecl.getType() instanceof ArrayType) && !(varDecl.getType() instanceof BoolType)) { // BoolType is either well-defined true/false, or a struct in disguise - AssumeStmt assumeStmt = CComplexType.getType(varDecl.getRef(), parseContext).limit(varDecl.getRef()); + if (!(varDecl.getType() instanceof ArrayType) + && !(varDecl.getType() + instanceof + BoolType)) { // BoolType is either well-defined true/false, + // or a struct in disguise + AssumeStmt assumeStmt = + CComplexType.getType(varDecl.getRef(), parseContext) + .limit(varDecl.getRef()); CAssume cAssume = new CAssume(assumeStmt, parseContext); compound.getcStatementList().add(cAssume); } } } else { VarDecl varDecl = declaration.getVarDecls().get(0); - if (!(varDecl.getType() instanceof ArrayType) && !(varDecl.getType() instanceof BoolType) && !(CComplexType.getType(varDecl.getRef(), parseContext) instanceof CVoid)) { - AssumeStmt assumeStmt = CComplexType.getType(varDecl.getRef(), parseContext).limit(varDecl.getRef()); + if (!(varDecl.getType() instanceof ArrayType) + && !(varDecl.getType() instanceof BoolType) + && !(CComplexType.getType(varDecl.getRef(), parseContext) + instanceof CVoid)) { + AssumeStmt assumeStmt = + CComplexType.getType(varDecl.getRef(), parseContext) + .limit(varDecl.getRef()); CAssume cAssume = new CAssume(assumeStmt, parseContext); compound.getcStatementList().add(cAssume); } @@ -520,7 +599,8 @@ public CStatement visitBodyDeclaration(CParser.BodyDeclarationContext ctx) { @Override public CStatement visitExpression(CParser.ExpressionContext ctx) { CCompound compound = new CCompound(parseContext); - for (CParser.AssignmentExpressionContext assignmentExpressionContext : ctx.assignmentExpression()) { + for (CParser.AssignmentExpressionContext assignmentExpressionContext : + ctx.assignmentExpression()) { compound.getcStatementList().add(assignmentExpressionContext.accept(this)); } recordMetadata(ctx, compound); @@ -528,8 +608,17 @@ public CStatement visitExpression(CParser.ExpressionContext ctx) { } @Override - public CStatement visitAssignmentExpressionAssignmentExpression(CParser.AssignmentExpressionAssignmentExpressionContext ctx) { - ExpressionVisitor expressionVisitor = new ExpressionVisitor(parseContext, this, variables, functions, typedefVisitor, typeVisitor, uniqueWarningLogger); + public CStatement visitAssignmentExpressionAssignmentExpression( + CParser.AssignmentExpressionAssignmentExpressionContext ctx) { + ExpressionVisitor expressionVisitor = + new ExpressionVisitor( + parseContext, + this, + variables, + functions, + typedefVisitor, + typeVisitor, + uniqueWarningLogger); CCompound compound = new CCompound(parseContext); CCompound preStatements = new CCompound(parseContext); CCompound postStatements = new CCompound(parseContext); @@ -543,7 +632,8 @@ public CStatement visitAssignmentExpressionAssignmentExpression(CParser.Assignme resetPreStatements(compoundInitExpr); resetPostStatements(compoundInitExpr); } - CAssignment cAssignment = new CAssignment(ret, rhs, ctx.assignmentOperator().getText(), parseContext); + CAssignment cAssignment = + new CAssignment(ret, rhs, ctx.assignmentOperator().getText(), parseContext); compound.getcStatementList().add(cAssignment); preStatements.getcStatementList().addAll(expressionVisitor.getPreStatements()); compound.setPreStatements(preStatements); @@ -555,7 +645,8 @@ public CStatement visitAssignmentExpressionAssignmentExpression(CParser.Assignme } @Override - public CStatement visitAssignmentExpressionConditionalExpression(CParser.AssignmentExpressionConditionalExpressionContext ctx) { + public CStatement visitAssignmentExpressionConditionalExpression( + CParser.AssignmentExpressionConditionalExpressionContext ctx) { return ctx.conditionalExpression().accept(this); } @@ -579,7 +670,9 @@ private void resetPostStatements(CStatement statement) { private List getStatementList(CStatement statement) { if (statement instanceof CCompound compound) { - return compound.getcStatementList().stream().flatMap(i -> getStatementList(i).stream()).toList(); + return compound.getcStatementList().stream() + .flatMap(i -> getStatementList(i).stream()) + .toList(); } else if (statement != null) { return List.of(statement); } else { @@ -596,11 +689,17 @@ private List getStatementList(CStatement statement) { private List collectPreStatements(CStatement cStatement) { if (cStatement instanceof CCompound) { return Stream.concat( - Stream.concat( - collectPreStatements(cStatement.getPreStatements()).stream(), - getStatementList(cStatement.getPreStatements()).stream()), - ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPreStatements(cStatement1).stream()) - ).filter(i -> !(i instanceof CExpr)).toList(); + Stream.concat( + collectPreStatements(cStatement.getPreStatements()).stream(), + getStatementList(cStatement.getPreStatements()).stream()), + ((CCompound) cStatement) + .getcStatementList().stream() + .flatMap( + cStatement1 -> + collectPreStatements(cStatement1) + .stream())) + .filter(i -> !(i instanceof CExpr)) + .toList(); } else return List.of(); } @@ -613,11 +712,17 @@ private List collectPreStatements(CStatement cStatement) { private List collectPostStatements(CStatement cStatement) { if (cStatement instanceof CCompound) { return Stream.concat( - ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPostStatements(cStatement1).stream()), - Stream.concat( - getStatementList(cStatement.getPostStatements()).stream(), - collectPostStatements(cStatement.getPostStatements()).stream()) - ).filter(i -> !(i instanceof CExpr)).toList(); + ((CCompound) cStatement) + .getcStatementList().stream() + .flatMap( + cStatement1 -> + collectPostStatements(cStatement1) + .stream()), + Stream.concat( + getStatementList(cStatement.getPostStatements()).stream(), + collectPostStatements(cStatement.getPostStatements()).stream())) + .filter(i -> !(i instanceof CExpr)) + .toList(); } else return List.of(); } @@ -630,7 +735,15 @@ public CStatement visitConditionalExpression(CParser.ConditionalExpressionContex CCompound preStatements = new CCompound(parseContext); CCompound postStatements = new CCompound(parseContext); - ExpressionVisitor expressionVisitor = new ExpressionVisitor(parseContext, this, variables, functions, typedefVisitor, typeVisitor, uniqueWarningLogger); + ExpressionVisitor expressionVisitor = + new ExpressionVisitor( + parseContext, + this, + variables, + functions, + typedefVisitor, + typeVisitor, + uniqueWarningLogger); Expr iteExpr; if (!ctx.expression().isEmpty()) { @@ -646,7 +759,6 @@ public CStatement visitConditionalExpression(CParser.ConditionalExpressionContex guardCompound.setPostStatements(new CCompound(parseContext)); guardCompound.setPreStatements(new CCompound(parseContext)); - CCompound ifTruePre = new CCompound(parseContext); List ifTruePreList = collectPreStatements(ifTrue); ifTruePre.getcStatementList().addAll(ifTruePreList); @@ -669,20 +781,29 @@ public CStatement visitConditionalExpression(CParser.ConditionalExpressionContex ifFalsePost.setPostStatements(new CCompound(parseContext)); ifFalsePost.setPreStatements(new CCompound(parseContext)); - if (!ifTruePreList.isEmpty() || !ifFalsePreList.isEmpty()) { - preStatements.getcStatementList().add(new CIf(guardCompound, ifTruePre, ifFalsePre, parseContext)); + preStatements + .getcStatementList() + .add(new CIf(guardCompound, ifTruePre, ifFalsePre, parseContext)); } if (!ifTruePostList.isEmpty() || !ifFalsePostList.isEmpty()) { - postStatements.getcStatementList().add(new CIf(guardCompound, ifTruePost, ifFalsePost, parseContext)); + postStatements + .getcStatementList() + .add(new CIf(guardCompound, ifTruePost, ifFalsePost, parseContext)); } - CComplexType smallestCommonType = CComplexType.getSmallestCommonType(List.of(CComplexType.getType(lhs, parseContext), CComplexType.getType(rhs, parseContext)), parseContext); - IteExpr ite = Ite( - AbstractExprs.Neq(CComplexType.getType(expr, parseContext).getNullValue(), expr), - smallestCommonType.castTo(lhs), - smallestCommonType.castTo(rhs) - ); + CComplexType smallestCommonType = + CComplexType.getSmallestCommonType( + List.of( + CComplexType.getType(lhs, parseContext), + CComplexType.getType(rhs, parseContext)), + parseContext); + IteExpr ite = + Ite( + AbstractExprs.Neq( + CComplexType.getType(expr, parseContext).getNullValue(), expr), + smallestCommonType.castTo(lhs), + smallestCommonType.castTo(rhs)); parseContext.getMetadata().create(ite, "cType", smallestCommonType); iteExpr = ite; } else { @@ -702,12 +823,21 @@ public CStatement visitConditionalExpression(CParser.ConditionalExpressionContex @Override public CStatement visitForDeclaration(CParser.ForDeclarationContext ctx) { - List declarations = declarationVisitor.getDeclarations(ctx.declarationSpecifiers(), ctx.initDeclaratorList()); + List declarations = + declarationVisitor.getDeclarations( + ctx.declarationSpecifiers(), ctx.initDeclaratorList()); CCompound compound = new CCompound(parseContext); for (CDeclaration declaration : declarations) { createVars(declaration); - checkState(declaration.getVarDecls().size() == 1, "For loops cannot have struct declarations! (not yet implemented)"); - CAssignment cAssignment = new CAssignment(declaration.getVarDecls().get(0).getRef(), declaration.getInitExpr(), "=", parseContext); + checkState( + declaration.getVarDecls().size() == 1, + "For loops cannot have struct declarations! (not yet implemented)"); + CAssignment cAssignment = + new CAssignment( + declaration.getVarDecls().get(0).getRef(), + declaration.getInitExpr(), + "=", + parseContext); recordMetadata(ctx, cAssignment); if (declaration.getInitExpr() != null) compound.getcStatementList().add(cAssignment); } @@ -718,7 +848,8 @@ public CStatement visitForDeclaration(CParser.ForDeclarationContext ctx) { @Override public CStatement visitForExpression(CParser.ForExpressionContext ctx) { CCompound compound = new CCompound(parseContext); - for (CParser.AssignmentExpressionContext assignmentExpressionContext : ctx.assignmentExpression()) { + for (CParser.AssignmentExpressionContext assignmentExpressionContext : + ctx.assignmentExpression()) { compound.getcStatementList().add(assignmentExpressionContext.accept(this)); } recordMetadata(ctx, compound); diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java index 7b569aada4..989f18d3b8 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.frontend.transformation.model.statements; import hu.bme.mit.theta.core.type.Expr; @@ -22,9 +21,9 @@ import org.antlr.v4.runtime.ParserRuleContext; /** - * Every Program, Function and Statement is a subclass of this base class. - * Any CStatement might have an id associated with it, in case there was a label in the source code. This also provides - * an XcfaLocation, which can be used when jumping to this named location via a _goto_ instruction + * Every Program, Function and Statement is a subclass of this base class. Any CStatement might have + * an id associated with it, in case there was a label in the source code. This also provides an + * XcfaLocation, which can be used when jumping to this named location via a _goto_ instruction */ public abstract class CStatement { protected final ParseContext parseContext; @@ -55,10 +54,10 @@ public void setId(String id) { } /** - * Returns the expression associated with a CStatement, which by default throws an exception, as not all subtypes - * will return one. For example, the C language statement `int a = (b = 0, 2)` will create a CCompound statement as - * the right-hand side of the assignment, whose associated expression will be 2, but the assignment to b has to come - * beforehand. + * Returns the expression associated with a CStatement, which by default throws an exception, as + * not all subtypes will return one. For example, the C language statement `int a = (b = 0, 2)` + * will create a CCompound statement as the right-hand side of the assignment, whose associated + * expression will be 2, but the assignment to b has to come beforehand. * * @return The expression associated with the statement. */ @@ -71,7 +70,8 @@ public CStatement getPostStatements() { } public void setPostStatements(CStatement postStatements) { - throw new UnsupportedFrontendElementException("Only CCompounds shall currently have pre- and post statements!"); + throw new UnsupportedFrontendElementException( + "Only CCompounds shall currently have pre- and post statements!"); } public CStatement getPreStatements() { @@ -79,7 +79,8 @@ public CStatement getPreStatements() { } public void setPreStatements(CStatement preStatements) { - throw new UnsupportedFrontendElementException("Only CCompounds shall currently have pre- and post statements!"); + throw new UnsupportedFrontendElementException( + "Only CCompounds shall currently have pre- and post statements!"); } public abstract R accept(CStatementVisitor visitor, P param); diff --git a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java index f1d0ef9bca..9457748898 100644 --- a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java +++ b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcBackwardXcfaBuilder.java @@ -15,6 +15,12 @@ */ package hu.bme.mit.theta.frontend.chc; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Bool; +import static hu.bme.mit.theta.frontend.chc.ChcUtils.createVars; +import static hu.bme.mit.theta.frontend.chc.ChcUtils.getTailConditionLabels; +import static hu.bme.mit.theta.frontend.chc.ChcUtils.transformConst; +import static hu.bme.mit.theta.frontend.chc.ChcUtils.transformSort; + import hu.bme.mit.theta.chc.frontend.dsl.gen.CHCBaseVisitor; import hu.bme.mit.theta.chc.frontend.dsl.gen.CHCParser; import hu.bme.mit.theta.core.decl.Decls; @@ -36,20 +42,13 @@ import hu.bme.mit.theta.xcfa.model.XcfaLocation; import hu.bme.mit.theta.xcfa.model.XcfaProcedureBuilder; import hu.bme.mit.theta.xcfa.passes.ProcedurePassManager; -import kotlin.Pair; -import org.antlr.v4.runtime.RuleContext; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; - -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Bool; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.createVars; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.getTailConditionLabels; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.transformConst; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.transformSort; +import kotlin.Pair; +import org.antlr.v4.runtime.RuleContext; public class ChcBackwardXcfaBuilder extends CHCBaseVisitor implements ChcXcfaBuilder { private final Map procedures = new HashMap<>(); @@ -67,8 +66,8 @@ public XcfaBuilder buildXcfa(CHCParser parser) { visit(parser.benchmark()); -// xcfaBuilder.addProcess(procBuilder); -// xcfaBuilder.setMainProcess(procBuilder); + // xcfaBuilder.addProcess(procBuilder); + // xcfaBuilder.setMainProcess(procBuilder); return xcfaBuilder; } @@ -103,9 +102,19 @@ public Object visitChc_assert(CHCParser.Chc_assertContext ctx) { vars.put(ctx.chc_head().u_pred_atom().symbol(i++).getText(), param.getFirst()); } XcfaLocation middle = createLocation(procedure); - XcfaEdge edge = new XcfaEdge(procedure.getInitLoc(), middle, new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars)), EmptyMetaData.INSTANCE); + XcfaEdge edge = + new XcfaEdge( + procedure.getInitLoc(), + middle, + new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars)), + EmptyMetaData.INSTANCE); procedure.addEdge(edge); - createCalls(procedure, middle, procedure.getFinalLoc().get(), ctx.chc_tail().u_pred_atom(), vars); + createCalls( + procedure, + middle, + procedure.getFinalLoc().get(), + ctx.chc_tail().u_pred_atom(), + vars); } else { String procName; if (ctx.chc_head() != null) { @@ -115,7 +124,12 @@ public Object visitChc_assert(CHCParser.Chc_assertContext ctx) { } procedure = procedures.get(procName); Stmt returnTrue = AssignStmt.create(getOutParam(procedure), BoolLitExpr.of(true)); - XcfaEdge edge = new XcfaEdge(procedure.getInitLoc(), procedure.getFinalLoc().get(), new StmtLabel(returnTrue), EmptyMetaData.INSTANCE); + XcfaEdge edge = + new XcfaEdge( + procedure.getInitLoc(), + procedure.getFinalLoc().get(), + new StmtLabel(returnTrue), + EmptyMetaData.INSTANCE); procedure.addEdge(edge); } return super.visitChc_assert(ctx); @@ -128,9 +142,19 @@ public Object visitChc_query(CHCParser.Chc_queryContext ctx) { Map> vars = createVars(mainProcedure, ctx.var_decl()); XcfaLocation middle = createLocation(mainProcedure); - XcfaEdge edge = new XcfaEdge(mainProcedure.getInitLoc(), middle, new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars)), EmptyMetaData.INSTANCE); + XcfaEdge edge = + new XcfaEdge( + mainProcedure.getInitLoc(), + middle, + new SequenceLabel(getTailConditionLabels(ctx.chc_tail(), vars)), + EmptyMetaData.INSTANCE); mainProcedure.addEdge(edge); - createCalls(mainProcedure, middle, mainProcedure.getErrorLoc().get(), ctx.chc_tail().u_pred_atom(), vars); + createCalls( + mainProcedure, + middle, + mainProcedure.getErrorLoc().get(), + ctx.chc_tail().u_pred_atom(), + vars); return super.visitChc_query(ctx); } @@ -156,29 +180,50 @@ private XcfaProcedureBuilder createProcedure(String procName) { } private VarDecl getOutParam(XcfaProcedureBuilder procedure) { - Optional, ParamDirection>> param = procedure.getParams() - .stream().filter(entry -> entry.getSecond() == ParamDirection.OUT).findAny(); + Optional, ParamDirection>> param = + procedure.getParams().stream() + .filter(entry -> entry.getSecond() == ParamDirection.OUT) + .findAny(); return param.map(Pair::getFirst).orElse(null); } - private void createCalls(XcfaProcedureBuilder builder, XcfaLocation start, XcfaLocation end, List uPreds, Map> localVars) { + private void createCalls( + XcfaProcedureBuilder builder, + XcfaLocation start, + XcfaLocation end, + List uPreds, + Map> localVars) { XcfaLocation from = start; for (CHCParser.U_pred_atomContext uPred : uPreds) { XcfaLocation middle = createLocation(builder); XcfaLocation to = createLocation(builder); XcfaProcedureBuilder calledProcedure = procedures.get(uPred.u_predicate().getText()); - VarDecl ret = Decls.Var(calledProcedure.getName() + "_ret_" + callCount++, Bool()); + VarDecl ret = + Decls.Var(calledProcedure.getName() + "_ret_" + callCount++, Bool()); builder.addVar(ret); localVars.put(ret.getName(), ret); - List paramNames = new ArrayList<>(uPred.symbol().stream().map(RuleContext::getText).toList()); + List paramNames = + new ArrayList<>(uPred.symbol().stream().map(RuleContext::getText).toList()); paramNames.add(0, ret.getName()); - List> params = paramNames.stream().map(s -> localVars.get(s).getRef()).toList(); - - XcfaEdge callEdge = new XcfaEdge(from, middle, new InvokeLabel(calledProcedure.getName(), params, EmptyMetaData.INSTANCE), EmptyMetaData.INSTANCE); + List> params = + paramNames.stream().map(s -> localVars.get(s).getRef()).toList(); + + XcfaEdge callEdge = + new XcfaEdge( + from, + middle, + new InvokeLabel( + calledProcedure.getName(), params, EmptyMetaData.INSTANCE), + EmptyMetaData.INSTANCE); builder.addEdge(callEdge); - XcfaEdge assertEdge = new XcfaEdge(middle, to, new StmtLabel(AssumeStmt.of(ret.getRef())), EmptyMetaData.INSTANCE); + XcfaEdge assertEdge = + new XcfaEdge( + middle, + to, + new StmtLabel(AssumeStmt.of(ret.getRef())), + EmptyMetaData.INSTANCE); builder.addEdge(assertEdge); from = to; diff --git a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java index 04f591c913..84f38db5b0 100644 --- a/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java +++ b/subprojects/frontends/chc-frontend/src/main/java/hu/bme/mit/theta/frontend/chc/ChcForwardXcfaBuilder.java @@ -15,6 +15,8 @@ */ package hu.bme.mit.theta.frontend.chc; +import static hu.bme.mit.theta.frontend.chc.ChcUtils.*; + import hu.bme.mit.theta.chc.frontend.dsl.gen.CHCBaseVisitor; import hu.bme.mit.theta.chc.frontend.dsl.gen.CHCParser; import hu.bme.mit.theta.core.decl.Decls; @@ -24,14 +26,11 @@ import hu.bme.mit.theta.core.type.Type; import hu.bme.mit.theta.xcfa.model.*; import hu.bme.mit.theta.xcfa.passes.ProcedurePassManager; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import static hu.bme.mit.theta.frontend.chc.ChcUtils.*; - public class ChcForwardXcfaBuilder extends CHCBaseVisitor implements ChcXcfaBuilder { private final ProcedurePassManager procedurePassManager; private XcfaProcedureBuilder builder; @@ -120,27 +119,42 @@ public Object visitChc_query(CHCParser.Chc_queryContext ctx) { List labels = new ArrayList<>(); labels.addAll(getIncomingAssignments(ctx.chc_tail(), vars)); labels.addAll(getTailConditionLabels(ctx.chc_tail(), vars)); - XcfaEdge edge = new XcfaEdge(from, errorLocation, new SequenceLabel(labels), EmptyMetaData.INSTANCE); + XcfaEdge edge = + new XcfaEdge( + from, errorLocation, new SequenceLabel(labels), EmptyMetaData.INSTANCE); builder.addEdge(edge); return super.visitChc_query(ctx); } - private List getIncomingAssignments(CHCParser.Chc_tailContext tail, Map> localVars) { + private List getIncomingAssignments( + CHCParser.Chc_tailContext tail, Map> localVars) { List labels = new ArrayList<>(); UPred from = locations.get(getTailFrom(tail).getName()); - tail.u_pred_atom().forEach(u_pred -> { - List> params = u_pred.symbol().stream().map(symbol -> localVars.get(symbol.getText())).toList(); - localVars.values().forEach(var -> { - if (!params.contains(var)) - labels.add(new StmtLabel(HavocStmt.of(var))); - }); - labels.addAll(getParamAssignments(params, from.vars)); - }); + tail.u_pred_atom() + .forEach( + u_pred -> { + List> params = + u_pred.symbol().stream() + .map(symbol -> localVars.get(symbol.getText())) + .toList(); + localVars + .values() + .forEach( + var -> { + if (!params.contains(var)) + labels.add(new StmtLabel(HavocStmt.of(var))); + }); + labels.addAll(getParamAssignments(params, from.vars)); + }); return labels; } - private List getTargetAssignments(CHCParser.Chc_headContext head, Map> localVars) { - List> params = head.u_pred_atom().symbol().stream().map(symbol -> localVars.get(symbol.getText())).toList(); + private List getTargetAssignments( + CHCParser.Chc_headContext head, Map> localVars) { + List> params = + head.u_pred_atom().symbol().stream() + .map(symbol -> localVars.get(symbol.getText())) + .toList(); UPred to = locations.get(getHeadTo(head).getName()); return getParamAssignments(to.vars, params); } @@ -149,7 +163,9 @@ private XcfaLocation getTailFrom(CHCParser.Chc_tailContext tail) { XcfaLocation from; if (tail.u_pred_atom() != null && !tail.u_pred_atom().isEmpty()) { if (tail.u_pred_atom().size() != 1) - throw new UnsupportedOperationException("Non-linear CHCs are not supported with forward transformation, try using the --chc-transformation BACKWARD flag."); + throw new UnsupportedOperationException( + "Non-linear CHCs are not supported with forward transformation, try using" + + " the --chc-transformation BACKWARD flag."); from = locations.get(tail.u_pred_atom().get(0).u_predicate().getText()).location; } else { from = initLocation; @@ -161,7 +177,8 @@ private XcfaLocation getHeadTo(CHCParser.Chc_headContext head) { return locations.get(head.u_pred_atom().u_predicate().getText()).location; } - private List getParamAssignments(List> lhs, List> rhs) { + private List getParamAssignments( + List> lhs, List> rhs) { List labels = new ArrayList<>(); for (int i = 0; i < lhs.size(); ++i) { labels.add(new StmtLabel(AssignStmt.create(lhs.get(i), rhs.get(i).getRef()))); diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt index d62b191661..9e10ca93f7 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/CMetaData.kt @@ -16,71 +16,83 @@ package hu.bme.mit.theta.c2xcfa import hu.bme.mit.theta.xcfa.model.* -import org.antlr.v4.runtime.ParserRuleContext import kotlin.math.max import kotlin.math.min data class CMetaData( - val lineNumberStart: Int?, - val colNumberStart: Int?, - val lineNumberStop: Int?, - val colNumberStop: Int?, - val offsetStart: Int?, - val offsetEnd: Int?, - val sourceText: String?, + val lineNumberStart: Int?, + val colNumberStart: Int?, + val lineNumberStop: Int?, + val colNumberStop: Int?, + val offsetStart: Int?, + val offsetEnd: Int?, + val sourceText: String?, ) : MetaData() { - override fun combine(other: MetaData): MetaData { - if (other is CMetaData) { - return CMetaData( - lineNumberStart = min( - lineNumberStart ?: other.lineNumberStart ?: -1, other.lineNumberStart ?: lineNumberStart ?: -1 - ).takeIf { it > 0 } ?: 0, - colNumberStart = min( - colNumberStart ?: other.colNumberStart ?: -1, other.colNumberStart ?: colNumberStart ?: -1 - ).takeIf { it > 0 } ?: 0, - offsetStart = min( - offsetStart ?: other.offsetStart ?: -1, other.offsetStart ?: offsetStart ?: -1 - ).takeIf { it > 0 } ?: 0, - lineNumberStop = max( - lineNumberStop ?: other.lineNumberStop ?: -1, other.lineNumberStop ?: lineNumberStop ?: -1 - ).takeIf { it > 0 } ?: 0, - colNumberStop = max( - colNumberStop ?: other.colNumberStop ?: -1, other.colNumberStop ?: colNumberStop ?: -1 - ).takeIf { it > 0 } ?: 0, - offsetEnd = max( - offsetEnd ?: other.offsetEnd ?: -1, other.offsetEnd ?: offsetEnd ?: -1 - ).takeIf { it > 0 } ?: 0, - sourceText = (sourceText ?: "") + (other.sourceText ?: ""), + override fun combine(other: MetaData): MetaData { + if (other is CMetaData) { + return CMetaData( + lineNumberStart = + min( + lineNumberStart ?: other.lineNumberStart ?: -1, + other.lineNumberStart ?: lineNumberStart ?: -1, ) - } else if (other is EmptyMetaData) { - return this - } else { - error("Cannot combine metadata of different types: $this vs $other") - } + .takeIf { it > 0 } ?: 0, + colNumberStart = + min( + colNumberStart ?: other.colNumberStart ?: -1, + other.colNumberStart ?: colNumberStart ?: -1, + ) + .takeIf { it > 0 } ?: 0, + offsetStart = + min(offsetStart ?: other.offsetStart ?: -1, other.offsetStart ?: offsetStart ?: -1) + .takeIf { it > 0 } ?: 0, + lineNumberStop = + max( + lineNumberStop ?: other.lineNumberStop ?: -1, + other.lineNumberStop ?: lineNumberStop ?: -1, + ) + .takeIf { it > 0 } ?: 0, + colNumberStop = + max( + colNumberStop ?: other.colNumberStop ?: -1, + other.colNumberStop ?: colNumberStop ?: -1, + ) + .takeIf { it > 0 } ?: 0, + offsetEnd = + max(offsetEnd ?: other.offsetEnd ?: -1, other.offsetEnd ?: offsetEnd ?: -1).takeIf { + it > 0 + } ?: 0, + sourceText = (sourceText ?: "") + (other.sourceText ?: ""), + ) + } else if (other is EmptyMetaData) { + return this + } else { + error("Cannot combine metadata of different types: $this vs $other") } + } } fun XcfaLabel.getCMetaData(): CMetaData? { - return if (this.metadata is CMetaData) { - this.metadata as CMetaData - } else { - null - } + return if (this.metadata is CMetaData) { + this.metadata as CMetaData + } else { + null + } } fun XcfaLocation.getCMetaData(): CMetaData? { - return if (this.metadata is CMetaData) { - this.metadata as CMetaData - } else { - null - } + return if (this.metadata is CMetaData) { + this.metadata as CMetaData + } else { + null + } } fun XcfaEdge.getCMetaData(): CMetaData? { - return if (this.metadata is CMetaData) { - this.metadata as CMetaData - } else { - null - } -} \ No newline at end of file + return if (this.metadata is CMetaData) { + this.metadata as CMetaData + } else { + null + } +} diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index ebc4fd3da7..7c2ac51694 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -50,814 +50,1002 @@ import hu.bme.mit.theta.frontend.transformation.model.types.complex.integer.CInt import hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory import hu.bme.mit.theta.xcfa.model.* import hu.bme.mit.theta.xcfa.passes.CPasses -import org.abego.treelayout.internal.util.Contract.checkState import java.math.BigInteger import java.util.stream.Collectors +import org.abego.treelayout.internal.util.Contract.checkState -class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boolean = false, - val uniqueWarningLogger: Logger) : - CStatementVisitorBase() { - - private val locationLut: MutableMap = LinkedHashMap() - private var ptrCnt = 1 // counts up, uses 3k+1 - get() = field.also { field += 3 } - - private fun getLoc(builder: XcfaProcedureBuilder, name: String?, - metadata: MetaData): XcfaLocation { - if (name == null) return getAnonymousLoc(builder, metadata = metadata) - locationLut.putIfAbsent(name, XcfaLocation(name, metadata = metadata)) - val location = locationLut[name] - builder.addLoc(checkNotNull(location)) - return location - } +class FrontendXcfaBuilder( + val parseContext: ParseContext, + val checkOverflow: Boolean = false, + val uniqueWarningLogger: Logger, +) : CStatementVisitorBase() { - private fun getAnonymousLoc(builder: XcfaProcedureBuilder, metadata: MetaData): XcfaLocation { - return getLoc(builder, "__loc_" + XcfaLocation.uniqueCounter(), metadata) - } + private val locationLut: MutableMap = LinkedHashMap() + private var ptrCnt = 1 // counts up, uses 3k+1 + get() = field.also { field += 3 } - private fun getMetadata(source: CStatement): CMetaData = CMetaData( - lineNumberStart = source.lineNumberStart.takeIf { it != -1 }, - lineNumberStop = source.lineNumberStop.takeIf { it != -1 }, - colNumberStart = source.colNumberStart.takeIf { it != -1 }, - colNumberStop = source.colNumberStop.takeIf { it != -1 }, - offsetStart = source.offsetStart.takeIf { it != -1 }, - offsetEnd = source.offsetEnd.takeIf { it != -1 }, - sourceText = source.sourceText, - ) + private fun getLoc( + builder: XcfaProcedureBuilder, + name: String?, + metadata: MetaData, + ): XcfaLocation { + if (name == null) return getAnonymousLoc(builder, metadata = metadata) + locationLut.putIfAbsent(name, XcfaLocation(name, metadata = metadata)) + val location = locationLut[name] + builder.addLoc(checkNotNull(location)) + return location + } - fun buildXcfa(cProgram: CProgram): XcfaBuilder { - val builder = XcfaBuilder(cProgram.id ?: "") - val initStmtList: MutableList = ArrayList() - for (globalDeclaration in cProgram.globalDeclarations) { - val type = CComplexType.getType(globalDeclaration.get2().ref, parseContext) - if (type is CVoid) { - continue - } - if (type is CStruct) { - uniqueWarningLogger.write( - Logger.Level.INFO, "Not handling init expression of struct array ${globalDeclaration.get1()}" - ) - } - builder.addVar(XcfaGlobalVar(globalDeclaration.get2(), type.nullValue)) - if (type is CArray) { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.getValue("$ptrCnt"), globalDeclaration.get2().type)) - )) - } else { - if (globalDeclaration.get1().initExpr != null && globalDeclaration.get1().initExpr.expression !is UnsupportedInitializer) { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.castTo(globalDeclaration.get1().initExpr.expression), - globalDeclaration.get2().type)) - )) - } else { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.nullValue, globalDeclaration.get2().type)) - )) - } - } - - if (globalDeclaration.get1().arrayDimensions.size == 1) { - val bounds = ExprUtils.simplify(CComplexType.getUnsignedLong(parseContext) - .castTo(globalDeclaration.get1().arrayDimensions[0].expression)) - checkState(bounds is IntLitExpr || bounds is BvLitExpr, - "Only IntLit and BvLit expression expected here.") - val literalValue = if (bounds is IntLitExpr) bounds.value.toLong() else BvUtils.neutralBvLitExprToBigInteger( - bounds as BvLitExpr).toLong() - val literalToExpr = { x: Long -> - if (bounds is IntLitExpr) IntLitExpr.of( - BigInteger.valueOf(x)) else BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.valueOf(x), - (bounds as BvLitExpr).type.size) - } - val initExprs: Map> = (globalDeclaration.get1()?.initExpr as? CInitializerList)?.statements?.mapIndexed { i, it -> - Pair(i, it.get2().expression) - }?.toMap() ?: emptyMap() - for (i in 0 until literalValue) { - checkState(globalDeclaration.get1().actualType is CArray, "Only arrays are expected here") - val embeddedType = (globalDeclaration.get1().actualType as CArray).embeddedType - initStmtList.add(StmtLabel( - Stmts.MemoryAssign( - Dereference(globalDeclaration.get2().ref, literalToExpr(i), embeddedType.smtType), - cast(initExprs[i.toInt()]?.let { embeddedType.castTo(it) } ?: embeddedType.nullValue, - embeddedType.smtType)) - )) - } - } else if (globalDeclaration.get1().arrayDimensions.size > 1) { - error("Not handling init expression of high dimsension array ${globalDeclaration.get1()}") - } - } - for (function in cProgram.functions) { - val toAdd: XcfaProcedureBuilder = handleFunction(function, initStmtList, builder) - if (toAdd.name.equals("main")) builder.addEntryPoint(toAdd, listOf()) - } - return builder - } + private fun getAnonymousLoc(builder: XcfaProcedureBuilder, metadata: MetaData): XcfaLocation { + return getLoc(builder, "__loc_" + XcfaLocation.uniqueCounter(), metadata) + } - private fun handleFunction(function: CFunction, param: List, - xcfaBuilder: XcfaBuilder): XcfaProcedureBuilder { - locationLut.clear() - val flatVariables = function.flatVariables - val funcDecl = function.funcDecl - val compound = function.compound - val builder = XcfaProcedureBuilder(funcDecl.name, CPasses(checkOverflow, parseContext, uniqueWarningLogger)) - xcfaBuilder.addProcedure(builder) - val initStmtList = ArrayList() - if (param.size > 0 && builder.name.equals("main")) { - initStmtList.addAll(param) - } -// builder.setRetType(if (funcDecl.actualType is CVoid) null else funcDecl.actualType.smtType) TODO: we never need the ret type, do we? - if (funcDecl.actualType !is CVoid) { - val toAdd: VarDecl<*> = Decls.Var(funcDecl.name + "_ret", funcDecl.actualType.smtType) - parseContext.metadata.create(toAdd.ref, "cType", funcDecl.actualType) - builder.addParam(toAdd, ParamDirection.OUT) + private fun getMetadata(source: CStatement): CMetaData = + CMetaData( + lineNumberStart = source.lineNumberStart.takeIf { it != -1 }, + lineNumberStop = source.lineNumberStop.takeIf { it != -1 }, + colNumberStart = source.colNumberStart.takeIf { it != -1 }, + colNumberStop = source.colNumberStop.takeIf { it != -1 }, + offsetStart = source.offsetStart.takeIf { it != -1 }, + offsetEnd = source.offsetEnd.takeIf { it != -1 }, + sourceText = source.sourceText, + ) + + fun buildXcfa(cProgram: CProgram): XcfaBuilder { + val builder = XcfaBuilder(cProgram.id ?: "") + val initStmtList: MutableList = ArrayList() + for (globalDeclaration in cProgram.globalDeclarations) { + val type = CComplexType.getType(globalDeclaration.get2().ref, parseContext) + if (type is CVoid) { + continue + } + if (type is CStruct) { + uniqueWarningLogger.write( + Logger.Level.INFO, + "Not handling init expression of struct array ${globalDeclaration.get1()}", + ) + } + builder.addVar(XcfaGlobalVar(globalDeclaration.get2(), type.nullValue)) + if (type is CArray) { + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.getValue("$ptrCnt"), globalDeclaration.get2().type), + ) + ) + ) + } else { + if ( + globalDeclaration.get1().initExpr != null && + globalDeclaration.get1().initExpr.expression !is UnsupportedInitializer + ) { + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast( + type.castTo(globalDeclaration.get1().initExpr.expression), + globalDeclaration.get2().type, + ), + ) + ) + ) } else { - // TODO we assume later that there is always a ret var, but this should change - val toAdd: VarDecl<*> = Decls.Var(funcDecl.name + "_ret", funcDecl.actualType.smtType) - val signedIntType = CSimpleTypeFactory.NamedType("int", parseContext, uniqueWarningLogger) - signedIntType.setSigned(true) - parseContext.metadata.create(toAdd.ref, "cType", signedIntType) - builder.addParam(toAdd, ParamDirection.OUT) - } - for (functionParam in funcDecl.functionParams) { - Preconditions.checkState( - functionParam.actualType is CVoid || functionParam.varDecls.size > 0, - "Function param should have an associated variable!") - for (varDecl in functionParam.varDecls) { - if (varDecl != null) builder.addParam(varDecl, ParamDirection.IN) - } + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.nullValue, globalDeclaration.get2().type), + ) + ) + ) } + } - for (flatVariable in flatVariables) { - builder.addVar(flatVariable) - val type = CComplexType.getType(flatVariable.ref, parseContext) - if ((type is CArray || type is CStruct) && builder.getParams().none { it.first == flatVariable }) { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(flatVariable, flatVariable.type), - cast(type.getValue("$ptrCnt"), flatVariable.type)) - )) - } + if (globalDeclaration.get1().arrayDimensions.size == 1) { + val bounds = + ExprUtils.simplify( + CComplexType.getUnsignedLong(parseContext) + .castTo(globalDeclaration.get1().arrayDimensions[0].expression) + ) + checkState( + bounds is IntLitExpr || bounds is BvLitExpr, + "Only IntLit and BvLit expression expected here.", + ) + val literalValue = + if (bounds is IntLitExpr) bounds.value.toLong() + else BvUtils.neutralBvLitExprToBigInteger(bounds as BvLitExpr).toLong() + val literalToExpr = { x: Long -> + if (bounds is IntLitExpr) IntLitExpr.of(BigInteger.valueOf(x)) + else + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.valueOf(x), + (bounds as BvLitExpr).type.size, + ) } - builder.createInitLoc(getMetadata(function)) - var init = builder.initLoc - - for (flatVariable in flatVariables) { - val type = CComplexType.getType(flatVariable.ref, parseContext) - if (type is CArray && type.embeddedType is CArray) { - // some day this is where initialization will occur. But this is not today. - error("Not handling init expression of high dimsension array $flatVariable") - } + val initExprs: Map> = + (globalDeclaration.get1()?.initExpr as? CInitializerList) + ?.statements + ?.mapIndexed { i, it -> Pair(i, it.get2().expression) } + ?.toMap() ?: emptyMap() + for (i in 0 until literalValue) { + checkState(globalDeclaration.get1().actualType is CArray, "Only arrays are expected here") + val embeddedType = (globalDeclaration.get1().actualType as CArray).embeddedType + initStmtList.add( + StmtLabel( + Stmts.MemoryAssign( + Dereference(globalDeclaration.get2().ref, literalToExpr(i), embeddedType.smtType), + cast( + initExprs[i.toInt()]?.let { embeddedType.castTo(it) } ?: embeddedType.nullValue, + embeddedType.smtType, + ), + ) + ) + ) } - - val endinit = getAnonymousLoc(builder, getMetadata(function)) - builder.addLoc(endinit) - val initEdge = XcfaEdge(init, endinit, SequenceLabel(initStmtList), - metadata = getMetadata(function)) - builder.addEdge(initEdge) - init = endinit - builder.createFinalLoc(getMetadata(function)) - val ret = builder.finalLoc.get() - builder.addLoc(ret) - val end = compound.accept(this, ParamPack(builder, init, null, null, ret)) - val edge = XcfaEdge(end, ret, metadata = getMetadata(function)) - builder.addEdge(edge) - return builder + } else if (globalDeclaration.get1().arrayDimensions.size > 1) { + error("Not handling init expression of high dimsension array ${globalDeclaration.get1()}") + } } + for (function in cProgram.functions) { + val toAdd: XcfaProcedureBuilder = handleFunction(function, initStmtList, builder) + if (toAdd.name.equals("main")) builder.addEntryPoint(toAdd, listOf()) + } + return builder + } - override fun visit(statement: CAssignment, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val lValue = statement.getlValue() - val rValue = statement.getrValue() - var initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - var xcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(location) - initLoc = rValue.accept(this, ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) - val rExpression = statement.getrExpression() - val label: StmtLabel = when (lValue) { - is Dereference<*, *, *> -> { - val op = cast(lValue.array, lValue.array.type) - val offset = cast(lValue.offset, op.type) - val castRExpression = CComplexType.getType(lValue, parseContext).castTo(rExpression) - val type = CComplexType.getType(castRExpression, parseContext) - - val deref = Dereference(op, offset, type.smtType) - - val memassign = MemoryAssignStmt.create(deref, castRExpression) - - parseContext.metadata.create(deref, "cType", CPointer(null, type, parseContext)) - StmtLabel(memassign, metadata = getMetadata(statement)) - } - - is RefExpr<*> -> { - StmtLabel(Stmts.Assign( - cast(lValue.decl as VarDecl<*>, (lValue.decl as VarDecl<*>).type), - cast(CComplexType.getType(lValue, parseContext).castTo(rExpression), lValue.type)), - metadata = getMetadata(statement)) - } - - else -> { - error("Could not handle left-hand side of assignment $statement") - } - } - - val lhs = (label.stmt as? AssignStmt<*>)?.varDecl - val type = lhs?.let { CComplexType.getType(it.ref, parseContext) } - - if (!checkOverflow || type == null || type !is CInteger || !type.isSsigned) { - xcfaEdge = XcfaEdge(initLoc, location, label, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } else { - lhs!! - val middleLoc1 = getAnonymousLoc(builder, getMetadata(statement)) - val middleLoc2 = getAnonymousLoc(builder, getMetadata(statement)) - xcfaEdge = XcfaEdge(initLoc, middleLoc1, label, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - - xcfaEdge = XcfaEdge(middleLoc1, location, - StmtLabel(type.limit(lhs.ref), metadata = getMetadata(statement)), - metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge(middleLoc1, middleLoc2, - StmtLabel(Assume(Not(type.limit(lhs.ref).cond)), metadata = getMetadata(statement)), - metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge(middleLoc2, location, - InvokeLabel("overflow", listOf(), metadata = getMetadata(statement)), - metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - return location + private fun handleFunction( + function: CFunction, + param: List, + xcfaBuilder: XcfaBuilder, + ): XcfaProcedureBuilder { + locationLut.clear() + val flatVariables = function.flatVariables + val funcDecl = function.funcDecl + val compound = function.compound + val builder = + XcfaProcedureBuilder(funcDecl.name, CPasses(checkOverflow, parseContext, uniqueWarningLogger)) + xcfaBuilder.addProcedure(builder) + val initStmtList = ArrayList() + if (param.size > 0 && builder.name.equals("main")) { + initStmtList.addAll(param) + } + // builder.setRetType(if (funcDecl.actualType is CVoid) null else + // funcDecl.actualType.smtType) TODO: we never need the ret type, do we? + if (funcDecl.actualType !is CVoid) { + val toAdd: VarDecl<*> = Decls.Var(funcDecl.name + "_ret", funcDecl.actualType.smtType) + parseContext.metadata.create(toAdd.ref, "cType", funcDecl.actualType) + builder.addParam(toAdd, ParamDirection.OUT) + } else { + // TODO we assume later that there is always a ret var, but this should change + val toAdd: VarDecl<*> = Decls.Var(funcDecl.name + "_ret", funcDecl.actualType.smtType) + val signedIntType = CSimpleTypeFactory.NamedType("int", parseContext, uniqueWarningLogger) + signedIntType.setSigned(true) + parseContext.metadata.create(toAdd.ref, "cType", signedIntType) + builder.addParam(toAdd, ParamDirection.OUT) + } + for (functionParam in funcDecl.functionParams) { + Preconditions.checkState( + functionParam.actualType is CVoid || functionParam.varDecls.size > 0, + "Function param should have an associated variable!", + ) + for (varDecl in functionParam.varDecls) { + if (varDecl != null) builder.addParam(varDecl, ParamDirection.IN) + } } - override fun visit(statement: CAssume, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(location) - xcfaEdge = XcfaEdge(initLoc, location, StmtLabel( - statement.assumeStmt, - choiceType = ChoiceType.MAIN_PATH, - metadata = getMetadata(statement) - ), metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - return location + for (flatVariable in flatVariables) { + builder.addVar(flatVariable) + val type = CComplexType.getType(flatVariable.ref, parseContext) + if ( + (type is CArray || type is CStruct) && builder.getParams().none { it.first == flatVariable } + ) { + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(flatVariable, flatVariable.type), + cast(type.getValue("$ptrCnt"), flatVariable.type), + ) + ) + ) + } } + builder.createInitLoc(getMetadata(function)) + var init = builder.initLoc - override fun visit(statement: CBreak, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(edge) - check(breakLoc != null) - edge = XcfaEdge(initLoc, breakLoc, metadata = getMetadata(statement)) - val unreachableLoc = XcfaLocation("Unreachable" + XcfaLocation.uniqueCounter(), - metadata = getMetadata(statement)) - builder.addLoc(unreachableLoc) - builder.addEdge(edge) - return unreachableLoc + for (flatVariable in flatVariables) { + val type = CComplexType.getType(flatVariable.ref, parseContext) + if (type is CArray && type.embeddedType is CArray) { + // some day this is where initialization will occur. But this is not today. + error("Not handling init expression of high dimsension array $flatVariable") + } } - override fun visit(statement: CCall, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val ret = statement.ret - val myParams = statement.params - var initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(location) - val params: MutableList> = ArrayList() - builder.addVar(ret) - params.add(ret.ref) - for (cStatement in myParams) { - initLoc = cStatement.accept(this, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) + val endinit = getAnonymousLoc(builder, getMetadata(function)) + builder.addLoc(endinit) + val initEdge = + XcfaEdge(init, endinit, SequenceLabel(initStmtList), metadata = getMetadata(function)) + builder.addEdge(initEdge) + init = endinit + builder.createFinalLoc(getMetadata(function)) + val ret = builder.finalLoc.get() + builder.addLoc(ret) + val end = compound.accept(this, ParamPack(builder, init, null, null, ret)) + val edge = XcfaEdge(end, ret, metadata = getMetadata(function)) + builder.addEdge(edge) + return builder + } + + override fun visit(statement: CAssignment, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val lValue = statement.getlValue() + val rValue = statement.getrValue() + var initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var xcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(location) + initLoc = rValue.accept(this, ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) + val rExpression = statement.getrExpression() + val label: StmtLabel = + when (lValue) { + is Dereference<*, *, *> -> { + val op = cast(lValue.array, lValue.array.type) + val offset = cast(lValue.offset, op.type) + val castRExpression = CComplexType.getType(lValue, parseContext).castTo(rExpression) + val type = CComplexType.getType(castRExpression, parseContext) + + val deref = Dereference(op, offset, type.smtType) + + val memassign = MemoryAssignStmt.create(deref, castRExpression) + + parseContext.metadata.create(deref, "cType", CPointer(null, type, parseContext)) + StmtLabel(memassign, metadata = getMetadata(statement)) } - params.addAll(myParams.stream().map { obj: CStatement -> obj.expression } - .collect(Collectors.toList())) - val call = InvokeLabel(statement.functionId, params, metadata = getMetadata(statement)) - xcfaEdge = XcfaEdge(initLoc, location, call, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - return location - } - override fun visit(statement: CCase, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - return statement.statement.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - } + is RefExpr<*> -> { + StmtLabel( + Stmts.Assign( + cast(lValue.decl as VarDecl<*>, (lValue.decl as VarDecl<*>).type), + cast(CComplexType.getType(lValue, parseContext).castTo(rExpression), lValue.type), + ), + metadata = getMetadata(statement), + ) + } - override fun visit(statement: CCompound, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - var lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val preStatements = statement.preStatements - val postStatements = statement.postStatements - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(edge) - lastLoc = initLoc - if (preStatements != null) lastLoc = preStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - for (cStatement in statement.getcStatementList()) { - if (cStatement != null) lastLoc = cStatement.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + else -> { + error("Could not handle left-hand side of assignment $statement") } - if (postStatements != null) lastLoc = postStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - return lastLoc - } + } - override fun visit(statement: CContinue, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(edge) - check(continueLoc != null) - edge = XcfaEdge(initLoc, continueLoc, metadata = getMetadata(statement)) - val unreachableLoc: XcfaLocation = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) - builder.addLoc(unreachableLoc) - builder.addEdge(edge) - return unreachableLoc - } + val lhs = (label.stmt as? AssignStmt<*>)?.varDecl + val type = lhs?.let { CComplexType.getType(it.ref, parseContext) } - override fun visit(statement: CDefault, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - return statement.statement.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + if (!checkOverflow || type == null || type !is CInteger || !type.isSsigned) { + xcfaEdge = XcfaEdge(initLoc, location, label, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + } else { + lhs!! + val middleLoc1 = getAnonymousLoc(builder, getMetadata(statement)) + val middleLoc2 = getAnonymousLoc(builder, getMetadata(statement)) + xcfaEdge = XcfaEdge(initLoc, middleLoc1, label, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + + xcfaEdge = + XcfaEdge( + middleLoc1, + location, + StmtLabel(type.limit(lhs.ref), metadata = getMetadata(statement)), + metadata = getMetadata(statement), + ) + builder.addEdge(xcfaEdge) + xcfaEdge = + XcfaEdge( + middleLoc1, + middleLoc2, + StmtLabel(Assume(Not(type.limit(lhs.ref).cond)), metadata = getMetadata(statement)), + metadata = getMetadata(statement), + ) + builder.addEdge(xcfaEdge) + xcfaEdge = + XcfaEdge( + middleLoc2, + location, + InvokeLabel("overflow", listOf(), metadata = getMetadata(statement)), + metadata = getMetadata(statement), + ) + builder.addEdge(xcfaEdge) } + return location + } - override fun visit(statement: CDoWhile, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val body = statement.body - val guard = statement.guard - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val innerEndLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val innerInnerGuard = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val outerInnerGuard = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(endLoc) - builder.addLoc(innerInnerGuard) - builder.addLoc(outerInnerGuard) - builder.addLoc(innerEndLoc) - builder.addLoc(initLoc) - var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val lastBody = body.accept(this, - ParamPack(builder, initLoc, endLoc, innerEndLoc, returnLoc)) - xcfaEdge = XcfaEdge(lastBody, innerEndLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val lastPre = buildWithoutPostStatement(guard, - ParamPack(builder, innerEndLoc, null, null, returnLoc)) - val assume = StmtLabel(Stmts.Assume( - AbstractExprs.Neq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard)) - xcfaEdge = XcfaEdge(lastPre, innerInnerGuard, assume, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val assume1 = StmtLabel(Stmts.Assume( - AbstractExprs.Eq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard)) - xcfaEdge = XcfaEdge(lastPre, outerInnerGuard, assume1, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val outerLastGuard = buildPostStatement(guard, - ParamPack(builder, outerInnerGuard, null, null, null)) - val innerLastGuard = buildPostStatement(guard, - ParamPack(builder, innerInnerGuard, null, null, null)) - xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge(innerLastGuard, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - return endLoc + override fun visit(statement: CAssume, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(location) + xcfaEdge = + XcfaEdge( + initLoc, + location, + StmtLabel( + statement.assumeStmt, + choiceType = ChoiceType.MAIN_PATH, + metadata = getMetadata(statement), + ), + metadata = getMetadata(statement), + ) + builder.addEdge(xcfaEdge) + return location + } + + override fun visit(statement: CBreak, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(edge) + check(breakLoc != null) + edge = XcfaEdge(initLoc, breakLoc, metadata = getMetadata(statement)) + val unreachableLoc = + XcfaLocation("Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) + builder.addLoc(unreachableLoc) + builder.addEdge(edge) + return unreachableLoc + } + + override fun visit(statement: CCall, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val ret = statement.ret + val myParams = statement.params + var initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(location) + val params: MutableList> = ArrayList() + builder.addVar(ret) + params.add(ret.ref) + for (cStatement in myParams) { + initLoc = + cStatement.accept(this, ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) } + params.addAll( + myParams.stream().map { obj: CStatement -> obj.expression }.collect(Collectors.toList()) + ) + val call = InvokeLabel(statement.functionId, params, metadata = getMetadata(statement)) + xcfaEdge = XcfaEdge(initLoc, location, call, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + return location + } + + override fun visit(statement: CCase, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + return statement.statement.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc), + ) + } - override fun visit(statement: CExpr, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - return lastLoc + override fun visit(statement: CCompound, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + var lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val preStatements = statement.preStatements + val postStatements = statement.postStatements + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(edge) + lastLoc = initLoc + if (preStatements != null) + lastLoc = + preStatements.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + for (cStatement in statement.getcStatementList()) { + if (cStatement != null) + lastLoc = + cStatement.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } + if (postStatements != null) + lastLoc = + postStatements.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + return lastLoc + } - override fun visit(statement: CFor, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val increment = statement.increment - val init = statement.init - val guard = statement.guard - val body = statement.body - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val endInit = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val startIncrement = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val outerLastTest = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(endLoc) - builder.addLoc(outerLastTest) - builder.addLoc(endInit) - builder.addLoc(initLoc) - builder.addLoc(startIncrement) - var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val lastInit = if (init == null) initLoc else init.accept(this, - ParamPack(builder, initLoc, null, null, returnLoc)) - val lastTest = if (guard == null) lastInit else buildWithoutPostStatement(guard, - ParamPack(builder, lastInit!!, null, null, returnLoc)) - val assume = StmtLabel( - Stmts.Assume(if (guard == null) True() else AbstractExprs.Neq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.MAIN_PATH, - metadata = if (guard == null) getMetadata(statement) else getMetadata(guard) + override fun visit(statement: CContinue, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(edge) + check(continueLoc != null) + edge = XcfaEdge(initLoc, continueLoc, metadata = getMetadata(statement)) + val unreachableLoc: XcfaLocation = + XcfaLocation("Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) + builder.addLoc(unreachableLoc) + builder.addEdge(edge) + return unreachableLoc + } + + override fun visit(statement: CDefault, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + return statement.statement.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc), + ) + } + + override fun visit(statement: CDoWhile, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val body = statement.body + val guard = statement.guard + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val innerEndLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val innerInnerGuard = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val outerInnerGuard = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(endLoc) + builder.addLoc(innerInnerGuard) + builder.addLoc(outerInnerGuard) + builder.addLoc(innerEndLoc) + builder.addLoc(initLoc) + var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val lastBody = body.accept(this, ParamPack(builder, initLoc, endLoc, innerEndLoc, returnLoc)) + xcfaEdge = XcfaEdge(lastBody, innerEndLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val lastPre = + buildWithoutPostStatement(guard, ParamPack(builder, innerEndLoc, null, null, returnLoc)) + val assume = + StmtLabel( + Stmts.Assume( + AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, + ) + ), + choiceType = ChoiceType.MAIN_PATH, + metadata = getMetadata(guard), + ) + xcfaEdge = XcfaEdge(lastPre, innerInnerGuard, assume, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val assume1 = + StmtLabel( + Stmts.Assume( + AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, + ) + ), + choiceType = ChoiceType.ALTERNATIVE_PATH, + metadata = getMetadata(guard), + ) + xcfaEdge = XcfaEdge(lastPre, outerInnerGuard, assume1, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val outerLastGuard = + buildPostStatement(guard, ParamPack(builder, outerInnerGuard, null, null, null)) + val innerLastGuard = + buildPostStatement(guard, ParamPack(builder, innerInnerGuard, null, null, null)) + xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + xcfaEdge = XcfaEdge(innerLastGuard, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + return endLoc + } + + override fun visit(statement: CExpr, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + return lastLoc + } + + override fun visit(statement: CFor, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val increment = statement.increment + val init = statement.init + val guard = statement.guard + val body = statement.body + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val endInit = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val startIncrement = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val outerLastTest = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(endLoc) + builder.addLoc(outerLastTest) + builder.addLoc(endInit) + builder.addLoc(initLoc) + builder.addLoc(startIncrement) + var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val lastInit = + if (init == null) initLoc + else init.accept(this, ParamPack(builder, initLoc, null, null, returnLoc)) + val lastTest = + if (guard == null) lastInit + else buildWithoutPostStatement(guard, ParamPack(builder, lastInit!!, null, null, returnLoc)) + val assume = + StmtLabel( + Stmts.Assume( + if (guard == null) True() + else + AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, + ) + ), + choiceType = ChoiceType.MAIN_PATH, + metadata = if (guard == null) getMetadata(statement) else getMetadata(guard), + ) + check(lastTest != null) + xcfaEdge = XcfaEdge(lastTest, endInit, assume, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val assume1 = + StmtLabel( + Stmts.Assume( + if (guard == null) False() + else + AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, + ) + ), + choiceType = ChoiceType.ALTERNATIVE_PATH, + metadata = if (guard == null) getMetadata(statement) else getMetadata(guard), + ) + xcfaEdge = XcfaEdge(lastTest, outerLastTest, assume1, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val innerLastGuard = + if (guard == null) endInit + else buildPostStatement(guard, ParamPack(builder, endInit, endLoc, startIncrement, returnLoc)) + val lastBody = + if (body == null) innerLastGuard + else body.accept(this, ParamPack(builder, innerLastGuard, endLoc, startIncrement, returnLoc)) + xcfaEdge = XcfaEdge(lastBody, startIncrement, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + if (increment != null) { + val lastIncrement = + increment.accept(this, ParamPack(builder, startIncrement, null, null, returnLoc)) + xcfaEdge = XcfaEdge(lastIncrement, lastInit, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + } else { + xcfaEdge = XcfaEdge(startIncrement, lastInit, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + } + val outerLastGuard = + if (guard == null) outerLastTest + else + buildPostStatement( + guard, + ParamPack(builder, outerLastTest, endLoc, startIncrement, returnLoc), ) - check(lastTest != null) - xcfaEdge = XcfaEdge(lastTest, endInit, assume, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val assume1 = StmtLabel( - Stmts.Assume(if (guard == null) False() else AbstractExprs.Eq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.ALTERNATIVE_PATH, - metadata = if (guard == null) getMetadata(statement) else getMetadata(guard) + xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + return endLoc + } + + override fun visit(statement: CGoto, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(edge) + edge = + XcfaEdge( + initLoc, + getLoc(builder, statement.label, metadata = getMetadata(statement)), + metadata = getMetadata(statement), + ) + builder.addLoc(getLoc(builder, statement.label, metadata = getMetadata(statement))) + val unreachableLoc: XcfaLocation = + XcfaLocation("Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) + builder.addLoc(unreachableLoc) + builder.addEdge(edge) + return unreachableLoc + } + + override fun visit(statement: CIf, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val elseStatement = statement.elseStatement + val body = statement.body + val guard = statement.guard + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val mainBranch = getAnonymousLoc(builder, metadata = getMetadata(statement)) + val elseBranch = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(endLoc) + builder.addLoc(mainBranch) + builder.addLoc(elseBranch) + builder.addLoc(initLoc) + var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val endGuard = + buildWithoutPostStatement( + guard, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc), + ) + val assume = + StmtLabel( + Stmts.Assume( + AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, + ) + ), + choiceType = ChoiceType.MAIN_PATH, + metadata = getMetadata(guard), + ) + xcfaEdge = XcfaEdge(endGuard, mainBranch, assume, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val assume1 = + StmtLabel( + Stmts.Assume( + AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, + ) + ), + choiceType = ChoiceType.ALTERNATIVE_PATH, + metadata = getMetadata(guard), + ) + xcfaEdge = XcfaEdge(endGuard, elseBranch, assume1, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val mainAfterGuard = + buildPostStatement(guard, ParamPack(builder, mainBranch, breakLoc, continueLoc, returnLoc)) + val mainEnd = + body.accept(this, ParamPack(builder, mainAfterGuard, breakLoc, continueLoc, returnLoc)) + if (elseStatement != null) { + val elseAfterGuard = + buildPostStatement(guard, ParamPack(builder, elseBranch, breakLoc, continueLoc, returnLoc)) + val elseEnd = + elseStatement.accept( + this, + ParamPack(builder, elseAfterGuard, breakLoc, continueLoc, returnLoc), ) - xcfaEdge = XcfaEdge(lastTest, outerLastTest, assume1, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val innerLastGuard = if (guard == null) endInit else buildPostStatement(guard, - ParamPack(builder, endInit, endLoc, startIncrement, returnLoc)) - val lastBody = if (body == null) innerLastGuard else body.accept(this, - ParamPack(builder, innerLastGuard, endLoc, startIncrement, returnLoc)) - xcfaEdge = XcfaEdge(lastBody, startIncrement, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - if (increment != null) { - val lastIncrement = increment.accept(this, - ParamPack(builder, startIncrement, null, null, returnLoc)) - xcfaEdge = XcfaEdge(lastIncrement, lastInit, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } else { - xcfaEdge = XcfaEdge(startIncrement, lastInit, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - val outerLastGuard = if (guard == null) outerLastTest else buildPostStatement(guard, - ParamPack(builder, outerLastTest, endLoc, startIncrement, returnLoc)) - xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - return endLoc + xcfaEdge = XcfaEdge(elseEnd, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + } else { + xcfaEdge = XcfaEdge(elseBranch, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) } + xcfaEdge = XcfaEdge(mainEnd, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + return endLoc + } - override fun visit(statement: CGoto, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(edge) - edge = XcfaEdge(initLoc, - getLoc(builder, statement.label, metadata = getMetadata(statement)), - metadata = getMetadata(statement) - ) - builder.addLoc(getLoc(builder, statement.label, metadata = getMetadata(statement))) - val unreachableLoc: XcfaLocation = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) - builder.addLoc(unreachableLoc) - builder.addEdge(edge) - return unreachableLoc + override fun visit(statement: CInitializerList, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + var lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + for (cStatement in statement.statements) { + lastLoc = + cStatement + .get2() + .accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } + return lastLoc + } - override fun visit(statement: CIf, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val elseStatement = statement.elseStatement - val body = statement.body - val guard = statement.guard - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val mainBranch = getAnonymousLoc(builder, metadata = getMetadata(statement)) - val elseBranch = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(endLoc) - builder.addLoc(mainBranch) - builder.addLoc(elseBranch) - builder.addLoc(initLoc) - var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + override fun visit(statement: CRet, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val expr = statement.expr + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + val xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val endExpr = + expr?.accept(this, ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) ?: initLoc + val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(endLoc) + val key: VarDecl<*> = builder.getParams()[0].first + check(returnLoc != null) + val type = CComplexType.getType(key.ref, parseContext) + val edge = + XcfaEdge( + endExpr, + returnLoc, + StmtLabel( + Stmts.Assign( + cast(key, key.type), + cast(type.castTo(expr?.expression ?: type.nullValue), key.type), + ), + metadata = getMetadata(statement), + ), + metadata = getMetadata(statement), + ) + builder.addEdge(edge) + return endLoc + } + + override fun visit(statement: CSwitch, param: ParamPack): XcfaLocation { + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val testValue = statement.testValue + val body = statement.body + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(endLoc) + val edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(edge) + val endInit = + buildWithoutPostStatement( + testValue, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc), + ) + Preconditions.checkState(body is CCompound, "Switch body has to be a CompoundStatement!") + var defaultExpr: Expr? = True() + for (cStatement in (body as CCompound).getcStatementList()) { + if (cStatement is CCase) { + defaultExpr = + BoolExprs.And( + defaultExpr, + AbstractExprs.Neq(testValue.expression, cStatement.expr.expression), + ) + } + } + var lastLocation: XcfaLocation? = null + for (cStatement in body.getcStatementList()) { + val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(location) + var xcfaEdge: XcfaEdge + if (lastLocation != null) { + xcfaEdge = XcfaEdge(lastLocation, location, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val endGuard = buildWithoutPostStatement(guard, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) - val assume = StmtLabel( - Stmts.Assume(AbstractExprs.Neq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + } + if (cStatement is CCase) { + val afterGuard = + buildPostStatement( + testValue, + ParamPack(builder, checkNotNull(endInit), breakLoc, continueLoc, returnLoc), + ) + val assume = + StmtLabel( + Stmts.Assume(AbstractExprs.Eq(testValue.expression, cStatement.expr.expression)), choiceType = ChoiceType.MAIN_PATH, - metadata = getMetadata(guard) - ) - xcfaEdge = XcfaEdge(endGuard, mainBranch, assume, metadata = getMetadata(statement)) + metadata = getMetadata(testValue), + ) + xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val assume1 = StmtLabel( - Stmts.Assume(AbstractExprs.Eq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.ALTERNATIVE_PATH, - metadata = getMetadata(guard) - ) - xcfaEdge = XcfaEdge(endGuard, elseBranch, assume1, metadata = getMetadata(statement)) + } else if (cStatement is CDefault) { + val afterGuard = + buildPostStatement( + testValue, + ParamPack(builder, endInit!!, breakLoc, continueLoc, returnLoc), + ) + val assume = + StmtLabel( + Stmts.Assume(defaultExpr), + choiceType = ChoiceType.MAIN_PATH, // TODO: is this what validators expect? + metadata = getMetadata(cStatement), + ) + xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val mainAfterGuard = buildPostStatement(guard, - ParamPack(builder, mainBranch, breakLoc, continueLoc, returnLoc)) - val mainEnd = body.accept(this, - ParamPack(builder, mainAfterGuard, breakLoc, continueLoc, returnLoc)) - if (elseStatement != null) { - val elseAfterGuard = buildPostStatement(guard, - ParamPack(builder, elseBranch, breakLoc, continueLoc, returnLoc)) - val elseEnd = elseStatement.accept(this, - ParamPack(builder, elseAfterGuard, breakLoc, continueLoc, returnLoc)) - xcfaEdge = XcfaEdge(elseEnd, endLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } else { - xcfaEdge = XcfaEdge(elseBranch, endLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - xcfaEdge = XcfaEdge(mainEnd, endLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - return endLoc - } - - override fun visit(statement: CInitializerList, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - var lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - for (cStatement in statement.statements) { - lastLoc = cStatement.get2() - .accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - } - return lastLoc - } - - override fun visit(statement: CRet, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val expr = statement.expr - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - val xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val endExpr = expr?.accept(this, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) ?: initLoc - val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(endLoc) - val key: VarDecl<*> = builder.getParams()[0].first - check(returnLoc != null) - val type = CComplexType.getType(key.ref, parseContext) - val edge = XcfaEdge(endExpr, returnLoc, StmtLabel(Stmts.Assign(cast(key, key.type), - cast(type.castTo(expr?.expression ?: type.nullValue), key.type)), - metadata = getMetadata(statement)), metadata = getMetadata(statement)) - builder.addEdge(edge) - return endLoc + } + lastLocation = + cStatement.accept(this, ParamPack(builder, location, endLoc, continueLoc, returnLoc)) } - - override fun visit(statement: CSwitch, param: ParamPack): XcfaLocation { - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val testValue = statement.testValue - val body = statement.body - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(endLoc) - val edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(edge) - val endInit = buildWithoutPostStatement(testValue, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) - Preconditions.checkState(body is CCompound, "Switch body has to be a CompoundStatement!") - var defaultExpr: Expr? = True() - for (cStatement in (body as CCompound).getcStatementList()) { - if (cStatement is CCase) { - defaultExpr = BoolExprs.And(defaultExpr, - AbstractExprs.Neq(testValue.expression, cStatement.expr.expression)) - } - } - var lastLocation: XcfaLocation? = null - for (cStatement in body.getcStatementList()) { - val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(location) - var xcfaEdge: XcfaEdge - if (lastLocation != null) { - xcfaEdge = XcfaEdge(lastLocation, location, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - if (cStatement is CCase) { - val afterGuard = buildPostStatement(testValue, - ParamPack(builder, checkNotNull(endInit), breakLoc, continueLoc, returnLoc)) - val assume = StmtLabel( - Stmts.Assume( - AbstractExprs.Eq(testValue.expression, cStatement.expr.expression)), - choiceType = ChoiceType.MAIN_PATH, - metadata = getMetadata(testValue) - ) - xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } else if (cStatement is CDefault) { - val afterGuard = buildPostStatement(testValue, - ParamPack(builder, endInit!!, breakLoc, continueLoc, returnLoc)) - val assume = StmtLabel( - Stmts.Assume(defaultExpr), - choiceType = ChoiceType.MAIN_PATH, // TODO: is this what validators expect? - metadata = getMetadata(cStatement) - ) - xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - lastLocation = cStatement.accept(this, - ParamPack(builder, location, endLoc, continueLoc, returnLoc)) - } - if (lastLocation != null) { - val xcfaEdge: XcfaEdge = XcfaEdge(lastLocation, endLoc, - metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - return endLoc + if (lastLocation != null) { + val xcfaEdge: XcfaEdge = XcfaEdge(lastLocation, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) } + return endLoc + } - override fun visit(statement: CWhile, param: ParamPack): XcfaLocation { - val UNROLL_COUNT = 0 - val builder: XcfaProcedureBuilder = param.builder - val lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val guard = statement.guard - val body = statement.body - var initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + override fun visit(statement: CWhile, param: ParamPack): XcfaLocation { + val UNROLL_COUNT = 0 + val builder: XcfaProcedureBuilder = param.builder + val lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val guard = statement.guard + val body = statement.body + var initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(endLoc) + val outerBeforeGuard = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(outerBeforeGuard) + for (i in 0 until if (UNROLL_COUNT == 0) 1 else UNROLL_COUNT) { + val innerLoop = getAnonymousLoc(builder, metadata = getMetadata(statement)) + builder.addLoc(innerLoop) + val testEndLoc = + buildWithoutPostStatement(guard, ParamPack(builder, initLoc, null, null, returnLoc)) + if (UNROLL_COUNT > 0) { + initLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(initLoc) - var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(endLoc) - val outerBeforeGuard = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(outerBeforeGuard) - for (i in 0 until if (UNROLL_COUNT == 0) 1 else UNROLL_COUNT) { - val innerLoop = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(innerLoop) - val testEndLoc = buildWithoutPostStatement(guard, - ParamPack(builder, initLoc, null, null, returnLoc)) - if (UNROLL_COUNT > 0) { - initLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - } - val assume = StmtLabel( - Stmts.Assume(AbstractExprs.Neq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.MAIN_PATH, - metadata = getMetadata(guard) + } + val assume = + StmtLabel( + Stmts.Assume( + AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, ) - xcfaEdge = XcfaEdge(testEndLoc, innerLoop, assume, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val assume1 = StmtLabel( - Stmts.Assume(AbstractExprs.Eq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.ALTERNATIVE_PATH, - metadata = getMetadata(statement) + ), + choiceType = ChoiceType.MAIN_PATH, + metadata = getMetadata(guard), + ) + xcfaEdge = XcfaEdge(testEndLoc, innerLoop, assume, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val assume1 = + StmtLabel( + Stmts.Assume( + AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue, ) - xcfaEdge = XcfaEdge(testEndLoc, outerBeforeGuard, assume1, - metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - val lastGuard = buildPostStatement(guard, - ParamPack(builder, innerLoop, endLoc, initLoc, returnLoc)) - val lastBody = body.accept(this, - ParamPack(builder, lastGuard, endLoc, initLoc, returnLoc)) - xcfaEdge = XcfaEdge(lastBody, initLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - } - val outerLastGuard = buildPostStatement(guard, - ParamPack(builder, outerBeforeGuard, null, null, null)) - xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) - builder.addEdge(xcfaEdge) - return endLoc + ), + choiceType = ChoiceType.ALTERNATIVE_PATH, + metadata = getMetadata(statement), + ) + xcfaEdge = XcfaEdge(testEndLoc, outerBeforeGuard, assume1, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + val lastGuard = + buildPostStatement(guard, ParamPack(builder, innerLoop, endLoc, initLoc, returnLoc)) + val lastBody = body.accept(this, ParamPack(builder, lastGuard, endLoc, initLoc, returnLoc)) + xcfaEdge = XcfaEdge(lastBody, initLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) } + val outerLastGuard = + buildPostStatement(guard, ParamPack(builder, outerBeforeGuard, null, null, null)) + xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) + builder.addEdge(xcfaEdge) + return endLoc + } - private fun buildWithoutPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { - Preconditions.checkState(cStatement is CCompound, - "Currently only CCompounds have pre- and post statements!") - val statement = cStatement as CCompound - val builder: XcfaProcedureBuilder = param.builder - var lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val preStatements = statement.preStatements - val postStatements = statement.postStatements - val cStatementList = statement.getcStatementList() - val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) - builder.addLoc(initLoc) - val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) - builder.addEdge(edge) - lastLoc = initLoc - if (preStatements != null) lastLoc = preStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - for (i in 0 until cStatementList.size - 1) { - val stmt = cStatementList[i] - if (stmt != null) lastLoc = stmt.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - } - if (cStatementList.size == 0) return lastLoc - val lastStatement = cStatementList[cStatementList.size - 1] - lastLoc = if (postStatements == null) { - buildWithoutPostStatement(lastStatement, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - } else { - lastStatement.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - } - return lastLoc + private fun buildWithoutPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { + Preconditions.checkState( + cStatement is CCompound, + "Currently only CCompounds have pre- and post statements!", + ) + val statement = cStatement as CCompound + val builder: XcfaProcedureBuilder = param.builder + var lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val preStatements = statement.preStatements + val postStatements = statement.postStatements + val cStatementList = statement.getcStatementList() + val initLoc = getLoc(builder, statement.id, metadata = getMetadata(statement)) + builder.addLoc(initLoc) + val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) + builder.addEdge(edge) + lastLoc = initLoc + if (preStatements != null) + lastLoc = + preStatements.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + for (i in 0 until cStatementList.size - 1) { + val stmt = cStatementList[i] + if (stmt != null) + lastLoc = stmt.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } + if (cStatementList.size == 0) return lastLoc + val lastStatement = cStatementList[cStatementList.size - 1] + lastLoc = + if (postStatements == null) { + buildWithoutPostStatement( + lastStatement, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc), + ) + } else { + lastStatement.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + } + return lastLoc + } - private fun buildPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { - Preconditions.checkState(cStatement is CCompound, - "Currently only CCompounds have pre- and post statements!") - val statement = cStatement as CCompound - val builder: XcfaProcedureBuilder = param.builder - var lastLoc = param.lastLoc - val breakLoc = param.breakLoc - val continueLoc = param.continueLoc - val returnLoc = param.returnLoc - val preStatements = statement.preStatements - val postStatements = statement.postStatements - val cStatementList = statement.getcStatementList() - lastLoc = if (postStatements != null) postStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) else buildPostStatement( - cStatementList[cStatementList.size - 1], - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) - return lastLoc - } + private fun buildPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { + Preconditions.checkState( + cStatement is CCompound, + "Currently only CCompounds have pre- and post statements!", + ) + val statement = cStatement as CCompound + val builder: XcfaProcedureBuilder = param.builder + var lastLoc = param.lastLoc + val breakLoc = param.breakLoc + val continueLoc = param.continueLoc + val returnLoc = param.returnLoc + val preStatements = statement.preStatements + val postStatements = statement.postStatements + val cStatementList = statement.getcStatementList() + lastLoc = + if (postStatements != null) + postStatements.accept(this, ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + else + buildPostStatement( + cStatementList[cStatementList.size - 1], + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc), + ) + return lastLoc + } - class ParamPack(builder: XcfaProcedureBuilder, lastLoc: XcfaLocation, breakLoc: XcfaLocation?, - continueLoc: XcfaLocation?, returnLoc: XcfaLocation?) { - - val builder: XcfaProcedureBuilder - val lastLoc: XcfaLocation - val breakLoc: XcfaLocation? - val continueLoc: XcfaLocation? - val returnLoc: XcfaLocation? - - init { - this.builder = builder - this.lastLoc = lastLoc - this.breakLoc = breakLoc - this.continueLoc = continueLoc - this.returnLoc = returnLoc - } + class ParamPack( + builder: XcfaProcedureBuilder, + lastLoc: XcfaLocation, + breakLoc: XcfaLocation?, + continueLoc: XcfaLocation?, + returnLoc: XcfaLocation?, + ) { + + val builder: XcfaProcedureBuilder + val lastLoc: XcfaLocation + val breakLoc: XcfaLocation? + val continueLoc: XcfaLocation? + val returnLoc: XcfaLocation? + + init { + this.builder = builder + this.lastLoc = lastLoc + this.breakLoc = breakLoc + this.continueLoc = continueLoc + this.returnLoc = returnLoc } -} \ No newline at end of file + } +} diff --git a/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java b/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java index c6a06d5bb8..f143194257 100644 --- a/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java +++ b/subprojects/xcfa/litmus2xcfa/src/main/java/hu/bme/mit/theta/frontend/litmus2xcfa/dsl/LitmusAArch64.java @@ -13,9 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.frontend.litmus2xcfa.dsl; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.decl.Decls.Var; +import static hu.bme.mit.theta.core.stmt.Stmts.Assign; +import static hu.bme.mit.theta.core.stmt.Stmts.Assume; +import static hu.bme.mit.theta.core.type.bvtype.BvExprs.*; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; + import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.type.Expr; @@ -26,18 +33,9 @@ import hu.bme.mit.theta.litmus2xcfa.dsl.gen.LitmusAArch64Parser; import hu.bme.mit.theta.xcfa.model.*; import hu.bme.mit.theta.xcfa.passes.LitmusPasses; - import java.math.BigInteger; import java.util.*; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.decl.Decls.Var; -import static hu.bme.mit.theta.core.stmt.Stmts.Assign; -import static hu.bme.mit.theta.core.stmt.Stmts.Assume; -import static hu.bme.mit.theta.core.type.bvtype.BvExprs.*; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; - public class LitmusAArch64 extends LitmusAArch64BaseVisitor { private final Map, Optional>>> vars; private final Map>> regLookup; @@ -68,25 +66,42 @@ public LitmusAArch64() { public XCFA visitMain(LitmusAArch64Parser.MainContext ctx) { XcfaBuilder builder = new XcfaBuilder(""); - for (final LitmusAArch64Parser.VariableDeclaratorContext variableDeclaratorContext : ctx.variableDeclaratorList().variableDeclarator()) { - final LitmusAArch64Parser.VariableDeclaratorLocationContext varDeclCtx = variableDeclaratorContext.variableDeclaratorLocation(); - final LitmusAArch64Parser.VariableDeclaratorRegisterLocationContext regDeclCtx = variableDeclaratorContext.variableDeclaratorRegisterLocation(); + for (final LitmusAArch64Parser.VariableDeclaratorContext variableDeclaratorContext : + ctx.variableDeclaratorList().variableDeclarator()) { + final LitmusAArch64Parser.VariableDeclaratorLocationContext varDeclCtx = + variableDeclaratorContext.variableDeclaratorLocation(); + final LitmusAArch64Parser.VariableDeclaratorRegisterLocationContext regDeclCtx = + variableDeclaratorContext.variableDeclaratorRegisterLocation(); if (varDeclCtx != null) { - getGlobalFromName(varDeclCtx.location().getText(), BvUtils.bigIntegerToNeutralBvLitExpr(new BigInteger(varDeclCtx.constant().getText()), 64), builder); + getGlobalFromName( + varDeclCtx.location().getText(), + BvUtils.bigIntegerToNeutralBvLitExpr( + new BigInteger(varDeclCtx.constant().getText()), 64), + builder); } else if (regDeclCtx != null && regDeclCtx.Amp() == null) { final int id = regDeclCtx.threadId().id; globalAddresses.putIfAbsent(id, new LinkedHashMap<>()); - globalAddresses.get(id).put(regDeclCtx.register64().getText(), getGlobalFromName(regDeclCtx.location().getText(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 64), builder)); + globalAddresses + .get(id) + .put( + regDeclCtx.register64().getText(), + getGlobalFromName( + regDeclCtx.location().getText(), + BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 64), + builder)); } else { - throw new UnsupportedOperationException("Only registers storing addresses of global variables are supported!"); + throw new UnsupportedOperationException( + "Only registers storing addresses of global variables are supported!"); } } - for (final LitmusAArch64Parser.ThreadIdContext threadIdContext : ctx.program().threadDeclaratorList().threadId()) { + for (final LitmusAArch64Parser.ThreadIdContext threadIdContext : + ctx.program().threadDeclaratorList().threadId()) { final int id = threadIdContext.id; regLookup.putIfAbsent(id, new LinkedHashMap<>()); globalAddresses.putIfAbsent(id, new LinkedHashMap<>()); locations.putIfAbsent(id, new LinkedHashMap<>()); - final XcfaProcedureBuilder procedure = new XcfaProcedureBuilder("thrd" + id, new LitmusPasses()); + final XcfaProcedureBuilder procedure = + new XcfaProcedureBuilder("thrd" + id, new LitmusPasses()); builder.addProcedure(procedure); builder.addEntryPoint(procedure, List.of()); procedure.createInitLoc(); @@ -94,10 +109,13 @@ public XCFA visitMain(LitmusAArch64Parser.MainContext ctx) { lastLocation.put(id, procedure.getInitLoc()); threadIds.add(id); } - for (LitmusAArch64Parser.InstructionRowContext instructionRowContext : ctx.program().instructionList().instructionRow()) { - List instruction = instructionRowContext.instruction(); + for (LitmusAArch64Parser.InstructionRowContext instructionRowContext : + ctx.program().instructionList().instructionRow()) { + List instruction = + instructionRowContext.instruction(); for (int i = 0; i < instruction.size(); i++) { - final LitmusAArch64Parser.InstructionContext instructionContext = instruction.get(i); + final LitmusAArch64Parser.InstructionContext instructionContext = + instruction.get(i); currentProc = threadIds.get(i); instructionContext.accept(locationVisitor); } @@ -105,12 +123,18 @@ public XCFA visitMain(LitmusAArch64Parser.MainContext ctx) { for (Integer threadId : threadIds) { XcfaProcedureBuilder procBuilder = builders.get(threadId); procBuilder.createFinalLoc(); - procBuilder.addEdge(new XcfaEdge(lastLocation.get(threadId), procBuilder.getFinalLoc().get(), NopLabel.INSTANCE, EmptyMetaData.INSTANCE)); + procBuilder.addEdge( + new XcfaEdge( + lastLocation.get(threadId), + procBuilder.getFinalLoc().get(), + NopLabel.INSTANCE, + EmptyMetaData.INSTANCE)); } return builder.build(); } - private VarDecl getGlobalFromName(final String name, final LitExpr litExpr, final XcfaBuilder builder) { + private VarDecl getGlobalFromName( + final String name, final LitExpr litExpr, final XcfaBuilder builder) { if (!vars.containsKey(name)) { VarDecl var = Var(name, BvType(64)); checkNotNull(litExpr); @@ -121,7 +145,9 @@ private VarDecl getGlobalFromName(final String name, final LitExpr getOrCreateVar(final String name, final int size) { - checkState(!globalAddresses.get(currentProc).containsKey(name), "Register cannot be modified if it holds an address!"); + checkState( + !globalAddresses.get(currentProc).containsKey(name), + "Register cannot be modified if it holds an address!"); if (!regLookup.get(currentProc).containsKey(name)) { final VarDecl var = Var(name, BvType(size)); regLookup.get(currentProc).put(name, var); @@ -131,8 +157,12 @@ private VarDecl getOrCreateVar(final String name, final int size) { } private VarDecl getGlobalFromReg(final String name) { - checkState(!regLookup.get(currentProc).containsKey(name), "Register cannot be modified if it holds an address!"); - checkState(globalAddresses.get(currentProc).containsKey(name), "Register holds an unknown address!"); + checkState( + !regLookup.get(currentProc).containsKey(name), + "Register cannot be modified if it holds an address!"); + checkState( + globalAddresses.get(currentProc).containsKey(name), + "Register holds an unknown address!"); return globalAddresses.get(currentProc).get(name); } @@ -151,18 +181,23 @@ private XcfaLocation getOrCreateLoc(final String name) { private class ExpressionVisitor extends LitmusAArch64BaseVisitor> { @Override - public Expr visitExpressionConversion(LitmusAArch64Parser.ExpressionConversionContext ctx) { + public Expr visitExpressionConversion( + LitmusAArch64Parser.ExpressionConversionContext ctx) { return ctx.register32().accept(this); } @Override - public Expr visitExpressionImmediate64(LitmusAArch64Parser.ExpressionImmediate64Context ctx) { - return BvUtils.bigIntegerToNeutralBvLitExpr(new BigInteger(ctx.expressionImmediate().immediate().constant().getText()), 64); + public Expr visitExpressionImmediate64( + LitmusAArch64Parser.ExpressionImmediate64Context ctx) { + return BvUtils.bigIntegerToNeutralBvLitExpr( + new BigInteger(ctx.expressionImmediate().immediate().constant().getText()), 64); } @Override - public Expr visitExpressionImmediate32(LitmusAArch64Parser.ExpressionImmediate32Context ctx) { - return BvUtils.bigIntegerToNeutralBvLitExpr(new BigInteger(ctx.expressionImmediate().immediate().constant().getText()), 32); + public Expr visitExpressionImmediate32( + LitmusAArch64Parser.ExpressionImmediate32Context ctx) { + return BvUtils.bigIntegerToNeutralBvLitExpr( + new BigInteger(ctx.expressionImmediate().immediate().constant().getText()), 32); } @Override @@ -179,22 +214,38 @@ public Expr visitRegister32(LitmusAArch64Parser.Register32Context ctx) { private class LabelVisitor extends LitmusAArch64BaseVisitor { @Override public XcfaLabel visitMov32(LitmusAArch64Parser.Mov32Context ctx) { - return new StmtLabel(Assign(getOrCreateVar(ctx.r32.getText(), 32), ctx.expr32().accept(expressionVisitor))); + return new StmtLabel( + Assign( + getOrCreateVar(ctx.r32.getText(), 32), + ctx.expr32().accept(expressionVisitor))); } @Override public XcfaLabel visitMov64(LitmusAArch64Parser.Mov64Context ctx) { - return new StmtLabel(Assign(getOrCreateVar(ctx.r64.getText(), 64), ctx.expr64().accept(expressionVisitor))); + return new StmtLabel( + Assign( + getOrCreateVar(ctx.r64.getText(), 64), + ctx.expr64().accept(expressionVisitor))); } @Override public XcfaLabel visitCmp32(LitmusAArch64Parser.Cmp32Context ctx) { - return new StmtLabel(Assign(getOrCreateVar("Xcmp", 32), Sub(ctx.r32.accept(expressionVisitor), ctx.expr32().accept(expressionVisitor)))); + return new StmtLabel( + Assign( + getOrCreateVar("Xcmp", 32), + Sub( + ctx.r32.accept(expressionVisitor), + ctx.expr32().accept(expressionVisitor)))); } @Override public XcfaLabel visitCmp64(LitmusAArch64Parser.Cmp64Context ctx) { - return new StmtLabel(Assign(getOrCreateVar("Wcmp", 64), Sub(ctx.r64.accept(expressionVisitor), ctx.expr64().accept(expressionVisitor)))); + return new StmtLabel( + Assign( + getOrCreateVar("Wcmp", 64), + Sub( + ctx.r64.accept(expressionVisitor), + ctx.expr64().accept(expressionVisitor)))); } @Override @@ -208,7 +259,10 @@ public XcfaLabel visitArith32(LitmusAArch64Parser.Arith32Context ctx) { case "EOR" -> new StmtLabel(Assign(target, Xor(List.of(a, b)))); case "AND" -> new StmtLabel(Assign(target, And(List.of(a, b)))); default -> - throw new UnsupportedOperationException("Arithmetic instruction " + ctx.arithmeticInstruction().getText() + " not supported."); + throw new UnsupportedOperationException( + "Arithmetic instruction " + + ctx.arithmeticInstruction().getText() + + " not supported."); }; } @@ -223,41 +277,70 @@ public XcfaLabel visitArith64(LitmusAArch64Parser.Arith64Context ctx) { case "EOR" -> new StmtLabel(Assign(target, Xor(List.of(a, b)))); case "AND" -> new StmtLabel(Assign(target, And(List.of(a, b)))); default -> - throw new UnsupportedOperationException("Arithmetic instruction " + ctx.arithmeticInstruction().getText() + " not supported."); + throw new UnsupportedOperationException( + "Arithmetic instruction " + + ctx.arithmeticInstruction().getText() + + " not supported."); }; } @Override public XcfaLabel visitLoad32(LitmusAArch64Parser.Load32Context ctx) { final VarDecl var = getOrCreateVar(ctx.rD32.getText(), 32); - final VarDecl tmp = getOrCreateVar("tmp" + XcfaLocation.Companion.uniqueCounter(), 64); + final VarDecl tmp = + getOrCreateVar("tmp" + XcfaLocation.Companion.uniqueCounter(), 64); StmtLabel cast = new StmtLabel(Assign(var, Extract(tmp.getRef(), Int(0), Int(32)))); - ReadLabel load = new ReadLabel(getGlobalFromReg(ctx.address().r.getText()), tmp, Set.of(ctx.loadInstruction().mo), EmptyMetaData.INSTANCE); + ReadLabel load = + new ReadLabel( + getGlobalFromReg(ctx.address().r.getText()), + tmp, + Set.of(ctx.loadInstruction().mo), + EmptyMetaData.INSTANCE); return new SequenceLabel(List.of(load, cast)); } @Override public XcfaLabel visitLoad64(LitmusAArch64Parser.Load64Context ctx) { - return new ReadLabel(getGlobalFromReg(ctx.address().r.getText()), getOrCreateVar(ctx.rD64.getText(), 32), Set.of(ctx.loadInstruction().mo), EmptyMetaData.INSTANCE); + return new ReadLabel( + getGlobalFromReg(ctx.address().r.getText()), + getOrCreateVar(ctx.rD64.getText(), 32), + Set.of(ctx.loadInstruction().mo), + EmptyMetaData.INSTANCE); } @Override public XcfaLabel visitStore32(LitmusAArch64Parser.Store32Context ctx) { final VarDecl var = getOrCreateVar(ctx.rV32.getText(), 32); - final VarDecl tmp = getOrCreateVar("tmp" + XcfaLocation.Companion.uniqueCounter(), 64); + final VarDecl tmp = + getOrCreateVar("tmp" + XcfaLocation.Companion.uniqueCounter(), 64); StmtLabel cast = new StmtLabel(Assign(tmp, ZExt(var.getRef(), BvType(64)))); - WriteLabel store = new WriteLabel(getGlobalFromReg(ctx.address().r.getText()), tmp, Set.of(ctx.storeInstruction().mo), EmptyMetaData.INSTANCE); + WriteLabel store = + new WriteLabel( + getGlobalFromReg(ctx.address().r.getText()), + tmp, + Set.of(ctx.storeInstruction().mo), + EmptyMetaData.INSTANCE); return new SequenceLabel(List.of(cast, store)); } @Override public XcfaLabel visitStore64(LitmusAArch64Parser.Store64Context ctx) { - return new WriteLabel(getGlobalFromReg(ctx.address().r.getText()), getOrCreateVar(ctx.rV64.getText(), 64), Set.of(ctx.storeInstruction().mo), EmptyMetaData.INSTANCE); + return new WriteLabel( + getGlobalFromReg(ctx.address().r.getText()), + getOrCreateVar(ctx.rV64.getText(), 64), + Set.of(ctx.storeInstruction().mo), + EmptyMetaData.INSTANCE); } @Override public XcfaLabel visitFence(LitmusAArch64Parser.FenceContext ctx) { - return new FenceLabel(Set.of(ctx.Fence().getText() + (ctx.FenceOpt() == null ? "" : "." + ctx.FenceOpt().getText())), EmptyMetaData.INSTANCE); + return new FenceLabel( + Set.of( + ctx.Fence().getText() + + (ctx.FenceOpt() == null + ? "" + : "." + ctx.FenceOpt().getText())), + EmptyMetaData.INSTANCE); } } @@ -267,22 +350,52 @@ public XcfaLocation visitBranchRegister32(LitmusAArch64Parser.BranchRegister32Co VarDecl var = getOrCreateVar(ctx.rV32.getText(), 32); final StmtLabel stmt1, stmt2; if (ctx.branchRegInstruction().zerotest) { - stmt1 = new StmtLabel(Assume(Eq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 32)))); - stmt2 = new StmtLabel(Assume(Neq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 32)))); + stmt1 = + new StmtLabel( + Assume( + Eq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 32)))); + stmt2 = + new StmtLabel( + Assume( + Neq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 32)))); } else { - stmt1 = new StmtLabel(Assume(Neq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 32)))); - stmt2 = new StmtLabel(Assume(Eq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 32)))); + stmt1 = + new StmtLabel( + Assume( + Neq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 32)))); + stmt2 = + new StmtLabel( + Assume( + Eq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 32)))); } final XcfaLocation branchTo = getOrCreateLoc(ctx.label().getText()); final XcfaLocation newLoc = newAnonymousLoc(); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - branchTo, - stmt1, EmptyMetaData.INSTANCE)); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - newLoc, - stmt2, EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + branchTo, + stmt1, + EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + newLoc, + stmt2, + EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -292,22 +405,52 @@ public XcfaLocation visitBranchRegister64(LitmusAArch64Parser.BranchRegister64Co VarDecl var = getOrCreateVar(ctx.rV64.getText(), 64); final StmtLabel stmt1, stmt2; if (ctx.branchRegInstruction().zerotest) { - stmt1 = new StmtLabel(Assume(Eq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 64)))); - stmt2 = new StmtLabel(Assume(Neq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 64)))); + stmt1 = + new StmtLabel( + Assume( + Eq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 64)))); + stmt2 = + new StmtLabel( + Assume( + Neq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 64)))); } else { - stmt1 = new StmtLabel(Assume(Neq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 64)))); - stmt2 = new StmtLabel(Assume(Eq(var.getRef(), BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, 64)))); + stmt1 = + new StmtLabel( + Assume( + Neq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 64)))); + stmt2 = + new StmtLabel( + Assume( + Eq( + var.getRef(), + BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.ZERO, 64)))); } final XcfaLocation branchTo = getOrCreateLoc(ctx.label().getText()); final XcfaLocation newLoc = newAnonymousLoc(); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - branchTo, - stmt1, EmptyMetaData.INSTANCE)); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - newLoc, - stmt2, EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + branchTo, + stmt1, + EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + newLoc, + stmt2, + EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -316,9 +459,13 @@ public XcfaLocation visitBranchRegister64(LitmusAArch64Parser.BranchRegister64Co public XcfaLocation visitBranch(LitmusAArch64Parser.BranchContext ctx) { final XcfaLocation branchTo = getOrCreateLoc(ctx.label().getText()); final XcfaLocation newLoc = newAnonymousLoc(); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - branchTo, NopLabel.INSTANCE, EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + branchTo, + NopLabel.INSTANCE, + EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -326,22 +473,30 @@ public XcfaLocation visitBranch(LitmusAArch64Parser.BranchContext ctx) { @Override public XcfaLocation visitBranchLabel(LitmusAArch64Parser.BranchLabelContext ctx) { final XcfaLocation newLoc = getOrCreateLoc(ctx.label().getText()); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - newLoc, NopLabel.INSTANCE, EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + newLoc, + NopLabel.INSTANCE, + EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @Override - public XcfaLocation visitSimpleInstruction(LitmusAArch64Parser.SimpleInstructionContext ctx) { + public XcfaLocation visitSimpleInstruction( + LitmusAArch64Parser.SimpleInstructionContext ctx) { final XcfaLabel label = ctx.accept(labelVisitor); if (label != null) { final XcfaLocation newLoc = newAnonymousLoc(); - builders.get(currentProc).addEdge(new XcfaEdge( - lastLocation.get(currentProc), - newLoc, - label, EmptyMetaData.INSTANCE)); + builders.get(currentProc) + .addEdge( + new XcfaEdge( + lastLocation.get(currentProc), + newLoc, + label, + EmptyMetaData.INSTANCE)); lastLocation.put(currentProc, newLoc); return newLoc; } @@ -349,7 +504,8 @@ public XcfaLocation visitSimpleInstruction(LitmusAArch64Parser.SimpleInstruction } @Override - public XcfaLocation visitExclusiveInstruction(LitmusAArch64Parser.ExclusiveInstructionContext ctx) { + public XcfaLocation visitExclusiveInstruction( + LitmusAArch64Parser.ExclusiveInstructionContext ctx) { throw new UnsupportedOperationException(); } } diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java index 422517ddfd..9d997a808d 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/LlvmMetadata.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.llvm2xcfa; import hu.bme.mit.theta.xcfa.model.MetaData; @@ -26,8 +25,7 @@ public LlvmMetadata(int lineNumber) { this.lineNumber = lineNumber; } - @NotNull - @Override + @NotNull @Override public MetaData combine(@NotNull MetaData other) { return this; } diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java index f07bf60d2a..13b3ab00f7 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/Utils.java @@ -13,9 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.llvm2xcfa; +import static hu.bme.mit.theta.core.decl.Decls.Var; +import static hu.bme.mit.theta.core.stmt.Stmts.Assign; +import static hu.bme.mit.theta.core.type.arraytype.ArrayExprs.Array; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Bool; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; +import static hu.bme.mit.theta.core.type.rattype.RatExprs.Rat; +import static hu.bme.mit.theta.core.utils.TypeUtils.cast; + import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.stmt.Stmt; @@ -41,20 +48,11 @@ import hu.bme.mit.theta.xcfa.model.StmtLabel; import hu.bme.mit.theta.xcfa.model.XcfaEdge; import hu.bme.mit.theta.xcfa.model.XcfaLocation; - import java.math.BigInteger; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static hu.bme.mit.theta.core.decl.Decls.Var; -import static hu.bme.mit.theta.core.stmt.Stmts.Assign; -import static hu.bme.mit.theta.core.type.arraytype.ArrayExprs.Array; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Bool; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; -import static hu.bme.mit.theta.core.type.rattype.RatExprs.Rat; -import static hu.bme.mit.theta.core.utils.TypeUtils.cast; - public class Utils { private static final int doublePrecision = 1 << 8; public static ArithmeticType arithmeticType; @@ -86,7 +84,8 @@ public static Type createType(String type) { case "i1": return Bool(); default: -// new RuntimeException("Type " + type + " not known! (Using 32 bit int instead)").printStackTrace(); + // new RuntimeException("Type " + type + " not known! (Using 32 bit + // int instead)").printStackTrace(); if (arithmeticType == ArithmeticType.bitvector) return BvType.of(32); return Int(); } @@ -100,7 +99,9 @@ public static VarDecl createVariable(String name, String type) { public static LitExpr parseConstant(Type type, String value) { if (type instanceof RatType) - return RatLitExpr.of(BigInteger.valueOf((long) (Float.parseFloat(value) * doublePrecision)), BigInteger.valueOf(doublePrecision)); + return RatLitExpr.of( + BigInteger.valueOf((long) (Float.parseFloat(value) * doublePrecision)), + BigInteger.valueOf(doublePrecision)); return IntLitExpr.of(new BigInteger(value)); } @@ -111,15 +112,20 @@ public static LitExpr createConstant(String value) { public static LitExpr createConstant(Type type, String value) { String[] arguments = value.split(" "); if (arguments.length != 2) { - System.err.println("Constant should be of form \"(type=[a-zA-Z0-9]*) (value=[\\.0-9fe+-]*)\", got: " + value); + System.err.println( + "Constant should be of form \"(type=[a-zA-Z0-9]*) (value=[\\.0-9fe+-]*)\", got:" + + " " + + value); return getDefaultValue(type); - } switch (arguments[0]) { case "double": case "float": - return RatLitExpr.of(BigInteger.valueOf((long) (Float.parseFloat(arguments[1]) * doublePrecision)), BigInteger.valueOf(doublePrecision)); + return RatLitExpr.of( + BigInteger.valueOf( + (long) (Float.parseFloat(arguments[1]) * doublePrecision)), + BigInteger.valueOf(doublePrecision)); case "i64": if (arithmeticType == ArithmeticType.bitvector) return BvUtils.bigIntegerToNeutralBvLitExpr(new BigInteger(arguments[1]), 64); @@ -136,7 +142,9 @@ public static LitExpr createConstant(Type type, String value) { case "i1": return BoolLitExpr.of(arguments[1].equals("true")); default: - new RuntimeException("Type " + arguments[0] + " not known! (Using int32(0) instead)").printStackTrace(); + new RuntimeException( + "Type " + arguments[0] + " not known! (Using int32(0) instead)") + .printStackTrace(); if (arithmeticType == ArithmeticType.bitvector) return BvUtils.bigIntegerToNeutralBvLitExpr(new BigInteger("0"), 32); return IntLitExpr.of(BigInteger.ZERO); @@ -147,16 +155,25 @@ private static LitExpr getDefaultValue(Type type) { if (type instanceof RatType) return RatLitExpr.of(BigInteger.ZERO, BigInteger.ONE); else if (type instanceof BvType) return BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.ZERO, ((BvType) type).getSize()); - else if (type instanceof ArrayType) return ArrayLitExpr.of( - List.of(Tuple2.of(IntLitExpr.of(BigInteger.ZERO), cast(getDefaultValue(((ArrayType) type).getElemType()), ((ArrayType) type).getElemType()))), - cast(getDefaultValue(((ArrayType) type).getElemType()), ((ArrayType) type).getElemType()), - ArrayType.of(Int(), ((ArrayType) type).getElemType())); + else if (type instanceof ArrayType) + return ArrayLitExpr.of( + List.of( + Tuple2.of( + IntLitExpr.of(BigInteger.ZERO), + cast( + getDefaultValue(((ArrayType) type).getElemType()), + ((ArrayType) type).getElemType()))), + cast( + getDefaultValue(((ArrayType) type).getElemType()), + ((ArrayType) type).getElemType()), + ArrayType.of(Int(), ((ArrayType) type).getElemType())); return IntLitExpr.of(BigInteger.ZERO); } public static VarDecl getOrCreateVar(FunctionState functionState, Argument regArgument) { VarDecl var; - Tuple2, Integer> objects = functionState.getLocalVars().get(regArgument.getName()); + Tuple2, Integer> objects = + functionState.getLocalVars().get(regArgument.getName()); if (objects == null) { var = Var(regArgument.getName(), regArgument.getType()); functionState.getProcedureBuilder().getVars().add(var); @@ -178,28 +195,48 @@ public static VarDecl getOrCreateVar(FunctionState functionState, Argument re } } - public static void foldExpression(Instruction instruction, FunctionState functionState, BlockState blockState, String opName, Expr op, int ref) { + public static void foldExpression( + Instruction instruction, + FunctionState functionState, + BlockState blockState, + String opName, + Expr op, + int ref) { //noinspection OptionalGetWithoutIsPresent RegArgument ret = instruction.getRetVar().get(); if (ret instanceof LocalArgument) { - XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); + XcfaLocation loc = + new XcfaLocation( + blockState.getName() + "_" + blockState.getBlockCnt(), + EmptyMetaData.INSTANCE); VarDecl lhs = Utils.getOrCreateVar(functionState, ret); Stmt stmt = Assign(cast(lhs, lhs.getType()), cast(op, lhs.getType())); XcfaEdge edge; if (!lhs.getRef().equals(op)) - edge = new XcfaEdge(blockState.getLastLocation(), loc, new StmtLabel(stmt), new LlvmMetadata(instruction.getLineNumber())); + edge = + new XcfaEdge( + blockState.getLastLocation(), + loc, + new StmtLabel(stmt), + new LlvmMetadata(instruction.getLineNumber())); else - edge = new XcfaEdge(blockState.getLastLocation(), loc, NopLabel.INSTANCE, new LlvmMetadata(instruction.getLineNumber())); + edge = + new XcfaEdge( + blockState.getLastLocation(), + loc, + NopLabel.INSTANCE, + new LlvmMetadata(instruction.getLineNumber())); functionState.getProcedureBuilder().addLoc(loc); functionState.getProcedureBuilder().addEdge(edge); blockState.setLastLocation(loc); } else { if (functionState.getLocalVars().containsKey(opName)) { Tuple2, Integer> oldVar = functionState.getLocalVars().get(opName); - functionState.getLocalVars().put(ret.getName(), Tuple2.of(oldVar.get1(), oldVar.get2() + ref)); + functionState + .getLocalVars() + .put(ret.getName(), Tuple2.of(oldVar.get1(), oldVar.get2() + ref)); } functionState.getValues().put(ret.getName(), op); } } - } diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java index 45b7de6eae..0d6cc6e5a6 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/ArrayIntrinsicsHandler.java @@ -13,9 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.llvm2xcfa.handlers.concrete; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.stmt.Stmts.Assign; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; +import static hu.bme.mit.theta.core.utils.TypeUtils.cast; +import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; + import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.stmt.Stmt; import hu.bme.mit.theta.core.type.Expr; @@ -35,17 +40,16 @@ import hu.bme.mit.theta.xcfa.model.XcfaEdge; import hu.bme.mit.theta.xcfa.model.XcfaLocation; -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.stmt.Stmts.Assign; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; -import static hu.bme.mit.theta.core.utils.TypeUtils.cast; -import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; - public class ArrayIntrinsicsHandler extends BaseInstructionHandler { @Override - public void handleInstruction(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + public void handleInstruction( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { if (instruction.getOpName().equals("call")) { - String name = instruction.getArguments().get(instruction.getArguments().size() - 1).getName(); + String name = + instruction.getArguments().get(instruction.getArguments().size() - 1).getName(); if (name.startsWith("getArrayElement")) { getArrayElement(instruction, globalState, functionState, blockState); return; @@ -57,36 +61,69 @@ public void handleInstruction(Instruction instruction, GlobalState globalState, super.handleInstruction(instruction, globalState, functionState, blockState); } - private void getArrayElement(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void getArrayElement( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument arr = instruction.getArguments().get(0); Argument idx = instruction.getArguments().get(1); - checkState(arr.getType() instanceof ArrayType, "getArrayElement used on non-array type."); - checkState(idx.getType() == IntType.getInstance(), "getArrayElement used with non-int index."); - checkState(instruction.getRetVar().isPresent(), "getArrayElement used without return value."); + checkState( + arr.getType() instanceof ArrayType, + "getArrayElement used on non-array type."); + checkState( + idx.getType() == IntType.getInstance(), "getArrayElement used with non-int index."); + checkState( + instruction.getRetVar().isPresent(), "getArrayElement used without return value."); //noinspection unchecked - foldExpression(instruction, functionState, blockState, null, ArrayExprs.Read((Expr>) arr.getExpr(functionState.getValues()), cast(idx.getExpr(functionState.getValues()), Int())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + ArrayExprs.Read( + (Expr>) arr.getExpr(functionState.getValues()), + cast(idx.getExpr(functionState.getValues()), Int())), + 0); } - private void setArrayElement(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void setArrayElement( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument arr = instruction.getArguments().get(0); Argument idx = instruction.getArguments().get(1); Argument val = instruction.getArguments().get(2); - checkState(arr.getType() instanceof ArrayType, "getArrayElement used on non-array type."); - checkState(idx.getType() == IntType.getInstance(), "getArrayElement used with non-int index."); + checkState( + arr.getType() instanceof ArrayType, + "getArrayElement used on non-array type."); + checkState( + idx.getType() == IntType.getInstance(), "getArrayElement used with non-int index."); - XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); + XcfaLocation loc = + new XcfaLocation( + blockState.getName() + "_" + blockState.getBlockCnt(), + EmptyMetaData.INSTANCE); VarDecl var = functionState.getLocalVars().get(arr.getName()).get1(); - Expr expr = ArrayExprs.Write(cast(var.getRef(), ArrayType.of(Int(), val.getType())), cast(idx.getExpr(functionState.getValues()), Int()), cast(val.getExpr(functionState.getValues()), val.getType())); + Expr expr = + ArrayExprs.Write( + cast(var.getRef(), ArrayType.of(Int(), val.getType())), + cast(idx.getExpr(functionState.getValues()), Int()), + cast(val.getExpr(functionState.getValues()), val.getType())); Stmt stmt = Assign(cast(var, var.getType()), cast(expr, var.getType())); - XcfaEdge edge = new XcfaEdge(blockState.getLastLocation(), loc, new StmtLabel(stmt), new LlvmMetadata(instruction.getLineNumber())); + XcfaEdge edge = + new XcfaEdge( + blockState.getLastLocation(), + loc, + new StmtLabel(stmt), + new LlvmMetadata(instruction.getLineNumber())); functionState.getProcedureBuilder().addLoc(loc); functionState.getProcedureBuilder().addEdge(edge); blockState.setLastLocation(loc); } - - } diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java index 82c0a2414d..cf6132e31a 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/MemoryInstructionHandler.java @@ -13,9 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.llvm2xcfa.handlers.concrete; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.decl.Decls.Var; +import static hu.bme.mit.theta.core.stmt.Stmts.Assign; +import static hu.bme.mit.theta.core.utils.TypeUtils.cast; +import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; + import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.stmt.Stmt; @@ -32,18 +37,15 @@ import hu.bme.mit.theta.xcfa.model.StmtLabel; import hu.bme.mit.theta.xcfa.model.XcfaEdge; import hu.bme.mit.theta.xcfa.model.XcfaLocation; - import java.util.Optional; -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.decl.Decls.Var; -import static hu.bme.mit.theta.core.stmt.Stmts.Assign; -import static hu.bme.mit.theta.core.utils.TypeUtils.cast; -import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; - public class MemoryInstructionHandler extends BaseInstructionHandler { @Override - public void handleInstruction(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + public void handleInstruction( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { switch (instruction.getOpName()) { case "alloca": alloca(instruction, globalState, functionState, blockState); @@ -65,24 +67,37 @@ public void handleInstruction(Instruction instruction, GlobalState globalState, super.handleInstruction(instruction, globalState, functionState, blockState); break; } - } - private void load(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void load( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument isatomic = instruction.getArguments().get(0); Argument op; checkState(instruction.getRetVar().isPresent(), "Load must load into a variable"); Argument ret = instruction.getRetVar().get(); - if (isatomic.getName().equals("atomic")) - op = instruction.getArguments().get(2); - else - op = instruction.getArguments().get(1); - checkState(functionState.getLocalVars().containsKey(op.getName()), "Load must load a variable!"); + if (isatomic.getName().equals("atomic")) op = instruction.getArguments().get(2); + else op = instruction.getArguments().get(1); + checkState( + functionState.getLocalVars().containsKey(op.getName()), + "Load must load a variable!"); - foldExpression(instruction, functionState, blockState, op.getName(), Utils.getOrCreateVar(functionState, op).getRef(), 1); + foldExpression( + instruction, + functionState, + blockState, + op.getName(), + Utils.getOrCreateVar(functionState, op).getRef(), + 1); } - private void store(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void store( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument isatomic = instruction.getArguments().get(0); Argument op1; Argument op2; @@ -95,13 +110,20 @@ private void store(Instruction instruction, GlobalState globalState, FunctionSta } Tuple2, Integer> oldVar = functionState.getLocalVars().get(op2.getName()); - Tuple2, Integer> potentialParam = functionState.getLocalVars().get(op1.getName()); - checkState(functionState.getLocalVars().containsKey(op2.getName()) || functionState.getParams().contains(oldVar.get1()), "Store must store into a variable!"); + Tuple2, Integer> potentialParam = + functionState.getLocalVars().get(op1.getName()); + checkState( + functionState.getLocalVars().containsKey(op2.getName()) + || functionState.getParams().contains(oldVar.get1()), + "Store must store into a variable!"); if (oldVar.get2() > 1) { - functionState.getLocalVars().put(op2.getName(), Tuple2.of(oldVar.get1(), oldVar.get2() - 1)); + functionState + .getLocalVars() + .put(op2.getName(), Tuple2.of(oldVar.get1(), oldVar.get2() - 1)); } else if (oldVar.get2() == 1) { - if (potentialParam != null && functionState.getParams().contains(potentialParam.get1())) { + if (potentialParam != null + && functionState.getParams().contains(potentialParam.get1())) { VarDecl var = functionState.getLocalVars().get(op2.getName()).get1(); functionState.getProcedureBuilder().getVars().remove(var); var = functionState.getLocalVars().get(op1.getName()).get1(); @@ -109,23 +131,41 @@ private void store(Instruction instruction, GlobalState globalState, FunctionSta functionState.getValues().put(op1.getName(), var.getRef()); functionState.getValues().put(op2.getName(), var.getRef()); } else { - XcfaLocation loc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); + XcfaLocation loc = + new XcfaLocation( + blockState.getName() + "_" + blockState.getBlockCnt(), + EmptyMetaData.INSTANCE); VarDecl var = functionState.getLocalVars().get(op2.getName()).get1(); - Stmt stmt = Assign(cast(var, var.getType()), cast(op1.getExpr(functionState.getValues()), var.getType())); - XcfaEdge edge = new XcfaEdge(blockState.getLastLocation(), loc, new StmtLabel(stmt), new LlvmMetadata(instruction.getLineNumber())); + Stmt stmt = + Assign( + cast(var, var.getType()), + cast(op1.getExpr(functionState.getValues()), var.getType())); + XcfaEdge edge = + new XcfaEdge( + blockState.getLastLocation(), + loc, + new StmtLabel(stmt), + new LlvmMetadata(instruction.getLineNumber())); functionState.getProcedureBuilder().addLoc(loc); functionState.getProcedureBuilder().addEdge(edge); blockState.setLastLocation(loc); } } - } - private void getelementptr(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void getelementptr( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { throw new RuntimeException("Not yet implemented!"); } - private void alloca(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void alloca( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Optional retVar = instruction.getRetVar(); checkState(retVar.isPresent(), "Alloca must have a variable tied to it"); VarDecl var = Var(retVar.get().getName(), retVar.get().getType()); diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java index 80690a6595..1109a27361 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/concrete/OtherInstructionHandler.java @@ -13,9 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.llvm2xcfa.handlers.concrete; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.stmt.Stmts.Assign; +import static hu.bme.mit.theta.core.stmt.Stmts.Havoc; +import static hu.bme.mit.theta.core.type.anytype.Exprs.Ite; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.*; +import static hu.bme.mit.theta.core.utils.TypeUtils.cast; +import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; +import static hu.bme.mit.theta.llvm2xcfa.Utils.getOrCreateVar; + import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.common.Tuple4; import hu.bme.mit.theta.core.decl.VarDecl; @@ -37,23 +45,17 @@ import hu.bme.mit.theta.llvm2xcfa.handlers.states.GlobalState; import hu.bme.mit.theta.llvm2xcfa.handlers.utils.PlaceholderAssignmentStmt; import hu.bme.mit.theta.xcfa.model.*; - import java.util.ArrayList; import java.util.List; import java.util.Optional; -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.stmt.Stmts.Assign; -import static hu.bme.mit.theta.core.stmt.Stmts.Havoc; -import static hu.bme.mit.theta.core.type.anytype.Exprs.Ite; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.*; -import static hu.bme.mit.theta.core.utils.TypeUtils.cast; -import static hu.bme.mit.theta.llvm2xcfa.Utils.foldExpression; -import static hu.bme.mit.theta.llvm2xcfa.Utils.getOrCreateVar; - public class OtherInstructionHandler extends BaseInstructionHandler { @Override - public void handleInstruction(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + public void handleInstruction( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { switch (instruction.getOpName()) { case "icmp": icmp(instruction, globalState, functionState, blockState); @@ -80,13 +82,21 @@ public void handleInstruction(Instruction instruction, GlobalState globalState, super.handleInstruction(instruction, globalState, functionState, blockState); break; } - } - private void call(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { - Argument functionName = instruction.getArguments().get(instruction.getArguments().size() - 1); - XcfaLocation newLoc = new XcfaLocation(blockState.getName() + "_" + blockState.getBlockCnt(), EmptyMetaData.INSTANCE); - if (globalState.getProcedures().stream().anyMatch(objects -> objects.get1().equals(functionName.getName()))) { + private void call( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { + Argument functionName = + instruction.getArguments().get(instruction.getArguments().size() - 1); + XcfaLocation newLoc = + new XcfaLocation( + blockState.getName() + "_" + blockState.getBlockCnt(), + EmptyMetaData.INSTANCE); + if (globalState.getProcedures().stream() + .anyMatch(objects -> objects.get1().equals(functionName.getName()))) { System.err.println("More than one function."); System.exit(-80); } else { @@ -95,39 +105,64 @@ private void call(Instruction instruction, GlobalState globalState, FunctionStat stmts.add(havocVar(instruction.getRetVar().get(), functionState, blockState)); } for (Argument argument : instruction.getArguments()) { - Tuple2, Integer> objects = functionState.getLocalVars().get(argument.getName()); + Tuple2, Integer> objects = + functionState.getLocalVars().get(argument.getName()); if (objects != null && objects.get2() > 0) stmts.add(havocVar(argument, functionState, blockState)); } - XcfaEdge edge = new XcfaEdge(blockState.getLastLocation(), newLoc, new SequenceLabel(stmts.stream().map(stmt -> new StmtLabel(stmt)).toList()), new LlvmMetadata(instruction.getLineNumber())); + XcfaEdge edge = + new XcfaEdge( + blockState.getLastLocation(), + newLoc, + new SequenceLabel( + stmts.stream().map(stmt -> new StmtLabel(stmt)).toList()), + new LlvmMetadata(instruction.getLineNumber())); functionState.getProcedureBuilder().addLoc(newLoc); functionState.getProcedureBuilder().addEdge(edge); } blockState.setLastLocation(newLoc); } - private Stmt havocVar(Argument reg, FunctionState functionState, BlockState blockState) { VarDecl callVar = getOrCreateVar(functionState, reg); return Havoc(callVar); } - private void select(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void select( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument cond = instruction.getArguments().get(0); Argument op1 = instruction.getArguments().get(1); Argument op2 = instruction.getArguments().get(2); - checkState(cond.getType() == BoolType.getInstance(), "Select only supports boolean condition!"); + checkState( + cond.getType() == BoolType.getInstance(), + "Select only supports boolean condition!"); checkState(op1.getType().equals(op2.getType()), "Select only supports common types!"); checkState(instruction.getRetVar().isPresent(), "Instruction must have return variable"); Expr expr1 = op1.getExpr(functionState.getValues()); - //TODO: what to do, when null? + // TODO: what to do, when null? Expr expr2 = op2.getExpr(functionState.getValues()); - foldExpression(instruction, functionState, blockState, null, Ite(cast(cond.getExpr(functionState.getValues()), BoolType.getInstance()), cast(expr1, expr1.getType()), cast(expr2, expr1.getType())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Ite( + cast(cond.getExpr(functionState.getValues()), BoolType.getInstance()), + cast(expr1, expr1.getType()), + cast(expr2, expr1.getType())), + 0); } // Phi nodes are the only possible place where an argument might not be known yet. - private void phi(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void phi( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Optional retVar = instruction.getRetVar(); checkState(retVar.isPresent(), "Return var must be present!"); VarDecl phiVar = getOrCreateVar(functionState, retVar.get()); @@ -135,8 +170,19 @@ private void phi(Instruction instruction, GlobalState globalState, FunctionState Argument block = instruction.getArguments().get(2 * i + 1); Argument value = instruction.getArguments().get(2 * i); Tuple2 key = Tuple2.of(block.getName(), blockState.getName()); - Tuple4, Integer> val = functionState.getInterBlockEdges().getOrDefault(key, Tuple4.of(new XcfaLocation(key.get1(), EmptyMetaData.INSTANCE), new XcfaLocation(key.get2(), EmptyMetaData.INSTANCE), new ArrayList<>(), instruction.getLineNumber())); - checkState(phiVar.getType().equals(value.getType()), "phiVar and value has to be of the same type!"); + Tuple4, Integer> val = + functionState + .getInterBlockEdges() + .getOrDefault( + key, + Tuple4.of( + new XcfaLocation(key.get1(), EmptyMetaData.INSTANCE), + new XcfaLocation(key.get2(), EmptyMetaData.INSTANCE), + new ArrayList<>(), + instruction.getLineNumber())); + checkState( + phiVar.getType().equals(value.getType()), + "phiVar and value has to be of the same type!"); Stmt stmt; Expr expr; if ((expr = value.getExpr(functionState.getValues())) != null) { @@ -152,39 +198,105 @@ private void phi(Instruction instruction, GlobalState globalState, FunctionState } } - private void fcmp(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void fcmp( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument op1 = instruction.getArguments().get(0); Argument op2 = instruction.getArguments().get(1); Argument op3 = instruction.getArguments().get(2); - checkState(op1 instanceof StringArgument, "Icmp has to have string argument as first operand!"); + checkState( + op1 instanceof StringArgument, + "Icmp has to have string argument as first operand!"); checkState(op2.getType() == RatType.getInstance(), "Icmp only supports integer types!"); checkState(op3.getType() == RatType.getInstance(), "Icmp only supports integer types!"); checkState(instruction.getRetVar().isPresent(), "Instruction must have return variable"); switch (op1.getName()) { case "ueq": case "oeq": - foldExpression(instruction, functionState, blockState, null, RatExprs.Eq(cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), cast(op3.getExpr(functionState.getValues()), RatType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + RatExprs.Eq( + cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + RatType.getInstance())), + 0); break; case "one": case "une": - foldExpression(instruction, functionState, blockState, null, RatExprs.Neq(cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), cast(op3.getExpr(functionState.getValues()), RatType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + RatExprs.Neq( + cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + RatType.getInstance())), + 0); break; case "ugt": case "ogt": - foldExpression(instruction, functionState, blockState, null, RatExprs.Gt(cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), cast(op3.getExpr(functionState.getValues()), RatType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + RatExprs.Gt( + cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + RatType.getInstance())), + 0); break; case "uge": case "oge": - foldExpression(instruction, functionState, blockState, null, RatExprs.Geq(cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), cast(op3.getExpr(functionState.getValues()), RatType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + RatExprs.Geq( + cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + RatType.getInstance())), + 0); break; case "ult": case "olt": - foldExpression(instruction, functionState, blockState, null, RatExprs.Lt(cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), cast(op3.getExpr(functionState.getValues()), RatType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + RatExprs.Lt( + cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + RatType.getInstance())), + 0); break; case "ole": case "ule": - foldExpression(instruction, functionState, blockState, null, RatExprs.Leq(cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), cast(op3.getExpr(functionState.getValues()), RatType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + RatExprs.Leq( + cast(op2.getExpr(functionState.getValues()), RatType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + RatType.getInstance())), + 0); break; case "ord": case "true": @@ -198,37 +310,103 @@ private void fcmp(Instruction instruction, GlobalState globalState, FunctionStat } } - private void icmp(Instruction instruction, GlobalState globalState, FunctionState functionState, BlockState blockState) { + private void icmp( + Instruction instruction, + GlobalState globalState, + FunctionState functionState, + BlockState blockState) { Argument op1 = instruction.getArguments().get(0); Argument op2 = instruction.getArguments().get(1); Argument op3 = instruction.getArguments().get(2); - checkState(op1 instanceof StringArgument, "Icmp has to have string argument as first operand!"); + checkState( + op1 instanceof StringArgument, + "Icmp has to have string argument as first operand!"); checkState(op2.getType() == IntType.getInstance(), "Icmp only supports integer types!"); checkState(op3.getType() == IntType.getInstance(), "Icmp only supports integer types!"); checkState(instruction.getRetVar().isPresent(), "Instruction must have return variable"); switch (op1.getName()) { case "eq": - foldExpression(instruction, functionState, blockState, null, Eq(cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), cast(op3.getExpr(functionState.getValues()), IntType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Eq( + cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + IntType.getInstance())), + 0); break; case "ne": - foldExpression(instruction, functionState, blockState, null, Neq(cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), cast(op3.getExpr(functionState.getValues()), IntType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Neq( + cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + IntType.getInstance())), + 0); break; case "ugt": case "sgt": - foldExpression(instruction, functionState, blockState, null, Gt(cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), cast(op3.getExpr(functionState.getValues()), IntType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Gt( + cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + IntType.getInstance())), + 0); break; case "uge": case "sge": - foldExpression(instruction, functionState, blockState, null, Geq(cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), cast(op3.getExpr(functionState.getValues()), IntType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Geq( + cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + IntType.getInstance())), + 0); break; case "ult": case "slt": - foldExpression(instruction, functionState, blockState, null, Lt(cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), cast(op3.getExpr(functionState.getValues()), IntType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Lt( + cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + IntType.getInstance())), + 0); break; case "ule": case "sle": - foldExpression(instruction, functionState, blockState, null, Leq(cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), cast(op3.getExpr(functionState.getValues()), IntType.getInstance())), 0); + foldExpression( + instruction, + functionState, + blockState, + null, + Leq( + cast(op2.getExpr(functionState.getValues()), IntType.getInstance()), + cast( + op3.getExpr(functionState.getValues()), + IntType.getInstance())), + 0); break; default: throw new IllegalStateException("Unexpected value: " + op1.getName()); diff --git a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java index 7c4a26f388..691cee8555 100644 --- a/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java +++ b/subprojects/xcfa/llvm2xcfa/src/main/java/hu/bme/mit/theta/llvm2xcfa/handlers/states/FunctionState.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.llvm2xcfa.handlers.states; +import static hu.bme.mit.theta.llvm2xcfa.Utils.createVariable; + import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.common.Tuple3; import hu.bme.mit.theta.common.Tuple4; @@ -32,7 +33,6 @@ import hu.bme.mit.theta.xcfa.model.XcfaLocation; import hu.bme.mit.theta.xcfa.model.XcfaProcedureBuilder; import hu.bme.mit.theta.xcfa.passes.ProcedurePassManager; - import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -42,8 +42,6 @@ import java.util.Set; import java.util.stream.Collectors; -import static hu.bme.mit.theta.llvm2xcfa.Utils.createVariable; - public class FunctionState { private final GlobalState globalState; private final Tuple3, List>> function; @@ -52,20 +50,26 @@ public class FunctionState { private final Set> params; private final Map> values; private final Map locations; - private final Map, Tuple4, Integer>> interBlockEdges; + private final Map< + Tuple2, Tuple4, Integer>> + interBlockEdges; private VarDecl returnVar = null; - public FunctionState(GlobalState globalState, Tuple3, List>> function) { + public FunctionState( + GlobalState globalState, + Tuple3, List>> function) { this.globalState = globalState; this.function = function; procedureBuilder = new XcfaProcedureBuilder(function.get1(), new ProcedurePassManager()); -// procedureBuilder.setName(function.get1()); + // procedureBuilder.setName(function.get1()); localVars = new HashMap<>(); params = new HashSet<>(); values = new HashMap<>(); interBlockEdges = new HashMap<>(); - globalState.getGlobalVars().forEach((s, varDecl) -> localVars.put(s, Tuple2.of(varDecl, 1))); + globalState + .getGlobalVars() + .forEach((s, varDecl) -> localVars.put(s, Tuple2.of(varDecl, 1))); // Adding return variable if (function.get2().isPresent()) { @@ -74,7 +78,7 @@ public FunctionState(GlobalState globalState, Tuple3, L procedureBuilder.addParam(var, ParamDirection.OUT); localVars.put(function.get1() + "_ret", Tuple2.of(var, 1)); params.add(var); -// procedureBuilder.setRetType(var.getType()); + // procedureBuilder.setRetType(var.getType()); } // Adding params @@ -106,22 +110,39 @@ public FunctionState(GlobalState globalState, Tuple3, L } localVars.forEach((s, var) -> values.put(s, var.get1().getRef())); - } public void finalizeFunctionState(BuiltState builtState) { - interBlockEdges.forEach((_obj, edgeTup) -> { - List stmts = edgeTup.get3().stream().filter(stmt -> - !(stmt instanceof PlaceholderAssignmentStmt) || !((PlaceholderAssignmentStmt) stmt).isSelfAssignment(getValues()) - ).map(stmt -> { - if (stmt instanceof PlaceholderAssignmentStmt) { - return ((PlaceholderAssignmentStmt) stmt).toAssignStmt(getValues()); - } - return stmt; - }).collect(Collectors.toUnmodifiableList()); - XcfaEdge edge = new XcfaEdge(edgeTup.get1(), edgeTup.get2(), new SequenceLabel(stmts.stream().map(stmt -> new StmtLabel(stmt)).toList()), new LlvmMetadata(edgeTup.get4())); - procedureBuilder.addEdge(edge); - }); + interBlockEdges.forEach( + (_obj, edgeTup) -> { + List stmts = + edgeTup.get3().stream() + .filter( + stmt -> + !(stmt instanceof PlaceholderAssignmentStmt) + || !((PlaceholderAssignmentStmt) + stmt) + .isSelfAssignment(getValues())) + .map( + stmt -> { + if (stmt instanceof PlaceholderAssignmentStmt) { + return ((PlaceholderAssignmentStmt) stmt) + .toAssignStmt(getValues()); + } + return stmt; + }) + .collect(Collectors.toUnmodifiableList()); + XcfaEdge edge = + new XcfaEdge( + edgeTup.get1(), + edgeTup.get2(), + new SequenceLabel( + stmts.stream() + .map(stmt -> new StmtLabel(stmt)) + .toList()), + new LlvmMetadata(edgeTup.get4())); + procedureBuilder.addEdge(edge); + }); } public GlobalState getGlobalState() { @@ -148,7 +169,8 @@ public Map getLocations() { return locations; } - public Map, Tuple4, Integer>> getInterBlockEdges() { + public Map, Tuple4, Integer>> + getInterBlockEdges() { return interBlockEdges; } @@ -160,4 +182,3 @@ public VarDecl getReturnVar() { return returnVar; } } - diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt index b14d714142..e93dbb1ff1 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.analysis import hu.bme.mit.theta.analysis.ptr.PtrAction @@ -24,37 +23,40 @@ import hu.bme.mit.theta.xcfa.passes.flatten data class XcfaAction @JvmOverloads -constructor(val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTriples = emptyMap(), - private val nextCnt: Int = 0) : - PtrAction(lastWrites, nextCnt) { - - val source: XcfaLocation = edge.source - val target: XcfaLocation = edge.target - val label: XcfaLabel = edge.label - private val stmts: List = label.toStmt().flatten() - - constructor(pid: Int, - source: XcfaLocation, - target: XcfaLocation, - label: XcfaLabel = NopLabel, - metaData: MetaData = EmptyMetaData, - lastWrites: WriteTriples = emptyMap(), - nextCnt: Int = 0) : - this(pid, XcfaEdge(source, target, label, metaData), lastWrites, nextCnt) - - override val stmtList: List - get() = stmts - - override fun toString(): String { - return "$pid: $source -> $target [${getStmts()}]" - } - - fun withLabel(sequenceLabel: SequenceLabel): XcfaAction { - return XcfaAction(pid, source, target, sequenceLabel, edge.metadata, nextCnt = nextCnt) - } - - fun withLastWrites(writeTriples: WriteTriples, nextCnt: Int): XcfaAction { - return XcfaAction(pid, source, target, label, edge.metadata, writeTriples, nextCnt) - } - +constructor( + val pid: Int, + val edge: XcfaEdge, + private val lastWrites: WriteTriples = emptyMap(), + private val nextCnt: Int = 0, +) : PtrAction(lastWrites, nextCnt) { + + val source: XcfaLocation = edge.source + val target: XcfaLocation = edge.target + val label: XcfaLabel = edge.label + private val stmts: List = label.toStmt().flatten() + + constructor( + pid: Int, + source: XcfaLocation, + target: XcfaLocation, + label: XcfaLabel = NopLabel, + metaData: MetaData = EmptyMetaData, + lastWrites: WriteTriples = emptyMap(), + nextCnt: Int = 0, + ) : this(pid, XcfaEdge(source, target, label, metaData), lastWrites, nextCnt) + + override val stmtList: List + get() = stmts + + override fun toString(): String { + return "$pid: $source -> $target [${getStmts()}]" + } + + fun withLabel(sequenceLabel: SequenceLabel): XcfaAction { + return XcfaAction(pid, source, target, sequenceLabel, edge.metadata, nextCnt = nextCnt) + } + + fun withLastWrites(writeTriples: WriteTriples, nextCnt: Int): XcfaAction { + return XcfaAction(pid, source, target, label, edge.metadata, writeTriples, nextCnt) + } } diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt index a35a2ed980..04a679d9e3 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt @@ -38,11 +38,11 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory import hu.bme.mit.theta.xcfa.analysis.coi.ConeOfInfluence import hu.bme.mit.theta.xcfa.analysis.coi.XcfaCoiMultiThread import hu.bme.mit.theta.xcfa.analysis.por.* +import java.util.* +import kotlin.random.Random import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -import java.util.* -import kotlin.random.Random class XcfaExplAnalysisTest { diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt index c6932048db..cf094ab486 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt @@ -38,11 +38,11 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory import hu.bme.mit.theta.xcfa.analysis.coi.ConeOfInfluence import hu.bme.mit.theta.xcfa.analysis.coi.XcfaCoiMultiThread import hu.bme.mit.theta.xcfa.analysis.por.* +import java.util.* +import kotlin.random.Random import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -import java.util.* -import kotlin.random.Random class XcfaPredAnalysisTest { diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt index 67ffcf637f..3b144ffeb6 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.analysis import hu.bme.mit.theta.analysis.expl.ExplPrec @@ -24,139 +23,147 @@ import hu.bme.mit.theta.xcfa.analysis.XcfaProcessState.Companion.createLookup import hu.bme.mit.theta.xcfa.analysis.por.XcfaAasporLts import hu.bme.mit.theta.xcfa.analysis.por.XcfaSporLts import hu.bme.mit.theta.xcfa.model.* -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Test import java.util.* import java.util.function.Predicate +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test class XcfaStateLtsTest { - @Test - fun testApply() { - val actionOrder: MutableList<(XcfaState>) -> XcfaAction> = ArrayList() - val expectations: MutableList>>> = ArrayList() - val lts = getXcfaLts() - lateinit var initState: XcfaState> - lateinit var xcfa: XCFA - - val edges: MutableList = ArrayList() - xcfa = xcfa("example") { - val proc1 = procedure("proc1") { - val a = "a" type IntExprs.Int() direction ParamDirection.IN - val b = "b" type IntExprs.Int() direction ParamDirection.OUT - - edges.add((init to final) { - b assign a.ref - }) - } - val main = procedure("main") { - val tmp = "tmp" type IntExprs.Int() - edges.add((init to "L1") { - proc1("1", tmp.ref) - }) - edges.add(("L1" to "L2") { - tmp.start(proc1, tmp.ref) - }) - edges.add(("L2" to final) { - tmp.join() - }) - } - - main.start() - } - initState = XcfaState( - xcfa, - mapOf( - Pair(0, - XcfaProcessState( - locs = LinkedList(listOf(edges[1].source)), - varLookup = LinkedList(listOf(createLookup(xcfa.initProcedures[0].first, "T0", "P0"))) - ) - ) + @Test + fun testApply() { + val actionOrder: MutableList<(XcfaState>) -> XcfaAction> = ArrayList() + val expectations: MutableList>>> = ArrayList() + val lts = getXcfaLts() + lateinit var initState: XcfaState> + lateinit var xcfa: XCFA + + val edges: MutableList = ArrayList() + xcfa = + xcfa("example") { + val proc1 = + procedure("proc1") { + val a = "a" type IntExprs.Int() direction ParamDirection.IN + val b = "b" type IntExprs.Int() direction ParamDirection.OUT + + edges.add((init to final) { b assign a.ref }) + } + val main = + procedure("main") { + val tmp = "tmp" type IntExprs.Int() + edges.add((init to "L1") { proc1("1", tmp.ref) }) + edges.add(("L1" to "L2") { tmp.start(proc1, tmp.ref) }) + edges.add(("L2" to final) { tmp.join() }) + } + + main.start() + } + initState = + XcfaState( + xcfa, + mapOf( + Pair( + 0, + XcfaProcessState( + locs = LinkedList(listOf(edges[1].source)), + varLookup = LinkedList(listOf(createLookup(xcfa.initProcedures[0].first, "T0", "P0"))), ), - PtrState(ExplState.bottom()) - ) - val sporLts = XcfaSporLts(xcfa) - val aasporLts = XcfaAasporLts(xcfa, LinkedHashMap()) - - actionOrder.add { XcfaAction(0, edges[1]) } - expectations.add { - it.processes[0]!!.locs.size == 2 && it.processes[0]!!.locs.peek() == edges[0].source && - lts.getEnabledActionsFor(it).size == 1 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + ) + ), + PtrState(ExplState.bottom()), + ) + val sporLts = XcfaSporLts(xcfa) + val aasporLts = XcfaAasporLts(xcfa, LinkedHashMap()) + + actionOrder.add { XcfaAction(0, edges[1]) } + expectations.add { + it.processes[0]!!.locs.size == 2 && + it.processes[0]!!.locs.peek() == edges[0].source && + lts.getEnabledActionsFor(it).size == 1 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - actionOrder.add { XcfaAction(0, edges[0]) } - expectations.add { - it.processes[0]!!.locs.size == 2 && it.processes[0]!!.locs.peek() == edges[0].target && - lts.getEnabledActionsFor(it).size == 1 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + actionOrder.add { XcfaAction(0, edges[0]) } + expectations.add { + it.processes[0]!!.locs.size == 2 && + it.processes[0]!!.locs.peek() == edges[0].target && + lts.getEnabledActionsFor(it).size == 1 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - actionOrder.add { - XcfaAction( - 0, XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel), EmptyMetaData) - ) - } - expectations.add { - it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[1].target && - lts.getEnabledActionsFor(it).size == 1 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + actionOrder.add { + XcfaAction( + 0, + XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel), EmptyMetaData), + ) + } + expectations.add { + it.processes[0]!!.locs.size == 1 && + it.processes[0]!!.locs.peek() == edges[1].target && + lts.getEnabledActionsFor(it).size == 1 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - actionOrder.add { XcfaAction(0, edges[2]) } - expectations.add { - it.processes.size == 2 && - it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[2].target && - it.processes[it.foreignKey()!!]!!.locs.size == 1 && it.processes[it.foreignKey()!!]!!.locs.peek() == edges[0].source && - lts.getEnabledActionsFor(it).size == 2 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + actionOrder.add { XcfaAction(0, edges[2]) } + expectations.add { + it.processes.size == 2 && + it.processes[0]!!.locs.size == 1 && + it.processes[0]!!.locs.peek() == edges[2].target && + it.processes[it.foreignKey()!!]!!.locs.size == 1 && + it.processes[it.foreignKey()!!]!!.locs.peek() == edges[0].source && + lts.getEnabledActionsFor(it).size == 2 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - actionOrder.add { s -> XcfaAction(s.foreignKey()!!, edges[0]) } - expectations.add { - it.processes.size == 2 && - it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[2].target && - it.processes[it.foreignKey()!!]!!.locs.size == 1 && it.processes[it.foreignKey()!!]!!.locs.peek() == edges[0].target && - lts.getEnabledActionsFor(it).size == 2 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + actionOrder.add { s -> XcfaAction(s.foreignKey()!!, edges[0]) } + expectations.add { + it.processes.size == 2 && + it.processes[0]!!.locs.size == 1 && + it.processes[0]!!.locs.peek() == edges[2].target && + it.processes[it.foreignKey()!!]!!.locs.size == 1 && + it.processes[it.foreignKey()!!]!!.locs.peek() == edges[0].target && + lts.getEnabledActionsFor(it).size == 2 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - actionOrder.add { s -> - XcfaAction( - s.foreignKey()!!, XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel), EmptyMetaData) - ) - } - expectations.add { - it.processes.size == 1 && it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[2].target && - lts.getEnabledActionsFor(it).size == 1 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + actionOrder.add { s -> + XcfaAction( + s.foreignKey()!!, + XcfaEdge(edges[0].target, edges[0].target, ReturnLabel(NopLabel), EmptyMetaData), + ) + } + expectations.add { + it.processes.size == 1 && + it.processes[0]!!.locs.size == 1 && + it.processes[0]!!.locs.peek() == edges[2].target && + lts.getEnabledActionsFor(it).size == 1 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - actionOrder.add { XcfaAction(0, edges[3]) } - expectations.add { - it.processes[0]!!.locs.size == 1 && it.processes[0]!!.locs.peek() == edges[3].target && - lts.getEnabledActionsFor(it).size == 1 && - sporLts.getEnabledActionsFor(it).size == 1 && - aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 - } + actionOrder.add { XcfaAction(0, edges[3]) } + expectations.add { + it.processes[0]!!.locs.size == 1 && + it.processes[0]!!.locs.peek() == edges[3].target && + lts.getEnabledActionsFor(it).size == 1 && + sporLts.getEnabledActionsFor(it).size == 1 && + aasporLts.getEnabledActionsFor(it, emptyList(), ExplPrec.empty()).size == 1 + } - var state = initState - for ((index, xcfaAction) in actionOrder.withIndex()) { - println("Test $index: $xcfaAction") - val newState = state.apply(xcfaAction(state)) - assertTrue(expectations[index].test(newState.first)) - state = newState.first - println("Test $index OK") - } + var state = initState + for ((index, xcfaAction) in actionOrder.withIndex()) { + println("Test $index: $xcfaAction") + val newState = state.apply(xcfaAction(state)) + assertTrue(expectations[index].test(newState.first)) + state = newState.first + println("Test $index OK") } + } } -private fun XcfaState<*>.foreignKey(): Int? = - processes.keys.firstOrNull { key -> key != 0 } +private fun XcfaState<*>.foreignKey(): Int? = processes.keys.firstOrNull { key -> key != 0 } diff --git a/subprojects/xcfa/xcfa-cli/build.gradle.kts b/subprojects/xcfa/xcfa-cli/build.gradle.kts index 83c5989fe7..63d27c1109 100644 --- a/subprojects/xcfa/xcfa-cli/build.gradle.kts +++ b/subprojects/xcfa/xcfa-cli/build.gradle.kts @@ -51,4 +51,3 @@ dependencies { application { mainClass.set("hu.bme.mit.theta.xcfa.cli.XcfaCli") } - diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt index e5370bdf2e..29d44360d2 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt @@ -32,105 +32,102 @@ import java.io.File import java.io.FileReader import kotlin.system.exitProcess - class XcfaCli(private val args: Array) { - @Parameter(names = ["--config", "-c"], description = "Configuration file (CLI options will overwrite these!)") - var configFile: File? = null - - @Parameter(names = ["--help", "-h"], help = true) - private var help = false - - @Parameter(names = ["--svcomp"]) - private var svcomp = false - - @Parameter - var remainingFlags: MutableList = ArrayList() - - private fun run() { - lateinit var config: XcfaConfig<*, *> - /// Checking flags - try { - JCommander.newBuilder().addObject(this).programName(JAR_NAME).build().parse(*args) - val configFile = this.configFile - if (configFile != null) { - config = getGson().fromJson(FileReader(configFile), XcfaConfig::class.java) - } else { - config = XcfaConfig() - } - if (svcomp) { - remainingFlags.addAll( - listOf( - "--enable-output", - "--disable-xcfa-serialization", - "--disable-arg-generation", - "--disable-chc-serialization", - "--disable-c-serialization", - "--only-svcomp-witness", - ) - ) - if (!remainingFlags.contains("--backend")) { - remainingFlags.addAll(listOf("--backend", "PORTFOLIO")) - } - } - while (remainingFlags.isNotEmpty()) { - val nextArgs = remainingFlags.toTypedArray() - remainingFlags.clear() - val builder = JCommander.newBuilder().addObject(this) - for (obj in config.getObjects()) { - builder.addObject(obj) - } - builder.programName(JAR_NAME).build().parse(*nextArgs) - if (!config.update() && remainingFlags.isNotEmpty()) { - throw ParameterException("Extraneous parameters: $remainingFlags") - } - } - } catch (ex: ParameterException) { - println("Invalid parameters, details:") - ex.printStackTrace() - ex.usage() - exitProcess(ExitCodes.INVALID_PARAM.code) - } catch (ex: JsonIOException) { - println("There was a problem reading from ${configFile}:") - ex.printStackTrace() - exitProcess(ExitCodes.INVALID_PARAM.code) - } catch (ex: JsonSyntaxException) { - println("There was a problem parsing ${configFile}:") - ex.printStackTrace() - exitProcess(ExitCodes.INVALID_PARAM.code) + @Parameter( + names = ["--config", "-c"], + description = "Configuration file (CLI options will overwrite these!)", + ) + var configFile: File? = null + + @Parameter(names = ["--help", "-h"], help = true) private var help = false + + @Parameter(names = ["--svcomp"]) private var svcomp = false + + @Parameter var remainingFlags: MutableList = ArrayList() + + private fun run() { + lateinit var config: XcfaConfig<*, *> + /// Checking flags + try { + JCommander.newBuilder().addObject(this).programName(JAR_NAME).build().parse(*args) + val configFile = this.configFile + if (configFile != null) { + config = getGson().fromJson(FileReader(configFile), XcfaConfig::class.java) + } else { + config = XcfaConfig() + } + if (svcomp) { + remainingFlags.addAll( + listOf( + "--enable-output", + "--disable-xcfa-serialization", + "--disable-arg-generation", + "--disable-chc-serialization", + "--disable-c-serialization", + "--only-svcomp-witness", + ) + ) + if (!remainingFlags.contains("--backend")) { + remainingFlags.addAll(listOf("--backend", "PORTFOLIO")) } - - - if (help) { - val builder = JCommander.newBuilder().addObject(this) - for (obj in config.getObjects()) { - builder.addObject(obj) - } - builder.build().usage() - return + } + while (remainingFlags.isNotEmpty()) { + val nextArgs = remainingFlags.toTypedArray() + remainingFlags.clear() + val builder = JCommander.newBuilder().addObject(this) + for (obj in config.getObjects()) { + builder.addObject(obj) } - - /// version - if (config.outputConfig.versionInfo) { - CliUtils.printVersion(System.out) - return + builder.programName(JAR_NAME).build().parse(*nextArgs) + if (!config.update() && remainingFlags.isNotEmpty()) { + throw ParameterException("Extraneous parameters: $remainingFlags") } + } + } catch (ex: ParameterException) { + println("Invalid parameters, details:") + ex.printStackTrace() + ex.usage() + exitProcess(ExitCodes.INVALID_PARAM.code) + } catch (ex: JsonIOException) { + println("There was a problem reading from ${configFile}:") + ex.printStackTrace() + exitProcess(ExitCodes.INVALID_PARAM.code) + } catch (ex: JsonSyntaxException) { + println("There was a problem parsing ${configFile}:") + ex.printStackTrace() + exitProcess(ExitCodes.INVALID_PARAM.code) + } - val logger = ConsoleLogger(config.debugConfig.logLevel) - val uniqueLogger = UniqueWarningLogger(logger) + if (help) { + val builder = JCommander.newBuilder().addObject(this) + for (obj in config.getObjects()) { + builder.addObject(obj) + } + builder.build().usage() + return + } - runConfig(config, logger, uniqueLogger, false) + /// version + if (config.outputConfig.versionInfo) { + CliUtils.printVersion(System.out) + return } + val logger = ConsoleLogger(config.debugConfig.logLevel) + val uniqueLogger = UniqueWarningLogger(logger) - companion object { + runConfig(config, logger, uniqueLogger, false) + } - private const val JAR_NAME = "theta-xcfa-cli.jar" + companion object { - @JvmStatic - fun main(args: Array) { - val mainApp = XcfaCli(args) - mainApp.run() - } + private const val JAR_NAME = "theta-xcfa-cli.jar" + + @JvmStatic + fun main(args: Array) { + val mainApp = XcfaCli(args) + mainApp.run() } + } } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt index 881a3202cf..264f014285 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GraphmlWitnessWriter.kt @@ -36,92 +36,126 @@ import java.util.* class GraphmlWitnessWriter { - fun writeWitness( - safetyResult: SafetyResult<*, *>, - inputFile: File, - cexSolverFactory: SolverFactory, - parseContext: ParseContext, - witnessfile: File, - ) { - // TODO eliminate the need for the instanceof check - if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { - val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( - safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, cexSolverFactory, - parseContext) + fun writeWitness( + safetyResult: SafetyResult<*, *>, + inputFile: File, + cexSolverFactory: SolverFactory, + parseContext: ParseContext, + witnessfile: File, + ) { + // TODO eliminate the need for the instanceof check + if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { + val concrTrace: Trace, XcfaAction> = + XcfaTraceConcretizer.concretize( + safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, + cexSolverFactory, + parseContext, + ) - val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) - val graphmlWitness = GraphmlWitness(witnessTrace, inputFile) - val xml = graphmlWitness.toPrettyXml() - witnessfile.writeText(xml) - } else if (safetyResult.isSafe) { - val taskHash = WitnessWriter.createTaskHash(inputFile.absolutePath) - val dummyWitness = StringBuilder() - dummyWitness.append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "false").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "false").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "") - .append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "correctness_witness") - .append(System.lineSeparator()).append( - "theta").append(System.lineSeparator()).append( - "CHECK( init(main()), LTL(G ! call(reach_error())) )") - .append(System.lineSeparator()).append( - "C").append(System.lineSeparator()).append( - "32bit").append(System.lineSeparator()) - .append( - "") - dummyWitness.append(taskHash) - dummyWitness.append("").append(System.lineSeparator()).append( - "") + val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) + val graphmlWitness = GraphmlWitness(witnessTrace, inputFile) + val xml = graphmlWitness.toPrettyXml() + witnessfile.writeText(xml) + } else if (safetyResult.isSafe) { + val taskHash = WitnessWriter.createTaskHash(inputFile.absolutePath) + val dummyWitness = StringBuilder() + dummyWitness + .append( + "" + ) + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("false") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("false") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append( + "" + ) + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append( + "" + ) + .append(System.lineSeparator()) + .append( + "" + ) + .append(System.lineSeparator()) + .append( + "" + ) + .append(System.lineSeparator()) + .append( + "" + ) + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("correctness_witness") + .append(System.lineSeparator()) + .append("theta") + .append(System.lineSeparator()) + .append( + "CHECK( init(main()), LTL(G ! call(reach_error())) )" + ) + .append(System.lineSeparator()) + .append("C") + .append(System.lineSeparator()) + .append("32bit") + .append(System.lineSeparator()) + .append("") + dummyWitness.append(taskHash) + dummyWitness + .append("") + .append(System.lineSeparator()) + .append("") - val tz: TimeZone = TimeZone.getTimeZone("UTC") - val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset + val tz: TimeZone = TimeZone.getTimeZone("UTC") + val df: DateFormat = + SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ) // Quoted "Z" to indicate UTC, no timezone offset - df.timeZone = tz - val isoDate: String = df.format(Date()) + df.timeZone = tz + val isoDate: String = df.format(Date()) - dummyWitness.append(isoDate) - dummyWitness.append("").append(System.lineSeparator()).append( - "") - dummyWitness.append(inputFile.name) - dummyWitness.append("").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "true").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "") + dummyWitness.append(isoDate) + dummyWitness + .append("") + .append(System.lineSeparator()) + .append("") + dummyWitness.append(inputFile.name) + dummyWitness + .append("") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("true") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("") + .append(System.lineSeparator()) + .append("") - try { - BufferedWriter(FileWriter(witnessfile)).use { bw -> - bw.write(dummyWitness.toString()) - } - } catch (ioe: IOException) { - ioe.printStackTrace() - } - } + try { + BufferedWriter(FileWriter(witnessfile)).use { bw -> bw.write(dummyWitness.toString()) } + } catch (ioe: IOException) { + ioe.printStackTrace() + } } -} \ No newline at end of file + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt index a7e0b45aa3..d38d2c3b64 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.utils import com.google.gson.Gson @@ -55,83 +54,136 @@ import java.io.File import java.util.* private fun argAdapterHelper(stateType: java.lang.reflect.Type): java.lang.reflect.Type = - TypeToken.getParameterized( - TypeToken.get(ArgAdapterHelper::class.java).type, - TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, stateType).type, - TypeToken.get(XcfaAction::class.java).type, - ).type + TypeToken.getParameterized( + TypeToken.get(ArgAdapterHelper::class.java).type, + TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, stateType).type, + TypeToken.get(XcfaAction::class.java).type, + ) + .type private fun argHelper(stateType: java.lang.reflect.Type): java.lang.reflect.Type = - TypeToken.getParameterized( - TypeToken.get(ARG::class.java).type, - TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, stateType).type, - TypeToken.get(XcfaAction::class.java).type, - ).type + TypeToken.getParameterized( + TypeToken.get(ARG::class.java).type, + TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, stateType).type, + TypeToken.get(XcfaAction::class.java).type, + ) + .type private fun traceHelper(stateType: java.lang.reflect.Type): java.lang.reflect.Type = - TypeToken.getParameterized( - TypeToken.get(Trace::class.java).type, - TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, stateType).type, - TypeToken.get(XcfaAction::class.java).type, - ).type + TypeToken.getParameterized( + TypeToken.get(Trace::class.java).type, + TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, stateType).type, + TypeToken.get(XcfaAction::class.java).type, + ) + .type @JvmOverloads -internal fun getGson(xcfa: XCFA, domain: () -> Domain = { error("Domain needs to be specified.") }, - solver: () -> Solver = { error("Solver is necessary.") }): Gson { - val (scope, env) = xcfa.getSymbols() - return getGson(scope, env, false, domain, solver) +internal fun getGson( + xcfa: XCFA, + domain: () -> Domain = { error("Domain needs to be specified.") }, + solver: () -> Solver = { error("Solver is necessary.") }, +): Gson { + val (scope, env) = xcfa.getSymbols() + return getGson(scope, env, false, domain, solver) } @JvmOverloads -internal fun getGson(domain: () -> Domain = { error("Domain needs to be specified.") }, - solver: () -> Solver = { error("Solver is necessary.") }): Gson { - return getGson(XcfaScope(SymbolTable()), Env(), true, domain, solver) +internal fun getGson( + domain: () -> Domain = { error("Domain needs to be specified.") }, + solver: () -> Solver = { error("Solver is necessary.") }, +): Gson { + return getGson(XcfaScope(SymbolTable()), Env(), true, domain, solver) } -private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> Domain, - solver: () -> Solver): Gson { - val gsonBuilder = GsonBuilder() - lateinit var gson: Gson - gsonBuilder.registerTypeHierarchyAdapter(FrontendConfig::class.java, SpecFrontendConfigTypeAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(BackendConfig::class.java, SpecBackendConfigTypeAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(File::class.java, StringTypeAdapter { File(it) }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, XcfaLocationAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, - VarDeclAdapter({ gson }, scope, env, !newScope)) - gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, - StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) - gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, - StringTypeAdapter { ExpressionWrapper(scope, it).instantiate(env) }) - gsonBuilder.registerTypeHierarchyAdapter(Type::class.java, - StringTypeAdapter { TypeWrapper(it).instantiate() }) - gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, - StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) - gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) - gsonBuilder.registerTypeHierarchyAdapter(PredState::class.java, - PredStateAdapter({ gson }, scope, env)) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, - XcfaLabelAdapter(scope, env, { gson })) - gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) - gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaState::class.java, - XcfaStateAdapter({ gson }) { domain().stateType }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaAction::class.java, XcfaActionAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, TraceAdapter({ gson }, { - TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, - domain().stateType).type - }, TypeToken.get(XcfaAction::class.java).type)) - gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, - ArgAdapter({ gson }, { domain().partialOrd(solver()) }, - { argAdapterHelper(domain().stateType) })) - gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, - SafetyResultAdapter({ gson }, { argHelper(domain().stateType) }, - { traceHelper(domain().stateType) })) - gsonBuilder.registerTypeHierarchyAdapter(ParseContext::class.java, - ParseContextAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(FrontendMetadata::class.java, - FrontendMetadataAdapter { gson }) - gson = gsonBuilder.create() - return gson -} \ No newline at end of file +private fun getGson( + scope: XcfaScope, + env: Env, + newScope: Boolean, + domain: () -> Domain, + solver: () -> Solver, +): Gson { + val gsonBuilder = GsonBuilder() + lateinit var gson: Gson + gsonBuilder.registerTypeHierarchyAdapter( + FrontendConfig::class.java, + SpecFrontendConfigTypeAdapter { gson }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + BackendConfig::class.java, + SpecBackendConfigTypeAdapter { gson }, + ) + gsonBuilder.registerTypeHierarchyAdapter(File::class.java, StringTypeAdapter { File(it) }) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, XcfaLocationAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter( + VarDecl::class.java, + VarDeclAdapter({ gson }, scope, env, !newScope), + ) + gsonBuilder.registerTypeHierarchyAdapter( + Stmt::class.java, + StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + Expr::class.java, + StringTypeAdapter { ExpressionWrapper(scope, it).instantiate(env) }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + Type::class.java, + StringTypeAdapter { TypeWrapper(it).instantiate() }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + VarIndexing::class.java, + StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }, + ) + gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) + gsonBuilder.registerTypeHierarchyAdapter( + PredState::class.java, + PredStateAdapter({ gson }, scope, env), + ) + gsonBuilder.registerTypeHierarchyAdapter( + XcfaLabel::class.java, + XcfaLabelAdapter(scope, env, { gson }), + ) + gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) + gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter( + XcfaState::class.java, + XcfaStateAdapter({ gson }) { domain().stateType }, + ) + gsonBuilder.registerTypeHierarchyAdapter(XcfaAction::class.java, XcfaActionAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter( + Trace::class.java, + TraceAdapter( + { gson }, + { + TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, domain().stateType) + .type + }, + TypeToken.get(XcfaAction::class.java).type, + ), + ) + gsonBuilder.registerTypeHierarchyAdapter( + ARG::class.java, + ArgAdapter( + { gson }, + { domain().partialOrd(solver()) }, + { argAdapterHelper(domain().stateType) }, + ), + ) + gsonBuilder.registerTypeHierarchyAdapter( + SafetyResult::class.java, + SafetyResultAdapter( + { gson }, + { argHelper(domain().stateType) }, + { traceHelper(domain().stateType) }, + ), + ) + gsonBuilder.registerTypeHierarchyAdapter(ParseContext::class.java, ParseContextAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter( + FrontendMetadata::class.java, + FrontendMetadataAdapter { gson }, + ) + gson = gsonBuilder.create() + return gson +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt index ae39115e9f..f1d2efd0fb 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/YmlWitnessWriter.kt @@ -37,159 +37,189 @@ import hu.bme.mit.theta.xcfa.toC import java.io.File import java.util.* - class YmlWitnessWriter { - fun writeWitness( - safetyResult: SafetyResult<*, *>, - inputFile: File, - property: ErrorDetection, - architecture: ArchitectureConfig.ArchitectureType?, - cexSolverFactory: SolverFactory, - parseContext: ParseContext, - witnessfile: File, - ) { - val metadata = Metadata( - formatVersion = "2.0", - uuid = UUID.randomUUID().toString(), - creationTime = getIsoDate(), - producer = Producer( - name = (System.getenv("VERIFIER_NAME")?:"").ifEmpty { "Theta" }, - version = (System.getenv("VERIFIER_VERSION")?:"").ifEmpty { "no version found" }, - ), - task = Task( - inputFiles = listOf(inputFile.name), - inputFileHashes = listOf(createTaskHash(inputFile.path)), - specification = property.name, - dataModel = architecture?.let { if(it == ArchitectureConfig.ArchitectureType.ILP32) DataModel.ILP32 else DataModel.LP64 } ?: DataModel.ILP32, - language = Language.C, - ) + fun writeWitness( + safetyResult: SafetyResult<*, *>, + inputFile: File, + property: ErrorDetection, + architecture: ArchitectureConfig.ArchitectureType?, + cexSolverFactory: SolverFactory, + parseContext: ParseContext, + witnessfile: File, + ) { + val metadata = + Metadata( + formatVersion = "2.0", + uuid = UUID.randomUUID().toString(), + creationTime = getIsoDate(), + producer = + Producer( + name = (System.getenv("VERIFIER_NAME") ?: "").ifEmpty { "Theta" }, + version = (System.getenv("VERIFIER_VERSION") ?: "").ifEmpty { "no version found" }, + ), + task = + Task( + inputFiles = listOf(inputFile.name), + inputFileHashes = listOf(createTaskHash(inputFile.path)), + specification = property.name, + dataModel = + architecture?.let { + if (it == ArchitectureConfig.ArchitectureType.ILP32) DataModel.ILP32 + else DataModel.LP64 + } ?: DataModel.ILP32, + language = Language.C, + ), + ) + + if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { + val concrTrace: Trace, XcfaAction> = + XcfaTraceConcretizer.concretize( + safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, + cexSolverFactory, + parseContext, ) - if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { - val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( - safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, cexSolverFactory, - parseContext) - - val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) - - val witness = YamlWitness( - entryType = EntryType.VIOLATION, - metadata = metadata, - content = (0..(witnessTrace.length())).flatMap { - listOfNotNull( - witnessTrace.states.get(it)?.toSegment(witnessTrace.actions.getOrNull(it-1), inputFile), - witnessTrace.actions.getOrNull(it)?.toSegment(inputFile) - ) - } - ) + val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) + + val witness = + YamlWitness( + entryType = EntryType.VIOLATION, + metadata = metadata, + content = + (0..(witnessTrace.length())).flatMap { + listOfNotNull( + witnessTrace.states + .get(it) + ?.toSegment(witnessTrace.actions.getOrNull(it - 1), inputFile), + witnessTrace.actions.getOrNull(it)?.toSegment(inputFile), + ) + }, + ) - witnessfile.writeText(WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness)) - } else if (safetyResult.isSafe) { + witnessfile.writeText(WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness)) + } else if (safetyResult.isSafe) { - val witness = YamlWitness( - entryType = EntryType.INVARIANTS, - metadata = metadata, - content = safetyResult.asSafe().proof.toContent(inputFile, parseContext) - ) + val witness = + YamlWitness( + entryType = EntryType.INVARIANTS, + metadata = metadata, + content = safetyResult.asSafe().proof.toContent(inputFile, parseContext), + ) - witnessfile.writeText(WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness)) - } + witnessfile.writeText(WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness)) } + } } private fun getLocation(inputFile: File, metadata: MetaData?): Location? { - val line = (metadata as? CMetaData)?.lineNumberStart ?: (metadata as? CMetaData)?.lineNumberStop ?: return null - val column = (metadata as? CMetaData)?.colNumberStart ?: (metadata as? CMetaData)?.colNumberStop - return Location( - fileName = inputFile.name, - line = line, - column = column, - ) + val line = + (metadata as? CMetaData)?.lineNumberStart + ?: (metadata as? CMetaData)?.lineNumberStop + ?: return null + val column = (metadata as? CMetaData)?.colNumberStart ?: (metadata as? CMetaData)?.colNumberStop + return Location(fileName = inputFile.name, line = line, column = column) } private fun getLocation(inputFile: File, witnessEdge: WitnessEdge?): Location? { - if(witnessEdge == null) return null - val endLoc = Location( - fileName = inputFile.name, - line = witnessEdge.endline ?: witnessEdge.startline ?: return null, - column = (witnessEdge.endcol ?: witnessEdge.startcol)?.plus(1), + if (witnessEdge == null) return null + val endLoc = + Location( + fileName = inputFile.name, + line = witnessEdge.endline ?: witnessEdge.startline ?: return null, + column = (witnessEdge.endcol ?: witnessEdge.startcol)?.plus(1), ) - return endLoc + return endLoc } private fun WitnessNode.toSegment(witnessEdge: WitnessEdge?, inputFile: File): ContentItem? { - if(violation) { - val loc = xcfaLocations.values.first().first() - val locLoc = getLocation(inputFile, loc.metadata) ?: getLocation(inputFile, witnessEdge) ?: getLocation(inputFile, witnessEdge?.edge?.metadata) ?: return null - return ContentItem(Segment( - Waypoint( - type = WaypointType.TARGET, - location = locLoc, - action = Action.FOLLOW - ) - )) - } else { - return null - } + if (violation) { + val loc = xcfaLocations.values.first().first() + val locLoc = + getLocation(inputFile, loc.metadata) + ?: getLocation(inputFile, witnessEdge) + ?: getLocation(inputFile, witnessEdge?.edge?.metadata) + ?: return null + return ContentItem( + Segment(Waypoint(type = WaypointType.TARGET, location = locLoc, action = Action.FOLLOW)) + ) + } else { + return null + } } private fun WitnessEdge.toSegment(inputFile: File): ContentItem? { - val endLoc = Location( - fileName = inputFile.name, - line = endline ?: startline ?: return null, - column = (endcol ?: startcol)?.plus(1), + val endLoc = + Location( + fileName = inputFile.name, + line = endline ?: startline ?: return null, + column = (endcol ?: startcol)?.plus(1), ) - val startLoc = Location( - fileName = inputFile.name, - line = startline ?: endline ?: return null, - column = (startcol ?: endcol)?.plus(1), + val startLoc = + Location( + fileName = inputFile.name, + line = startline ?: endline ?: return null, + column = (startcol ?: endcol)?.plus(1), ) - val (loc, constraint, type) = if(assumption != null) { - Triple(endLoc, Constraint(value = assumption, format = Format.C_EXPRESSION), WaypointType.ASSUMPTION) - } else if(control != null) { - Triple(startLoc, Constraint(value = control.toString()), WaypointType.BRANCHING) - } else if(enterLoopHead) { - Triple(startLoc, Constraint(value = "true"), WaypointType.BRANCHING) - } else if(enterFunction != null) { - Triple(startLoc, Constraint(value = enterFunction), WaypointType.FUNCTION_ENTER) - } else if(returnFromFunction != null) { - Triple(endLoc, Constraint(value = returnFromFunction), WaypointType.FUNCTION_RETURN) + val (loc, constraint, type) = + if (assumption != null) { + Triple( + endLoc, + Constraint(value = assumption, format = Format.C_EXPRESSION), + WaypointType.ASSUMPTION, + ) + } else if (control != null) { + Triple(startLoc, Constraint(value = control.toString()), WaypointType.BRANCHING) + } else if (enterLoopHead) { + Triple(startLoc, Constraint(value = "true"), WaypointType.BRANCHING) + } else if (enterFunction != null) { + Triple(startLoc, Constraint(value = enterFunction), WaypointType.FUNCTION_ENTER) + } else if (returnFromFunction != null) { + Triple(endLoc, Constraint(value = returnFromFunction), WaypointType.FUNCTION_RETURN) } else return null - return ContentItem(Segment( - Waypoint( - type = type, - constraint = constraint, - location = loc, - action = Action.FOLLOW - ) - )) + return ContentItem( + Segment(Waypoint(type = type, constraint = constraint, location = loc, action = Action.FOLLOW)) + ) } private fun Proof.toContent(inputFile: File, parseContext: ParseContext): List { - if(this is ARG<*, *>) { - val locMap = nodes.toList().mapNotNull { - it as ArgNode, XcfaAction> - val loc = it.state.processes.values.firstOrNull()?.locs?.peek() ?: return@mapNotNull null - val locLoc = Location( - fileName = inputFile.name, - line = (loc.metadata as? CMetaData)?.lineNumberStart ?: (loc.metadata as? CMetaData)?.lineNumberStop ?: return@mapNotNull null, - column = (loc.metadata as? CMetaData)?.colNumberStart ?: (loc.metadata as? CMetaData)?.colNumberStop, - ) - locLoc to it.state.sGlobal.toExpr() - }.groupBy{ it.first } - val invs = locMap.mapValues { entry -> ExprUtils.simplify(Or(entry.value.map { it.second })) }.map { - ContentItem( - invariant = Invariant( - type = InvariantType.LOCATION_INVARIANT, - location = it.key, - value = it.value.toC(parseContext), - format = Format.C_EXPRESSION - ) + if (this is ARG<*, *>) { + val locMap = + nodes + .toList() + .mapNotNull { + it as ArgNode, XcfaAction> + val loc = it.state.processes.values.firstOrNull()?.locs?.peek() ?: return@mapNotNull null + val locLoc = + Location( + fileName = inputFile.name, + line = + (loc.metadata as? CMetaData)?.lineNumberStart + ?: (loc.metadata as? CMetaData)?.lineNumberStop + ?: return@mapNotNull null, + column = + (loc.metadata as? CMetaData)?.colNumberStart + ?: (loc.metadata as? CMetaData)?.colNumberStop, ) + locLoc to it.state.sGlobal.toExpr() } - return invs - } - return listOf() -} \ No newline at end of file + .groupBy { it.first } + val invs = + locMap + .mapValues { entry -> ExprUtils.simplify(Or(entry.value.map { it.second })) } + .map { + ContentItem( + invariant = + Invariant( + type = InvariantType.LOCATION_INVARIANT, + location = it.key, + value = it.value.toC(parseContext), + format = Format.C_EXPRESSION, + ) + ) + } + return invs + } + return listOf() +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt index fcaf982dfb..e5f6748d54 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/CommonWitness.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.witnesses import hu.bme.mit.theta.analysis.Action @@ -32,87 +31,80 @@ import java.text.SimpleDateFormat import java.util.* data class WitnessNode( - val id: String, - val entry: Boolean = false, - val sink: Boolean = false, - val violation: Boolean = false, - - val xcfaLocations: Map> = emptyMap(), - val cSources: Map> = emptyMap(), - val globalState: ExplState? = null + val id: String, + val entry: Boolean = false, + val sink: Boolean = false, + val violation: Boolean = false, + val xcfaLocations: Map> = emptyMap(), + val cSources: Map> = emptyMap(), + val globalState: ExplState? = null, ) : State { - override fun isBottom(): Boolean { - error("Not applicable for witness states.") - } + override fun isBottom(): Boolean { + error("Not applicable for witness states.") + } } data class WitnessEdge( - val sourceId: String, - val targetId: String, - val assumption: String? = null, - val assumption_scope: String? = null, - val assumption_resultfunction: String? = null, - val control: Boolean? = null, - val startline: Int? = null, - val endline: Int? = null, - val startoffset: Int? = null, - val endoffset: Int? = null, - val startcol: Int? = null, - val endcol: Int? = null, - val enterLoopHead: Boolean = false, - val enterFunction: String? = null, - val returnFromFunction: String? = null, - val threadId: String? = null, - val createThread: String? = null, - - val stmt: String? = null, - val cSource: String? = null, - val edge: XcfaEdge? = null, -) : Action { -} + val sourceId: String, + val targetId: String, + val assumption: String? = null, + val assumption_scope: String? = null, + val assumption_resultfunction: String? = null, + val control: Boolean? = null, + val startline: Int? = null, + val endline: Int? = null, + val startoffset: Int? = null, + val endoffset: Int? = null, + val startcol: Int? = null, + val endcol: Int? = null, + val enterLoopHead: Boolean = false, + val enterFunction: String? = null, + val returnFromFunction: String? = null, + val threadId: String? = null, + val createThread: String? = null, + val stmt: String? = null, + val cSource: String? = null, + val edge: XcfaEdge? = null, +) : Action {} fun createTaskHash(programFile: String): String { - var md: MessageDigest? = null - try { - md = MessageDigest.getInstance("SHA-256") - } catch (e: NoSuchAlgorithmException) { - e.printStackTrace() - } - try { - Files.newInputStream(Paths.get(programFile)).use { `is` -> - DigestInputStream(`is`, md).use { dis -> - while (dis.read() != -1) { - } - } - } - } catch (e: IOException) { - e.printStackTrace() + var md: MessageDigest? = null + try { + md = MessageDigest.getInstance("SHA-256") + } catch (e: NoSuchAlgorithmException) { + e.printStackTrace() + } + try { + Files.newInputStream(Paths.get(programFile)).use { `is` -> + DigestInputStream(`is`, md).use { dis -> while (dis.read() != -1) {} } } - assert(md != null) - val digest = md!!.digest() - return bytesToHex(digest) + } catch (e: IOException) { + e.printStackTrace() + } + assert(md != null) + val digest = md!!.digest() + return bytesToHex(digest) } // source: https://www.baeldung.com/sha-256-hashing-java fun bytesToHex(hash: ByteArray): String { - val hexString = StringBuilder(2 * hash.size) - for (i in hash.indices) { - val hex = Integer.toHexString(0xff and hash[i].toInt()) - if (hex.length == 1) { - hexString.append('0') - } - hexString.append(hex) + val hexString = StringBuilder(2 * hash.size) + for (i in hash.indices) { + val hex = Integer.toHexString(0xff and hash[i].toInt()) + if (hex.length == 1) { + hexString.append('0') } - return hexString.toString() + hexString.append(hex) + } + return hexString.toString() } fun getIsoDate(): String { - val tz: TimeZone = TimeZone.getTimeZone("UTC") - val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'" - ) // Quoted "Z" to indicate UTC, no timezone offset + val tz: TimeZone = TimeZone.getTimeZone("UTC") + val df: DateFormat = + SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset - df.timeZone = tz - return df.format(Date()) -} \ No newline at end of file + df.timeZone = tz + return df.format(Date()) +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt index d2906d7359..5d774f1d36 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/GraphmlWitness.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.witnesses import hu.bme.mit.theta.analysis.Trace @@ -28,63 +27,69 @@ import javax.xml.transform.TransformerFactory import javax.xml.transform.stream.StreamResult import javax.xml.transform.stream.StreamSource - class GraphmlWitness(private val trace: Trace, programFile: File) { - private val attributes: MutableList = ArrayList() - private val data: MutableList> = ArrayList() - - init { - attributes.add(GraphmlWitnessAttribute("sourcecodelang", "string", "graph", "sourcecodelang")) - attributes.add(GraphmlWitnessAttribute("creationtime", "string", "graph", "creationtime")) - attributes.add(GraphmlWitnessAttribute("witness-type", "string", "graph", "witness-type")) - attributes.add(GraphmlWitnessAttribute("producer", "string", "graph", "producer")) - attributes.add(GraphmlWitnessAttribute("architecture", "string", "graph", "architecture")) - attributes.add(GraphmlWitnessAttribute("programHash", "string", "graph", "programhash")) - attributes.add(GraphmlWitnessAttribute("programfile", "string", "graph", "programfile")) - attributes.add(GraphmlWitnessAttribute("specification", "string", "graph", "specification")) - - attributes.add(GraphmlWitnessAttribute("assumption", "string", "edge", "assumption")) - attributes.add(GraphmlWitnessAttribute("assumption.scope", "string", "edge", "assumption.scope")) - attributes.add( - GraphmlWitnessAttribute( - "assumption.resultfunction", "string", "edge", - "assumption.resultfunction")) - attributes.add(GraphmlWitnessAttribute("control", "string", "edge", "control")) - attributes.add(GraphmlWitnessAttribute("startline", "string", "edge", "startline")) - attributes.add(GraphmlWitnessAttribute("endline", "string", "edge", "endline")) - attributes.add(GraphmlWitnessAttribute("startoffset", "string", "edge", "startoffset")) - attributes.add(GraphmlWitnessAttribute("endoffset", "string", "edge", "endoffset")) - attributes.add(GraphmlWitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead")) - attributes.add(GraphmlWitnessAttribute("enterFunction", "string", "edge", "enterFunction")) - attributes.add( - GraphmlWitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction") - ) - attributes.add(GraphmlWitnessAttribute("threadId", "string", "edge", "threadId")) - attributes.add(GraphmlWitnessAttribute("createThread", "string", "edge", "createThread")) - attributes.add(GraphmlWitnessAttribute("stmt", "string", "edge", "stmt")) - attributes.add(GraphmlWitnessAttribute("cSource", "string", "edge", "cSource")) - - attributes.add(GraphmlWitnessAttribute("entry", "string", "node", "entry", "false")) - attributes.add(GraphmlWitnessAttribute("sink", "string", "node", "sink", "false")) - attributes.add(GraphmlWitnessAttribute("violation", "string", "node", "violation", "false")) - attributes.add(GraphmlWitnessAttribute("locationStacks", "string", "node", "locationStacks")) - attributes.add(GraphmlWitnessAttribute("sourceLines", "string", "node", "sourceLines")) - attributes.add(GraphmlWitnessAttribute("state", "string", "node", "state")) - - data.add(Pair("witness-type", "violation_witness")) - data.add(Pair("producer", "theta")) - data.add(Pair("sourcecodelang", "C")) - data.add(Pair("specification", "CHECK( init(main()), LTL(G ! call(reach_error())) )")) - data.add(Pair("programfile", programFile.absolutePath)) - data.add(Pair("programhash", createTaskHash(programFile.path))) - data.add(Pair("architecture", "32bit")) - data.add(Pair("creationtime", getIsoDate())) - } - - fun toPrettyXml(): String = prettyFormat(toXml(), 4) - - fun toXml(): String = """ + private val attributes: MutableList = ArrayList() + private val data: MutableList> = ArrayList() + + init { + attributes.add(GraphmlWitnessAttribute("sourcecodelang", "string", "graph", "sourcecodelang")) + attributes.add(GraphmlWitnessAttribute("creationtime", "string", "graph", "creationtime")) + attributes.add(GraphmlWitnessAttribute("witness-type", "string", "graph", "witness-type")) + attributes.add(GraphmlWitnessAttribute("producer", "string", "graph", "producer")) + attributes.add(GraphmlWitnessAttribute("architecture", "string", "graph", "architecture")) + attributes.add(GraphmlWitnessAttribute("programHash", "string", "graph", "programhash")) + attributes.add(GraphmlWitnessAttribute("programfile", "string", "graph", "programfile")) + attributes.add(GraphmlWitnessAttribute("specification", "string", "graph", "specification")) + + attributes.add(GraphmlWitnessAttribute("assumption", "string", "edge", "assumption")) + attributes.add( + GraphmlWitnessAttribute("assumption.scope", "string", "edge", "assumption.scope") + ) + attributes.add( + GraphmlWitnessAttribute( + "assumption.resultfunction", + "string", + "edge", + "assumption.resultfunction", + ) + ) + attributes.add(GraphmlWitnessAttribute("control", "string", "edge", "control")) + attributes.add(GraphmlWitnessAttribute("startline", "string", "edge", "startline")) + attributes.add(GraphmlWitnessAttribute("endline", "string", "edge", "endline")) + attributes.add(GraphmlWitnessAttribute("startoffset", "string", "edge", "startoffset")) + attributes.add(GraphmlWitnessAttribute("endoffset", "string", "edge", "endoffset")) + attributes.add(GraphmlWitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead")) + attributes.add(GraphmlWitnessAttribute("enterFunction", "string", "edge", "enterFunction")) + attributes.add( + GraphmlWitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction") + ) + attributes.add(GraphmlWitnessAttribute("threadId", "string", "edge", "threadId")) + attributes.add(GraphmlWitnessAttribute("createThread", "string", "edge", "createThread")) + attributes.add(GraphmlWitnessAttribute("stmt", "string", "edge", "stmt")) + attributes.add(GraphmlWitnessAttribute("cSource", "string", "edge", "cSource")) + + attributes.add(GraphmlWitnessAttribute("entry", "string", "node", "entry", "false")) + attributes.add(GraphmlWitnessAttribute("sink", "string", "node", "sink", "false")) + attributes.add(GraphmlWitnessAttribute("violation", "string", "node", "violation", "false")) + attributes.add(GraphmlWitnessAttribute("locationStacks", "string", "node", "locationStacks")) + attributes.add(GraphmlWitnessAttribute("sourceLines", "string", "node", "sourceLines")) + attributes.add(GraphmlWitnessAttribute("state", "string", "node", "state")) + + data.add(Pair("witness-type", "violation_witness")) + data.add(Pair("producer", "theta")) + data.add(Pair("sourcecodelang", "C")) + data.add(Pair("specification", "CHECK( init(main()), LTL(G ! call(reach_error())) )")) + data.add(Pair("programfile", programFile.absolutePath)) + data.add(Pair("programhash", createTaskHash(programFile.path))) + data.add(Pair("architecture", "32bit")) + data.add(Pair("creationtime", getIsoDate())) + } + + fun toPrettyXml(): String = prettyFormat(toXml(), 4) + + fun toXml(): String = + """ @@ -100,19 +105,20 @@ ${trace.actions.map(WitnessEdge::toXml).reduce { a, b -> "$a\n$b" }} - """.trimIndent() - + """ + .trimIndent() } data class GraphmlWitnessAttribute( - val name: String, - val type: String, - val `for`: String, - val id: String, - val defaultValue: String? = null + val name: String, + val type: String, + val `for`: String, + val id: String, + val defaultValue: String? = null, ) { - fun toXml(): String = """ + fun toXml(): String = + """ """.trimIndent() } -""".trimIndent() +""" + .trimIndent() } private fun escapeXml(toEscape: String): String { - var toEscape = toEscape - toEscape = toEscape.replace("&", "&") - toEscape = toEscape.replace("\"", """) - toEscape = toEscape.replace("'", "'") - toEscape = toEscape.replace("<", "<") - toEscape = toEscape.replace(">", ">") - return toEscape + var toEscape = toEscape + toEscape = toEscape.replace("&", "&") + toEscape = toEscape.replace("\"", """) + toEscape = toEscape.replace("'", "'") + toEscape = toEscape.replace("<", "<") + toEscape = toEscape.replace(">", ">") + return toEscape } // from https://stackoverflow.com/a/1264912 private fun prettyFormat(input: String, indent: Int): String { - return try { - val xmlInput: Source = StreamSource( - StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), ""))) - val stringWriter = StringWriter() - val xmlOutput = StreamResult(stringWriter) - val transformerFactory: TransformerFactory = TransformerFactory.newInstance() - transformerFactory.setAttribute("indent-number", indent) - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "") - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "") - val transformer: Transformer = transformerFactory.newTransformer() - transformer.setOutputProperty(OutputKeys.INDENT, "yes") - transformer.transform(xmlInput, xmlOutput) - xmlOutput.getWriter().toString() - } catch (e: Exception) { - System.err.println(input.replace(Regex("( )|[\\t\\n\\r]"), "")) - throw RuntimeException(e) - } + return try { + val xmlInput: Source = StreamSource(StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), ""))) + val stringWriter = StringWriter() + val xmlOutput = StreamResult(stringWriter) + val transformerFactory: TransformerFactory = TransformerFactory.newInstance() + transformerFactory.setAttribute("indent-number", indent) + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "") + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "") + val transformer: Transformer = transformerFactory.newTransformer() + transformer.setOutputProperty(OutputKeys.INDENT, "yes") + transformer.transform(xmlInput, xmlOutput) + xmlOutput.getWriter().toString() + } catch (e: Exception) { + System.err.println(input.replace(Regex("( )|[\\t\\n\\r]"), "")) + throw RuntimeException(e) + } } -fun WitnessNode.toXml(): String = """ +fun WitnessNode.toXml(): String = + """ ${if (entry) "true" else ""} ${if (sink) "true" else ""} @@ -178,9 +185,11 @@ fun WitnessNode.toXml(): String = """ }" else "" } - """.trimIndent() + """ + .trimIndent() -fun WitnessEdge.toXml(): String = """ +fun WitnessEdge.toXml(): String = + """ ${if (assumption != null) "$assumption" else ""} ${if (assumption_scope != null) "$assumption_scope" else ""} @@ -204,4 +213,5 @@ fun WitnessEdge.toXml(): String = """ } - """.trimIndent() \ No newline at end of file + """ + .trimIndent() diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt index 252e248e45..48c1ea369b 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.witnesses import com.google.common.collect.Lists @@ -32,185 +31,209 @@ import hu.bme.mit.theta.xcfa.model.* import java.math.BigInteger enum class Verbosity { - NECESSARY, - SOURCE_EXISTS, - STMT_EXISTS, - EVERYTHING + NECESSARY, + SOURCE_EXISTS, + STMT_EXISTS, + EVERYTHING, } fun traceToWitness( - verbosity: Verbosity = Verbosity.SOURCE_EXISTS, - trace: Trace, XcfaAction>, - parseContext: ParseContext + verbosity: Verbosity = Verbosity.SOURCE_EXISTS, + trace: Trace, XcfaAction>, + parseContext: ParseContext, ): Trace { - val newStates = ArrayList() - val newActions = ArrayList() - - var lastNode = WitnessNode(id = "N${newStates.size}", entry = true, sink = false, - violation = false) - newStates.add(lastNode) - - for (i in 0 until trace.length()) { - val state = trace.states[i] - val action = trace.actions[i] - val nextState = trace.states[i + 1] - val newThreads = nextState.processes.keys - state.processes.keys - val node = WitnessNode( - id = "N${newStates.size}", - entry = false, - sink = false, - violation = state.processes.any { it.value.locs.any(XcfaLocation::error) }, - xcfaLocations = state.processes.map { Pair(it.key, it.value.locs) }.toMap(), - cSources = state.processes.map { - Pair(it.key, it.value.locs.map { it.getCMetaData()?.sourceText ?: "" }) - }.toMap(), - globalState = state.sGlobal - ) - if (node != WitnessNode(id = "N${newStates.size}")) { - newStates.add(node) - val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id, - threadId = trace.actions[i].pid.toString(), edge = action.edge - ) - newActions.add(edge) - lastNode = node - } - - val flattenedSequence = flattenSequence(action.edge.label) - for (xcfaLabel in flattenedSequence) { - val node = WitnessNode(id = "N${newStates.size}", entry = false, sink = false, - violation = false) - var edge = labelToEdge(lastNode, node, xcfaLabel, action.pid, - nextState.sGlobal.getVal(), parseContext, action.edge - ) - if (newThreads.isNotEmpty() && xcfaLabel is StartLabel) { - edge = edge.copy(createThread = newThreads.joinToString(",")) - } - if (node != WitnessNode(id = "N${newStates.size}") || shouldInclude(edge, verbosity)) { - newStates.add(node) - newActions.add(edge) - lastNode = node - } - } - } - - val lastState = trace.states[trace.length()] - val node = WitnessNode( + val newStates = ArrayList() + val newActions = ArrayList() + + var lastNode = + WitnessNode(id = "N${newStates.size}", entry = true, sink = false, violation = false) + newStates.add(lastNode) + + for (i in 0 until trace.length()) { + val state = trace.states[i] + val action = trace.actions[i] + val nextState = trace.states[i + 1] + val newThreads = nextState.processes.keys - state.processes.keys + val node = + WitnessNode( id = "N${newStates.size}", entry = false, sink = false, - violation = lastState.processes.any { it.value.locs.any(XcfaLocation::error) }, - xcfaLocations = lastState.processes.map { Pair(it.key, it.value.locs) }.toMap(), - cSources = lastState.processes.map { - Pair(it.key, it.value.locs.map { it.getCMetaData()?.sourceText ?: "" }) - }.toMap(), - globalState = lastState.sGlobal - ) - newStates.add(node) - val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id, edge = trace.actions[trace.length() - 1].edge) - newActions.add(edge) + violation = state.processes.any { it.value.locs.any(XcfaLocation::error) }, + xcfaLocations = state.processes.map { Pair(it.key, it.value.locs) }.toMap(), + cSources = + state.processes + .map { + Pair(it.key, it.value.locs.map { it.getCMetaData()?.sourceText ?: "" }) + } + .toMap(), + globalState = state.sGlobal, + ) + if (node != WitnessNode(id = "N${newStates.size}")) { + newStates.add(node) + val edge = + WitnessEdge( + sourceId = lastNode.id, + targetId = node.id, + threadId = trace.actions[i].pid.toString(), + edge = action.edge, + ) + newActions.add(edge) + lastNode = node + } - return Trace.of(newStates, newActions) + val flattenedSequence = flattenSequence(action.edge.label) + for (xcfaLabel in flattenedSequence) { + val node = + WitnessNode(id = "N${newStates.size}", entry = false, sink = false, violation = false) + var edge = + labelToEdge( + lastNode, + node, + xcfaLabel, + action.pid, + nextState.sGlobal.getVal(), + parseContext, + action.edge, + ) + if (newThreads.isNotEmpty() && xcfaLabel is StartLabel) { + edge = edge.copy(createThread = newThreads.joinToString(",")) + } + if (node != WitnessNode(id = "N${newStates.size}") || shouldInclude(edge, verbosity)) { + newStates.add(node) + newActions.add(edge) + lastNode = node + } + } + } + + val lastState = trace.states[trace.length()] + val node = + WitnessNode( + id = "N${newStates.size}", + entry = false, + sink = false, + violation = lastState.processes.any { it.value.locs.any(XcfaLocation::error) }, + xcfaLocations = lastState.processes.map { Pair(it.key, it.value.locs) }.toMap(), + cSources = + lastState.processes + .map { Pair(it.key, it.value.locs.map { it.getCMetaData()?.sourceText ?: "" }) } + .toMap(), + globalState = lastState.sGlobal, + ) + newStates.add(node) + val edge = + WitnessEdge( + sourceId = lastNode.id, + targetId = node.id, + edge = trace.actions[trace.length() - 1].edge, + ) + newActions.add(edge) + return Trace.of(newStates, newActions) } fun shouldInclude(edge: WitnessEdge, verbosity: Verbosity): Boolean = - when (verbosity) { - Verbosity.NECESSARY -> edge.control != null || edge.assumption != null || edge.createThread != null - Verbosity.SOURCE_EXISTS -> shouldInclude(edge, Verbosity.NECESSARY) || edge.cSource != null - Verbosity.STMT_EXISTS -> shouldInclude(edge, Verbosity.NECESSARY) || edge.stmt != null - Verbosity.EVERYTHING -> true - } - + when (verbosity) { + Verbosity.NECESSARY -> + edge.control != null || edge.assumption != null || edge.createThread != null + Verbosity.SOURCE_EXISTS -> shouldInclude(edge, Verbosity.NECESSARY) || edge.cSource != null + Verbosity.STMT_EXISTS -> shouldInclude(edge, Verbosity.NECESSARY) || edge.stmt != null + Verbosity.EVERYTHING -> true + } private fun labelToEdge( - lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, - valuation: Valuation, parseContext: ParseContext, edge: XcfaEdge + lastNode: WitnessNode, + node: WitnessNode, + xcfaLabel: XcfaLabel, + pid: Int, + valuation: Valuation, + parseContext: ParseContext, + edge: XcfaEdge, ): WitnessEdge = - WitnessEdge( - sourceId = lastNode.id, - targetId = node.id, - - assumption = if (xcfaLabel is StmtLabel && xcfaLabel.stmt is HavocStmt<*>) { - val varDecl = (xcfaLabel.stmt as HavocStmt<*>).varDecl - val eval = valuation.eval(varDecl) - val splitName = varDecl.name.split("::") - val rootName = if (splitName[0].matches(Regex("T[0-9]*"))) splitName.subList(2, splitName.size) - .joinToString("::") else varDecl.name - if (parseContext.metadata.getMetadataValue(rootName, "cName").isPresent && eval.isPresent) - "${parseContext.metadata.getMetadataValue(rootName, "cName").get()} == ${ + WitnessEdge( + sourceId = lastNode.id, + targetId = node.id, + assumption = + if (xcfaLabel is StmtLabel && xcfaLabel.stmt is HavocStmt<*>) { + val varDecl = (xcfaLabel.stmt as HavocStmt<*>).varDecl + val eval = valuation.eval(varDecl) + val splitName = varDecl.name.split("::") + val rootName = + if (splitName[0].matches(Regex("T[0-9]*"))) + splitName.subList(2, splitName.size).joinToString("::") + else varDecl.name + if (parseContext.metadata.getMetadataValue(rootName, "cName").isPresent && eval.isPresent) + "${parseContext.metadata.getMetadataValue(rootName, "cName").get()} == ${ printLit(eval.get()) }" - else null - } else null, - - control = if (xcfaLabel is StmtLabel && xcfaLabel.choiceType != ChoiceType.NONE) { - xcfaLabel.choiceType == ChoiceType.MAIN_PATH - } else null, - - startline = xcfaLabel.getCMetaData()?.lineNumberStart, - endline = xcfaLabel.getCMetaData()?.lineNumberStop, - startoffset = xcfaLabel.getCMetaData()?.offsetStart, - endoffset = xcfaLabel.getCMetaData()?.offsetEnd, - startcol = xcfaLabel.getCMetaData()?.colNumberStart, - endcol = xcfaLabel.getCMetaData()?.colNumberStop, - - threadId = if (pid != null) "$pid" else null, - - stmt = if (xcfaLabel is StmtLabel) xcfaLabel.stmt.toString() else null, - cSource = xcfaLabel.getCMetaData()?.sourceText, - edge = edge - ) + else null + } else null, + control = + if (xcfaLabel is StmtLabel && xcfaLabel.choiceType != ChoiceType.NONE) { + xcfaLabel.choiceType == ChoiceType.MAIN_PATH + } else null, + startline = xcfaLabel.getCMetaData()?.lineNumberStart, + endline = xcfaLabel.getCMetaData()?.lineNumberStop, + startoffset = xcfaLabel.getCMetaData()?.offsetStart, + endoffset = xcfaLabel.getCMetaData()?.offsetEnd, + startcol = xcfaLabel.getCMetaData()?.colNumberStart, + endcol = xcfaLabel.getCMetaData()?.colNumberStop, + threadId = if (pid != null) "$pid" else null, + stmt = if (xcfaLabel is StmtLabel) xcfaLabel.stmt.toString() else null, + cSource = xcfaLabel.getCMetaData()?.sourceText, + edge = edge, + ) private fun flattenSequence(label: XcfaLabel): List = - when (label) { - is NondetLabel -> error("Cannot handle nondet labels in witnesses") - is SequenceLabel -> label.labels.map { flattenSequence(it) }.flatten() - else -> listOf(label) - } + when (label) { + is NondetLabel -> error("Cannot handle nondet labels in witnesses") + is SequenceLabel -> label.labels.map { flattenSequence(it) }.flatten() + else -> listOf(label) + } private fun printLit(litExpr: LitExpr<*>): String? { - return if (litExpr is BvLitExpr) { - val value = litExpr.value - var intValue = BigInteger.ZERO - for (i in value.indices) { - val b = value[i] - if (b) { - intValue = intValue.add(BigInteger.ONE.shiftLeft(value.size - 1 - i)) - } - } - "0x" + intValue.toString(16) - } else if (litExpr is FpLitExpr) { - val boolList: MutableList = java.util.ArrayList() - val tmpList: MutableList = java.util.ArrayList() - for (b in litExpr.significand.value) { - tmpList.add(b) - } - boolList.addAll(Lists.reverse(tmpList)) - tmpList.clear() - for (b in litExpr.exponent.value) { - tmpList.add(b) - } - boolList.addAll(Lists.reverse(tmpList)) - boolList.add(litExpr.hidden) - var aggregate = 0 - val hexDigits: MutableList = java.util.ArrayList() - for (i in boolList.indices) { - if (i % 4 == 0 && i > 0) { - if (aggregate < 10) hexDigits.add( - ('0'.code + aggregate).toChar()) else hexDigits.add( - ('A'.code - 10 + aggregate).toChar()) - aggregate = 0 - } - if (boolList[i]) aggregate += 1 shl i % 4 - } - if (aggregate < 10) hexDigits.add(('0'.code + aggregate).toChar()) else hexDigits.add( - ('A'.code - 10 + aggregate).toChar()) - val stringBuilder = StringBuilder("0x") - for (character in Lists.reverse(hexDigits)) { - stringBuilder.append(character) - } - stringBuilder.toString() - } else { - litExpr.toString() + return if (litExpr is BvLitExpr) { + val value = litExpr.value + var intValue = BigInteger.ZERO + for (i in value.indices) { + val b = value[i] + if (b) { + intValue = intValue.add(BigInteger.ONE.shiftLeft(value.size - 1 - i)) + } + } + "0x" + intValue.toString(16) + } else if (litExpr is FpLitExpr) { + val boolList: MutableList = java.util.ArrayList() + val tmpList: MutableList = java.util.ArrayList() + for (b in litExpr.significand.value) { + tmpList.add(b) } -} \ No newline at end of file + boolList.addAll(Lists.reverse(tmpList)) + tmpList.clear() + for (b in litExpr.exponent.value) { + tmpList.add(b) + } + boolList.addAll(Lists.reverse(tmpList)) + boolList.add(litExpr.hidden) + var aggregate = 0 + val hexDigits: MutableList = java.util.ArrayList() + for (i in boolList.indices) { + if (i % 4 == 0 && i > 0) { + if (aggregate < 10) hexDigits.add(('0'.code + aggregate).toChar()) + else hexDigits.add(('A'.code - 10 + aggregate).toChar()) + aggregate = 0 + } + if (boolList[i]) aggregate += 1 shl i % 4 + } + if (aggregate < 10) hexDigits.add(('0'.code + aggregate).toChar()) + else hexDigits.add(('A'.code - 10 + aggregate).toChar()) + val stringBuilder = StringBuilder("0x") + for (character in Lists.reverse(hexDigits)) { + stringBuilder.append(character) + } + stringBuilder.toString() + } else { + litExpr.toString() + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java index 435e3dbf9e..ab8faa04bd 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/XcfaTraceConcretizer.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.witnesses; +import static com.google.common.base.Preconditions.checkArgument; + import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.analysis.expl.ExplState; @@ -39,20 +40,19 @@ import hu.bme.mit.theta.xcfa.analysis.XcfaAction; import hu.bme.mit.theta.xcfa.analysis.XcfaState; import hu.bme.mit.theta.xcfa.model.XcfaEdge; -import kotlin.Triple; - import java.util.*; import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkArgument; +import kotlin.Triple; /** - * Similar to CfaTraceConcretizer - * Takes a trace given by an unsafe result and uses and SMT solver to output a concrete counterexample + * Similar to CfaTraceConcretizer Takes a trace given by an unsafe result and uses and SMT solver to + * output a concrete counterexample */ public class XcfaTraceConcretizer { public static Trace, XcfaAction> concretize( - final Trace>, XcfaAction> trace, SolverFactory solverFactory, ParseContext parseContext) { + final Trace>, XcfaAction> trace, + SolverFactory solverFactory, + ParseContext parseContext) { List>> sbeStates = new ArrayList<>(); List sbeActions = new ArrayList<>(); @@ -60,15 +60,26 @@ public static Trace, XcfaAction> concretize( Map, Expr, Expr>>> nextW = Collections.emptyMap(); for (int i = 0; i < trace.getActions().size(); ++i) { - final XcfaEdge edge = new XcfaEdge(trace.getAction(i).getSource(), trace.getAction(i).getTarget(), trace.getAction(i).getLabel(), trace.getAction(i).getEdge().getMetadata()); - final XcfaAction action = new XcfaAction(trace.getAction(i).getPid(), edge, nextW, trace.getAction(i).getInCnt()); + final XcfaEdge edge = + new XcfaEdge( + trace.getAction(i).getSource(), + trace.getAction(i).getTarget(), + trace.getAction(i).getLabel(), + trace.getAction(i).getEdge().getMetadata()); + final XcfaAction action = + new XcfaAction( + trace.getAction(i).getPid(), + edge, + nextW, + trace.getAction(i).getInCnt()); sbeActions.add(action); nextW = action.nextWriteTriples(); sbeStates.add(trace.getState(i + 1).withState(new PtrState<>(ExplState.top()))); } Trace, XcfaAction> sbeTrace = Trace.of(sbeStates, sbeActions); - final ExprTraceChecker checker = ExprTraceFwBinItpChecker.create(BoolExprs.True(), - BoolExprs.True(), solverFactory.createItpSolver()); + final ExprTraceChecker checker = + ExprTraceFwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), solverFactory.createItpSolver()); final ExprTraceStatus status = checker.check(sbeTrace); checkArgument(status.isFeasible(), "Infeasible trace."); final Trace valuations = status.asFeasible().getValuations(); @@ -78,7 +89,19 @@ public static Trace, XcfaAction> concretize( final List> cfaStates = new ArrayList<>(); final Set> varSoFar = new LinkedHashSet<>(); for (int i = 0; i < sbeTrace.getStates().size(); ++i) { - cfaStates.add(new XcfaState<>(null, sbeTrace.getState(i).getProcesses(), ExplState.of(ImmutableValuation.from(valuations.getState(i).toMap().entrySet().stream().filter(it -> varSoFar.contains(it.getKey())).collect(Collectors.toMap(Map.Entry, LitExpr>::getKey, Map.Entry::getValue)))))); + cfaStates.add( + new XcfaState<>( + null, + sbeTrace.getState(i).getProcesses(), + ExplState.of( + ImmutableValuation.from( + valuations.getState(i).toMap().entrySet().stream() + .filter(it -> varSoFar.contains(it.getKey())) + .collect( + Collectors.toMap( + Map.Entry, LitExpr> + ::getKey, + Map.Entry::getValue)))))); if (i < sbeTrace.getActions().size()) { varSoFar.addAll(ExprUtils.getVars(sbeTrace.getAction(i).toExpr())); } @@ -86,5 +109,4 @@ public static Trace, XcfaAction> concretize( return Trace.of(cfaStates, sbeActions); } - } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt index b3c000f5ad..15fa63eada 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/YamlWitness.kt @@ -13,248 +13,289 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.witnesses import com.charleskorn.kaml.Yaml import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -val WitnessYamlConfig = Yaml(configuration = Yaml.default.configuration.copy(encodeDefaults = false)) +val WitnessYamlConfig = + Yaml(configuration = Yaml.default.configuration.copy(encodeDefaults = false)) // https://gitlab.com/sosy-lab/benchmarking/sv-witnesses/-/blob/8f5dc4bf00c01bc6d5636d7993e164d181e19204/violation-witness-schema.yml // https://gitlab.com/sosy-lab/benchmarking/sv-witnesses/-/blob/8f5dc4bf00c01bc6d5636d7993e164d181e19204/correctness-witness-schema.yml /** - * For violations: - * Each entry consists of three key-value pairs, namely the key `entry_type` with value `violation_sequence`, - * the key metadata, and the key content. - * For correctness: - * The `entry_type` defines what content is available in the content field. The only allowed entry type for a correctness witness is `invariant_set`. - * @param entryType The `entry_type` defines what content is available in the content field. The only allowed entry type for a correctness witness is `violation_sequence`. - * @param metadata The meta data describe the provenance of the data. - * @param content For violations: The content represents the semantical content of the violation witness. It is a sequence of one or more segments. The content contains a sequence of zero or more normal segments and exactly one final segment at the end. - * For correctness: The content represents the semantical content of the correctness witness. It is a sequence of one or more invariant elements. + * For violations: Each entry consists of three key-value pairs, namely the key `entry_type` with + * value `violation_sequence`, the key metadata, and the key content. For correctness: The + * `entry_type` defines what content is available in the content field. The only allowed entry type + * for a correctness witness is `invariant_set`. * + * @param entryType The `entry_type` defines what content is available in the content field. The + * only allowed entry type for a correctness witness is `violation_sequence`. + * @param metadata The meta data describe the provenance of the data. + * @param content For violations: The content represents the semantical content of the violation + * witness. It is a sequence of one or more segments. The content contains a sequence of zero or + * more normal segments and exactly one final segment at the end. For correctness: The content + * represents the semantical content of the correctness witness. It is a sequence of one or more + * invariant elements. */ -@Serializable data class YamlWitness( - @SerialName("entry_type") - val entryType: EntryType, - val metadata: Metadata, - val content: List, +@Serializable +data class YamlWitness( + @SerialName("entry_type") val entryType: EntryType, + val metadata: Metadata, + val content: List, ) -@Serializable enum class EntryType { - @SerialName("violation_sequence") VIOLATION, - @SerialName("invariant_set") INVARIANTS, +@Serializable +enum class EntryType { + @SerialName("violation_sequence") VIOLATION, + @SerialName("invariant_set") INVARIANTS, } /** * The meta data describe the provenance of the data. - * @param formatVersion The `version` of the format is given as a string (currently "2.0"). - * @param uuid The `uuid` is a unique identifier of the entry; it uses the UUID format defined in RFC4122. - * @param creationTime The `creation_time` describes the date and time when the entry was created; it uses the format given by ISO 8601. - * @param producer The key `producer` describes the tool that produced the entry. * + * @param formatVersion The `version` of the format is given as a string (currently "2.0"). + * @param uuid The `uuid` is a unique identifier of the entry; it uses the UUID format defined in + * RFC4122. + * @param creationTime The `creation_time` describes the date and time when the entry was created; + * it uses the format given by ISO 8601. + * @param producer The key `producer` describes the tool that produced the entry. */ -@Serializable data class Metadata( - @SerialName("format_version") - val formatVersion: String, - val uuid: String, - @SerialName("creation_time") - val creationTime: String, - val producer: Producer, - val task: Task, +@Serializable +data class Metadata( + @SerialName("format_version") val formatVersion: String, + val uuid: String, + @SerialName("creation_time") val creationTime: String, + val producer: Producer, + val task: Task, ) /** * The key `producer` describes the tool that produced the entry. + * * @param name The name of the tool that produced the witness. * @param version The version of the tool * @param configuration The configuration in which the tool ran (optional) - * @param commandLine The command line with which the tool ran; it should be a bash-compliant command (optional) + * @param commandLine The command line with which the tool ran; it should be a bash-compliant + * command (optional) * @param description Any information not fitting in the previous items (optional) */ -@Serializable data class Producer( - val name: String, - val version: String, - val configuration: String? = null, - @SerialName("command_line") - val commandLine: String? = null, - val description: String? = null, +@Serializable +data class Producer( + val name: String, + val version: String, + val configuration: String? = null, + @SerialName("command_line") val commandLine: String? = null, + val description: String? = null, ) /** * The task describes the verification task to which the entry is related. - * @param inputFiles The list of files given as input to the verifier, e.g. ["path/f1.c", "path/f2.c"]. - * @param inputFileHashes The SHA-256 hashes of all files in input_files, e.g. {"path/f1.c": 511..., "path/f2.c": f70...} - * @param specification The specification considered by the verifier; it uses the SV-COMP format given at https://sv-comp.sosy-lab.org/2023/rules.php. + * + * @param inputFiles The list of files given as input to the verifier, e.g. + * ["path/f1.c", "path/f2.c"]. + * @param inputFileHashes The SHA-256 hashes of all files in input_files, e.g. {"path/f1.c": 511..., + * "path/f2.c": f70...} + * @param specification The specification considered by the verifier; it uses the SV-COMP format + * given at https://sv-comp.sosy-lab.org/2023/rules.php. * @param dataModel The data model assumed for the input program. (ILP32 / LP64) - * @param language The programming language of the input files; the format currently supports only C. + * @param language The programming language of the input files; the format currently supports only + * C. */ -@Serializable data class Task( - @SerialName("input_files") - val inputFiles: List, - @SerialName("input_file_hashes") - val inputFileHashes: List, - val specification: String, - @SerialName("data_model") - val dataModel: DataModel, - val language: Language, +@Serializable +data class Task( + @SerialName("input_files") val inputFiles: List, + @SerialName("input_file_hashes") val inputFileHashes: List, + val specification: String, + @SerialName("data_model") val dataModel: DataModel, + val language: Language, ) -@Serializable enum class DataModel { - ILP32, - LP64, +@Serializable +enum class DataModel { + ILP32, + LP64, } -@Serializable enum class Language { - C +@Serializable +enum class Language { + C } /** - * @param segment A `segment` is a sequence of one or more waypoints. They are used to structure the waypoints into segments. Each `segment` is a sequence of zero or more waypoints with action `avoid` and exactly one waypoint of action `follow` at the end. A segment is called _final_ if it ends with the `target` waypoint and it is called _normal_ otherwise. items: type: object required: - waypoint properties: waypoint: type: object required: - type - action - location description: | The `waypoint` elements are the basic building block of violation witnesses. They have the form of simple restrictions on program executions. Technically, a waypoint is a mapping with four keys, namely type, location, constraint, and action. The values of the first three keys specify the requirement on a program execution to pass a waypoint: `type` describes the type of the requirement, `location` specifies the program location where the requirement is evaluated, and `constraint` gives the requirement itself and is not allowed for waypoints of type `function_enter` and `target`. The key `action` then states whether the executions represented by the witness should pass through the waypoint (value `follow`) or avoid it (value `avoid`). The format currently supports two possible values of type with the following meanings: - `assumption`: The location has to point to the beginning of a statement or a declaration inside a compound statement. A requirement of this type says that a given constraint is satisfied before the pointed statement or declaration inside a compound statement. The constraint is a mapping with two keys: `format` specifies the language of the assumption and `value` contains a side-effect-free assumption over variables in the current scope. The value of `format` is `c_expression` as C expressions are the only assumptions currently supported. In future, we plan to support also assumptions in ACSL. - `target`: This type of requirement can be used only with action `follow` and it marks the program location where the property is violated. More precisely, the location points at the first character of the statement or full expression whose evaluation is sequenced directly before the violation occurs, i.e., there is no other evaluation sequenced before the violation and the sequence point associated with the location. This also implies that it can only point to a function call if it calls a function of the C standard library - * @param invariant The key `invariant` is the basic building block of correctness witnesses. It is a mapping that describes one invariant. + * @param segment A `segment` is a sequence of one or more waypoints. They are used to structure the + * waypoints into segments. Each `segment` is a sequence of zero or more waypoints with action + * `avoid` and exactly one waypoint of action `follow` at the end. A segment is called _final_ if + * it ends with the `target` waypoint and it is called _normal_ otherwise. items: type: object + * required: - waypoint properties: waypoint: type: object required: - type - action - location + * description: | The `waypoint` elements are the basic building block of violation witnesses. + * They have the form of simple restrictions on program executions. Technically, a waypoint is a + * mapping with four keys, namely type, location, constraint, and action. The values of the first + * three keys specify the requirement on a program execution to pass a waypoint: `type` describes + * the type of the requirement, `location` specifies the program location where the requirement is + * evaluated, and `constraint` gives the requirement itself and is not allowed for waypoints of + * type `function_enter` and `target`. The key `action` then states whether the executions + * represented by the witness should pass through the waypoint (value `follow`) or avoid it (value + * `avoid`). The format currently supports two possible values of type with the following + * meanings: - `assumption`: The location has to point to the beginning of a statement or a + * declaration inside a compound statement. A requirement of this type says that a given + * constraint is satisfied before the pointed statement or declaration inside a compound + * statement. The constraint is a mapping with two keys: `format` specifies the language of the + * assumption and `value` contains a side-effect-free assumption over variables in the current + * scope. The value of `format` is `c_expression` as C expressions are the only assumptions + * currently supported. In future, we plan to support also assumptions in ACSL. - `target`: This + * type of requirement can be used only with action `follow` and it marks the program location + * where the property is violated. More precisely, the location points at the first character of + * the statement or full expression whose evaluation is sequenced directly before the violation + * occurs, i.e., there is no other evaluation sequenced before the violation and the sequence + * point associated with the location. This also implies that it can only point to a function call + * if it calls a function of the C standard library + * @param invariant The key `invariant` is the basic building block of correctness witnesses. It is + * a mapping that describes one invariant. */ -@Serializable data class ContentItem( - val segment: Segment? = null, - val invariant: Invariant? = null, -) +@Serializable +data class ContentItem(val segment: Segment? = null, val invariant: Invariant? = null) -@Serializable data class Segment( - val waypoint: Waypoint, -) +@Serializable data class Segment(val waypoint: Waypoint) /** - * The `waypoint` elements are the basic building block of violation witnesses. - * They have the form of simple restrictions on program executions. - * Technically, a waypoint is a mapping with four keys, namely type, location, constraint, and action. - * The values of the first three keys specify the requirement on a program execution to pass a waypoint: - * `type` describes the type of the requirement, - * `location` specifies the program location where the requirement is evaluated, and - * `constraint` gives the requirement itself and is not allowed for waypoints of type `function_enter` and `target`. - * The key `action` then states whether the executions represented by the witness should - * pass through the waypoint (value `follow`) or avoid it (value `avoid`). - * The format currently supports two possible values of type with the following meanings: + * The `waypoint` elements are the basic building block of violation witnesses. They have the form + * of simple restrictions on program executions. Technically, a waypoint is a mapping with four + * keys, namely type, location, constraint, and action. The values of the first three keys specify + * the requirement on a program execution to pass a waypoint: `type` describes the type of the + * requirement, `location` specifies the program location where the requirement is evaluated, and + * `constraint` gives the requirement itself and is not allowed for waypoints of type + * `function_enter` and `target`. The key `action` then states whether the executions represented by + * the witness should pass through the waypoint (value `follow`) or avoid it (value `avoid`). The + * format currently supports two possible values of type with the following meanings: + * - `assumption`: The location has to point to the beginning of a statement or a declaration inside + * a compound statement. A requirement of this type says that a given constraint is satisfied + * before the pointed statement or declaration inside a compound statement. The constraint is a + * mapping with two keys: `format` specifies the language of the assumption and `value` contains a + * side-effect-free assumption over variables in the current scope. The value of `format` is + * `c_expression` as C expressions are the only assumptions currently supported. In future, we + * plan to support also assumptions in ACSL. + * - `target`: This type of requirement can be used only with action `follow` and it marks the + * program location where the property is violated. More precisely, the location points at the + * first character of the statement or full expression whose evaluation is sequenced directly + * before the violation occurs, i.e., there is no other evaluation sequenced before the violation + * and the sequence point associated with the location. This also implies that it can only point + * to a function call if it calls a function of the C standard library that violates the property + * or if the function call itself is the property violation. The key constraint has to be omitted + * for type `target`. + * - `function_enter`: The location points to the right parenthesis after the function arguments at + * the call site and the requirement says that the called function is entered. The key constraint + * has to be omitted in this case. + * - `function_return`: Such a requirement says that a given function call has been evaluated and + * the returned value satisfies a given constraint. The location points to the right parenthesis + * after the function arguments at the call site. The constraint is a mapping with keys format and + * value. We currently support only ACSL expressions of the form `\result + * `, where `` is one of `==`, `!=`, `<=`, `<`, `>`, `>=` and + * `` is a constant expression. The value of format has to be `acsl_expression`. + * - `branching`: A requirement of this type says that a given branching is evaluated in a given + * way. The location points to a branching keyword like `if`, `while`, `switch`, or to the + * character `?` in the ternary operator (`?:`). The constraint is then a mapping with only one + * key value. For binary branchings, value can be either `true` or `false` saying whether the true + * branch is used or not. For the keyword switch, value holds an integer constant or default. The + * integer constant specifies the value of the controlling expression of the switch statement. The + * value default says that the value of this expression does not match any case of the switch with + * the potential exception of the default case. * - * - `assumption`: - * The location has to point to the beginning of a statement or a declaration inside a compound statement. - * A requirement of this type says that a given constraint is satisfied before the pointed statement - * or declaration inside a compound statement. - * The constraint is a mapping with two keys: `format` specifies the language of the assumption and - * `value` contains a side-effect-free assumption over variables in the current scope. - * The value of `format` is `c_expression` as C expressions are the only assumptions currently supported. - * In future, we plan to support also assumptions in ACSL. - * - `target`: - * This type of requirement can be used only with action `follow` and it marks the program location where the property is violated. - * More precisely, the location points at the first character of the statement or - * full expression whose evaluation is sequenced directly before the violation occurs, - * i.e., there is no other evaluation sequenced before the violation and the sequence point associated with the location. - * This also implies that it can only point to a function call if it calls a function of the C standard library - * that violates the property or if the function call itself is the property violation. - * The key constraint has to be omitted for type `target`. - * - `function_enter`: - * The location points to the right parenthesis after the function arguments at the call site and the requirement - * says that the called function is entered. The key constraint has to be omitted in this case. - * - `function_return`: - * Such a requirement says that a given function call has been evaluated and the returned - * value satisfies a given constraint. The location points to the right parenthesis after the - * function arguments at the call site. The constraint is a mapping with keys format and value. - * We currently support only ACSL expressions of the form `\result `, - * where `` is one of `==`, `!=`, `<=`, `<`, `>`, `>=` and `` is a constant expression. - * The value of format has to be `acsl_expression`. - * - `branching`: - * A requirement of this type says that a given branching is evaluated in a given way. - * The location points to a branching keyword like `if`, `while`, `switch`, or to the character `?` - * in the ternary operator (`?:`). The constraint is then a mapping with only one key value. - * For binary branchings, value can be either `true` or `false` saying whether the true branch - * is used or not. For the keyword switch, value holds an integer constant or default. The - * integer constant specifies the value of the controlling expression of the switch statement. - * The value default says that the value of this expression does not match any case of the - * switch with the potential exception of the default case. - * - * An `assumption` waypoint is evaluated at the sequence point - * immediately before the waypoint location. The waypoint is passed if - * the given constraint evaluates to true. A `branching` waypoint - * is evaluated at the sequence point immediately after evaluation of the - * controlling expression of the corresponding branching statement. The - * waypoint is passed if the resulting value of the controlling - * expression corresponds to the given constraint. A - * `function_enter` waypoint is evaluated at the sequence point - * immediately after evaluation of all arguments of the function - * call. The waypoint is passed without any additional constraint. A - * `function_return` waypoint is evaluated immediately after - * evaluation of the corresponding function call. The waypoint is passed - * if the returned value satisfies the given constraint. + * An `assumption` waypoint is evaluated at the sequence point immediately before the waypoint + * location. The waypoint is passed if the given constraint evaluates to true. A `branching` + * waypoint is evaluated at the sequence point immediately after evaluation of the controlling + * expression of the corresponding branching statement. The waypoint is passed if the resulting + * value of the controlling expression corresponds to the given constraint. A `function_enter` + * waypoint is evaluated at the sequence point immediately after evaluation of all arguments of the + * function call. The waypoint is passed without any additional constraint. A `function_return` + * waypoint is evaluated immediately after evaluation of the corresponding function call. The + * waypoint is passed if the returned value satisfies the given constraint. * * @param type - * @param constraint The constraint of the waypoint. A constraint is not allowed for type `target`. - * @param location The `location` is a mapping with mandatory keys file_name and line. All other keys are optional. If the location provides an inconsistent information (e.g., identifier specifies a function that is not called at the given column on the given line ), the witness is syntactically invalid. - * @param action Action `follow` means that the waypoint should be passed through. Action `avoid` means that the waypoint should be avoided. + * @param constraint The constraint of the waypoint. A constraint is not allowed for type `target`. + * @param location The `location` is a mapping with mandatory keys file_name and line. All other + * keys are optional. If the location provides an inconsistent information (e.g., identifier + * specifies a function that is not called at the given column on the given line ), the witness is + * syntactically invalid. + * @param action Action `follow` means that the waypoint should be passed through. Action `avoid` + * means that the waypoint should be avoided. */ - -@Serializable data class Waypoint( - val type: WaypointType, - val constraint: Constraint? = null, - val location: Location, - val action: Action, +@Serializable +data class Waypoint( + val type: WaypointType, + val constraint: Constraint? = null, + val location: Location, + val action: Action, ) -@Serializable enum class WaypointType { - @SerialName("assumption") ASSUMPTION, - @SerialName("target") TARGET, - @SerialName("function_enter") FUNCTION_ENTER, - @SerialName("function_return") FUNCTION_RETURN, - @SerialName("branching") BRANCHING, +@Serializable +enum class WaypointType { + @SerialName("assumption") ASSUMPTION, + @SerialName("target") TARGET, + @SerialName("function_enter") FUNCTION_ENTER, + @SerialName("function_return") FUNCTION_RETURN, + @SerialName("branching") BRANCHING, } /** * The constraint of the waypoint. A constraint is not allowed for type `target`. + * * @param value * @param format */ -@Serializable data class Constraint( - val value: String, - val format: Format? = null, -) +@Serializable data class Constraint(val value: String, val format: Format? = null) -@Serializable enum class Format { - @SerialName("c_expression") C_EXPRESSION, - @SerialName("acsl_expression") ACSL_EXPRESSION, +@Serializable +enum class Format { + @SerialName("c_expression") C_EXPRESSION, + @SerialName("acsl_expression") ACSL_EXPRESSION, } /** - * The `location` is a mapping with mandatory keys file_name and line. All other keys are optional. If the location provides an inconsistent information (e.g., identifier specifies a function that is not called at the given column on the given line ), the witness is syntactically invalid. - * @param fileName The name of the file of the location + * The `location` is a mapping with mandatory keys file_name and line. All other keys are optional. + * If the location provides an inconsistent information (e.g., identifier specifies a function that + * is not called at the given column on the given line ), the witness is syntactically invalid. + * + * @param fileName The name of the file of the location * @param line The line number pf the program location in the file. - * @param column The key `column` specifies the column number of the location, i.e., the position of the `column`-th character in the line that the location points to (value 1 is the position of the first character). If the column is not given, then it is interpreted as the leftmost suitable position on the line, where suitability is given by `type`. - * @param function The key `function` gives the name of the function containing the location. It is usually determined by the `file_name` and `line`, but the information can improve human readability of the witness. + * @param column The key `column` specifies the column number of the location, i.e., the position of + * the `column`-th character in the line that the location points to (value 1 is the position of + * the first character). If the column is not given, then it is interpreted as the leftmost + * suitable position on the line, where suitability is given by `type`. + * @param function The key `function` gives the name of the function containing the location. It is + * usually determined by the `file_name` and `line`, but the information can improve human + * readability of the witness. */ -@Serializable data class Location( - @SerialName("file_name") - val fileName: String, - val line: Int, - val column: Int? = null, - val function: String? = null, +@Serializable +data class Location( + @SerialName("file_name") val fileName: String, + val line: Int, + val column: Int? = null, + val function: String? = null, ) /** - * Action `follow` means that the waypoint should be passed through. - * Action `avoid` means that the waypoint should be avoided. + * Action `follow` means that the waypoint should be passed through. Action `avoid` means that the + * waypoint should be avoided. */ -@Serializable enum class Action { - @SerialName("follow") FOLLOW, - @SerialName("avoid") AVOID, +@Serializable +enum class Action { + @SerialName("follow") FOLLOW, + @SerialName("avoid") AVOID, } -@Serializable data class Invariant( - val type: InvariantType, - val location: Location, - val value: String, - val format: Format, +@Serializable +data class Invariant( + val type: InvariantType, + val location: Location, + val value: String, + val format: Format, ) -@Serializable enum class InvariantType { - @SerialName("loop_invariant") LOOP_INVARIANT, - @SerialName("location_invariant") LOCATION_INVARIANT, -} \ No newline at end of file +@Serializable +enum class InvariantType { + @SerialName("loop_invariant") LOOP_INVARIANT, + @SerialName("location_invariant") LOCATION_INVARIANT, +} diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt index 8e0c2b4d39..75d179405f 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt @@ -18,262 +18,303 @@ package hu.bme.mit.theta.xcfa.cli import com.google.common.base.Preconditions.checkState import hu.bme.mit.theta.frontend.chc.ChcFrontend import hu.bme.mit.theta.xcfa.cli.XcfaCli.Companion.main +import java.util.stream.Stream +import kotlin.io.path.createTempDirectory import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.MethodSource -import java.io.File -import java.util.stream.Stream -import kotlin.io.path.createTempDirectory class XcfaCliParseTest { - companion object { + companion object { - @JvmStatic - fun cFiles(): Stream { - return Stream.of( - Arguments.of("/c/dekker.i"), - Arguments.of("/c/litmustest/singlethread/00assignment.c"), - Arguments.of("/c/litmustest/singlethread/01cast.c"), - Arguments.of("/c/litmustest/singlethread/02types.c"), - Arguments.of("/c/litmustest/singlethread/03bitwise.c"), - Arguments.of("/c/litmustest/singlethread/04real.c"), - Arguments.of("/c/litmustest/singlethread/05math.c"), - Arguments.of("/c/litmustest/singlethread/06arrays.c"), - Arguments.of("/c/litmustest/singlethread/07arrayinit.c"), - Arguments.of("/c/litmustest/singlethread/08vararray.c"), -// Arguments.of("/c/litmustest/singlethread/09struct.c"), -// Arguments.of("/c/litmustest/singlethread/10ptr.c"), -// Arguments.of("/c/litmustest/singlethread/11ptrs.c"), -// Arguments.of("/c/litmustest/singlethread/12ptrtypes.c"), - Arguments.of("/c/litmustest/singlethread/13typedef.c"), - Arguments.of("/c/litmustest/singlethread/14ushort.c"), - Arguments.of("/c/litmustest/singlethread/15addition.c"), - Arguments.of("/c/litmustest/singlethread/16loop.c"), - Arguments.of("/c/litmustest/singlethread/17recursive.c"), - Arguments.of("/c/litmustest/singlethread/18multithread.c"), - Arguments.of("/c/litmustest/singlethread/19dportest.c"), - Arguments.of("/c/litmustest/singlethread/20testinline.c"), - Arguments.of("/c/litmustest/singlethread/21namecollision.c"), - Arguments.of("/c/litmustest/singlethread/22nondet.c"), - Arguments.of("/c/litmustest/singlethread/23overflow.c"), - Arguments.of("/c/litmustest/singlethread/25malloc.c"), - ) - } - - @JvmStatic - fun simpleCFiles(): Stream { - return Stream.of( - Arguments.of("/c/litmustest/singlethread/00assignment.c"), - Arguments.of("/c/litmustest/singlethread/01cast.c"), - Arguments.of("/c/litmustest/singlethread/02types.c"), - Arguments.of("/c/litmustest/singlethread/03bitwise.c"), - Arguments.of("/c/litmustest/singlethread/14ushort.c"), - Arguments.of("/c/litmustest/singlethread/15addition.c"), - Arguments.of("/c/litmustest/singlethread/16loop.c"), - Arguments.of("/c/litmustest/singlethread/17recursive.c"), - Arguments.of("/c/litmustest/singlethread/21namecollision.c"), - Arguments.of("/c/litmustest/singlethread/22nondet.c"), - Arguments.of("/c/litmustest/singlethread/23overflow.c"), - ) - } + @JvmStatic + fun cFiles(): Stream { + return Stream.of( + Arguments.of("/c/dekker.i"), + Arguments.of("/c/litmustest/singlethread/00assignment.c"), + Arguments.of("/c/litmustest/singlethread/01cast.c"), + Arguments.of("/c/litmustest/singlethread/02types.c"), + Arguments.of("/c/litmustest/singlethread/03bitwise.c"), + Arguments.of("/c/litmustest/singlethread/04real.c"), + Arguments.of("/c/litmustest/singlethread/05math.c"), + Arguments.of("/c/litmustest/singlethread/06arrays.c"), + Arguments.of("/c/litmustest/singlethread/07arrayinit.c"), + Arguments.of("/c/litmustest/singlethread/08vararray.c"), + // Arguments.of("/c/litmustest/singlethread/09struct.c"), + // Arguments.of("/c/litmustest/singlethread/10ptr.c"), + // Arguments.of("/c/litmustest/singlethread/11ptrs.c"), + // Arguments.of("/c/litmustest/singlethread/12ptrtypes.c"), + Arguments.of("/c/litmustest/singlethread/13typedef.c"), + Arguments.of("/c/litmustest/singlethread/14ushort.c"), + Arguments.of("/c/litmustest/singlethread/15addition.c"), + Arguments.of("/c/litmustest/singlethread/16loop.c"), + Arguments.of("/c/litmustest/singlethread/17recursive.c"), + Arguments.of("/c/litmustest/singlethread/18multithread.c"), + Arguments.of("/c/litmustest/singlethread/19dportest.c"), + Arguments.of("/c/litmustest/singlethread/20testinline.c"), + Arguments.of("/c/litmustest/singlethread/21namecollision.c"), + Arguments.of("/c/litmustest/singlethread/22nondet.c"), + Arguments.of("/c/litmustest/singlethread/23overflow.c"), + Arguments.of("/c/litmustest/singlethread/25malloc.c"), + ) + } - @JvmStatic - fun llvmFiles(): Stream { - return Stream.of( - Arguments.of("/c/dekker.i"), - Arguments.of("/c/litmustest/singlethread/00assignment.c"), -// Arguments.of("/c/litmustest/singlethread/01cast.c"), - Arguments.of("/c/litmustest/singlethread/02types.c"), - Arguments.of("/c/litmustest/singlethread/03bitwise.c"), -// Arguments.of("/c/litmustest/singlethread/04real.c"), -// Arguments.of("/c/litmustest/singlethread/05math.c"), - Arguments.of("/c/litmustest/singlethread/06arrays.c"), - Arguments.of("/c/litmustest/singlethread/07arrayinit.c"), - Arguments.of("/c/litmustest/singlethread/08vararray.c"), -// Arguments.of("/c/litmustest/singlethread/09struct.c"), -// Arguments.of("/c/litmustest/singlethread/10ptr.c"), -// Arguments.of("/c/litmustest/singlethread/11ptrs.c"), -// Arguments.of("/c/litmustest/singlethread/12ptrtypes.c"), - Arguments.of("/c/litmustest/singlethread/13typedef.c"), - Arguments.of("/c/litmustest/singlethread/14ushort.c"), - Arguments.of("/c/litmustest/singlethread/15addition.c"), - Arguments.of("/c/litmustest/singlethread/16loop.c"), -// Arguments.of("/c/litmustest/singlethread/17recursive.c"), - Arguments.of("/c/litmustest/singlethread/18multithread.c"), - Arguments.of("/c/litmustest/singlethread/19dportest.c"), - Arguments.of("/c/litmustest/singlethread/20testinline.c"), - Arguments.of("/c/litmustest/singlethread/21namecollision.c"), -// Arguments.of("/c/litmustest/singlethread/22nondet.c"), - Arguments.of("/c/litmustest/singlethread/23overflow.c"), - ) - } + @JvmStatic + fun simpleCFiles(): Stream { + return Stream.of( + Arguments.of("/c/litmustest/singlethread/00assignment.c"), + Arguments.of("/c/litmustest/singlethread/01cast.c"), + Arguments.of("/c/litmustest/singlethread/02types.c"), + Arguments.of("/c/litmustest/singlethread/03bitwise.c"), + Arguments.of("/c/litmustest/singlethread/14ushort.c"), + Arguments.of("/c/litmustest/singlethread/15addition.c"), + Arguments.of("/c/litmustest/singlethread/16loop.c"), + Arguments.of("/c/litmustest/singlethread/17recursive.c"), + Arguments.of("/c/litmustest/singlethread/21namecollision.c"), + Arguments.of("/c/litmustest/singlethread/22nondet.c"), + Arguments.of("/c/litmustest/singlethread/23overflow.c"), + ) + } - @JvmStatic - fun chcFiles(): Stream { - return Stream.of( - Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), - Arguments.of("/chc/chc-LIA-Lin-Arrays_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), - Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), - Arguments.of("/chc/chc-LIA_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), + @JvmStatic + fun llvmFiles(): Stream { + return Stream.of( + Arguments.of("/c/dekker.i"), + Arguments.of("/c/litmustest/singlethread/00assignment.c"), + // Arguments.of("/c/litmustest/singlethread/01cast.c"), + Arguments.of("/c/litmustest/singlethread/02types.c"), + Arguments.of("/c/litmustest/singlethread/03bitwise.c"), + // Arguments.of("/c/litmustest/singlethread/04real.c"), + // Arguments.of("/c/litmustest/singlethread/05math.c"), + Arguments.of("/c/litmustest/singlethread/06arrays.c"), + Arguments.of("/c/litmustest/singlethread/07arrayinit.c"), + Arguments.of("/c/litmustest/singlethread/08vararray.c"), + // Arguments.of("/c/litmustest/singlethread/09struct.c"), + // Arguments.of("/c/litmustest/singlethread/10ptr.c"), + // Arguments.of("/c/litmustest/singlethread/11ptrs.c"), + // Arguments.of("/c/litmustest/singlethread/12ptrtypes.c"), + Arguments.of("/c/litmustest/singlethread/13typedef.c"), + Arguments.of("/c/litmustest/singlethread/14ushort.c"), + Arguments.of("/c/litmustest/singlethread/15addition.c"), + Arguments.of("/c/litmustest/singlethread/16loop.c"), + // Arguments.of("/c/litmustest/singlethread/17recursive.c"), + Arguments.of("/c/litmustest/singlethread/18multithread.c"), + Arguments.of("/c/litmustest/singlethread/19dportest.c"), + Arguments.of("/c/litmustest/singlethread/20testinline.c"), + Arguments.of("/c/litmustest/singlethread/21namecollision.c"), + // Arguments.of("/c/litmustest/singlethread/22nondet.c"), + Arguments.of("/c/litmustest/singlethread/23overflow.c"), + ) + } -// Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.FORWARD), // nonlin - Arguments.of("/chc/chc-LIA-Lin-Arrays_000.smt2", ChcFrontend.ChcTransformation.FORWARD), - Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.FORWARD), -// Arguments.of("/chc/chc-LIA_000.smt2", ChcFrontend.ChcTransformation.FORWARD), // nonlin + @JvmStatic + fun chcFiles(): Stream { + return Stream.of( + Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), + Arguments.of("/chc/chc-LIA-Lin-Arrays_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), + Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), + Arguments.of("/chc/chc-LIA_000.smt2", ChcFrontend.ChcTransformation.PORTFOLIO), - Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), - Arguments.of("/chc/chc-LIA-Lin-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), - Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), - Arguments.of("/chc/chc-LIA_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), - ) - } + // Arguments.of("/chc/chc-LIA-Arrays_000.smt2", + // ChcFrontend.ChcTransformation.FORWARD), // nonlin + Arguments.of("/chc/chc-LIA-Lin-Arrays_000.smt2", ChcFrontend.ChcTransformation.FORWARD), + Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.FORWARD), + // Arguments.of("/chc/chc-LIA_000.smt2", + // ChcFrontend.ChcTransformation.FORWARD), // nonlin - @JvmStatic - fun dslFiles(): Stream { - return Stream.of( - Arguments.of("/dsl/async.xcfa.kts"), - Arguments.of("/dsl/sync.xcfa.kts"), - ) - } + Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), + Arguments.of("/chc/chc-LIA-Lin-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), + Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), + Arguments.of("/chc/chc-LIA_000.smt2", ChcFrontend.ChcTransformation.BACKWARD), + ) + } - @JvmStatic - fun jsonFiles(): Stream { - return Stream.of( - Arguments.of("/json/00assignment.c.json"), - Arguments.of("/json/01cast.c.json"), - Arguments.of("/json/02types.c.json"), - Arguments.of("/json/03bitwise.c.json"), - Arguments.of("/json/04real.c.json"), - Arguments.of("/json/05math.c.json"), - Arguments.of("/json/06arrays.c.json"), - Arguments.of("/json/07arrayinit.c.json"), - Arguments.of("/json/08vararray.c.json"), -// Arguments.of("/json/09struct.c.json"), -// Arguments.of("/json/10ptr.c.json"), -// Arguments.of("/json/11ptrs.c.json"), -// Arguments.of("/json/12ptrtypes.c.json"), - Arguments.of("/json/13typedef.c.json"), - Arguments.of("/json/14ushort.c.json"), - Arguments.of("/json/15addition.c.json"), - Arguments.of("/json/16loop.c.json"), - Arguments.of("/json/17recursive.c.json"), - Arguments.of("/json/18multithread.c.json"), - Arguments.of("/json/19dportest.c.json"), - Arguments.of("/json/20testinline.c.json"), - Arguments.of("/json/21namecollision.c.json"), - Arguments.of("/json/22nondet.c.json"), - Arguments.of("/json/23overflow.c.json"), - ) - } + @JvmStatic + fun dslFiles(): Stream { + return Stream.of(Arguments.of("/dsl/async.xcfa.kts"), Arguments.of("/dsl/sync.xcfa.kts")) } - @ParameterizedTest - @MethodSource("cFiles") - fun testCParse(filePath: String) { - main(arrayOf( - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", "--stacktrace", - "--debug" - )) + @JvmStatic + fun jsonFiles(): Stream { + return Stream.of( + Arguments.of("/json/00assignment.c.json"), + Arguments.of("/json/01cast.c.json"), + Arguments.of("/json/02types.c.json"), + Arguments.of("/json/03bitwise.c.json"), + Arguments.of("/json/04real.c.json"), + Arguments.of("/json/05math.c.json"), + Arguments.of("/json/06arrays.c.json"), + Arguments.of("/json/07arrayinit.c.json"), + Arguments.of("/json/08vararray.c.json"), + // Arguments.of("/json/09struct.c.json"), + // Arguments.of("/json/10ptr.c.json"), + // Arguments.of("/json/11ptrs.c.json"), + // Arguments.of("/json/12ptrtypes.c.json"), + Arguments.of("/json/13typedef.c.json"), + Arguments.of("/json/14ushort.c.json"), + Arguments.of("/json/15addition.c.json"), + Arguments.of("/json/16loop.c.json"), + Arguments.of("/json/17recursive.c.json"), + Arguments.of("/json/18multithread.c.json"), + Arguments.of("/json/19dportest.c.json"), + Arguments.of("/json/20testinline.c.json"), + Arguments.of("/json/21namecollision.c.json"), + Arguments.of("/json/22nondet.c.json"), + Arguments.of("/json/23overflow.c.json"), + ) } + } -// @ParameterizedTest -// @MethodSource("llvmFiles") -// fun testLLVMParse(filePath: String) { -// if (OsHelper.getOs() == OsHelper.OperatingSystem.LINUX) { -// main(arrayOf( -// "--input-type", "LLVM", -// "--input", javaClass.getResource(filePath)!!.path, -// "--backend", "NONE", "--stacktrace" -// )) -// } -// } + @ParameterizedTest + @MethodSource("cFiles") + fun testCParse(filePath: String) { + main( + arrayOf( + "--input-type", + "C", + "--input", + javaClass.getResource(filePath)!!.path, + "--backend", + "NONE", + "--stacktrace", + "--debug", + ) + ) + } - @ParameterizedTest - @MethodSource("chcFiles") - fun testCHCParse(filePath: String, chcTransformation: ChcFrontend.ChcTransformation) { - main(arrayOf( - "--input-type", "CHC", - "--chc-transformation", chcTransformation.toString(), - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - )) - } + // @ParameterizedTest + // @MethodSource("llvmFiles") + // fun testLLVMParse(filePath: String) { + // if (OsHelper.getOs() == OsHelper.OperatingSystem.LINUX) { + // main(arrayOf( + // "--input-type", "LLVM", + // "--input", javaClass.getResource(filePath)!!.path, + // "--backend", "NONE", "--stacktrace" + // )) + // } + // } - @ParameterizedTest - @MethodSource("dslFiles") - fun testDSLParse(filePath: String) { - main(arrayOf( - "--input-type", "DSL", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - )) - } + @ParameterizedTest + @MethodSource("chcFiles") + fun testCHCParse(filePath: String, chcTransformation: ChcFrontend.ChcTransformation) { + main( + arrayOf( + "--input-type", + "CHC", + "--chc-transformation", + chcTransformation.toString(), + "--input", + javaClass.getResource(filePath)!!.path, + "--backend", + "NONE", + "--stacktrace", + "--debug", + ) + ) + } - @ParameterizedTest - @MethodSource("jsonFiles") - fun testJSONParse(filePath: String) { - main(arrayOf( - "--input-type", "JSON", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - )) - } + @ParameterizedTest + @MethodSource("dslFiles") + fun testDSLParse(filePath: String) { + main( + arrayOf( + "--input-type", + "DSL", + "--input", + javaClass.getResource(filePath)!!.path, + "--backend", + "NONE", + "--stacktrace", + "--debug", + ) + ) + } - @ParameterizedTest - @MethodSource("cFiles") - fun testJSONParseRoundTrip(filePath: String) { - val temp = createTempDirectory() - main(arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--output-directory", temp.toAbsolutePath().toString(), - "--debug" - )) - val xcfaJson = temp.resolve("xcfa.json").toFile() - main(arrayOf( - "--input-type", "JSON", - "--input", xcfaJson.absolutePath.toString(), - "--backend", "NONE", - "--stacktrace", - "--debug" - )) - temp.toFile().deleteRecursively() - } + @ParameterizedTest + @MethodSource("jsonFiles") + fun testJSONParse(filePath: String) { + main( + arrayOf( + "--input-type", + "JSON", + "--input", + javaClass.getResource(filePath)!!.path, + "--backend", + "NONE", + "--stacktrace", + "--debug", + ) + ) + } - @ParameterizedTest - @MethodSource("simpleCFiles") - fun testCParseRoundTrip(filePath: String) { - val temp = createTempDirectory() - main(arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--output-directory", temp.toAbsolutePath().toString(), - "--debug" - )) - val xcfaC = temp.resolve("xcfa.c").toFile() - checkState(xcfaC.exists(), "File does not exist: $xcfaC") - main(arrayOf( - "--input-type", "C", - "--input", xcfaC.absolutePath.toString(), - "--backend", "NONE", - "--stacktrace", - "--debug" - )) - temp.toFile().deleteRecursively() - } + @ParameterizedTest + @MethodSource("cFiles") + fun testJSONParseRoundTrip(filePath: String) { + val temp = createTempDirectory() + main( + arrayOf( + "--enable-output", + "--input-type", + "C", + "--input", + javaClass.getResource(filePath)!!.path, + "--backend", + "NONE", + "--stacktrace", + "--output-directory", + temp.toAbsolutePath().toString(), + "--debug", + ) + ) + val xcfaJson = temp.resolve("xcfa.json").toFile() + main( + arrayOf( + "--input-type", + "JSON", + "--input", + xcfaJson.absolutePath.toString(), + "--backend", + "NONE", + "--stacktrace", + "--debug", + ) + ) + temp.toFile().deleteRecursively() + } + @ParameterizedTest + @MethodSource("simpleCFiles") + fun testCParseRoundTrip(filePath: String) { + val temp = createTempDirectory() + main( + arrayOf( + "--enable-output", + "--input-type", + "C", + "--input", + javaClass.getResource(filePath)!!.path, + "--backend", + "NONE", + "--stacktrace", + "--output-directory", + temp.toAbsolutePath().toString(), + "--debug", + ) + ) + val xcfaC = temp.resolve("xcfa.c").toFile() + checkState(xcfaC.exists(), "File does not exist: $xcfaC") + main( + arrayOf( + "--input-type", + "C", + "--input", + xcfaC.absolutePath.toString(), + "--backend", + "NONE", + "--stacktrace", + "--debug", + ) + ) + temp.toFile().deleteRecursively() + } } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt index 5ae3925c3e..bc39de1553 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt @@ -16,14 +16,14 @@ package hu.bme.mit.theta.xcfa.cli import hu.bme.mit.theta.xcfa.cli.XcfaCli.Companion.main -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.Arguments -import org.junit.jupiter.params.provider.MethodSource import java.util.stream.Stream import kotlin.io.path.absolutePathString import kotlin.io.path.createTempDirectory import kotlin.io.path.exists +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource data class WitnessEdge( val startlineRange: Pair?, diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt index f157011728..6744a352b0 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/YamlParseTest.kt @@ -13,60 +13,56 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli import com.charleskorn.kaml.Yaml import hu.bme.mit.theta.xcfa.cli.witnesses.* +import java.util.* import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test -import java.util.* class YamlParseTest { - @Test - fun serialize() { - val witness = YamlWitness( - entryType = EntryType.VIOLATION, - metadata = Metadata( - formatVersion = "2.0", - uuid = UUID.randomUUID().toString(), - creationTime = getIsoDate(), - producer = Producer( - name = "test", - version = "1.0.0", - ), - task = Task( - inputFiles = listOf("example.c"), - inputFileHashes = listOf("hash"), - specification = "unreach_call", - dataModel = DataModel.LP64, - language = Language.C, + @Test + fun serialize() { + val witness = + YamlWitness( + entryType = EntryType.VIOLATION, + metadata = + Metadata( + formatVersion = "2.0", + uuid = UUID.randomUUID().toString(), + creationTime = getIsoDate(), + producer = Producer(name = "test", version = "1.0.0"), + task = + Task( + inputFiles = listOf("example.c"), + inputFileHashes = listOf("hash"), + specification = "unreach_call", + dataModel = DataModel.LP64, + language = Language.C, + ), + ), + content = + listOf( + ContentItem( + Segment( + Waypoint( + type = WaypointType.ASSUMPTION, + constraint = Constraint(value = "1 < x", format = Format.C_EXPRESSION), + location = Location(fileName = "example.c", line = 15), + action = Action.FOLLOW, ) - ), - content = listOf( - ContentItem( - Segment(Waypoint( - type = WaypointType.ASSUMPTION, - constraint = Constraint( - value = "1 < x", - format = Format.C_EXPRESSION, - ), - location = Location( - fileName = "example.c", - line = 15, - ), - action = Action.FOLLOW, - )) - ), - ), - ) + ) + ) + ), + ) - val result = WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness) + val result = WitnessYamlConfig.encodeToString(YamlWitness.serializer(), witness) - System.err.println(result) + System.err.println(result) - val parsedPack = Yaml.default.decodeFromString(YamlWitness.serializer(), result) + val parsedPack = Yaml.default.decodeFromString(YamlWitness.serializer(), result) - Assertions.assertEquals(witness, parsedPack) - } -} \ No newline at end of file + Assertions.assertEquals(witness, parsedPack) + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt index f4a5801ad3..4c7c6673ef 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.gson import com.google.gson.Gson @@ -29,183 +28,199 @@ import java.util.* class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { - private lateinit var gson: Gson - override fun write(writer: JsonWriter, value: XCFA) { - initGson() - writer.beginObject() - writer.name("name").value(value.name) - //vars - writer.name("vars") - gson.toJson(gson.toJsonTree(value.vars), writer) - - //procedures - writer.name("procedures").beginArray() - for (xcfaProcedure in value.procedures) { - writer.beginObject() - writer.name("name").value(xcfaProcedure.name) - writer.name("params") - gson.toJson(gson.toJsonTree(xcfaProcedure.params), writer) - writer.name("vars") - gson.toJson(gson.toJsonTree(xcfaProcedure.vars), writer) - writer.name("locs") - gson.toJson(gson.toJsonTree(xcfaProcedure.locs), writer) - writer.name("edges") - writer.beginArray().also { - xcfaProcedure.edges.forEach { - writer.beginObject() - .name("source").value(it.source.name) - .name("target").value(it.target.name) - .name("label") - gson.toJson(gson.toJsonTree(it.label), writer) - writer.name("metadata") - gson.toJson(gson.toJsonTree(it.metadata), writer) - writer.endObject() - } - }.endArray() - - writer.endObject() - } - writer.endArray() - - //initProcedures - writer.name("initProcedures").beginArray() - value.initProcedures.forEach { - writer.beginObject() - writer.name("params") - gson.toJson(gson.toJsonTree(it.second), writer) - writer.name("procedure").value(it.first.name) + private lateinit var gson: Gson + + override fun write(writer: JsonWriter, value: XCFA) { + initGson() + writer.beginObject() + writer.name("name").value(value.name) + // vars + writer.name("vars") + gson.toJson(gson.toJsonTree(value.vars), writer) + + // procedures + writer.name("procedures").beginArray() + for (xcfaProcedure in value.procedures) { + writer.beginObject() + writer.name("name").value(xcfaProcedure.name) + writer.name("params") + gson.toJson(gson.toJsonTree(xcfaProcedure.params), writer) + writer.name("vars") + gson.toJson(gson.toJsonTree(xcfaProcedure.vars), writer) + writer.name("locs") + gson.toJson(gson.toJsonTree(xcfaProcedure.locs), writer) + writer.name("edges") + writer + .beginArray() + .also { + xcfaProcedure.edges.forEach { + writer + .beginObject() + .name("source") + .value(it.source.name) + .name("target") + .value(it.target.name) + .name("label") + gson.toJson(gson.toJsonTree(it.label), writer) + writer.name("metadata") + gson.toJson(gson.toJsonTree(it.metadata), writer) writer.endObject() + } } - writer.endArray() + .endArray() - writer.endObject() + writer.endObject() } - - override fun read(reader: JsonReader): XCFA { - initGson() - - reader.beginObject() - lateinit var name: String - lateinit var vars: Set - lateinit var xcfaProcedures: Map - lateinit var initProcedures: List>>> - - val varsType = object : TypeToken>() {}.type - - lateinit var xcfa: XCFA - while (reader.peek() != JsonToken.END_OBJECT) { - val nextName = reader.nextName() - when (nextName) { - "name" -> name = reader.nextString() - "vars" -> vars = gson.fromJson(reader, varsType) - "procedures" -> { - xcfa = XCFA(name, vars) - xcfaProcedures = parseProcedures(reader, xcfa) - } - - "initProcedures" -> initProcedures = parseInitProcedures(reader, xcfaProcedures) - } + writer.endArray() + + // initProcedures + writer.name("initProcedures").beginArray() + value.initProcedures.forEach { + writer.beginObject() + writer.name("params") + gson.toJson(gson.toJsonTree(it.second), writer) + writer.name("procedure").value(it.first.name) + writer.endObject() + } + writer.endArray() + + writer.endObject() + } + + override fun read(reader: JsonReader): XCFA { + initGson() + + reader.beginObject() + lateinit var name: String + lateinit var vars: Set + lateinit var xcfaProcedures: Map + lateinit var initProcedures: List>>> + + val varsType = object : TypeToken>() {}.type + + lateinit var xcfa: XCFA + while (reader.peek() != JsonToken.END_OBJECT) { + val nextName = reader.nextName() + when (nextName) { + "name" -> name = reader.nextString() + "vars" -> vars = gson.fromJson(reader, varsType) + "procedures" -> { + xcfa = XCFA(name, vars) + xcfaProcedures = parseProcedures(reader, xcfa) } - reader.endObject() - return xcfa.recreate(xcfaProcedures.values.toSet(), initProcedures) + "initProcedures" -> initProcedures = parseInitProcedures(reader, xcfaProcedures) + } } - - private fun parseInitProcedures( - reader: JsonReader, - procedures: Map): List>>> { - reader.beginArray() - val ret = ArrayList>>>() - val paramsType = object : TypeToken>>() {}.type - while (reader.peek() != JsonToken.END_ARRAY) { - reader.beginObject() - lateinit var params: List> - lateinit var procedure: XcfaProcedure - while (reader.peek() != JsonToken.END_OBJECT) { - when (reader.nextName()) { - "params" -> params = gson.fromJson(reader, paramsType) - "procedure" -> procedure = checkNotNull(procedures[reader.nextString()]) - } - } - ret.add(Pair(procedure, params)) - reader.endObject() + reader.endObject() + + return xcfa.recreate(xcfaProcedures.values.toSet(), initProcedures) + } + + private fun parseInitProcedures( + reader: JsonReader, + procedures: Map, + ): List>>> { + reader.beginArray() + val ret = ArrayList>>>() + val paramsType = object : TypeToken>>() {}.type + while (reader.peek() != JsonToken.END_ARRAY) { + reader.beginObject() + lateinit var params: List> + lateinit var procedure: XcfaProcedure + while (reader.peek() != JsonToken.END_OBJECT) { + when (reader.nextName()) { + "params" -> params = gson.fromJson(reader, paramsType) + "procedure" -> procedure = checkNotNull(procedures[reader.nextString()]) } - reader.endArray() - return ret + } + ret.add(Pair(procedure, params)) + reader.endObject() } - - private fun parseProcedures(reader: JsonReader, xcfa: XCFA): Map { - reader.beginArray() - val ret = LinkedHashMap() - val paramsType = object : TypeToken, ParamDirection>>>() {}.type - val varsType = object : TypeToken>>() {}.type - val locsType = object : TypeToken>() {}.type - val labelType = object : TypeToken() {}.type - val metadataType = object : TypeToken() {}.type - - while (reader.peek() != JsonToken.END_ARRAY) { - reader.beginObject() - lateinit var name: String - lateinit var params: List, ParamDirection>> - lateinit var vars: Set> - lateinit var locs: Map - val edges: MutableSet = LinkedHashSet() - lateinit var initLoc: XcfaLocation - var finalLoc: XcfaLocation? = null - var errorLoc: XcfaLocation? = null - - while (reader.peek() != JsonToken.END_OBJECT) { + reader.endArray() + return ret + } + + private fun parseProcedures(reader: JsonReader, xcfa: XCFA): Map { + reader.beginArray() + val ret = LinkedHashMap() + val paramsType = object : TypeToken, ParamDirection>>>() {}.type + val varsType = object : TypeToken>>() {}.type + val locsType = object : TypeToken>() {}.type + val labelType = object : TypeToken() {}.type + val metadataType = object : TypeToken() {}.type + + while (reader.peek() != JsonToken.END_ARRAY) { + reader.beginObject() + lateinit var name: String + lateinit var params: List, ParamDirection>> + lateinit var vars: Set> + lateinit var locs: Map + val edges: MutableSet = LinkedHashSet() + lateinit var initLoc: XcfaLocation + var finalLoc: XcfaLocation? = null + var errorLoc: XcfaLocation? = null + + while (reader.peek() != JsonToken.END_OBJECT) { + when (reader.nextName()) { + "name" -> name = reader.nextString() + "params" -> params = gson.fromJson(reader, paramsType) + "vars" -> vars = gson.fromJson(reader, varsType) + "locs" -> { + val locations: Set = gson.fromJson(reader, locsType) + locations.forEach { + if (it.error) errorLoc = it + if (it.initial) initLoc = it + if (it.final) finalLoc = it + } + locs = locations.associateBy { it.name } + } + + "edges" -> { + reader.beginArray() + while (reader.peek() != JsonToken.END_ARRAY) { + reader.beginObject() + lateinit var source: XcfaLocation + lateinit var target: XcfaLocation + lateinit var label: XcfaLabel + lateinit var metadata: MetaData + while (reader.peek() != JsonToken.END_OBJECT) { when (reader.nextName()) { - "name" -> name = reader.nextString() - "params" -> params = gson.fromJson(reader, paramsType) - "vars" -> vars = gson.fromJson(reader, varsType) - "locs" -> { - val locations: Set = gson.fromJson(reader, locsType) - locations.forEach { - if (it.error) errorLoc = it - if (it.initial) initLoc = it - if (it.final) finalLoc = it - } - locs = locations.associateBy { it.name } - } - - "edges" -> { - reader.beginArray() - while (reader.peek() != JsonToken.END_ARRAY) { - reader.beginObject() - lateinit var source: XcfaLocation - lateinit var target: XcfaLocation - lateinit var label: XcfaLabel - lateinit var metadata: MetaData - while (reader.peek() != JsonToken.END_OBJECT) { - when (reader.nextName()) { - "source" -> source = checkNotNull(locs[reader.nextString()]) - "target" -> target = checkNotNull(locs[reader.nextString()]) - "label" -> label = gson.fromJson(reader, labelType) - "metadata" -> metadata = gson.fromJson(reader, metadataType) - } - } - val edge = XcfaEdge(source, target, label, metadata) - edges.add(edge) - source.outgoingEdges.add(edge) - target.incomingEdges.add(edge) - reader.endObject() - } - reader.endArray() - } + "source" -> source = checkNotNull(locs[reader.nextString()]) + "target" -> target = checkNotNull(locs[reader.nextString()]) + "label" -> label = gson.fromJson(reader, labelType) + "metadata" -> metadata = gson.fromJson(reader, metadataType) } + } + val edge = XcfaEdge(source, target, label, metadata) + edges.add(edge) + source.outgoingEdges.add(edge) + target.incomingEdges.add(edge) + reader.endObject() } - ret[name] = XcfaProcedure(name, params, vars, locs.values.toSet(), edges, initLoc, - Optional.ofNullable(finalLoc), - Optional.ofNullable(errorLoc)).also { it.parent = xcfa } - reader.endObject() + reader.endArray() + } } - reader.endArray() - return ret - } - - private fun initGson() { - if (!this::gson.isInitialized) gson = gsonSupplier() + } + ret[name] = + XcfaProcedure( + name, + params, + vars, + locs.values.toSet(), + edges, + initLoc, + Optional.ofNullable(finalLoc), + Optional.ofNullable(errorLoc), + ) + .also { it.parent = xcfa } + reader.endObject() } - -} \ No newline at end of file + reader.endArray() + return ret + } + + private fun initGson() { + if (!this::gson.isInitialized) gson = gsonSupplier() + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt index 02d6e50e50..0358151fce 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLocationAdapter.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.gson import com.google.gson.Gson @@ -26,47 +25,47 @@ import hu.bme.mit.theta.xcfa.model.XcfaLocation class XcfaLocationAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { - private lateinit var gson: Gson - override fun write(writer: JsonWriter, value: XcfaLocation) { - initGson() - writer.beginObject() - writer.name("name").value(value.name) - writer.name("initial").value(value.initial) - writer.name("final").value(value.final) - writer.name("error").value(value.error) - writer.name("metadata") - gson.toJson(gson.toJsonTree(value.metadata), writer) - writer.endObject() - } + private lateinit var gson: Gson - override fun read(reader: JsonReader): XcfaLocation { - initGson() - reader.beginObject() + override fun write(writer: JsonWriter, value: XcfaLocation) { + initGson() + writer.beginObject() + writer.name("name").value(value.name) + writer.name("initial").value(value.initial) + writer.name("final").value(value.final) + writer.name("error").value(value.error) + writer.name("metadata") + gson.toJson(gson.toJsonTree(value.metadata), writer) + writer.endObject() + } - lateinit var name: String - var initial = false - var final = false - var error = false - var metaData: MetaData? = null + override fun read(reader: JsonReader): XcfaLocation { + initGson() + reader.beginObject() - while (reader.hasNext()) { - val jsonName = reader.nextName() - when (jsonName) { - "name" -> name = reader.nextString() - "initial" -> initial = reader.nextBoolean() - "final" -> final = reader.nextBoolean() - "error" -> error = reader.nextBoolean() - "metaData" -> metaData = gson.fromJson(reader, MetaData::class.java) - else -> reader.skipValue() - } - } - reader.endObject() + lateinit var name: String + var initial = false + var final = false + var error = false + var metaData: MetaData? = null - return XcfaLocation(name, initial, final, error, metaData ?: EmptyMetaData) + while (reader.hasNext()) { + val jsonName = reader.nextName() + when (jsonName) { + "name" -> name = reader.nextString() + "initial" -> initial = reader.nextBoolean() + "final" -> final = reader.nextBoolean() + "error" -> error = reader.nextBoolean() + "metaData" -> metaData = gson.fromJson(reader, MetaData::class.java) + else -> reader.skipValue() + } } + reader.endObject() - private fun initGson() { - if (!this::gson.isInitialized) gson = gsonSupplier() - } + return XcfaLocation(name, initial, final, error, metaData ?: EmptyMetaData) + } -} \ No newline at end of file + private fun initGson() { + if (!this::gson.isInitialized) gson = gsonSupplier() + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt index 96b21e4b97..90e05c8a19 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt @@ -30,287 +30,307 @@ import hu.bme.mit.theta.grammar.dsl.expr.ExpressionWrapper import hu.bme.mit.theta.xcfa.passes.ProcedurePassManager fun xcfa(name: String, lambda: XcfaBuilder.() -> Unit): XCFA = - XcfaBuilder(name).apply(lambda).build() + XcfaBuilder(name).apply(lambda).build() class VarContext(val builder: XcfaBuilder, private val local: Boolean) { - infix fun String.type(type: Type): Pair = Pair(this, type) - - infix fun Pair.init(initValue: String): VarDecl { - val varDecl = Var(first, second) - builder.addVar( - XcfaGlobalVar(varDecl, - ExpressionWrapper(SimpleScope(SymbolTable()), initValue).instantiate( - Env()) as LitExpr<*>, - local)) - return varDecl - } + infix fun String.type(type: Type): Pair = Pair(this, type) + + infix fun Pair.init(initValue: String): VarDecl { + val varDecl = Var(first, second) + builder.addVar( + XcfaGlobalVar( + varDecl, + ExpressionWrapper(SimpleScope(SymbolTable()), initValue).instantiate(Env()) as LitExpr<*>, + local, + ) + ) + return varDecl + } } fun XcfaProcedureBuilder.lookup(name: String): VarDecl = - getVars().find { it.name.equals(name) } ?: parent.getVars().map { it.wrappedVar } - .find { it.name.equals(name) } ?: error("Variable $name not found in scope.") + getVars().find { it.name.equals(name) } + ?: parent.getVars().map { it.wrappedVar }.find { it.name.equals(name) } + ?: error("Variable $name not found in scope.") data class NamedSymbol(val _name: String) : Symbol { - override fun getName(): String { - return _name - } + override fun getName(): String { + return _name + } } fun XcfaProcedureBuilder.parse(expr: String): Expr { - val symbolTable = SymbolTable() - getVars().forEach { symbolTable.add(NamedSymbol(it.name)) } - parent.getVars().map { it.wrappedVar }.forEach { symbolTable.add(NamedSymbol(it.name)) } - val env = Env() - getVars().forEach { env.define(NamedSymbol(it.name), it) } - parent.getVars().map { it.wrappedVar }.forEach { env.define(NamedSymbol(it.name), it) } - - return ExpressionWrapper(SimpleScope(symbolTable), expr).instantiate(env) + val symbolTable = SymbolTable() + getVars().forEach { symbolTable.add(NamedSymbol(it.name)) } + parent.getVars().map { it.wrappedVar }.forEach { symbolTable.add(NamedSymbol(it.name)) } + val env = Env() + getVars().forEach { env.define(NamedSymbol(it.name), it) } + parent.getVars().map { it.wrappedVar }.forEach { env.define(NamedSymbol(it.name), it) } + + return ExpressionWrapper(SimpleScope(symbolTable), expr).instantiate(env) } @XcfaDsl class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { - private val locationLut: MutableMap = LinkedHashMap() - val init: String = "init" - val err: String = "err" - val final: String = "final" - - init { - builder.createInitLoc() - builder.createErrorLoc() - builder.createFinalLoc() - locationLut[init] = builder.initLoc - locationLut[err] = builder.errorLoc.get() - locationLut[final] = builder.finalLoc.get() + private val locationLut: MutableMap = LinkedHashMap() + val init: String = "init" + val err: String = "err" + val final: String = "final" + + init { + builder.createInitLoc() + builder.createErrorLoc() + builder.createFinalLoc() + locationLut[init] = builder.initLoc + locationLut[err] = builder.errorLoc.get() + locationLut[final] = builder.finalLoc.get() + } + + fun start(vararg expr: Any) { + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") + } + builder.parent.addEntryPoint(builder, exprs) + } + + infix fun String.type(type: Type): VarDecl { + val v = Var(this, type) + builder.addVar(v) + return v + } + + infix fun VarDecl.direction(direction: ParamDirection): VarDecl { + builder.addParam(this, direction) + return this + } + + @XcfaDsl + inner class SequenceLabelContext { + + private val labelList: MutableList = ArrayList() + + infix fun String.assign(to: String): SequenceLabel { + val lhs: VarDecl = + this@XcfaProcedureBuilderContext.builder.lookup(this) as VarDecl + val rhs: Expr = this@XcfaProcedureBuilderContext.builder.parse(to) as Expr + val label = StmtLabel(Assign(lhs, rhs)) + labelList.add(label) + return SequenceLabel(labelList) } - fun start(vararg expr: Any) { - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - builder.parent.addEntryPoint(builder, exprs) + infix fun VarDecl<*>.assign(to: String): SequenceLabel { + val rhs: Expr = this@XcfaProcedureBuilderContext.builder.parse(to) as Expr + val label = StmtLabel(Assign(this as VarDecl, rhs)) + labelList.add(label) + return SequenceLabel(labelList) } - infix fun String.type(type: Type): VarDecl { - val v = Var(this, type) - builder.addVar(v) - return v + infix fun String.assign(to: Expr<*>): SequenceLabel { + val lhs: VarDecl = + this@XcfaProcedureBuilderContext.builder.lookup(this) as VarDecl + val rhs: Expr = to as Expr + val label = StmtLabel(Assign(lhs, rhs)) + labelList.add(label) + return SequenceLabel(labelList) } - infix fun VarDecl.direction(direction: ParamDirection): VarDecl { - builder.addParam(this, direction) - return this + infix fun VarDecl<*>.assign(to: Expr<*>): SequenceLabel { + val rhs: Expr = to as Expr + val label = StmtLabel(Assign(this as VarDecl, rhs)) + labelList.add(label) + return SequenceLabel(labelList) } - @XcfaDsl - inner class SequenceLabelContext { - - private val labelList: MutableList = ArrayList() - - infix fun String.assign(to: String): SequenceLabel { - val lhs: VarDecl = this@XcfaProcedureBuilderContext.builder.lookup( - this) as VarDecl - val rhs: Expr = this@XcfaProcedureBuilderContext.builder.parse(to) as Expr - val label = StmtLabel(Assign(lhs, rhs)) - labelList.add(label) - return SequenceLabel(labelList) - } - - infix fun VarDecl<*>.assign(to: String): SequenceLabel { - val rhs: Expr = this@XcfaProcedureBuilderContext.builder.parse(to) as Expr - val label = StmtLabel(Assign(this as VarDecl, rhs)) - labelList.add(label) - return SequenceLabel(labelList) - } - - infix fun String.assign(to: Expr<*>): SequenceLabel { - val lhs: VarDecl = this@XcfaProcedureBuilderContext.builder.lookup( - this) as VarDecl - val rhs: Expr = to as Expr - val label = StmtLabel(Assign(lhs, rhs)) - labelList.add(label) - return SequenceLabel(labelList) - } - - infix fun VarDecl<*>.assign(to: Expr<*>): SequenceLabel { - val rhs: Expr = to as Expr - val label = StmtLabel(Assign(this as VarDecl, rhs)) - labelList.add(label) - return SequenceLabel(labelList) - } - - fun assume(value: String): SequenceLabel { - val expr = this@XcfaProcedureBuilderContext.builder.parse(value) as Expr - val label = StmtLabel(Assume(expr)) - labelList.add(label) - return SequenceLabel(labelList) - } - - fun assume(expr: Expr): SequenceLabel { - val label = StmtLabel(Assume(expr)) - labelList.add(label) - return SequenceLabel(labelList) - } - - fun havoc(value: String): SequenceLabel { - val varDecl = this@XcfaProcedureBuilderContext.builder.lookup(value) - val label = StmtLabel(Havoc(varDecl)) - labelList.add(label) - return SequenceLabel(labelList) - } + fun assume(value: String): SequenceLabel { + val expr = this@XcfaProcedureBuilderContext.builder.parse(value) as Expr + val label = StmtLabel(Assume(expr)) + labelList.add(label) + return SequenceLabel(labelList) + } - fun havoc(varDecl: VarDecl<*>): SequenceLabel { - val label = StmtLabel(Havoc(varDecl)) - labelList.add(label) - return SequenceLabel(labelList) - } + fun assume(expr: Expr): SequenceLabel { + val label = StmtLabel(Assume(expr)) + labelList.add(label) + return SequenceLabel(labelList) + } - operator fun XcfaProcedureBuilderContext.invoke(vararg expr: Any): SequenceLabel { - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - val label = InvokeLabel(this.builder.name, exprs, EmptyMetaData) - this@SequenceLabelContext.labelList.add(label) - return SequenceLabel(this@SequenceLabelContext.labelList) - } + fun havoc(value: String): SequenceLabel { + val varDecl = this@XcfaProcedureBuilderContext.builder.lookup(value) + val label = StmtLabel(Havoc(varDecl)) + labelList.add(label) + return SequenceLabel(labelList) + } - operator fun String.invoke(vararg expr: Any): SequenceLabel { - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - val label = InvokeLabel(this, exprs, EmptyMetaData) - this@SequenceLabelContext.labelList.add(label) - return SequenceLabel(this@SequenceLabelContext.labelList) - } + fun havoc(varDecl: VarDecl<*>): SequenceLabel { + val label = StmtLabel(Havoc(varDecl)) + labelList.add(label) + return SequenceLabel(labelList) + } - fun String.start(ctx: XcfaProcedureBuilderContext, vararg expr: Any): SequenceLabel { - val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - val label = StartLabel(ctx.builder.name, exprs, lhs, EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) + operator fun XcfaProcedureBuilderContext.invoke(vararg expr: Any): SequenceLabel { + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") } + val label = InvokeLabel(this.builder.name, exprs, EmptyMetaData) + this@SequenceLabelContext.labelList.add(label) + return SequenceLabel(this@SequenceLabelContext.labelList) + } - fun VarDecl<*>.start(ctx: XcfaProcedureBuilderContext, vararg expr: Any): SequenceLabel { - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - val label = StartLabel(ctx.builder.name, exprs, this, EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) + operator fun String.invoke(vararg expr: Any): SequenceLabel { + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") } + val label = InvokeLabel(this, exprs, EmptyMetaData) + this@SequenceLabelContext.labelList.add(label) + return SequenceLabel(this@SequenceLabelContext.labelList) + } - fun String.start(ctx: String, vararg expr: Any): SequenceLabel { - val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - val label = StartLabel(ctx, exprs, lhs, EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) + fun String.start(ctx: XcfaProcedureBuilderContext, vararg expr: Any): SequenceLabel { + val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") } + val label = StartLabel(ctx.builder.name, exprs, lhs, EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) + } - fun VarDecl<*>.start(ctx: String, vararg expr: Any): SequenceLabel { - val exprs = expr.map { - if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") - } - val label = StartLabel(ctx, exprs, this, EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) + fun VarDecl<*>.start(ctx: XcfaProcedureBuilderContext, vararg expr: Any): SequenceLabel { + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") } + val label = StartLabel(ctx.builder.name, exprs, this, EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) + } - fun String.join(): SequenceLabel { - val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) - val label = JoinLabel(lhs, EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) + fun String.start(ctx: String, vararg expr: Any): SequenceLabel { + val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") } + val label = StartLabel(ctx, exprs, lhs, EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) + } - fun VarDecl<*>.join(): SequenceLabel { - val label = JoinLabel(this, EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) + fun VarDecl<*>.start(ctx: String, vararg expr: Any): SequenceLabel { + val exprs = + expr.map { + if (it is Expr<*>) it + else if (it is String) this@XcfaProcedureBuilderContext.builder.parse(it) + else error("Bad type") } + val label = StartLabel(ctx, exprs, this, EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) + } - fun sequence(lambda: SequenceLabelContext.() -> SequenceLabel): SequenceLabel { - val innerCtx = this@XcfaProcedureBuilderContext.SequenceLabelContext() - val label = lambda(innerCtx) - labelList.add(label) - return SequenceLabel(labelList) - } + fun String.join(): SequenceLabel { + val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) + val label = JoinLabel(lhs, EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) + } - fun nondet(lambda: SequenceLabelContext.() -> SequenceLabel): SequenceLabel { - val innerCtx = this@XcfaProcedureBuilderContext.SequenceLabelContext() - val label = NondetLabel(lambda(innerCtx).labels.toSet()) - labelList.add(label) - return SequenceLabel(labelList) - } + fun VarDecl<*>.join(): SequenceLabel { + val label = JoinLabel(this, EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) + } - fun fence(vararg content: String): SequenceLabel { - val label = FenceLabel(content.toSet(), EmptyMetaData) - labelList.add(label) - return SequenceLabel(labelList) - } + fun sequence(lambda: SequenceLabelContext.() -> SequenceLabel): SequenceLabel { + val innerCtx = this@XcfaProcedureBuilderContext.SequenceLabelContext() + val label = lambda(innerCtx) + labelList.add(label) + return SequenceLabel(labelList) + } - fun nop(): SequenceLabel { - val label = NopLabel - labelList.add(label) - return SequenceLabel(labelList) - } + fun nondet(lambda: SequenceLabelContext.() -> SequenceLabel): SequenceLabel { + val innerCtx = this@XcfaProcedureBuilderContext.SequenceLabelContext() + val label = NondetLabel(lambda(innerCtx).labels.toSet()) + labelList.add(label) + return SequenceLabel(labelList) + } - fun skip(): SequenceLabel { - return SequenceLabel(labelList) - } + fun fence(vararg content: String): SequenceLabel { + val label = FenceLabel(content.toSet(), EmptyMetaData) + labelList.add(label) + return SequenceLabel(labelList) } - infix fun String.to(to: String): (lambda: SequenceLabelContext.() -> SequenceLabel) -> XcfaEdge { - val loc1 = locationLut.getOrElse(this) { XcfaLocation(this, metadata = EmptyMetaData) } - locationLut.putIfAbsent(this, loc1) - builder.addLoc(loc1) - val loc2 = locationLut.getOrElse(to) { XcfaLocation(to, metadata = EmptyMetaData) } - locationLut.putIfAbsent(to, loc2) - builder.addLoc(loc2) - return { lambda -> - val edge = XcfaEdge(loc1, loc2, lambda(SequenceLabelContext()), EmptyMetaData) - builder.addEdge(edge) - edge - } + fun nop(): SequenceLabel { + val label = NopLabel + labelList.add(label) + return SequenceLabel(labelList) } + fun skip(): SequenceLabel { + return SequenceLabel(labelList) + } + } + + infix fun String.to(to: String): (lambda: SequenceLabelContext.() -> SequenceLabel) -> XcfaEdge { + val loc1 = locationLut.getOrElse(this) { XcfaLocation(this, metadata = EmptyMetaData) } + locationLut.putIfAbsent(this, loc1) + builder.addLoc(loc1) + val loc2 = locationLut.getOrElse(to) { XcfaLocation(to, metadata = EmptyMetaData) } + locationLut.putIfAbsent(to, loc2) + builder.addLoc(loc2) + return { lambda -> + val edge = XcfaEdge(loc1, loc2, lambda(SequenceLabelContext()), EmptyMetaData) + builder.addEdge(edge) + edge + } + } } - fun XcfaBuilder.global(lambda: VarContext.() -> Unit) { - val context = VarContext(this, false) - context.apply(lambda) + val context = VarContext(this, false) + context.apply(lambda) } fun XcfaBuilder.threadlocal(lambda: VarContext.() -> Unit) { - val context = VarContext(this, true) - context.apply(lambda) + val context = VarContext(this, true) + context.apply(lambda) } -fun XcfaBuilder.procedure(name: String, passManager: ProcedurePassManager, - lambda: XcfaProcedureBuilderContext.() -> Unit): XcfaProcedureBuilderContext { - val builder = XcfaProcedureBuilder(name, passManager) - builder.parent = this - val procBuilder = XcfaProcedureBuilderContext(builder).apply(lambda) - this.addProcedure(procBuilder.builder) - return procBuilder +fun XcfaBuilder.procedure( + name: String, + passManager: ProcedurePassManager, + lambda: XcfaProcedureBuilderContext.() -> Unit, +): XcfaProcedureBuilderContext { + val builder = XcfaProcedureBuilder(name, passManager) + builder.parent = this + val procBuilder = XcfaProcedureBuilderContext(builder).apply(lambda) + this.addProcedure(procBuilder.builder) + return procBuilder } -fun XcfaBuilder.procedure(name: String, - lambda: XcfaProcedureBuilderContext.() -> Unit): XcfaProcedureBuilderContext { - return procedure(name, ProcedurePassManager(), lambda) -} \ No newline at end of file +fun XcfaBuilder.procedure( + name: String, + lambda: XcfaProcedureBuilderContext.() -> Unit, +): XcfaProcedureBuilderContext { + return procedure(name, ProcedurePassManager(), lambda) +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt index ea1afc35ac..0b097d5027 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/MetaData.kt @@ -13,24 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.model abstract class MetaData { - abstract fun combine(other: MetaData): MetaData + abstract fun combine(other: MetaData): MetaData } object EmptyMetaData : MetaData() { - // TODO why is this necessary? {@see GsonTest.kt} - private val hash = 123123 + // TODO why is this necessary? {@see GsonTest.kt} + private val hash = 123123 - override fun combine(other: MetaData): MetaData { - return other - } + override fun combine(other: MetaData): MetaData { + return other + } - override fun equals(other: Any?): Boolean = - other is EmptyMetaData + override fun equals(other: Any?): Boolean = other is EmptyMetaData - override fun hashCode(): Int = hash + override fun hashCode(): Int = hash } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt index 91d3d567f2..9e90b22d57 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XCFA.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.model import hu.bme.mit.theta.core.decl.VarDecl @@ -23,132 +22,140 @@ import hu.bme.mit.theta.xcfa.lazyPointsToGraph import java.util.* class XCFA( - val name: String, - val vars: Set, // global variables - val procedureBuilders: Set = emptySet(), - val initProcedureBuilders: List>>> = emptyList() + val name: String, + val vars: Set, // global variables + val procedureBuilders: Set = emptySet(), + val initProcedureBuilders: List>>> = emptyList(), ) { - val pointsToGraph by this.lazyPointsToGraph - - var cachedHash: Int? = null - - var procedures: Set // procedure definitions - private set - - var initProcedures: List>>> // procedure names and parameter assignments - private set - - init { - var phase = 0 - do { - var ready = true - procedureBuilders.forEach { ready = it.optimize(phase) && ready } - initProcedureBuilders.forEach { ready = it.first.optimize(phase) && ready } - phase++ - } while (!ready) - - procedures = procedureBuilders.map { it.build(this) }.toSet() - initProcedures = initProcedureBuilders.map { Pair(it.first.build(this), it.second) } - } - - /** - * Recreate an existing XCFA by substituting the procedures and initProcedures fields. - */ - fun recreate(procedures: Set, initProcedures: List>>>): XCFA { - this.procedures = procedures - this.initProcedures = initProcedures - return this - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as XCFA - - if (name != other.name) return false - if (vars != other.vars) return false - if (procedures != other.procedures) return false - if (initProcedures != other.initProcedures) return false - - return true - } - - override fun hashCode(): Int { - if (cachedHash != null) return cachedHash as Int - var result = name.hashCode() - result = 31 * result + vars.hashCode() - result = 31 * result + procedures.hashCode() - result = 31 * result + initProcedures.hashCode() - cachedHash = result - return result - } - - override fun toString(): String { - return "XCFA(name='$name', vars=$vars, procedures=$procedures, initProcedures=$initProcedures)" - } - - + val pointsToGraph by this.lazyPointsToGraph + + var cachedHash: Int? = null + + var procedures: Set // procedure definitions + private set + + var initProcedures: + List>>> // procedure names and parameter assignments + private set + + init { + var phase = 0 + do { + var ready = true + procedureBuilders.forEach { ready = it.optimize(phase) && ready } + initProcedureBuilders.forEach { ready = it.first.optimize(phase) && ready } + phase++ + } while (!ready) + + procedures = procedureBuilders.map { it.build(this) }.toSet() + initProcedures = initProcedureBuilders.map { Pair(it.first.build(this), it.second) } + } + + /** Recreate an existing XCFA by substituting the procedures and initProcedures fields. */ + fun recreate( + procedures: Set, + initProcedures: List>>>, + ): XCFA { + this.procedures = procedures + this.initProcedures = initProcedures + return this + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as XCFA + + if (name != other.name) return false + if (vars != other.vars) return false + if (procedures != other.procedures) return false + if (initProcedures != other.initProcedures) return false + + return true + } + + override fun hashCode(): Int { + if (cachedHash != null) return cachedHash as Int + var result = name.hashCode() + result = 31 * result + vars.hashCode() + result = 31 * result + procedures.hashCode() + result = 31 * result + initProcedures.hashCode() + cachedHash = result + return result + } + + override fun toString(): String { + return "XCFA(name='$name', vars=$vars, procedures=$procedures, initProcedures=$initProcedures)" + } } data class XcfaProcedure( - val name: String, - val params: List, ParamDirection>>, // procedure params - val vars: Set>, // local variables - val locs: Set, // locations - val edges: Set, // edges - - val initLoc: XcfaLocation, // initial location - val finalLoc: Optional, // final location (optional) - val errorLoc: Optional // error location (optional) + val name: String, + val params: List, ParamDirection>>, // procedure params + val vars: Set>, // local variables + val locs: Set, // locations + val edges: Set, // edges + val initLoc: XcfaLocation, // initial location + val finalLoc: Optional, // final location (optional) + val errorLoc: Optional, // error location (optional) ) { - internal lateinit var parent: XCFA + internal lateinit var parent: XCFA } -data class XcfaLocation @JvmOverloads constructor( - val name: String, // label of the location - val initial: Boolean = false, // is this the initial location? - val final: Boolean = false, // is this the final location? - val error: Boolean = false, // is this the error location? - val metadata: MetaData, +data class XcfaLocation +@JvmOverloads +constructor( + val name: String, // label of the location + val initial: Boolean = false, // is this the initial location? + val final: Boolean = false, // is this the final location? + val error: Boolean = false, // is this the error location? + val metadata: MetaData, ) { - val incomingEdges: MutableSet = LinkedHashSet() // all incoming edges in the current procedure - val outgoingEdges: MutableSet = LinkedHashSet() // all outgoing edges in the current procedure + val incomingEdges: MutableSet = + LinkedHashSet() // all incoming edges in the current procedure + val outgoingEdges: MutableSet = + LinkedHashSet() // all outgoing edges in the current procedure + + companion object { - companion object { + private var cnt: Int = 0 - private var cnt: Int = 0 - fun uniqueCounter(): Int = cnt++ - } + fun uniqueCounter(): Int = cnt++ + } - override fun toString(): String { - return "$name ${if (initial) "{init}" else ""}${if (final) "{final}" else ""}${if (error) "{error}" else ""}" - } + override fun toString(): String { + return "$name ${if (initial) "{init}" else ""}${if (final) "{final}" else ""}${if (error) "{error}" else ""}" + } } data class XcfaEdge( - val source: XcfaLocation, // source location - val target: XcfaLocation, // target location - val label: XcfaLabel = NopLabel, // edge label - val metadata: MetaData + val source: XcfaLocation, // source location + val target: XcfaLocation, // target location + val label: XcfaLabel = NopLabel, // edge label + val metadata: MetaData, ) { - fun withLabel(label: XcfaLabel): XcfaEdge = XcfaEdge(source, target, label, metadata) - fun withTarget(target: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label, metadata) - fun withSource(source: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label, metadata) + fun withLabel(label: XcfaLabel): XcfaEdge = XcfaEdge(source, target, label, metadata) + + fun withTarget(target: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label, metadata) + + fun withSource(source: XcfaLocation): XcfaEdge = XcfaEdge(source, target, label, metadata) } -data class XcfaGlobalVar @JvmOverloads constructor( - val wrappedVar: VarDecl<*>, - val initValue: LitExpr<*>, - val threadLocal: Boolean = false +data class XcfaGlobalVar +@JvmOverloads +constructor( + val wrappedVar: VarDecl<*>, + val initValue: LitExpr<*>, + val threadLocal: Boolean = false, ) enum class ParamDirection { - IN, - OUT, - INOUT + IN, + OUT, + INOUT, } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt index 0248095a83..b30444ccab 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EliminateSelfLoops.kt @@ -20,22 +20,29 @@ import java.util.stream.Collectors class EliminateSelfLoops : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - val selfLoops: Set = builder.getEdges().stream() - .filter { xcfaEdge -> xcfaEdge.source === xcfaEdge.target }.collect(Collectors.toSet()) - for (selfLoop in selfLoops) { - builder.removeEdge(selfLoop) - val source = selfLoop.source - val target = XcfaLocation(source.name + "_" + XcfaLocation.uniqueCounter(), metadata = EmptyMetaData) - builder.addLoc(target) - for (outgoingEdge in LinkedHashSet(source.outgoingEdges)) { - builder.removeEdge(outgoingEdge) - builder.addEdge(XcfaEdge(target, outgoingEdge.target, outgoingEdge.label, outgoingEdge.metadata)) - } - builder.addEdge(XcfaEdge(source, target, selfLoop.label, selfLoop.metadata)) - builder.addEdge(XcfaEdge(target, source, SequenceLabel(listOf(NopLabel)), selfLoop.metadata)) - } - builder.metaData["noSelfLoops"] = Unit - return builder + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + val selfLoops: Set = + builder + .getEdges() + .stream() + .filter { xcfaEdge -> xcfaEdge.source === xcfaEdge.target } + .collect(Collectors.toSet()) + for (selfLoop in selfLoops) { + builder.removeEdge(selfLoop) + val source = selfLoop.source + val target = + XcfaLocation(source.name + "_" + XcfaLocation.uniqueCounter(), metadata = EmptyMetaData) + builder.addLoc(target) + for (outgoingEdge in LinkedHashSet(source.outgoingEdges)) { + builder.removeEdge(outgoingEdge) + builder.addEdge( + XcfaEdge(target, outgoingEdge.target, outgoingEdge.label, outgoingEdge.metadata) + ) + } + builder.addEdge(XcfaEdge(source, target, selfLoop.label, selfLoop.metadata)) + builder.addEdge(XcfaEdge(target, source, SequenceLabel(listOf(NopLabel)), selfLoop.metadata)) } -} \ No newline at end of file + builder.metaData["noSelfLoops"] = Unit + return builder + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt index 5de0ad72ad..43c29685ee 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/EmptyEdgeRemovalPass.kt @@ -13,48 +13,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.core.stmt.Stmts.Assume import hu.bme.mit.theta.core.type.booltype.BoolExprs.True import hu.bme.mit.theta.xcfa.model.* -/** - * Removes edges that only contain NopLabels (possibly nested) - */ - +/** Removes edges that only contain NopLabels (possibly nested) */ class EmptyEdgeRemovalPass : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - while (true) { - val edge = builder.getEdges().find { - it.label.isNop() && !it.target.error && !it.target.final && !it.source.initial && - (it.source.outgoingEdges.size == 1 || it.target.incomingEdges.size == 1) && - it.metadata is EmptyMetaData - } ?: return builder - val collapseBefore = edge.source.outgoingEdges.size == 1 - builder.removeEdge(edge) - if (collapseBefore) { - val incomingEdges = edge.source.incomingEdges.toList() - incomingEdges.forEach { builder.removeEdge(it) } - incomingEdges.forEach { builder.addEdge(it.withTarget(edge.target)) } - builder.removeLoc(edge.source) - } else { - val outgoingEdges = edge.target.outgoingEdges.toList() - outgoingEdges.forEach { builder.removeEdge(it) } - outgoingEdges.forEach { builder.addEdge(it.withSource(edge.source)) } - builder.removeLoc(edge.target) - } - } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + while (true) { + val edge = + builder.getEdges().find { + it.label.isNop() && + !it.target.error && + !it.target.final && + !it.source.initial && + (it.source.outgoingEdges.size == 1 || it.target.incomingEdges.size == 1) && + it.metadata is EmptyMetaData + } ?: return builder + val collapseBefore = edge.source.outgoingEdges.size == 1 + builder.removeEdge(edge) + if (collapseBefore) { + val incomingEdges = edge.source.incomingEdges.toList() + incomingEdges.forEach { builder.removeEdge(it) } + incomingEdges.forEach { builder.addEdge(it.withTarget(edge.target)) } + builder.removeLoc(edge.source) + } else { + val outgoingEdges = edge.target.outgoingEdges.toList() + outgoingEdges.forEach { builder.removeEdge(it) } + outgoingEdges.forEach { builder.addEdge(it.withSource(edge.source)) } + builder.removeLoc(edge.target) + } } + } - private fun XcfaLabel.isNop(): Boolean = - when (this) { - is NondetLabel -> labels.all { it.isNop() } - is SequenceLabel -> labels.all { it.isNop() } - is NopLabel -> true - is StmtLabel -> stmt == Assume(True()) - else -> false - }.and(metadata is EmptyMetaData) -} \ No newline at end of file + private fun XcfaLabel.isNop(): Boolean = + when (this) { + is NondetLabel -> labels.all { it.isNop() } + is SequenceLabel -> labels.all { it.isNop() } + is NopLabel -> true + is StmtLabel -> stmt == Assume(True()) + else -> false + }.and(metadata is EmptyMetaData) +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt index 0e65bbfc97..5964d29473 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.xcfa.model.* @@ -24,32 +23,37 @@ import hu.bme.mit.theta.xcfa.model.* */ class ErrorLocationPass(private val checkOverflow: Boolean) : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - checkNotNull(builder.metaData["deterministic"]) - for (edge in ArrayList(builder.getEdges())) { - val edges = edge.splitIf(this::predicate) - if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { - builder.removeEdge(edge) - edges.forEach { - val label = (it.label as SequenceLabel).labels[0] - if (predicate(label)) { - if (builder.errorLoc.isEmpty) builder.createErrorLoc() - builder.addEdge( - XcfaEdge( - it.source, builder.errorLoc.get(), SequenceLabel(listOf()), metadata = label.metadata - ) - ) - } else { - builder.addEdge(it) - } - } - } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + checkNotNull(builder.metaData["deterministic"]) + for (edge in ArrayList(builder.getEdges())) { + val edges = edge.splitIf(this::predicate) + if ( + edges.size > 1 || + (edges.size == 1 && predicate((edges[0].label as SequenceLabel).labels[0])) + ) { + builder.removeEdge(edge) + edges.forEach { + val label = (it.label as SequenceLabel).labels[0] + if (predicate(label)) { + if (builder.errorLoc.isEmpty) builder.createErrorLoc() + builder.addEdge( + XcfaEdge( + it.source, + builder.errorLoc.get(), + SequenceLabel(listOf()), + metadata = label.metadata, + ) + ) + } else { + builder.addEdge(it) + } } - return builder + } } + return builder + } - private fun predicate(it: XcfaLabel): Boolean { - return it is InvokeLabel && it.name == if (checkOverflow) "overflow" else "reach_error" - } -} \ No newline at end of file + private fun predicate(it: XcfaLabel): Boolean { + return it is InvokeLabel && it.name == if (checkOverflow) "overflow" else "reach_error" + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt index 3effbf99a7..2e776e805b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.core.stmt.Stmts @@ -26,38 +25,40 @@ import hu.bme.mit.theta.xcfa.model.* */ class FinalLocationPass(private val checkOverflow: Boolean) : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - checkNotNull(builder.metaData["deterministic"]) - for (edge in ArrayList(builder.getEdges())) { - val edges = edge.splitIf(this::predicate) - if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { - builder.removeEdge(edge) - edges.forEach { - if (predicate((it.label as SequenceLabel).labels[0])) { - if (builder.finalLoc.isEmpty) builder.createFinalLoc() - builder.addEdge(XcfaEdge(it.source, builder.finalLoc.get(), SequenceLabel( - listOf( - StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata)), - metadata = it.metadata - ), it.metadata - ) - ) - } else { - builder.addEdge(it) - } - } - } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + checkNotNull(builder.metaData["deterministic"]) + for (edge in ArrayList(builder.getEdges())) { + val edges = edge.splitIf(this::predicate) + if ( + edges.size > 1 || + (edges.size == 1 && predicate((edges[0].label as SequenceLabel).labels[0])) + ) { + builder.removeEdge(edge) + edges.forEach { + if (predicate((it.label as SequenceLabel).labels[0])) { + if (builder.finalLoc.isEmpty) builder.createFinalLoc() + builder.addEdge( + XcfaEdge( + it.source, + builder.finalLoc.get(), + SequenceLabel( + listOf(StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata)), + metadata = it.metadata, + ), + it.metadata, + ) + ) + } else { + builder.addEdge(it) + } } - return builder + } } + return builder + } - private fun predicate(it: XcfaLabel): Boolean { - val set = - if (checkOverflow) - setOf("abort", "exit", "reach_error") - else - setOf("abort", "exit") - return it is InvokeLabel && set.contains(it.name) - } -} \ No newline at end of file + private fun predicate(it: XcfaLabel): Boolean { + val set = if (checkOverflow) setOf("abort", "exit", "reach_error") else setOf("abort", "exit") + return it is InvokeLabel && set.contains(it.name) + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt index fb8f0d4b31..74d4c53ca9 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt @@ -32,274 +32,375 @@ import hu.bme.mit.theta.frontend.transformation.model.types.complex.integer.cint import hu.bme.mit.theta.xcfa.model.* import java.util.function.BiFunction -//TODO: type-right conversions (because sqrt and sqrtf might have different domains) +// TODO: type-right conversions (because sqrt and sqrtf might have different domains) class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - checkNotNull(builder.metaData["deterministic"]) - for (edge in ArrayList(builder.getEdges())) { - val newStmts: MutableList = ArrayList() - var found = false - for (stmt in (edge.label as SequenceLabel).labels) { - if (stmt is InvokeLabel) { - if (handlers.containsKey(stmt.name)) { - newStmts.add(checkNotNull(handlers[stmt.name]).apply(builder, stmt)) - found = true - } - } else newStmts.add(stmt) - } - if (found) { - builder.removeEdge(edge) - builder.addEdge(XcfaEdge(edge.source, edge.target, SequenceLabel(newStmts), edge.metadata)) - } - } - return builder + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + checkNotNull(builder.metaData["deterministic"]) + for (edge in ArrayList(builder.getEdges())) { + val newStmts: MutableList = ArrayList() + var found = false + for (stmt in (edge.label as SequenceLabel).labels) { + if (stmt is InvokeLabel) { + if (handlers.containsKey(stmt.name)) { + newStmts.add(checkNotNull(handlers[stmt.name]).apply(builder, stmt)) + found = true + } + } else newStmts.add(stmt) + } + if (found) { + builder.removeEdge(edge) + builder.addEdge(XcfaEdge(edge.source, edge.target, SequenceLabel(newStmts), edge.metadata)) + } } + return builder + } - private val handlers: MutableMap> = LinkedHashMap() - private fun addHandler(names: Array, - handler: BiFunction) { - for (name in names) { - handlers[name] = handler - } - } + private val handlers: + MutableMap> = + LinkedHashMap() - init { - addHandler(arrayOf("fabs", "fabsf", - "fabsl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleFabs(builder, callStmt) - } - addHandler(arrayOf("floor", "floorf", - "floorl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleFloor(builder, callStmt) - } - addHandler(arrayOf("fmax", "fmaxf", - "fmaxl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleFmax(builder, callStmt) - } - addHandler(arrayOf("fmin", "fminf", - "fminl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleFmin(builder, callStmt) - } - addHandler(arrayOf("fmod", "fmodf", - "fmodl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleFmod(builder, callStmt) - } - addHandler(arrayOf("sqrt", "sqrtf", - "sqrtl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleSqrt(builder, callStmt) - } - addHandler(arrayOf("round", "roundf", - "roundl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleRound(builder, callStmt) - } - addHandler(arrayOf("isnan", "__isnan", "isnanf", "__isnanf", "isnanl", - "__isnanl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleIsnan(builder, callStmt) - } - addHandler(arrayOf("trunc")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleTrunc(builder, callStmt) - } - addHandler(arrayOf("ceil")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleCeil(builder, callStmt) - } - addHandler(arrayOf( - "isnormal")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleIsnormal(builder, callStmt) - } - addHandler(arrayOf("isinf", "__isinf", "__isinff", "isinff", - "__isinfl", "isinfl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleIsinf(builder, callStmt) - } - addHandler(arrayOf( - "isfinite", "finite", "isfinitef", "finitef", "isfinite", "finitel", "__finite", "__finitef", "__finitel", - "__isfinite", - "__isfinitef", "__isfinitel")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleIsfinite(builder, callStmt) - } - addHandler(arrayOf("__fpclassify", "__fpclassifyf", - "__fpclassifyl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> - handleFpclassify(builder, callStmt) - } + private fun addHandler( + names: Array, + handler: BiFunction, + ) { + for (name in names) { + handlers[name] = handler } + } - private fun handleTrunc(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RTZ, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + init { + addHandler(arrayOf("fabs", "fabsf", "fabsl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleFabs(builder, callStmt) } - - private fun handleCeil(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RTP, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + addHandler(arrayOf("floor", "floorf", "floorl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleFloor(builder, callStmt) } - - private fun handleIsinf(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val type = CSignedInt(null, parseContext) - val assign: AssignStmt<*> = Stmts.Assign( - TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast(AbstractExprs.Ite( - FpIsInfiniteExpr.of(callStmt.params[1] as Expr), - type.unitValue, type.nullValue), - type.smtType)) - parseContext.metadata.create(assign.expr, "cType", type) - return StmtLabel(assign, metadata = callStmt.metadata) + addHandler(arrayOf("fmax", "fmaxf", "fmaxl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleFmax(builder, callStmt) } - - private fun handleIsfinite(builder: XcfaProcedureBuilder, - callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val type = CSignedInt(null, parseContext) - val assign: AssignStmt<*> = Stmts.Assign( - TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast(AbstractExprs.Ite( - Or(FpIsInfiniteExpr.of(callStmt.params[1] as Expr), - FpIsNanExpr.of(callStmt.params[1] as Expr)), - type.nullValue, type.unitValue), - type.smtType)) - parseContext.metadata.create(assign.expr, "cType", type) - return StmtLabel(assign, metadata = callStmt.metadata) + addHandler(arrayOf("fmin", "fminf", "fminl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleFmin(builder, callStmt) } - - private fun handleIsnormal(builder: XcfaProcedureBuilder, - callStmt: InvokeLabel): XcfaLabel { - throw UnsupportedOperationException() + addHandler(arrayOf("fmod", "fmodf", "fmodl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleFmod(builder, callStmt) + } + addHandler(arrayOf("sqrt", "sqrtf", "sqrtl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleSqrt(builder, callStmt) + } + addHandler(arrayOf("round", "roundf", "roundl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleRound(builder, callStmt) + } + addHandler(arrayOf("isnan", "__isnan", "isnanf", "__isnanf", "isnanl", "__isnanl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleIsnan(builder, callStmt) + } + addHandler(arrayOf("trunc")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + handleTrunc(builder, callStmt) + } + addHandler(arrayOf("ceil")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + handleCeil(builder, callStmt) } + addHandler(arrayOf("isnormal")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + handleIsnormal(builder, callStmt) + } + addHandler(arrayOf("isinf", "__isinf", "__isinff", "isinff", "__isinfl", "isinfl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleIsinf(builder, callStmt) + } + addHandler( + arrayOf( + "isfinite", + "finite", + "isfinitef", + "finitef", + "isfinite", + "finitel", + "__finite", + "__finitef", + "__finitel", + "__isfinite", + "__isfinitef", + "__isfinitel", + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + handleIsfinite(builder, callStmt) + } + addHandler(arrayOf("__fpclassify", "__fpclassifyf", "__fpclassifyl")) { + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel -> + handleFpclassify(builder, callStmt) + } + } - private fun handleFpclassify(builder: XcfaProcedureBuilder, - callStmt: InvokeLabel): XcfaLabel { - throw UnsupportedOperationException() + private fun handleTrunc(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RTZ, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } - private fun handleIsnan(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - val type = CComplexType.getType(expr, parseContext) - val assign: AssignStmt<*> = Stmts.Assign( - TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast( - AbstractExprs.Ite( - FpIsNanExpr.of(callStmt.params[1] as Expr), - type.unitValue, type.nullValue), type.smtType)) - parseContext.metadata.create(assign.expr, "cType", type) - return StmtLabel(assign, metadata = callStmt.metadata) - } else { - throw UnsupportedOperationException("Not yet supported without cType") - } + private fun handleCeil(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RTP, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } + + private fun handleIsinf(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val type = CSignedInt(null, parseContext) + val assign: AssignStmt<*> = + Stmts.Assign( + TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), + TypeUtils.cast( + AbstractExprs.Ite( + FpIsInfiniteExpr.of(callStmt.params[1] as Expr), + type.unitValue, + type.nullValue, + ), + type.smtType, + ), + ) + parseContext.metadata.create(assign.expr, "cType", type) + return StmtLabel(assign, metadata = callStmt.metadata) + } - private fun handleRound(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RNA, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + private fun handleIsfinite(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val type = CSignedInt(null, parseContext) + val assign: AssignStmt<*> = + Stmts.Assign( + TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), + TypeUtils.cast( + AbstractExprs.Ite( + Or( + FpIsInfiniteExpr.of(callStmt.params[1] as Expr), + FpIsNanExpr.of(callStmt.params[1] as Expr), + ), + type.nullValue, + type.unitValue, + ), + type.smtType, + ), + ) + parseContext.metadata.create(assign.expr, "cType", type) + return StmtLabel(assign, metadata = callStmt.metadata) + } + + private fun handleIsnormal(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + throw UnsupportedOperationException() + } + + private fun handleFpclassify(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + throw UnsupportedOperationException() + } + + private fun handleIsnan(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + val type = CComplexType.getType(expr, parseContext) + val assign: AssignStmt<*> = + Stmts.Assign( + TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), + TypeUtils.cast( + AbstractExprs.Ite( + FpIsNanExpr.of(callStmt.params[1] as Expr), + type.unitValue, + type.nullValue, + ), + type.smtType, + ), + ) + parseContext.metadata.create(assign.expr, "cType", type) + return StmtLabel(assign, metadata = callStmt.metadata) + } else { + throw UnsupportedOperationException("Not yet supported without cType") } + } - private fun handleSqrt(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpSqrtExpr.of(FpRoundingMode.RNE, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + private fun handleRound(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RNA, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } - private fun handleFmod(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - throw UnsupportedOperationException("Fmod not yet supported!") + private fun handleSqrt(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpSqrtExpr.of( + FpRoundingMode.RNE, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } + + private fun handleFmod(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + throw UnsupportedOperationException("Fmod not yet supported!") + } - private fun handleFmin(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 3, - "Function is presumed to be binary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpMinExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + private fun handleFmin(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 3, "Function is presumed to be binary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpMinExpr.of( + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } - private fun handleFmax(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 3, - "Function is presumed to be binary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpMaxExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + private fun handleFmax(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 3, "Function is presumed to be binary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpMaxExpr.of( + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } - private fun handleFloor(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RTN, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + private fun handleFloor(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RTN, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr, + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } + return StmtLabel(assign, metadata = callStmt.metadata) + } - private fun handleFabs(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") - val expr = callStmt.params[0] - Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpAbsExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) - if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { - parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) - } - return StmtLabel(assign, metadata = callStmt.metadata) + private fun handleFabs(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { + Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") + val expr = callStmt.params[0] + Preconditions.checkState(expr is RefExpr<*>) + val assign = + Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpAbsExpr.of( + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType, + ) as Expr + ), + ) + if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { + parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } -} \ No newline at end of file + return StmtLabel(assign, metadata = callStmt.metadata) + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt index 3e1fad28db..aa36b412ad 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.core.decl.VarDecl @@ -25,101 +24,131 @@ import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType import hu.bme.mit.theta.xcfa.model.* /** - * Inlines all procedure invocations in the current procedure. - * Requires the ProcedureBuilder to be `deterministic`. - * Sets the `inlined` flag on the ProcedureBuilder if successful. + * Inlines all procedure invocations in the current procedure. Requires the ProcedureBuilder to be + * `deterministic`. Sets the `inlined` flag on the ProcedureBuilder if successful. */ class InlineProceduresPass(val parseContext: ParseContext) : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - if (!builder.canInline()) return builder - checkNotNull(builder.metaData["deterministic"]) - check(builder.metaData["inlined"] == null) { "Recursive programs are not supported by inlining." } - builder.metaData["inlined"] = Unit - while (true) { - var foundOne = false - for (edge in ArrayList(builder.getEdges())) { - val pred: (XcfaLabel) -> Boolean = { it -> - it is InvokeLabel && builder.parent.getProcedures().any { p -> p.name == it.name } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + if (!builder.canInline()) return builder + checkNotNull(builder.metaData["deterministic"]) + check(builder.metaData["inlined"] == null) { + "Recursive programs are not supported by inlining." + } + builder.metaData["inlined"] = Unit + while (true) { + var foundOne = false + for (edge in ArrayList(builder.getEdges())) { + val pred: (XcfaLabel) -> Boolean = { it -> + it is InvokeLabel && builder.parent.getProcedures().any { p -> p.name == it.name } + } + val edges = edge.splitIf(pred) + if ( + edges.size > 1 || (edges.size == 1 && pred((edges[0].label as SequenceLabel).labels[0])) + ) { + builder.removeEdge(edge) + edges.forEach { e -> + if (pred((e.label as SequenceLabel).labels[0])) { + foundOne = true + val source = e.source + val target = e.target + val invokeLabel: InvokeLabel = e.label.labels[0] as InvokeLabel + val procedure = + builder.parent.getProcedures().find { p -> p.name == invokeLabel.name } + checkNotNull(procedure) + val inlineIndex = + builder.manager.passes.indexOfFirst { phase -> + phase.any { pass -> pass is InlineProceduresPass } } - val edges = edge.splitIf(pred) - if (edges.size > 1 || (edges.size == 1 && pred((edges[0].label as SequenceLabel).labels[0]))) { - builder.removeEdge(edge) - edges.forEach { e -> - if (pred((e.label as SequenceLabel).labels[0])) { - foundOne = true - val source = e.source - val target = e.target - val invokeLabel: InvokeLabel = e.label.labels[0] as InvokeLabel - val procedure = builder.parent.getProcedures().find { p -> p.name == invokeLabel.name } - checkNotNull(procedure) - val inlineIndex = builder.manager.passes.indexOfFirst { phase -> - phase.any { pass -> pass is InlineProceduresPass } - } - procedure.optimize(inlineIndex) + procedure.optimize(inlineIndex) - val newLocs: MutableMap = LinkedHashMap() - procedure.getLocs().forEach { newLocs[it] = it.inlinedCopy() } - procedure.getVars().forEach { builder.addVar(it) } - procedure.getParams().forEach { builder.addVar(it.first) } - procedure.getEdges().forEach { - builder.addEdge(it.withSource(checkNotNull(newLocs[it.source])) - .withTarget(checkNotNull(newLocs[it.target]))) - } + val newLocs: MutableMap = LinkedHashMap() + procedure.getLocs().forEach { newLocs[it] = it.inlinedCopy() } + procedure.getVars().forEach { builder.addVar(it) } + procedure.getParams().forEach { builder.addVar(it.first) } + procedure.getEdges().forEach { + builder.addEdge( + it + .withSource(checkNotNull(newLocs[it.source])) + .withTarget(checkNotNull(newLocs[it.target])) + ) + } - val inStmts: MutableList = ArrayList() - val outStmts: MutableList = ArrayList() - for ((i, param) in procedure.getParams().withIndex()) { - if (param.second != ParamDirection.OUT) { - val stmt = AssignStmt.of(cast(param.first, param.first.type), - cast(CComplexType.getType(param.first.ref, parseContext) - .castTo(invokeLabel.params[i]), param.first.type)) - inStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) - } - - if (param.second != ParamDirection.IN) { - val varDecl = (invokeLabel.params[i] as RefExpr<*>).decl as VarDecl<*> - val stmt = AssignStmt.of(cast(varDecl, param.first.type), cast( - CComplexType.getType(varDecl.ref, parseContext).castTo(param.first.ref), - param.first.type)) - outStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) - } - } + val inStmts: MutableList = ArrayList() + val outStmts: MutableList = ArrayList() + for ((i, param) in procedure.getParams().withIndex()) { + if (param.second != ParamDirection.OUT) { + val stmt = + AssignStmt.of( + cast(param.first, param.first.type), + cast( + CComplexType.getType(param.first.ref, parseContext) + .castTo(invokeLabel.params[i]), + param.first.type, + ), + ) + inStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) + } - val initLoc = procedure.initLoc - val finalLoc = procedure.finalLoc - val errorLoc = procedure.errorLoc + if (param.second != ParamDirection.IN) { + val varDecl = (invokeLabel.params[i] as RefExpr<*>).decl as VarDecl<*> + val stmt = + AssignStmt.of( + cast(varDecl, param.first.type), + cast( + CComplexType.getType(varDecl.ref, parseContext).castTo(param.first.ref), + param.first.type, + ), + ) + outStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) + } + } - builder.addEdge( - XcfaEdge(source, checkNotNull(newLocs[initLoc]), SequenceLabel(inStmts), e.metadata) - ) - if (finalLoc.isPresent) - builder.addEdge(XcfaEdge(checkNotNull(newLocs[finalLoc.get()]), target, - SequenceLabel(outStmts), EmptyMetaData - ) - ) - if (errorLoc.isPresent) { - if (builder.errorLoc.isEmpty) builder.createErrorLoc() - builder.addEdge( - XcfaEdge(checkNotNull(newLocs[errorLoc.get()]), builder.errorLoc.get(), - SequenceLabel(listOf(NopLabel)), EmptyMetaData - ) - ) - } - } else { - builder.addEdge(e) - } + val initLoc = procedure.initLoc + val finalLoc = procedure.finalLoc + val errorLoc = procedure.errorLoc - } - } - } - if (!foundOne) { - return builder + builder.addEdge( + XcfaEdge(source, checkNotNull(newLocs[initLoc]), SequenceLabel(inStmts), e.metadata) + ) + if (finalLoc.isPresent) + builder.addEdge( + XcfaEdge( + checkNotNull(newLocs[finalLoc.get()]), + target, + SequenceLabel(outStmts), + EmptyMetaData, + ) + ) + if (errorLoc.isPresent) { + if (builder.errorLoc.isEmpty) builder.createErrorLoc() + builder.addEdge( + XcfaEdge( + checkNotNull(newLocs[errorLoc.get()]), + builder.errorLoc.get(), + SequenceLabel(listOf(NopLabel)), + EmptyMetaData, + ) + ) + } + } else { + builder.addEdge(e) } + } } + } + if (!foundOne) { + return builder + } } + } - private fun XcfaLocation.inlinedCopy(): XcfaLocation { - return copy(name = name + "_" + XcfaLocation.uniqueCounter(), initial = false, final = false, error = false) - } -} \ No newline at end of file + private fun XcfaLocation.inlinedCopy(): XcfaLocation { + return copy( + name = name + "_" + XcfaLocation.uniqueCounter(), + initial = false, + final = false, + error = false, + ) + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt index 481d019cf0..40e24ad50a 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt @@ -28,294 +28,296 @@ import kotlin.collections.set /** * This pass simplifies the XCFA by joining certain edges to single edges. * - * * Definitions: - * - * * Parallel edges: edges with the same source and target location - * * Snake: a graph component where the incoming and outgoing degree of every location is 1 (except at the ends) - * * Middle location: a location whose incoming degree is 1 - * + * * Parallel edges: edges with the same source and target location + * * Snake: a graph component where the incoming and outgoing degree of every location is 1 (except + * at the ends) + * * Middle location: a location whose incoming degree is 1 */ class LbePass(val parseContext: ParseContext) : ProcedurePass { - companion object { + companion object { - /** - * The level of LBE that specifies which type of graph transformations to apply. - */ - var level = LbeLevel.NO_LBE - } + /** The level of LBE that specifies which type of graph transformations to apply. */ + var level = LbeLevel.NO_LBE + } - /** - * LBE modes. - */ - enum class LbeLevel { + /** LBE modes. */ + enum class LbeLevel { - /** - * The pass returns the builder without applying any changes. - */ - NO_LBE, + /** The pass returns the builder without applying any changes. */ + NO_LBE, - /** - * Applies sequential collapsing on atomic blocks and consecutive local operations. - */ - LBE_LOCAL, - - /** - * Enables collapsing of sequential edges of a location where the number of incoming edges to the location is - * exactly 1. A new edge is created for every outgoing edge of the location combined with the labels of the - * incoming - * edge. Parallel edges are not collapsed. - */ - LBE_SEQ, - - /** - * Enables collapsing of sequential and parallel edges too. - * Currently, [NondetLabel] is not supported by the analysis so this mode cannot be used. - */ - LBE_FULL - } + /** Applies sequential collapsing on atomic blocks and consecutive local operations. */ + LBE_LOCAL, /** - * Stores whether we are in the atomic collapsing phase. - * - * **Warning! Multiple parallel running of this pass instance does not work correctly!** + * Enables collapsing of sequential edges of a location where the number of incoming edges to + * the location is exactly 1. A new edge is created for every outgoing edge of the location + * combined with the labels of the incoming edge. Parallel edges are not collapsed. */ - private var atomicPhase = false - lateinit var builder: XcfaProcedureBuilder + LBE_SEQ, /** - * Steps of graph transformation: - * - * - * 1. Remove outgoing edges of the error location - * 1. Collapse atomic blocks sequentially (with LBE_LOCAL as [LbeLevel] configuration) - * 1. Join parallel edges to single edges and collapse snakes (see Definitions at [LbePass]) - * 1. Collapse sequential edges of locations whose incoming degree is 1, join possibly created parallel edges and - * edge-pairs described in step 2 - * + * Enables collapsing of sequential and parallel edges too. Currently, [NondetLabel] is not + * supported by the analysis so this mode cannot be used. */ - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - if (level == LbeLevel.NO_LBE) return builder + LBE_FULL, + } - if ((level == LbeLevel.LBE_SEQ || level == LbeLevel.LBE_FULL) && parseContext.multiThreading) { - level = LbeLevel.LBE_LOCAL - } + /** + * Stores whether we are in the atomic collapsing phase. + * + * **Warning! Multiple parallel running of this pass instance does not work correctly!** + */ + private var atomicPhase = false + lateinit var builder: XcfaProcedureBuilder - Preconditions.checkNotNull(builder.metaData["deterministic"]) - Preconditions.checkNotNull(builder.metaData["noSelfLoops"]) - this.builder = builder + /** + * Steps of graph transformation: + * 1. Remove outgoing edges of the error location + * 1. Collapse atomic blocks sequentially (with LBE_LOCAL as [LbeLevel] configuration) + * 1. Join parallel edges to single edges and collapse snakes (see Definitions at [LbePass]) + * 1. Collapse sequential edges of locations whose incoming degree is 1, join possibly created + * parallel edges and edge-pairs described in step 2 + */ + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + if (level == LbeLevel.NO_LBE) return builder - // Step 0 - if (builder.errorLoc.isPresent) { - builder.errorLoc.get().outgoingEdges.forEach(builder::removeEdge) - } - - // Step 1 - if (level == LbeLevel.LBE_LOCAL) { - collapseAtomics() - } + if ((level == LbeLevel.LBE_SEQ || level == LbeLevel.LBE_FULL) && parseContext.multiThreading) { + level = LbeLevel.LBE_LOCAL + } - // Step 2 - collapseParallelsAndSnakes(builder.getLocs().toList(), false) + Preconditions.checkNotNull(builder.metaData["deterministic"]) + Preconditions.checkNotNull(builder.metaData["noSelfLoops"]) + this.builder = builder - // Step 3 - //if (level != LbeLevel.LBE_LOCAL) { - removeAllMiddleLocations(builder.getLocs().toList(), false) - //} - return builder + // Step 0 + if (builder.errorLoc.isPresent) { + builder.errorLoc.get().outgoingEdges.forEach(builder::removeEdge) } - /** - * Collapses atomic blocks sequentially. - */ - private fun collapseAtomics() { - atomicPhase = true - val atomicBlockInnerLocations = getAtomicBlockInnerLocations(builder) - collapseParallelsAndSnakes(atomicBlockInnerLocations, true) - removeAllMiddleLocations(atomicBlockInnerLocations, true) - atomicPhase = false + // Step 1 + if (level == LbeLevel.LBE_LOCAL) { + collapseAtomics() } - /** - * Collapses parallel edges and snakes with a starting list of locations to check. Possibly created new parallel - * edges and snakes are collapsed too. - * - * @param locationsToVisit The starting list of locations to check. - * @param strict If true, cascade collapsing is limited to locations in locationsToVisit. - * @return Returns the list of removed locations. - */ - private fun collapseParallelsAndSnakes(locationsToVisit: List, - strict: Boolean): List { - val editedLocationsToVisit = locationsToVisit.toMutableList() - val removedLocations = mutableListOf() - while (editedLocationsToVisit.isNotEmpty()) { - val visiting = editedLocationsToVisit.first() - if (!strict || locationsToVisit.contains(visiting)) { - // Join parallel edges starting from "visiting" location - if (level == LbeLevel.LBE_FULL) { - collapseParallelEdges(visiting, editedLocationsToVisit) - } + // Step 2 + collapseParallelsAndSnakes(builder.getLocs().toList(), false) + + // Step 3 + // if (level != LbeLevel.LBE_LOCAL) { + removeAllMiddleLocations(builder.getLocs().toList(), false) + // } + return builder + } - // Collapse "visiting" location if it is part of a snake - collapsePartOfSnake(visiting, editedLocationsToVisit, removedLocations) - } - editedLocationsToVisit.remove(visiting) + /** Collapses atomic blocks sequentially. */ + private fun collapseAtomics() { + atomicPhase = true + val atomicBlockInnerLocations = getAtomicBlockInnerLocations(builder) + collapseParallelsAndSnakes(atomicBlockInnerLocations, true) + removeAllMiddleLocations(atomicBlockInnerLocations, true) + atomicPhase = false + } + + /** + * Collapses parallel edges and snakes with a starting list of locations to check. Possibly + * created new parallel edges and snakes are collapsed too. + * + * @param locationsToVisit The starting list of locations to check. + * @param strict If true, cascade collapsing is limited to locations in locationsToVisit. + * @return Returns the list of removed locations. + */ + private fun collapseParallelsAndSnakes( + locationsToVisit: List, + strict: Boolean, + ): List { + val editedLocationsToVisit = locationsToVisit.toMutableList() + val removedLocations = mutableListOf() + while (editedLocationsToVisit.isNotEmpty()) { + val visiting = editedLocationsToVisit.first() + if (!strict || locationsToVisit.contains(visiting)) { + // Join parallel edges starting from "visiting" location + if (level == LbeLevel.LBE_FULL) { + collapseParallelEdges(visiting, editedLocationsToVisit) } - return removedLocations + + // Collapse "visiting" location if it is part of a snake + collapsePartOfSnake(visiting, editedLocationsToVisit, removedLocations) + } + editedLocationsToVisit.remove(visiting) } + return removedLocations + } - /** - * Removes locations whose incoming degree is 1. A new edge is created for every outgoing edge of the location - * combined with the labels of the incoming edge as a sequence (the labels of the incoming edge will be the first in - * the sequence). - * - * @param locationsToVisit The starting list of locations to check. - * @param strict If true, cascade collapsing is limited to locations in locationsToVisit. - */ - private fun removeAllMiddleLocations(locationsToVisit: List, strict: Boolean) { - val editedLocationsToVisit = locationsToVisit.toMutableList() - while (editedLocationsToVisit.isNotEmpty()) { - val visiting = editedLocationsToVisit[0] - if (!strict || locationsToVisit.contains(visiting)) { - if (visiting.outgoingEdges.size == 1 && visiting.incomingEdges.size > 1) { - val nextLocation = visiting.outgoingEdges.first().target - val removed = removeMiddleLocation(visiting) - if (removed) { - val start = mutableListOf() - start.add(nextLocation) - val locationsToRemove = collapseParallelsAndSnakes(start, strict) - locationsToRemove.forEach { editedLocationsToVisit.remove(it) } - } - } - } - editedLocationsToVisit.remove(visiting) + /** + * Removes locations whose incoming degree is 1. A new edge is created for every outgoing edge of + * the location combined with the labels of the incoming edge as a sequence (the labels of the + * incoming edge will be the first in the sequence). + * + * @param locationsToVisit The starting list of locations to check. + * @param strict If true, cascade collapsing is limited to locations in locationsToVisit. + */ + private fun removeAllMiddleLocations(locationsToVisit: List, strict: Boolean) { + val editedLocationsToVisit = locationsToVisit.toMutableList() + while (editedLocationsToVisit.isNotEmpty()) { + val visiting = editedLocationsToVisit[0] + if (!strict || locationsToVisit.contains(visiting)) { + if (visiting.outgoingEdges.size == 1 && visiting.incomingEdges.size > 1) { + val nextLocation = visiting.outgoingEdges.first().target + val removed = removeMiddleLocation(visiting) + if (removed) { + val start = mutableListOf() + start.add(nextLocation) + val locationsToRemove = collapseParallelsAndSnakes(start, strict) + locationsToRemove.forEach { editedLocationsToVisit.remove(it) } + } } + } + editedLocationsToVisit.remove(visiting) } + } - /** - * Collapses all parallel edges starting from a location. - * - * @param location the location from where the parallel edges start that we want to remove - * @param locationsToVisit Adds the targets of parallel edges to this list (new parallel edges and snakes - * can appear in these locations) - */ - private fun collapseParallelEdges(location: XcfaLocation, - locationsToVisit: MutableList) { - val edgesByTarget = mutableMapOf>() - for (edge in location.outgoingEdges) { - val edgesToTarget = edgesByTarget.getOrDefault(edge.target, ArrayList()) - edgesToTarget.add(edge) - edgesByTarget[edge.target] = edgesToTarget - } - for (key in edgesByTarget.keys) { - val edgesToTarget: List = checkNotNull(edgesByTarget[key]) - if (edgesToTarget.size <= 1) continue - val source = edgesToTarget[0].source - val target = edgesToTarget[0].target - var nondetLabel = NondetLabel(emptySet()) - for (edge in edgesToTarget) { - val oldLabels = nondetLabel.labels.toMutableSet() - oldLabels.addAll(getNonDetBranch(edge.getFlatLabels())) - nondetLabel = NondetLabel(oldLabels) - builder.removeEdge(edge) - } - builder.addEdge( - XcfaEdge(source, target, nondetLabel, combineMetadata(edgesToTarget.map(XcfaEdge::metadata))) - ) - if (edgesToTarget.size >= 2 && !locationsToVisit.contains(key)) { - locationsToVisit.add(key) - } - } + /** + * Collapses all parallel edges starting from a location. + * + * @param location the location from where the parallel edges start that we want to remove + * @param locationsToVisit Adds the targets of parallel edges to this list (new parallel edges and + * snakes can appear in these locations) + */ + private fun collapseParallelEdges( + location: XcfaLocation, + locationsToVisit: MutableList, + ) { + val edgesByTarget = mutableMapOf>() + for (edge in location.outgoingEdges) { + val edgesToTarget = edgesByTarget.getOrDefault(edge.target, ArrayList()) + edgesToTarget.add(edge) + edgesByTarget[edge.target] = edgesToTarget } + for (key in edgesByTarget.keys) { + val edgesToTarget: List = checkNotNull(edgesByTarget[key]) + if (edgesToTarget.size <= 1) continue + val source = edgesToTarget[0].source + val target = edgesToTarget[0].target + var nondetLabel = NondetLabel(emptySet()) + for (edge in edgesToTarget) { + val oldLabels = nondetLabel.labels.toMutableSet() + oldLabels.addAll(getNonDetBranch(edge.getFlatLabels())) + nondetLabel = NondetLabel(oldLabels) + builder.removeEdge(edge) + } + builder.addEdge( + XcfaEdge( + source, + target, + nondetLabel, + combineMetadata(edgesToTarget.map(XcfaEdge::metadata)), + ) + ) + if (edgesToTarget.size >= 2 && !locationsToVisit.contains(key)) { + locationsToVisit.add(key) + } + } + } - /** - * Collapses the incoming and outgoing edges of a location whose incoming and outgoing degree is 1. - * - * @param location The location to collapse - * @param locationsToVisit The change list, the location that is the source of the incoming edge of the location is - * added to this list - * @param removedLocations The list of removed locations: the collapsed location is added to this list - */ - private fun collapsePartOfSnake(location: XcfaLocation, - locationsToVisit: MutableList, removedLocations: MutableList) { - if (location.incomingEdges.size == 1 && location.outgoingEdges.size == 1) { - val previousLocation = location.incomingEdges.first().source - val removed = removeMiddleLocation(location) - if (removed) removedLocations.add(location) - if (previousLocation !in locationsToVisit) { - locationsToVisit.add(previousLocation) - } - } + /** + * Collapses the incoming and outgoing edges of a location whose incoming and outgoing degree + * is 1. + * + * @param location The location to collapse + * @param locationsToVisit The change list, the location that is the source of the incoming edge + * of the location is added to this list + * @param removedLocations The list of removed locations: the collapsed location is added to this + * list + */ + private fun collapsePartOfSnake( + location: XcfaLocation, + locationsToVisit: MutableList, + removedLocations: MutableList, + ) { + if (location.incomingEdges.size == 1 && location.outgoingEdges.size == 1) { + val previousLocation = location.incomingEdges.first().source + val removed = removeMiddleLocation(location) + if (removed) removedLocations.add(location) + if (previousLocation !in locationsToVisit) { + locationsToVisit.add(previousLocation) + } } + } - /** - * Wraps edge labels to a [SequenceLabel] if the edge does not have - * exactly one label. If the labels contain one [NondetLabel], the - * NondetLabel's labels are returned to simplify the formula. - * - * @param edgeLabels the edge labels we would like to add to the NonDetLabel - * @return the list of labels to add to the NonDetLabel - */ - private fun getNonDetBranch(edgeLabels: List): Set { - if (edgeLabels.size == 1) { - return if (edgeLabels[0] is NondetLabel) { - (edgeLabels[0] as NondetLabel).labels - } else edgeLabels.toSet() - } - return setOf(SequenceLabel(edgeLabels)) + /** + * Wraps edge labels to a [SequenceLabel] if the edge does not have exactly one label. If the + * labels contain one [NondetLabel], the NondetLabel's labels are returned to simplify the + * formula. + * + * @param edgeLabels the edge labels we would like to add to the NonDetLabel + * @return the list of labels to add to the NonDetLabel + */ + private fun getNonDetBranch(edgeLabels: List): Set { + if (edgeLabels.size == 1) { + return if (edgeLabels[0] is NondetLabel) { + (edgeLabels[0] as NondetLabel).labels + } else edgeLabels.toSet() } + return setOf(SequenceLabel(edgeLabels)) + } - /** - * Removes a location whose outgoing degree is 1. A new edge is created for every incoming edge of the location - * combined with the labels of the outgoing edge as a sequence (the labels of the incoming edge will be the first in - * the sequence). - * - * @param location The location to remove - */ - private fun removeMiddleLocation(location: XcfaLocation): Boolean { - if (location.outgoingEdges.size != 1) return false - val outEdge = location.outgoingEdges.first() - if ( - location.incomingEdges.any { edge -> edge.getFlatLabels().any { it is InvokeLabel } } - || location.outgoingEdges.any { edge -> edge.getFlatLabels().any { it is InvokeLabel } } - || (level == LbeLevel.LBE_LOCAL && !atomicPhase && isNotLocal(outEdge)) - ) { - return false - } + /** + * Removes a location whose outgoing degree is 1. A new edge is created for every incoming edge of + * the location combined with the labels of the outgoing edge as a sequence (the labels of the + * incoming edge will be the first in the sequence). + * + * @param location The location to remove + */ + private fun removeMiddleLocation(location: XcfaLocation): Boolean { + if (location.outgoingEdges.size != 1) return false + val outEdge = location.outgoingEdges.first() + if ( + location.incomingEdges.any { edge -> edge.getFlatLabels().any { it is InvokeLabel } } || + location.outgoingEdges.any { edge -> edge.getFlatLabels().any { it is InvokeLabel } } || + (level == LbeLevel.LBE_LOCAL && !atomicPhase && isNotLocal(outEdge)) + ) { + return false + } - builder.removeEdge(outEdge) - builder.removeLoc(location) - val edgesToRemove = location.incomingEdges.toSet() - for (inEdge in edgesToRemove) { - builder.removeEdge(inEdge) - val newLabels = mutableListOf() - newLabels.addAll(inEdge.getFlatLabels()) - newLabels.addAll(outEdge.getFlatLabels()) - builder.addEdge( - XcfaEdge( - inEdge.source, outEdge.target, SequenceLabel(newLabels), - combineMetadata(inEdge.metadata, outEdge.metadata) - ) - ) - } - return true + builder.removeEdge(outEdge) + builder.removeLoc(location) + val edgesToRemove = location.incomingEdges.toSet() + for (inEdge in edgesToRemove) { + builder.removeEdge(inEdge) + val newLabels = mutableListOf() + newLabels.addAll(inEdge.getFlatLabels()) + newLabels.addAll(outEdge.getFlatLabels()) + builder.addEdge( + XcfaEdge( + inEdge.source, + outEdge.target, + SequenceLabel(newLabels), + combineMetadata(inEdge.metadata, outEdge.metadata), + ) + ) } + return true + } - /** - * Determines whether an edge performs only local operations or not (thread start and join operations are not - * considered local here). - * - * @param edge the edge whose "locality" is to be determined - * @return true, if the edge performs at least one non-local operation - */ - private fun isNotLocal(edge: XcfaEdge): Boolean { - return !edge.getFlatLabels().all { label -> - !(label is StartLabel || label is JoinLabel) && label.collectVars().all(builder.getVars()::contains) && - !(label is StmtLabel && label.stmt is AssumeStmt && label.stmt.cond is FalseExpr) && - !(label is FenceLabel && label.labels.any { name -> - listOf("ATOMIC_BEGIN", "mutex_lock", "cond_wait").any { name.startsWith(it) } - }) - } + /** + * Determines whether an edge performs only local operations or not (thread start and join + * operations are not considered local here). + * + * @param edge the edge whose "locality" is to be determined + * @return true, if the edge performs at least one non-local operation + */ + private fun isNotLocal(edge: XcfaEdge): Boolean { + return !edge.getFlatLabels().all { label -> + !(label is StartLabel || label is JoinLabel) && + label.collectVars().all(builder.getVars()::contains) && + !(label is StmtLabel && label.stmt is AssumeStmt && label.stmt.cond is FalseExpr) && + !(label is FenceLabel && + label.labels.any { name -> + listOf("ATOMIC_BEGIN", "mutex_lock", "cond_wait").any { name.startsWith(it) } + }) } -} \ No newline at end of file + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt index 0c34b94caa..52757d4551 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LoopUnrollPass.kt @@ -33,276 +33,300 @@ import hu.bme.mit.theta.xcfa.model.* import java.util.* /** - * Unrolls loops where the number of loop executions can be determined statically. - * The UNROLL_LIMIT refers to the number of loop executions: loops that are executed more times than this limit - * are not unrolled. Loops with unknown number of iterations are unrolled to FORCE_UNROLL_LIMIT iterations (this - * way a safe result might not be valid). + * Unrolls loops where the number of loop executions can be determined statically. The UNROLL_LIMIT + * refers to the number of loop executions: loops that are executed more times than this limit are + * not unrolled. Loops with unknown number of iterations are unrolled to FORCE_UNROLL_LIMIT + * iterations (this way a safe result might not be valid). */ class LoopUnrollPass : ProcedurePass { - companion object { + companion object { - var UNROLL_LIMIT = 1000 - var FORCE_UNROLL_LIMIT = -1 - var FORCE_UNROLL_USED = false + var UNROLL_LIMIT = 1000 + var FORCE_UNROLL_LIMIT = -1 + var FORCE_UNROLL_USED = false - private val solver: Solver = Z3SolverFactory.getInstance().createSolver() - } + private val solver: Solver = Z3SolverFactory.getInstance().createSolver() + } - private val testedLoops = mutableSetOf() + private val testedLoops = mutableSetOf() - private data class Loop( - val loopStart: XcfaLocation, val loopLocs: Set, val loopEdges: Set, - val loopVar: VarDecl<*>?, val loopVarInit: XcfaEdge?, val loopVarModifiers: List?, - val loopStartEdges: List, val exitEdges: Map>, - val properlyUnrollable: Boolean - ) { + private data class Loop( + val loopStart: XcfaLocation, + val loopLocs: Set, + val loopEdges: Set, + val loopVar: VarDecl<*>?, + val loopVarInit: XcfaEdge?, + val loopVarModifiers: List?, + val loopStartEdges: List, + val exitEdges: Map>, + val properlyUnrollable: Boolean, + ) { - private class BasicStmtAction(private val stmt: Stmt) : StmtAction() { - constructor(edge: XcfaEdge) : this(edge.label.toStmt()) - constructor(edges: List) : this(SequenceLabel(edges.map { it.label }).toStmt()) + private class BasicStmtAction(private val stmt: Stmt) : StmtAction() { + constructor(edge: XcfaEdge) : this(edge.label.toStmt()) - override fun getStmts() = listOf(stmt) - } + constructor(edges: List) : this(SequenceLabel(edges.map { it.label }).toStmt()) - fun unroll(builder: XcfaProcedureBuilder, transFunc: ExplStmtTransFunc) { - val count = count(transFunc) - if (count != null) { - unroll(builder, count, true) - } else if (FORCE_UNROLL_LIMIT != -1) { - FORCE_UNROLL_USED = true - unroll(builder, FORCE_UNROLL_LIMIT, false) - } - } + override fun getStmts() = listOf(stmt) + } - fun unroll(builder: XcfaProcedureBuilder, count: Int, removeCond: Boolean) { - (loopLocs - loopStart).forEach(builder::removeLoc) - loopLocs.flatMap { it.outgoingEdges }.forEach(builder::removeEdge) + fun unroll(builder: XcfaProcedureBuilder, transFunc: ExplStmtTransFunc) { + val count = count(transFunc) + if (count != null) { + unroll(builder, count, true) + } else if (FORCE_UNROLL_LIMIT != -1) { + FORCE_UNROLL_USED = true + unroll(builder, FORCE_UNROLL_LIMIT, false) + } + } - var startLocation = loopStart - for (i in 0 until count) { - startLocation = copyBody(builder, startLocation, i, removeCond) - } + fun unroll(builder: XcfaProcedureBuilder, count: Int, removeCond: Boolean) { + (loopLocs - loopStart).forEach(builder::removeLoc) + loopLocs.flatMap { it.outgoingEdges }.forEach(builder::removeEdge) - exitEdges[loopStart]?.forEach { edge -> - val label = if (removeCond) edge.label.removeCondition() else edge.label - builder.addEdge(XcfaEdge(startLocation, edge.target, label, edge.metadata)) - } - } + var startLocation = loopStart + for (i in 0 until count) { + startLocation = copyBody(builder, startLocation, i, removeCond) + } - private fun count(transFunc: ExplStmtTransFunc): Int? { - if (!properlyUnrollable) return null - check(loopVar != null && loopVarModifiers != null && loopVarInit != null) - check(loopStartEdges.size == 1) - - val prec = ExplPrec.of(listOf(loopVar)) - var state = ExplState.of(ImmutableValuation.empty()) - state = transFunc.getSuccStates(state, BasicStmtAction(loopVarInit), prec).first() - - var cnt = 0 - val loopCondAction = BasicStmtAction(loopStartEdges.first()) - while (!transFunc.getSuccStates(state, loopCondAction, prec).first().isBottom) { - cnt++ - if (UNROLL_LIMIT in 0 until cnt) return null - state = transFunc.getSuccStates(state, BasicStmtAction(loopVarModifiers), prec).first() - } - return cnt - } - - private fun copyBody(builder: XcfaProcedureBuilder, startLoc: XcfaLocation, index: Int, removeCond: Boolean) - : XcfaLocation { - val locs = loopLocs.associateWith { - val loc = XcfaLocation("${it.name}_loop${index}", metadata = it.metadata) - builder.addLoc(loc) - loc - } - - loopEdges.forEach { - val newSource = if (it.source == loopStart) startLoc else locs[it.source]!! - val newLabel = if (it.source == loopStart && removeCond) it.label.removeCondition() else it.label - val edge = XcfaEdge(newSource, locs[it.target]!!, newLabel, it.metadata) - builder.addEdge(edge) - } + exitEdges[loopStart]?.forEach { edge -> + val label = if (removeCond) edge.label.removeCondition() else edge.label + builder.addEdge(XcfaEdge(startLocation, edge.target, label, edge.metadata)) + } + } - exitEdges.forEach { (loc, edges) -> - for (edge in edges) { - if (removeCond && loc == loopStart) continue - val source = if (loc == loopStart) startLoc else locs[loc]!! - builder.addEdge(XcfaEdge(source, edge.target, edge.label, edge.metadata)) - } - } + private fun count(transFunc: ExplStmtTransFunc): Int? { + if (!properlyUnrollable) return null + check(loopVar != null && loopVarModifiers != null && loopVarInit != null) + check(loopStartEdges.size == 1) + + val prec = ExplPrec.of(listOf(loopVar)) + var state = ExplState.of(ImmutableValuation.empty()) + state = transFunc.getSuccStates(state, BasicStmtAction(loopVarInit), prec).first() + + var cnt = 0 + val loopCondAction = BasicStmtAction(loopStartEdges.first()) + while (!transFunc.getSuccStates(state, loopCondAction, prec).first().isBottom) { + cnt++ + if (UNROLL_LIMIT in 0 until cnt) return null + state = transFunc.getSuccStates(state, BasicStmtAction(loopVarModifiers), prec).first() + } + return cnt + } - return locs[loopStart]!! + private fun copyBody( + builder: XcfaProcedureBuilder, + startLoc: XcfaLocation, + index: Int, + removeCond: Boolean, + ): XcfaLocation { + val locs = + loopLocs.associateWith { + val loc = XcfaLocation("${it.name}_loop${index}", metadata = it.metadata) + builder.addLoc(loc) + loc } - private fun XcfaLabel.removeCondition(): XcfaLabel { - val stmtToRemove = getFlatLabels().find { - it is StmtLabel && it.stmt is AssumeStmt && (it.collectVars() - loopVar).isEmpty() - } - return when { - this == stmtToRemove -> NopLabel - this is SequenceLabel -> SequenceLabel(labels.map { it.removeCondition() }, metadata) - else -> this - } + loopEdges.forEach { + val newSource = if (it.source == loopStart) startLoc else locs[it.source]!! + val newLabel = + if (it.source == loopStart && removeCond) it.label.removeCondition() else it.label + val edge = XcfaEdge(newSource, locs[it.target]!!, newLabel, it.metadata) + builder.addEdge(edge) + } + + exitEdges.forEach { (loc, edges) -> + for (edge in edges) { + if (removeCond && loc == loopStart) continue + val source = if (loc == loopStart) startLoc else locs[loc]!! + builder.addEdge(XcfaEdge(source, edge.target, edge.label, edge.metadata)) } + } + + return locs[loopStart]!! } - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - val transFunc = ExplStmtTransFunc.create(solver, 1) - while (true) { - val loop = findLoop(builder.initLoc) ?: break - loop.unroll(builder, transFunc) - testedLoops.add(loop) + private fun XcfaLabel.removeCondition(): XcfaLabel { + val stmtToRemove = + getFlatLabels().find { + it is StmtLabel && it.stmt is AssumeStmt && (it.collectVars() - loopVar).isEmpty() } - return builder + return when { + this == stmtToRemove -> NopLabel + this is SequenceLabel -> SequenceLabel(labels.map { it.removeCondition() }, metadata) + else -> this + } } - - private fun findLoop(initLoc: XcfaLocation): Loop? { // DFS - val stack = Stack() - val explored = mutableSetOf() - stack.push(initLoc) - while (stack.isNotEmpty()) { - val current = stack.peek() - val edgesToExplore = current.outgoingEdges subtract explored - if (edgesToExplore.isEmpty()) { - stack.pop() - } else { - val edge = edgesToExplore.random() - if (edge.target in stack) { // loop found - getLoop(edge.target)?.let { return it } - } else { - stack.push(edge.target) - } - explored.add(edge) - } + } + + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + val transFunc = ExplStmtTransFunc.create(solver, 1) + while (true) { + val loop = findLoop(builder.initLoc) ?: break + loop.unroll(builder, transFunc) + testedLoops.add(loop) + } + return builder + } + + private fun findLoop(initLoc: XcfaLocation): Loop? { // DFS + val stack = Stack() + val explored = mutableSetOf() + stack.push(initLoc) + while (stack.isNotEmpty()) { + val current = stack.peek() + val edgesToExplore = current.outgoingEdges subtract explored + if (edgesToExplore.isEmpty()) { + stack.pop() + } else { + val edge = edgesToExplore.random() + if (edge.target in stack) { // loop found + getLoop(edge.target)?.let { + return it + } + } else { + stack.push(edge.target) } - return null + explored.add(edge) + } + } + return null + } + + /** Find a loop from the given start location that can be unrolled. */ + private fun getLoop(loopStart: XcfaLocation): Loop? { + var properlyUnrollable = true + if (loopStart.outgoingEdges.size != 2) { + properlyUnrollable = false // more than two outgoing edges from the loop start not supported } - /** - * Find a loop from the given start location that can be unrolled. - */ - private fun getLoop(loopStart: XcfaLocation): Loop? { - var properlyUnrollable = true - if (loopStart.outgoingEdges.size != 2) { - properlyUnrollable = false // more than two outgoing edges from the loop start not supported + val (loopLocations, loopEdges) = getLoopElements(loopStart) + if (loopEdges.isEmpty()) return null // unsupported loop structure + + val loopCondEdges = loopStart.outgoingEdges.filter { it.target in loopLocations } + if (loopCondEdges.size != 1) + properlyUnrollable = false // more than one loop condition not supported + + // find the loop variable based on the outgoing edges from the loop start location + val loopVar = + loopStart.outgoingEdges + .map { + val vars = it.label.collectVarsWithAccessType() + if (vars.size != 1) { + null // multiple variables in the loop condition not supported + } else { + vars.keys.first() + } + } + .reduce { v1, v2 -> if (v1 != v2) null else v1 } + if (loopVar == null) properlyUnrollable = false + + val (loopVarInit, loopVarModifiers) = + run { + if (!properlyUnrollable) return@run null + + // find (a subset of) edges that are executed in every loop iteration + var edge = loopStart.outgoingEdges.find { it.target in loopLocations }!! + val necessaryLoopEdges = mutableSetOf(edge) + while (edge.target.outgoingEdges.size == 1) { + edge = edge.target.outgoingEdges.first() + necessaryLoopEdges.add(edge) + } + val finalEdges = loopStart.incomingEdges.filter { it.source in loopLocations } + if (finalEdges.size == 1) { + edge = finalEdges.first() + necessaryLoopEdges.add(edge) + while (edge.source.incomingEdges.size == 1) { + edge = edge.source.incomingEdges.first() + necessaryLoopEdges.add(edge) + } } - val (loopLocations, loopEdges) = getLoopElements(loopStart) - if (loopEdges.isEmpty()) return null // unsupported loop structure - - val loopCondEdges = loopStart.outgoingEdges.filter { it.target in loopLocations } - if (loopCondEdges.size != 1) properlyUnrollable = false // more than one loop condition not supported - - // find the loop variable based on the outgoing edges from the loop start location - val loopVar = loopStart.outgoingEdges.map { + // find edges that modify the loop variable + val loopVarModifiers = + loopEdges.filter { val vars = it.label.collectVarsWithAccessType() - if (vars.size != 1) { - null // multiple variables in the loop condition not supported + if (vars[loopVar].isWritten) { + if (it !in necessaryLoopEdges || vars.size > 1) + return@run null // loop variable modification cannot be determined statically + true } else { - vars.keys.first() - } - }.reduce { v1, v2 -> if (v1 != v2) null else v1 } - if (loopVar == null) properlyUnrollable = false - - val (loopVarInit, loopVarModifiers) = run { - if (!properlyUnrollable) return@run null - - // find (a subset of) edges that are executed in every loop iteration - var edge = loopStart.outgoingEdges.find { it.target in loopLocations }!! - val necessaryLoopEdges = mutableSetOf(edge) - while (edge.target.outgoingEdges.size == 1) { - edge = edge.target.outgoingEdges.first() - necessaryLoopEdges.add(edge) - } - val finalEdges = loopStart.incomingEdges.filter { it.source in loopLocations } - if (finalEdges.size == 1) { - edge = finalEdges.first() - necessaryLoopEdges.add(edge) - while (edge.source.incomingEdges.size == 1) { - edge = edge.source.incomingEdges.first() - necessaryLoopEdges.add(edge) - } - } - - // find edges that modify the loop variable - val loopVarModifiers = loopEdges.filter { - val vars = it.label.collectVarsWithAccessType() - if (vars[loopVar].isWritten) { - if (it !in necessaryLoopEdges || vars.size > 1) return@run null // loop variable modification cannot be determined statically - true - } else { - false - } - } - - // find loop variable initialization before the loop - lateinit var loopVarInit: XcfaEdge - var loc = loopStart - while (true) { - val inEdges = loc.incomingEdges.filter { it.source !in loopLocations } - if (inEdges.size != 1) return@run null - val inEdge = inEdges.first() - val vars = inEdge.label.collectVarsWithAccessType() - if (vars[loopVar].isWritten) { - if (vars.size > 1) return@run null - loopVarInit = inEdge - break - } - loc = inEdge.source + false } + } - loopVarInit to loopVarModifiers - } ?: run { - properlyUnrollable = false - null to null + // find loop variable initialization before the loop + lateinit var loopVarInit: XcfaEdge + var loc = loopStart + while (true) { + val inEdges = loc.incomingEdges.filter { it.source !in loopLocations } + if (inEdges.size != 1) return@run null + val inEdge = inEdges.first() + val vars = inEdge.label.collectVarsWithAccessType() + if (vars[loopVar].isWritten) { + if (vars.size > 1) return@run null + loopVarInit = inEdge + break + } + loc = inEdge.source } - val exits = loopLocations.mapNotNull { loc -> - val exitEdges = loc.outgoingEdges.filter { it.target !in loopLocations } - if (exitEdges.isEmpty()) null else (loc to exitEdges) - }.toMap() - return Loop( - loopStart = loopStart, - loopLocs = loopLocations, - loopEdges = loopEdges, - loopVar = loopVar, - loopVarInit = loopVarInit, - loopVarModifiers = loopVarModifiers, - loopStartEdges = loopCondEdges, - exitEdges = exits, - properlyUnrollable = properlyUnrollable, - ).also { if (it in testedLoops) return null } - } - - /** - * Find loop locations and edges. - */ - private fun getLoopElements(loopStart: XcfaLocation): Pair, Set> { - val backSearch: (XcfaLocation) -> Pair, List>? = backSearch@{ startLoc -> - val locs = mutableSetOf() - val edges = mutableListOf() - val toVisit = mutableListOf(startLoc) - while (toVisit.isNotEmpty()) { - val current = toVisit.removeFirst() - if (current == loopStart) continue - if (current.incomingEdges.size == 0) return@backSearch null // not part of the loop - if (locs.add(current)) { - edges.addAll(current.incomingEdges) - toVisit.addAll(current.incomingEdges.map { it.source }) - } - } - locs to edges + loopVarInit to loopVarModifiers + } + ?: run { + properlyUnrollable = false + null to null } - val locs = mutableSetOf(loopStart) - val edges = mutableSetOf() - loopStart.incomingEdges.forEach { incoming -> - val (l, e) = backSearch(incoming.source) ?: return@forEach - locs.addAll(l) - edges.addAll(e) - edges.add(incoming) + val exits = + loopLocations + .mapNotNull { loc -> + val exitEdges = loc.outgoingEdges.filter { it.target !in loopLocations } + if (exitEdges.isEmpty()) null else (loc to exitEdges) + } + .toMap() + return Loop( + loopStart = loopStart, + loopLocs = loopLocations, + loopEdges = loopEdges, + loopVar = loopVar, + loopVarInit = loopVarInit, + loopVarModifiers = loopVarModifiers, + loopStartEdges = loopCondEdges, + exitEdges = exits, + properlyUnrollable = properlyUnrollable, + ) + .also { if (it in testedLoops) return null } + } + + /** Find loop locations and edges. */ + private fun getLoopElements(loopStart: XcfaLocation): Pair, Set> { + val backSearch: (XcfaLocation) -> Pair, List>? = + backSearch@{ startLoc -> + val locs = mutableSetOf() + val edges = mutableListOf() + val toVisit = mutableListOf(startLoc) + while (toVisit.isNotEmpty()) { + val current = toVisit.removeFirst() + if (current == loopStart) continue + if (current.incomingEdges.size == 0) return@backSearch null // not part of the loop + if (locs.add(current)) { + edges.addAll(current.incomingEdges) + toVisit.addAll(current.incomingEdges.map { it.source }) + } } - return locs to edges + locs to edges + } + + val locs = mutableSetOf(loopStart) + val edges = mutableSetOf() + loopStart.incomingEdges.forEach { incoming -> + val (l, e) = backSearch(incoming.source) ?: return@forEach + locs.addAll(l) + edges.addAll(e) + edges.add(incoming) } -} \ No newline at end of file + return locs to edges + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt index c505d0e99b..0ee0c65b9d 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.core.decl.Decls.Var @@ -31,63 +30,88 @@ import hu.bme.mit.theta.xcfa.model.* import org.abego.treelayout.internal.util.Contract.checkState /** - * Transforms mallocs into address assignments. - * Requires the ProcedureBuilder be `deterministic`. + * Transforms mallocs into address assignments. Requires the ProcedureBuilder be `deterministic`. */ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { - private val XcfaBuilder.malloc: VarDecl<*> by lazy { - Var("__malloc", CPointer(null, null, parseContext).smtType) - } + private val XcfaBuilder.malloc: VarDecl<*> by lazy { + Var("__malloc", CPointer(null, null, parseContext).smtType) + } - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - checkNotNull(builder.metaData["deterministic"]) - for (edge in ArrayList(builder.getEdges())) { - val edges = edge.splitIf(this::predicate) - if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { - builder.removeEdge(edge) - edges.forEach { - if (predicate((it.label as SequenceLabel).labels[0])) { - val invokeLabel = it.label.labels[0] as InvokeLabel - val ret = invokeLabel.params[0] as RefExpr<*> - val mallocVar = builder.parent.malloc - if (builder.parent.getVars().none { it.wrappedVar == mallocVar }) { // initial creation - builder.parent.addVar( - XcfaGlobalVar(mallocVar, CComplexType.getType(ret, parseContext).nullValue)) - val initProc = builder.parent.getInitProcedures().map { it.first } - checkState(initProc.size == 1, "Multiple start procedure are not handled well") - initProc.forEach { - val initAssign = StmtLabel(Assign(cast(mallocVar, mallocVar.type), - cast(CComplexType.getType(ret, parseContext).nullValue, mallocVar.type))) - val newEdges = it.initLoc.outgoingEdges.map { - it.withLabel( - SequenceLabel(listOf(initAssign) + it.label.getFlatLabels(), it.label.metadata)) - } - it.initLoc.outgoingEdges.forEach(it::removeEdge) - newEdges.forEach(it::addEdge) - } - } - val assign1 = AssignStmt.of( - cast(mallocVar, ret.type), - cast(Add(mallocVar.ref, CComplexType.getType(ret, parseContext).getValue("3")), - ret.type)) - val assign2 = AssignStmt.of( - cast(ret.decl as VarDecl<*>, ret.type), cast(mallocVar.ref, ret.type)) - builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( - listOf( - StmtLabel(assign1, metadata = invokeLabel.metadata), - StmtLabel(assign2, metadata = invokeLabel.metadata))), it.metadata)) - } else { - builder.addEdge(it) - } - } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + checkNotNull(builder.metaData["deterministic"]) + for (edge in ArrayList(builder.getEdges())) { + val edges = edge.splitIf(this::predicate) + if ( + edges.size > 1 || + (edges.size == 1 && predicate((edges[0].label as SequenceLabel).labels[0])) + ) { + builder.removeEdge(edge) + edges.forEach { + if (predicate((it.label as SequenceLabel).labels[0])) { + val invokeLabel = it.label.labels[0] as InvokeLabel + val ret = invokeLabel.params[0] as RefExpr<*> + val mallocVar = builder.parent.malloc + if (builder.parent.getVars().none { it.wrappedVar == mallocVar }) { // initial creation + builder.parent.addVar( + XcfaGlobalVar(mallocVar, CComplexType.getType(ret, parseContext).nullValue) + ) + val initProc = builder.parent.getInitProcedures().map { it.first } + checkState(initProc.size == 1, "Multiple start procedure are not handled well") + initProc.forEach { + val initAssign = + StmtLabel( + Assign( + cast(mallocVar, mallocVar.type), + cast(CComplexType.getType(ret, parseContext).nullValue, mallocVar.type), + ) + ) + val newEdges = + it.initLoc.outgoingEdges.map { + it.withLabel( + SequenceLabel( + listOf(initAssign) + it.label.getFlatLabels(), + it.label.metadata, + ) + ) + } + it.initLoc.outgoingEdges.forEach(it::removeEdge) + newEdges.forEach(it::addEdge) + } } + val assign1 = + AssignStmt.of( + cast(mallocVar, ret.type), + cast( + Add(mallocVar.ref, CComplexType.getType(ret, parseContext).getValue("3")), + ret.type, + ), + ) + val assign2 = + AssignStmt.of(cast(ret.decl as VarDecl<*>, ret.type), cast(mallocVar.ref, ret.type)) + builder.addEdge( + XcfaEdge( + it.source, + it.target, + SequenceLabel( + listOf( + StmtLabel(assign1, metadata = invokeLabel.metadata), + StmtLabel(assign2, metadata = invokeLabel.metadata), + ) + ), + it.metadata, + ) + ) + } else { + builder.addEdge(it) + } } - return builder + } } + return builder + } - private fun predicate(it: XcfaLabel): Boolean { - return it is InvokeLabel && it.name == "malloc" - } -} \ No newline at end of file + private fun predicate(it: XcfaLabel): Boolean { + return it is InvokeLabel && it.name == "malloc" + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt index 2737d1dbb1..c5e531a058 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt @@ -13,42 +13,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.frontend.ParseContext import hu.bme.mit.theta.xcfa.model.* /** - * Transforms all ignored calls into nop/skip labels. - * Requires the ProcedureBuilder be `deterministic`. + * Transforms all ignored calls into nop/skip labels. Requires the ProcedureBuilder be + * `deterministic`. */ class NoSideEffectPass(val parseContext: ParseContext) : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - checkNotNull(builder.metaData["deterministic"]) - for (edge in ArrayList(builder.getEdges())) { - val edges = edge.splitIf(this::predicate) - if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { - builder.removeEdge(edge) - edges.forEach { - if (predicate((it.label as SequenceLabel).labels[0])) { - builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel(listOf(NopLabel)), it.metadata)) - } else { - builder.addEdge(it) - } - } - } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + checkNotNull(builder.metaData["deterministic"]) + for (edge in ArrayList(builder.getEdges())) { + val edges = edge.splitIf(this::predicate) + if ( + edges.size > 1 || + (edges.size == 1 && predicate((edges[0].label as SequenceLabel).labels[0])) + ) { + builder.removeEdge(edge) + edges.forEach { + if (predicate((it.label as SequenceLabel).labels[0])) { + builder.addEdge( + XcfaEdge(it.source, it.target, SequenceLabel(listOf(NopLabel)), it.metadata) + ) + } else { + builder.addEdge(it) + } } - return builder + } } + return builder + } - private fun predicate(label: XcfaLabel): Boolean { - return label is InvokeLabel && listOf( - Regex("sleep"), - Regex("free"), - Regex("pthread_mutex_destroy"), // TODO: is this safe? - ).any { label.name.matches(it) } - } -} \ No newline at end of file + private fun predicate(label: XcfaLabel): Boolean { + return label is InvokeLabel && + listOf( + Regex("sleep"), + Regex("free"), + Regex("pthread_mutex_destroy"), // TODO: is this safe? + ) + .any { label.name.matches(it) } + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt index 9c2819461c..3e5167823a 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.core.decl.VarDecl @@ -21,36 +20,40 @@ import hu.bme.mit.theta.core.stmt.HavocStmt import hu.bme.mit.theta.core.type.anytype.RefExpr import hu.bme.mit.theta.xcfa.model.* -/** - * Transforms all procedure calls into havocs. - * Requires the ProcedureBuilder be `deterministic`. - */ +/** Transforms all procedure calls into havocs. Requires the ProcedureBuilder be `deterministic`. */ class NondetFunctionPass : ProcedurePass { - override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { - checkNotNull(builder.metaData["deterministic"]) - for (edge in ArrayList(builder.getEdges())) { - val edges = edge.splitIf(this::predicate) - if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { - builder.removeEdge(edge) - edges.forEach { - if (predicate((it.label as SequenceLabel).labels[0])) { - val invokeLabel = it.label.labels[0] as InvokeLabel - val havoc = HavocStmt.of( - (invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*>) - builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( - listOf(StmtLabel(havoc, metadata = invokeLabel.metadata))), it.metadata)) - } else { - builder.addEdge(it) - } - } - } + override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { + checkNotNull(builder.metaData["deterministic"]) + for (edge in ArrayList(builder.getEdges())) { + val edges = edge.splitIf(this::predicate) + if ( + edges.size > 1 || + (edges.size == 1 && predicate((edges[0].label as SequenceLabel).labels[0])) + ) { + builder.removeEdge(edge) + edges.forEach { + if (predicate((it.label as SequenceLabel).labels[0])) { + val invokeLabel = it.label.labels[0] as InvokeLabel + val havoc = HavocStmt.of((invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*>) + builder.addEdge( + XcfaEdge( + it.source, + it.target, + SequenceLabel(listOf(StmtLabel(havoc, metadata = invokeLabel.metadata))), + it.metadata, + ) + ) + } else { + builder.addEdge(it) + } } - return builder + } } + return builder + } - private fun predicate(it: XcfaLabel): Boolean { - return it is InvokeLabel && it.name.startsWith("__VERIFIER_nondet") - } -} \ No newline at end of file + private fun predicate(it: XcfaLabel): Boolean { + return it is InvokeLabel && it.name.startsWith("__VERIFIER_nondet") + } +} diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt index 43594c362a..6c00d3f8f2 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.passes import hu.bme.mit.theta.core.decl.Decl @@ -30,137 +29,162 @@ import hu.bme.mit.theta.xcfa.getFlatLabels import hu.bme.mit.theta.xcfa.model.* import java.util.* -/** - * XcfaEdge must be in a `deterministic` ProcedureBuilder - */ +/** XcfaEdge must be in a `deterministic` ProcedureBuilder */ fun XcfaEdge.splitIf(function: (XcfaLabel) -> Boolean): List { - check(label is SequenceLabel) - val newLabels = ArrayList() - var current = ArrayList() - for (label in label.labels) { - if (function(label)) { - if (current.size > 0) { - newLabels.add(SequenceLabel(current)) - current = ArrayList() - } - newLabels.add(SequenceLabel(listOf(label))) - } else { - current.add(label) - } + check(label is SequenceLabel) + val newLabels = ArrayList() + var current = ArrayList() + for (label in label.labels) { + if (function(label)) { + if (current.size > 0) { + newLabels.add(SequenceLabel(current)) + current = ArrayList() + } + newLabels.add(SequenceLabel(listOf(label))) + } else { + current.add(label) } - if (current.size > 0) newLabels.add(SequenceLabel(current)) - - val locations = ArrayList() - locations.add(source) - for (i in 2..(newLabels.size)) { - locations.add(XcfaLocation("loc" + XcfaLocation.uniqueCounter(), metadata = EmptyMetaData)) - } - locations.add(target) - - val newEdges = ArrayList() - for ((i, label) in newLabels.withIndex()) { - newEdges.add(XcfaEdge(locations[i], locations[i + 1], label, metadata)) - } - return newEdges + } + if (current.size > 0) newLabels.add(SequenceLabel(current)) + + val locations = ArrayList() + locations.add(source) + for (i in 2..(newLabels.size)) { + locations.add(XcfaLocation("loc" + XcfaLocation.uniqueCounter(), metadata = EmptyMetaData)) + } + locations.add(target) + + val newEdges = ArrayList() + for ((i, label) in newLabels.withIndex()) { + newEdges.add(XcfaEdge(locations[i], locations[i + 1], label, metadata)) + } + return newEdges } fun Stmt.flatten(): List { - return when (this) { - is SequenceStmt -> stmts.map { it.flatten() }.flatten() - is NonDetStmt -> error("Not possible") - else -> listOf(this) - } + return when (this) { + is SequenceStmt -> stmts.map { it.flatten() }.flatten() + is NonDetStmt -> error("Not possible") + else -> listOf(this) + } } @JvmOverloads -fun XcfaLabel.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): XcfaLabel = - if (varLut.isNotEmpty()) - when (this) { - is InvokeLabel -> InvokeLabel(name, params.map { it.changeVars(varLut, parseContext) }, - metadata = metadata) - - is JoinLabel -> JoinLabel(pidVar.changeVars(varLut), metadata = metadata) - is NondetLabel -> NondetLabel(labels.map { it.changeVars(varLut, parseContext) }.toSet(), - metadata = metadata) - - is ReadLabel -> ReadLabel(local.changeVars(varLut), global.changeVars(varLut), labels, - metadata = metadata) - - is SequenceLabel -> SequenceLabel(labels.map { it.changeVars(varLut, parseContext) }, - metadata = metadata) - - is StartLabel -> StartLabel(name, params.map { it.changeVars(varLut, parseContext) }, - pidVar.changeVars(varLut), metadata = metadata) - - is StmtLabel -> StmtLabel(stmt.changeVars(varLut, parseContext), metadata = metadata, - choiceType = this.choiceType) - - is WriteLabel -> WriteLabel(local.changeVars(varLut), global.changeVars(varLut), labels, - metadata = metadata) - - is ReturnLabel -> ReturnLabel(enclosedLabel.changeVars(varLut)) - - else -> this - } - else this +fun XcfaLabel.changeVars( + varLut: Map, VarDecl<*>>, + parseContext: ParseContext? = null, +): XcfaLabel = + if (varLut.isNotEmpty()) + when (this) { + is InvokeLabel -> + InvokeLabel(name, params.map { it.changeVars(varLut, parseContext) }, metadata = metadata) + + is JoinLabel -> JoinLabel(pidVar.changeVars(varLut), metadata = metadata) + is NondetLabel -> + NondetLabel(labels.map { it.changeVars(varLut, parseContext) }.toSet(), metadata = metadata) + + is ReadLabel -> + ReadLabel(local.changeVars(varLut), global.changeVars(varLut), labels, metadata = metadata) + + is SequenceLabel -> + SequenceLabel(labels.map { it.changeVars(varLut, parseContext) }, metadata = metadata) + + is StartLabel -> + StartLabel( + name, + params.map { it.changeVars(varLut, parseContext) }, + pidVar.changeVars(varLut), + metadata = metadata, + ) + + is StmtLabel -> + StmtLabel( + stmt.changeVars(varLut, parseContext), + metadata = metadata, + choiceType = this.choiceType, + ) + + is WriteLabel -> + WriteLabel(local.changeVars(varLut), global.changeVars(varLut), labels, metadata = metadata) + + is ReturnLabel -> ReturnLabel(enclosedLabel.changeVars(varLut)) + + else -> this + } + else this @JvmOverloads -fun Stmt.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): Stmt { - val stmt = when (this) { - is AssignStmt<*> -> AssignStmt.of(cast(varDecl.changeVars(varLut), varDecl.type), - cast(expr.changeVars(varLut, parseContext), varDecl.type)) - - is MemoryAssignStmt<*, *, *> -> MemoryAssignStmt.create(deref.changeVars(varLut) as Dereference, - expr.changeVars(varLut)) - - is HavocStmt<*> -> HavocStmt.of(varDecl.changeVars(varLut)) - is AssumeStmt -> AssumeStmt.of(cond.changeVars(varLut, parseContext)) - is SequenceStmt -> SequenceStmt.of(stmts.map { it.changeVars(varLut, parseContext) }) - is SkipStmt -> this - else -> TODO("Not yet implemented") +fun Stmt.changeVars( + varLut: Map, VarDecl<*>>, + parseContext: ParseContext? = null, +): Stmt { + val stmt = + when (this) { + is AssignStmt<*> -> + AssignStmt.of( + cast(varDecl.changeVars(varLut), varDecl.type), + cast(expr.changeVars(varLut, parseContext), varDecl.type), + ) + + is MemoryAssignStmt<*, *, *> -> + MemoryAssignStmt.create( + deref.changeVars(varLut) as Dereference, + expr.changeVars(varLut), + ) + + is HavocStmt<*> -> HavocStmt.of(varDecl.changeVars(varLut)) + is AssumeStmt -> AssumeStmt.of(cond.changeVars(varLut, parseContext)) + is SequenceStmt -> SequenceStmt.of(stmts.map { it.changeVars(varLut, parseContext) }) + is SkipStmt -> this + else -> TODO("Not yet implemented") } - val metadataValue = parseContext?.getMetadata()?.getMetadataValue(this, "sourceStatement") - if (metadataValue?.isPresent == true) - parseContext.getMetadata().create(stmt, "sourceStatement", metadataValue.get()) - return stmt + val metadataValue = parseContext?.getMetadata()?.getMetadataValue(this, "sourceStatement") + if (metadataValue?.isPresent == true) + parseContext.getMetadata().create(stmt, "sourceStatement", metadataValue.get()) + return stmt } @JvmOverloads -fun Expr.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): Expr = - if (this is RefExpr) (decl as Decl).changeVars(varLut).ref - else { - val ret = this.withOps(this.ops.map { it.changeVars(varLut, parseContext) }) - if (parseContext?.metadata?.getMetadataValue(this, "cType")?.isPresent == true) { - parseContext.metadata?.create(ret, "cType", CComplexType.getType(this, parseContext)) - } - ret +fun Expr.changeVars( + varLut: Map, VarDecl<*>>, + parseContext: ParseContext? = null, +): Expr = + if (this is RefExpr) (decl as Decl).changeVars(varLut).ref + else { + val ret = this.withOps(this.ops.map { it.changeVars(varLut, parseContext) }) + if (parseContext?.metadata?.getMetadataValue(this, "cType")?.isPresent == true) { + parseContext.metadata?.create(ret, "cType", CComplexType.getType(this, parseContext)) } + ret + } fun Decl.changeVars(varLut: Map, VarDecl<*>>): Decl = - (varLut[this] as? Decl ?: this) + (varLut[this] as? Decl ?: this) fun VarDecl.changeVars(varLut: Map, VarDecl<*>>): VarDecl = - (varLut[this] ?: this) as VarDecl - + (varLut[this] ?: this) as VarDecl fun XcfaProcedureBuilder.canInline(): Boolean = canInline(LinkedList()) + private fun XcfaProcedureBuilder.canInline(tally: LinkedList): Boolean { - if (metaData["recursive"] != null) return false - if (metaData["canInline"] != null) return true - - tally.push(name) - val recursive = getEdges() - .asSequence() - .map { it.getFlatLabels() }.flatten() - .filterIsInstance() - .mapNotNull { parent.getProcedures().find { proc -> proc.name == it.name } } - .any { tally.contains(it.name) || !it.canInline(tally) } - tally.pop() - metaData[if (recursive) "recursive" else "canInline"] = Unit - return !recursive + if (metaData["recursive"] != null) return false + if (metaData["canInline"] != null) return true + + tally.push(name) + val recursive = + getEdges() + .asSequence() + .map { it.getFlatLabels() } + .flatten() + .filterIsInstance() + .mapNotNull { parent.getProcedures().find { proc -> proc.name == it.name } } + .any { tally.contains(it.name) || !it.canInline(tally) } + tally.pop() + metaData[if (recursive) "recursive" else "canInline"] = Unit + return !recursive } fun combineMetadata(vararg metaData: MetaData): MetaData = combineMetadata(metaData.toList()) fun combineMetadata(metaData: Collection): MetaData = - metaData.reduce { i1, i2 -> i1.combine(i2) } + metaData.reduce { i1, i2 -> i1.combine(i2) } diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt index 456f2e4703..161f8a4f1a 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt @@ -37,83 +37,89 @@ import hu.bme.mit.theta.grammar.gson.StringTypeAdapter import hu.bme.mit.theta.grammar.gson.VarDeclAdapter import hu.bme.mit.theta.xcfa.XcfaScope import hu.bme.mit.theta.xcfa.model.* +import java.util.* import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test -import java.util.* class GsonTest { - private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean): Gson { - val gsonBuilder = GsonBuilder() - lateinit var gson: Gson - gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, XcfaLocationAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, - VarDeclAdapter({ gson }, scope, env, !newScope)) - gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, - StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) - gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, - StringTypeAdapter { ExpressionWrapper(scope, it).instantiate(env) }) - gsonBuilder.registerTypeHierarchyAdapter(Type::class.java, - StringTypeAdapter { TypeWrapper(it).instantiate() }) - gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, - StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, - XcfaLabelAdapter(scope, env, { gson })) - gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) - gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(ParseContext::class.java, - ParseContextAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(FrontendMetadata::class.java, - FrontendMetadataAdapter { gson }) - gson = gsonBuilder.create() - return gson - } - - @Test - fun testRoundtrip() { - val xcfaSource = xcfa("example") { - global { "x" type Int() init "0" } - procedure("main") { - (init to final) { - "proc1"("x") - } - } - procedure("proc1") { - (init to final) { - assume("true") - } - } - } - - val symbolTable = XcfaScope(SymbolTable()) - val x_symbol = NamedSymbol("x") - symbolTable.add(x_symbol) - val env = Env() - env.define(x_symbol, xcfaSource.vars.find { it.wrappedVar.name == "x" }!!.wrappedVar) - val gson = getGson(symbolTable, env, true) + private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean): Gson { + val gsonBuilder = GsonBuilder() + lateinit var gson: Gson + gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, XcfaLocationAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter( + VarDecl::class.java, + VarDeclAdapter({ gson }, scope, env, !newScope), + ) + gsonBuilder.registerTypeHierarchyAdapter( + Stmt::class.java, + StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + Expr::class.java, + StringTypeAdapter { ExpressionWrapper(scope, it).instantiate(env) }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + Type::class.java, + StringTypeAdapter { TypeWrapper(it).instantiate() }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + VarIndexing::class.java, + StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }, + ) + gsonBuilder.registerTypeHierarchyAdapter( + XcfaLabel::class.java, + XcfaLabelAdapter(scope, env, { gson }), + ) + gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) + gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter(ParseContext::class.java, ParseContextAdapter { gson }) + gsonBuilder.registerTypeHierarchyAdapter( + FrontendMetadata::class.java, + FrontendMetadataAdapter { gson }, + ) + gson = gsonBuilder.create() + return gson + } - val output = gson.fromJson(gson.toJson(xcfaSource), XCFA::class.java) - println(xcfaSource) - println(output) - assertEquals(xcfaSource, output) - } + @Test + fun testRoundtrip() { + val xcfaSource = + xcfa("example") { + global { "x" type Int() init "0" } + procedure("main") { (init to final) { "proc1"("x") } } + procedure("proc1") { (init to final) { assume("true") } } + } - @Test - fun testParseContextRoundTrip() { - val parseContext = ParseContext() - parseContext.metadata.create("owner", "key", "value") + val symbolTable = XcfaScope(SymbolTable()) + val x_symbol = NamedSymbol("x") + symbolTable.add(x_symbol) + val env = Env() + env.define(x_symbol, xcfaSource.vars.find { it.wrappedVar.name == "x" }!!.wrappedVar) + val gson = getGson(symbolTable, env, true) - val symbolTable = XcfaScope(SymbolTable()) - val x_symbol = NamedSymbol("x") - symbolTable.add(x_symbol) - val env = Env() + val output = gson.fromJson(gson.toJson(xcfaSource), XCFA::class.java) + println(xcfaSource) + println(output) + assertEquals(xcfaSource, output) + } - val gson = getGson(symbolTable, env, true) - assertEquals(parseContext.metadata.lookupKeyValue, - gson.fromJson(gson.toJson(parseContext), ParseContext::class.java).metadata.lookupKeyValue) + @Test + fun testParseContextRoundTrip() { + val parseContext = ParseContext() + parseContext.metadata.create("owner", "key", "value") - } + val symbolTable = XcfaScope(SymbolTable()) + val x_symbol = NamedSymbol("x") + symbolTable.add(x_symbol) + val env = Env() -} \ No newline at end of file + val gson = getGson(symbolTable, env, true) + assertEquals( + parseContext.metadata.lookupKeyValue, + gson.fromJson(gson.toJson(parseContext), ParseContext::class.java).metadata.lookupKeyValue, + ) + } +} diff --git a/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java b/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java index 7a3a159a80..52ae4fa72d 100644 --- a/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java +++ b/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsHornTest.java @@ -15,6 +15,8 @@ */ package hu.bme.mit.theta.xsts.analysis; +import static org.junit.Assert.assertTrue; + import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.chc.HornChecker; import hu.bme.mit.theta.common.OsHelper; @@ -28,20 +30,17 @@ import hu.bme.mit.theta.xsts.XSTS; import hu.bme.mit.theta.xsts.analysis.util.ChcUtilsKt; import hu.bme.mit.theta.xsts.dsl.XstsDslManager; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - import java.io.FileInputStream; import java.io.InputStream; import java.io.SequenceInputStream; import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; - -import static org.junit.Assert.assertTrue; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; @RunWith(value = Parameterized.class) public class XstsHornTest { @@ -62,294 +61,479 @@ public class XstsHornTest { @Parameterized.Parameters(name = "{index}: {0}, {1}, {2}, {3}") public static Collection data() { - return Arrays.asList(new Object[][]{ - - {"src/test/resources/model/trafficlight.xsts", - "src/test/resources/property/green_and_red.prop", true, - "z3:4.13.0"}, - - {"src/test/resources/model/trafficlight.xsts", - "src/test/resources/property/green_and_red.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/trafficlight.xsts", - "src/test/resources/property/green_and_red.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/trafficlight_v2.xsts", - "src/test/resources/property/green_and_red.prop", true, - "z3:4.13.0"}, - -// {"src/test/resources/model/trafficlight_v2.xsts", -// "src/test/resources/property/green_and_red.prop", true, -// "eldarica:2.1"}, - - {"src/test/resources/model/trafficlight_v2.xsts", - "src/test/resources/property/green_and_red.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/counter5.xsts", - "src/test/resources/property/x_between_0_and_5.prop", true, - "z3:4.13.0"}, - - {"src/test/resources/model/counter5.xsts", - "src/test/resources/property/x_between_0_and_5.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/counter5.xsts", - "src/test/resources/property/x_between_0_and_5.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/counter5.xsts", "src/test/resources/property/x_eq_5.prop", - false, "z3:4.13.0"}, - - {"src/test/resources/model/counter5.xsts", "src/test/resources/property/x_eq_5.prop", - false, "eldarica:2.1"}, - - {"src/test/resources/model/counter5.xsts", "src/test/resources/property/x_eq_5.prop", - false, "golem:0.5.0"}, - - {"src/test/resources/model/x_and_y.xsts", "src/test/resources/property/x_geq_y.prop", - true, "eldarica:2.1"}, - - {"src/test/resources/model/x_powers.xsts", "src/test/resources/property/x_even.prop", - true, "eldarica:2.1"}, - -// {"src/test/resources/model/cross_with.xsts", "src/test/resources/property/cross.prop", -// false, "eldarica:2.1"}, - -// { "src/test/resources/model/cross_with.xsts", "src/test/resources/property/cross.prop", false, "z3:4.13.0"}, - -// { "src/test/resources/model/cross_with.xsts", "src/test/resources/property/cross.prop", false, XstsConfigBuilder.Domain.PROD}, -// -// {"src/test/resources/model/cross_without.xsts", -// "src/test/resources/property/cross.prop", false, -// "eldarica:2.1"}, - -// { "src/test/resources/model/cross_without.xsts", "src/test/resources/property/cross.prop", false, "z3:4.13.0"}, - -// { "src/test/resources/model/cross_without.xsts", "src/test/resources/property/cross.prop", false, XstsConfigBuilder.Domain.PROD}, - - {"src/test/resources/model/choices.xsts", "src/test/resources/property/choices.prop", - false, "eldarica:2.1"}, - - {"src/test/resources/model/choices.xsts", "src/test/resources/property/choices.prop", - false, "z3:4.13.0"}, - - {"src/test/resources/model/choices.xsts", "src/test/resources/property/choices.prop", - false, "golem:0.5.0"}, - - {"src/test/resources/model/literals.xsts", "src/test/resources/property/literals.prop", - false, "eldarica:2.1"}, - - {"src/test/resources/model/literals.xsts", "src/test/resources/property/literals.prop", - false, "z3:4.13.0"}, - - {"src/test/resources/model/literals.xsts", "src/test/resources/property/literals.prop", - false, "golem:0.5.0"}, - -// {"src/test/resources/model/cross3.xsts", "src/test/resources/property/cross.prop", -// false, "eldarica:2.1"}, - -// { "src/test/resources/model/cross3.xsts", "src/test/resources/property/cross.prop", false, "z3:4.13.0"}, - -// { "src/test/resources/model/cross3.xsts", "src/test/resources/property/cross.prop", false, XstsConfigBuilder.Domain.PROD}, - - {"src/test/resources/model/sequential.xsts", - "src/test/resources/property/sequential.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/sequential.xsts", - "src/test/resources/property/sequential.prop", true, "z3:4.13.0"}, - - {"src/test/resources/model/sequential.xsts", - "src/test/resources/property/sequential.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/sequential.xsts", - "src/test/resources/property/sequential2.prop", false, - "eldarica:2.1"}, - - {"src/test/resources/model/sequential.xsts", - "src/test/resources/property/sequential2.prop", false, - "z3:4.13.0"}, - - {"src/test/resources/model/sequential.xsts", - "src/test/resources/property/sequential2.prop", false, - "golem:0.5.0"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine.prop", false, - "eldarica:2.1"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine.prop", false, - "z3:4.13.0"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine.prop", false, - "golem:0.5.0"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine2.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine2.prop", true, - "z3:4.13.0"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine2.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine3.prop", false, - "eldarica:2.1"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine3.prop", false, - "z3:4.13.0"}, - - {"src/test/resources/model/on_off_statemachine.xsts", - "src/test/resources/property/on_off_statemachine3.prop", false, - "golem:0.5.0"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_5.prop", - false, "eldarica:2.1"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_5.prop", - false, "z3:4.13.0"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_5.prop", - false, "golem:0.5.0"}, - -// { "src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_50.prop", false, "eldarica:2.1"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_50.prop", - false, "z3:4.13.0"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_50.prop", - false, "golem:0.5.0"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_51.prop", - true, "eldarica:2.1"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_51.prop", - true, "z3:4.13.0"}, - - {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_51.prop", - true, "golem:0.5.0"}, -// -// {"src/test/resources/model/count_up_down.xsts", -// "src/test/resources/property/count_up_down.prop", false, -// "eldarica:2.1"}, - - {"src/test/resources/model/count_up_down.xsts", - "src/test/resources/property/count_up_down.prop", false, - "z3:4.13.0"}, - - {"src/test/resources/model/count_up_down.xsts", - "src/test/resources/property/count_up_down.prop", false, - "golem:0.5.0"}, - - {"src/test/resources/model/count_up_down.xsts", - "src/test/resources/property/count_up_down2.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/count_up_down.xsts", - "src/test/resources/property/count_up_down2.prop", true, - "z3:4.13.0"}, - - {"src/test/resources/model/count_up_down.xsts", - "src/test/resources/property/count_up_down2.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/bhmr2007.xsts", "src/test/resources/property/bhmr2007.prop", - true, "eldarica:2.1"}, - -// { "src/test/resources/model/bhmr2007.xsts", "src/test/resources/property/bhmr2007.prop", true, "z3:4.13.0"}, - -// { "src/test/resources/model/bhmr2007.xsts", "src/test/resources/property/bhmr2007.prop", true, XstsConfigBuilder.Domain.PROD}, - - {"src/test/resources/model/css2003.xsts", "src/test/resources/property/css2003.prop", - true, "eldarica:2.1"}, - - {"src/test/resources/model/css2003.xsts", "src/test/resources/property/css2003.prop", - true, "z3:4.13.0"}, - - {"src/test/resources/model/css2003.xsts", "src/test/resources/property/css2003.prop", - true, "golem:0.5.0"}, - -// { "src/test/resources/model/ort.xsts", "src/test/resources/property/x_gt_2.prop", false, "eldarica:2.1"}, - -// { "src/test/resources/model/ort2.xsts", "src/test/resources/property/ort2.prop", true, "eldarica:2.1"}, - -// { "src/test/resources/model/crossroad_composite.xsts", "src/test/resources/property/both_green.prop", true, "z3:4.13.0"} - -// {"src/test/resources/model/array_counter.xsts", -// "src/test/resources/property/array_10.prop", false, -// "eldarica:2.1"}, - - {"src/test/resources/model/array_counter.xsts", - "src/test/resources/property/array_10.prop", false, "z3:4.13.0"}, -// -// {"src/test/resources/model/array_counter.xsts", -// "src/test/resources/property/array_10.prop", false, -// "golem:0.5.0"}, -// -// {"src/test/resources/model/array_constant.xsts", -// "src/test/resources/property/array_constant.prop", true, -// "eldarica:2.1"}, - - {"src/test/resources/model/array_constant.xsts", - "src/test/resources/property/array_constant.prop", true, - "z3:4.13.0"}, -// -// {"src/test/resources/model/array_constant.xsts", -// "src/test/resources/property/array_constant.prop", true, -// "golem:0.5.0"}, - - {"src/test/resources/model/localvars.xsts", - "src/test/resources/property/localvars.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/localvars.xsts", - "src/test/resources/property/localvars.prop", true, "z3:4.13.0"}, - - {"src/test/resources/model/localvars.xsts", - "src/test/resources/property/localvars.prop", true, - "golem:0.5.0"}, - - {"src/test/resources/model/localvars2.xsts", - "src/test/resources/property/localvars2.prop", true, - "eldarica:2.1"}, - - {"src/test/resources/model/localvars2.xsts", - "src/test/resources/property/localvars2.prop", true, "z3:4.13.0"}, - - {"src/test/resources/model/localvars2.xsts", - "src/test/resources/property/localvars2.prop", true, - "golem:0.5.0"}, - -// {"src/test/resources/model/loopxy.xsts", "src/test/resources/property/loopxy.prop", -// true, "z3:4.13.0"}, -// -// {"src/test/resources/model/loopxy.xsts", "src/test/resources/property/loopxy.prop", -// true, "golem:0.5.0"}, -// -// {"src/test/resources/model/loopxy.xsts", "src/test/resources/property/loopxy.prop", -// true, "eldarica:2.1"}, - - {"src/test/resources/model/arraywrite_sugar.xsts", - "src/test/resources/property/arraywrite_sugar.prop", false, - "eldarica:2.1"}, -// -// {"src/test/resources/model/if1.xsts", "src/test/resources/property/if1.prop", true, -// "eldarica:2.1"}, - -// {"src/test/resources/model/if2.xsts", "src/test/resources/property/if2.prop", false, -// "golem:0.5.0"} - }); + return Arrays.asList( + new Object[][] { + { + "src/test/resources/model/trafficlight.xsts", + "src/test/resources/property/green_and_red.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/trafficlight.xsts", + "src/test/resources/property/green_and_red.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/trafficlight.xsts", + "src/test/resources/property/green_and_red.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/trafficlight_v2.xsts", + "src/test/resources/property/green_and_red.prop", + true, + "z3:4.13.0" + }, + + // {"src/test/resources/model/trafficlight_v2.xsts", + // "src/test/resources/property/green_and_red.prop", + // true, + // "eldarica:2.1"}, + + { + "src/test/resources/model/trafficlight_v2.xsts", + "src/test/resources/property/green_and_red.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_between_0_and_5.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_between_0_and_5.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_between_0_and_5.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_eq_5.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_eq_5.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_eq_5.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/x_and_y.xsts", + "src/test/resources/property/x_geq_y.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/x_powers.xsts", + "src/test/resources/property/x_even.prop", + true, + "eldarica:2.1" + }, + + // {"src/test/resources/model/cross_with.xsts", + // "src/test/resources/property/cross.prop", + // false, "eldarica:2.1"}, + + // { "src/test/resources/model/cross_with.xsts", + // "src/test/resources/property/cross.prop", false, "z3:4.13.0"}, + + // { "src/test/resources/model/cross_with.xsts", + // "src/test/resources/property/cross.prop", false, + // XstsConfigBuilder.Domain.PROD}, + // + // {"src/test/resources/model/cross_without.xsts", + // "src/test/resources/property/cross.prop", false, + // "eldarica:2.1"}, + + // { "src/test/resources/model/cross_without.xsts", + // "src/test/resources/property/cross.prop", false, "z3:4.13.0"}, + + // { "src/test/resources/model/cross_without.xsts", + // "src/test/resources/property/cross.prop", false, + // XstsConfigBuilder.Domain.PROD}, + + { + "src/test/resources/model/choices.xsts", + "src/test/resources/property/choices.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/choices.xsts", + "src/test/resources/property/choices.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/choices.xsts", + "src/test/resources/property/choices.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/literals.xsts", + "src/test/resources/property/literals.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/literals.xsts", + "src/test/resources/property/literals.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/literals.xsts", + "src/test/resources/property/literals.prop", + false, + "golem:0.5.0" + }, + + // {"src/test/resources/model/cross3.xsts", + // "src/test/resources/property/cross.prop", + // false, "eldarica:2.1"}, + + // { "src/test/resources/model/cross3.xsts", + // "src/test/resources/property/cross.prop", false, "z3:4.13.0"}, + + // { "src/test/resources/model/cross3.xsts", + // "src/test/resources/property/cross.prop", false, + // XstsConfigBuilder.Domain.PROD}, + + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential2.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential2.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential2.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine2.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine2.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine2.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine3.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine3.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine3.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_5.prop", + false, + "eldarica:2.1" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_5.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_5.prop", + false, + "golem:0.5.0" + }, + + // { "src/test/resources/model/counter50.xsts", + // "src/test/resources/property/x_eq_50.prop", false, "eldarica:2.1"}, + + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_50.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_50.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_51.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_51.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/counter50.xsts", + "src/test/resources/property/x_eq_51.prop", + true, + "golem:0.5.0" + }, + // + // {"src/test/resources/model/count_up_down.xsts", + // "src/test/resources/property/count_up_down.prop", + // false, + // "eldarica:2.1"}, + + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down.prop", + false, + "z3:4.13.0" + }, + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down.prop", + false, + "golem:0.5.0" + }, + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down2.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down2.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down2.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/bhmr2007.xsts", + "src/test/resources/property/bhmr2007.prop", + true, + "eldarica:2.1" + }, + + // { "src/test/resources/model/bhmr2007.xsts", + // "src/test/resources/property/bhmr2007.prop", true, "z3:4.13.0"}, + + // { "src/test/resources/model/bhmr2007.xsts", + // "src/test/resources/property/bhmr2007.prop", true, + // XstsConfigBuilder.Domain.PROD}, + + { + "src/test/resources/model/css2003.xsts", + "src/test/resources/property/css2003.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/css2003.xsts", + "src/test/resources/property/css2003.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/css2003.xsts", + "src/test/resources/property/css2003.prop", + true, + "golem:0.5.0" + }, + + // { "src/test/resources/model/ort.xsts", + // "src/test/resources/property/x_gt_2.prop", false, "eldarica:2.1"}, + + // { "src/test/resources/model/ort2.xsts", + // "src/test/resources/property/ort2.prop", true, "eldarica:2.1"}, + + // { "src/test/resources/model/crossroad_composite.xsts", + // "src/test/resources/property/both_green.prop", true, "z3:4.13.0"} + + // {"src/test/resources/model/array_counter.xsts", + // "src/test/resources/property/array_10.prop", false, + // "eldarica:2.1"}, + + { + "src/test/resources/model/array_counter.xsts", + "src/test/resources/property/array_10.prop", + false, + "z3:4.13.0" + }, + // + // {"src/test/resources/model/array_counter.xsts", + // "src/test/resources/property/array_10.prop", false, + // "golem:0.5.0"}, + // + // {"src/test/resources/model/array_constant.xsts", + // "src/test/resources/property/array_constant.prop", + // true, + // "eldarica:2.1"}, + + { + "src/test/resources/model/array_constant.xsts", + "src/test/resources/property/array_constant.prop", + true, + "z3:4.13.0" + }, + // + // {"src/test/resources/model/array_constant.xsts", + // "src/test/resources/property/array_constant.prop", + // true, + // "golem:0.5.0"}, + + { + "src/test/resources/model/localvars.xsts", + "src/test/resources/property/localvars.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/localvars.xsts", + "src/test/resources/property/localvars.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/localvars.xsts", + "src/test/resources/property/localvars.prop", + true, + "golem:0.5.0" + }, + { + "src/test/resources/model/localvars2.xsts", + "src/test/resources/property/localvars2.prop", + true, + "eldarica:2.1" + }, + { + "src/test/resources/model/localvars2.xsts", + "src/test/resources/property/localvars2.prop", + true, + "z3:4.13.0" + }, + { + "src/test/resources/model/localvars2.xsts", + "src/test/resources/property/localvars2.prop", + true, + "golem:0.5.0" + }, + + // {"src/test/resources/model/loopxy.xsts", + // "src/test/resources/property/loopxy.prop", + // true, "z3:4.13.0"}, + // + // {"src/test/resources/model/loopxy.xsts", + // "src/test/resources/property/loopxy.prop", + // true, "golem:0.5.0"}, + // + // {"src/test/resources/model/loopxy.xsts", + // "src/test/resources/property/loopxy.prop", + // true, "eldarica:2.1"}, + + { + "src/test/resources/model/arraywrite_sugar.xsts", + "src/test/resources/property/arraywrite_sugar.prop", + false, + "eldarica:2.1" + }, + // + // {"src/test/resources/model/if1.xsts", + // "src/test/resources/property/if1.prop", true, + // "eldarica:2.1"}, + + // {"src/test/resources/model/if2.xsts", + // "src/test/resources/property/if2.prop", false, + // "golem:0.5.0"} + }); } @Before @@ -357,11 +541,20 @@ public void installSolver() { if (solverString.contains("Z3") || solverString.contains("JavaSMT")) { return; } - Assume.assumeTrue(OsHelper.getOs() == OsHelper.OperatingSystem.LINUX); // chc solvers are only properly on linux - try (final var solverManager = SmtLibSolverManager.create(SMTLIB_HOME, new ConsoleLogger(Level.DETAIL))) { + Assume.assumeTrue( + OsHelper.getOs() + == OsHelper.OperatingSystem + .LINUX); // chc solvers are only properly on linux + try (final var solverManager = + SmtLibSolverManager.create(SMTLIB_HOME, new ConsoleLogger(Level.DETAIL))) { String solverVersion = SmtLibSolverManager.getSolverVersion(solverString); String solverName = SmtLibSolverManager.getSolverName(solverString); - if (solverManager.managesSolver(solverString) && !solverManager.getInstalledVersions(solverName).contains(solverManager.getVersionString(solverName, solverVersion, false))) { + if (solverManager.managesSolver(solverString) + && !solverManager + .getInstalledVersions(solverName) + .contains( + solverManager.getVersionString( + solverName, solverVersion, false))) { solverManager.install(solverName, solverVersion, solverVersion, null, false); } } catch (Exception e) { @@ -372,7 +565,8 @@ public void installSolver() { @Test(timeout = 10_000) public void test() throws Exception { final Logger logger = new ConsoleLogger(Level.SUBSTEP); - SolverManager.registerSolverManager(hu.bme.mit.theta.solver.z3legacy.Z3SolverManager.create()); + SolverManager.registerSolverManager( + hu.bme.mit.theta.solver.z3legacy.Z3SolverManager.create()); SolverManager.registerSolverManager(hu.bme.mit.theta.solver.z3.Z3SolverManager.create()); SolverManager.registerSolverManager(SmtLibSolverManager.create(SMTLIB_HOME, logger)); SolverManager.registerSolverManager(JavaSMTSolverManager.create()); @@ -386,19 +580,16 @@ public void test() throws Exception { } XSTS xsts; - try (InputStream inputStream = new SequenceInputStream(new FileInputStream(filePath), - new FileInputStream(propPath))) { + try (InputStream inputStream = + new SequenceInputStream( + new FileInputStream(filePath), new FileInputStream(propPath))) { xsts = XstsDslManager.createXsts(inputStream); } try { final var relations = XstsToRelationsKt.toRelations(xsts); System.err.println(ChcUtilsKt.toSMT2(relations)); - final var checker = new HornChecker( - relations, - solverFactory, - logger - ); + final var checker = new HornChecker(relations, solverFactory, logger); final SafetyResult status = checker.check(); if (safe) { @@ -410,6 +601,4 @@ public void test() throws Exception { SolverManager.closeAll(); } } - } - From a49b95d7046046b8e798b9b0e980831fe9f39730 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:20:43 +0100 Subject: [PATCH 14/18] Formatted files From bda1f7275364776b329780ff50afbcc4ebbdd274 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:21:04 +0100 Subject: [PATCH 15/18] Formatted files From a6abad5e1bb16ee1118436bf66fdf6f00776cce4 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:24:00 +0100 Subject: [PATCH 16/18] version bump --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 06036a38d7..e4cbd21501 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.6.4" + version = "6.6.5" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } From 1ae278cd0a2ee82bc3c161b040ced1261d700315 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 22:58:16 +0100 Subject: [PATCH 17/18] fixed tests for windows --- .../java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt index bc39de1553..27c51fa5cf 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt @@ -46,8 +46,8 @@ class XcfaCliProofTest { WitnessEdge( startlineRange = Pair(5, 5), endlineRange = Pair(5, 5), - startoffsetRange = Pair(80, 82), - endoffsetRange = Pair(112, 114), + startoffsetRange = Pair(80, 90), + endoffsetRange = Pair(112, 122), assumption = Regex("i *== *-1"), ) ), @@ -59,8 +59,8 @@ class XcfaCliProofTest { WitnessEdge( startlineRange = Pair(5, 5), endlineRange = Pair(5, 5), - startoffsetRange = Pair(80, 82), - endoffsetRange = Pair(112, 114), + startoffsetRange = Pair(80, 90), + endoffsetRange = Pair(112, 122), assumption = Regex("i *== *-1"), ) ), From 6fd2d6dea1ca7278a2fa52cc882a5692350ef7f1 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 3 Nov 2024 23:21:12 +0100 Subject: [PATCH 18/18] fixed parsing of labels --- .../hu/bme/mit/theta/xcfa/model/XcfaLabel.kt | 365 +++++++++--------- .../hu/bme/mit/theta/xcfa/gson/GsonTest.kt | 28 ++ 2 files changed, 216 insertions(+), 177 deletions(-) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt index 93f636b306..4e6a2251e0 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.model import hu.bme.mit.theta.common.dsl.Env @@ -30,242 +29,254 @@ import java.util.* sealed class XcfaLabel(open val metadata: MetaData) { - open fun toStmt(): Stmt = Skip() + open fun toStmt(): Stmt = Skip() } -data class InvokeLabel @JvmOverloads constructor( - val name: String, - val params: List>, - override val metadata: MetaData, - val tempLookup: Map, VarDecl<*>> = emptyMap() +data class InvokeLabel +@JvmOverloads +constructor( + val name: String, + val params: List>, + override val metadata: MetaData, + val tempLookup: Map, VarDecl<*>> = emptyMap(), ) : XcfaLabel(metadata) { - override fun toString(): String { - val sj = StringJoiner(", ", "(", ")") - params.forEach { sj.add(it.toString()) } - return "$name$sj" - } - - companion object { - - fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { - val (name, params) = Regex("([^\\(]*)\\((.*)\\)").matchEntire(s)!!.destructured - return InvokeLabel(name, - params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, - metadata = metadata) - } + override fun toString(): String { + val sj = StringJoiner(", ", "(", ")") + params.forEach { sj.add(it.toString()) } + return "$name$sj" + } + + companion object { + + fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { + val (name, params) = Regex("^([^(]*)\\((.*)\\)$").matchEntire(s)!!.destructured + return InvokeLabel( + name, + params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, + metadata = metadata, + ) } + } } data class ReturnLabel(val enclosedLabel: XcfaLabel) : - XcfaLabel(metadata = enclosedLabel.metadata) { + XcfaLabel(metadata = enclosedLabel.metadata) { - override fun toStmt(): Stmt { - return enclosedLabel.toStmt() - } + override fun toStmt(): Stmt { + return enclosedLabel.toStmt() + } - override fun toString(): String { - return "Return ($enclosedLabel)" - } + override fun toString(): String { + return "Return ($enclosedLabel)" + } } data class StartLabel( - val name: String, - val params: List>, - val pidVar: VarDecl<*>, - override val metadata: MetaData, - val tempLookup: Map, VarDecl<*>> = emptyMap() + val name: String, + val params: List>, + val pidVar: VarDecl<*>, + override val metadata: MetaData, + val tempLookup: Map, VarDecl<*>> = emptyMap(), ) : XcfaLabel(metadata = metadata) { - override fun toString(): String { - val sj = StringJoiner(", ", "(", ")") - params.forEach { sj.add(it.toString()) } - return "$pidVar = start $name$sj" - } - - companion object { - - fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { - val (pidVarName, pidVarType, name, params) = Regex( - "\\(var (.*) (.*)\\) = start (.*)\\((.*)\\)").matchEntire(s)!!.destructured - val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> - return StartLabel(name, - params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, pidVar, - metadata = metadata) - } + override fun toString(): String { + val sj = StringJoiner(", ", "(", ")") + params.forEach { sj.add(it.toString()) } + return "$pidVar = start $name$sj" + } + + companion object { + + fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { + val (pidVarName, pidVarType, name, params) = + Regex("^\\(var (.*) (.*)\\) = start ([^(]*)\\((.*)\\)$").matchEntire(s)!!.destructured + val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> + return StartLabel( + name, + params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, + pidVar, + metadata = metadata, + ) } + } } -data class JoinLabel( - val pidVar: VarDecl<*>, - override val metadata: MetaData -) : XcfaLabel(metadata = metadata) { +data class JoinLabel(val pidVar: VarDecl<*>, override val metadata: MetaData) : + XcfaLabel(metadata = metadata) { - override fun toString(): String { - return "join $pidVar" - } + override fun toString(): String { + return "join $pidVar" + } - companion object { + companion object { - fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { - val (pidVarName, pidVarType) = Regex("join \\(var (.*) (.*)\\)").matchEntire( - s)!!.destructured - val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> - return JoinLabel(pidVar, metadata = metadata) - } + fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { + val (pidVarName, pidVarType) = + Regex("^join \\(var (.*) (.*)\\)$").matchEntire(s)!!.destructured + val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> + return JoinLabel(pidVar, metadata = metadata) } + } } enum class ChoiceType { - NONE, - MAIN_PATH, - ALTERNATIVE_PATH + NONE, + MAIN_PATH, + ALTERNATIVE_PATH, } -data class StmtLabel @JvmOverloads constructor( - val stmt: Stmt, - val choiceType: ChoiceType = ChoiceType.NONE, - override val metadata: MetaData = EmptyMetaData +data class StmtLabel +@JvmOverloads +constructor( + val stmt: Stmt, + val choiceType: ChoiceType = ChoiceType.NONE, + override val metadata: MetaData = EmptyMetaData, ) : XcfaLabel(metadata = metadata) { - init { - check( - stmt !is NonDetStmt && stmt !is SequenceStmt) { "NonDetStmt and SequenceStmt are not supported in XCFA. Use the corresponding labels instead." } - } - - override fun toStmt(): Stmt = stmt - override fun toString(): String { - if (choiceType != ChoiceType.NONE) - return "($stmt)[choiceType=$choiceType]" - else - return stmt.toString() + init { + check(stmt !is NonDetStmt && stmt !is SequenceStmt) { + "NonDetStmt and SequenceStmt are not supported in XCFA. Use the corresponding labels instead." } - - companion object { - - fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { - val matchResult = Regex("\\((.*)\\)\\[choiceType=(.*)]").matchEntire(s) - if (matchResult != null) { - val (stmt, choiceTypeStr) = matchResult.destructured - return StmtLabel(StatementWrapper(stmt, scope).instantiate(env), - choiceType = ChoiceType.valueOf(choiceTypeStr), metadata = metadata) - } else { - return StmtLabel(StatementWrapper(s, scope).instantiate(env), - choiceType = ChoiceType.NONE, metadata = metadata) - } - } + } + + override fun toStmt(): Stmt = stmt + + override fun toString(): String { + if (choiceType != ChoiceType.NONE) return "($stmt)[choiceType=$choiceType]" + else return stmt.toString() + } + + companion object { + + fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { + val matchResult = Regex("^\\((.*)\\)\\[choiceType=(.*)]$").matchEntire(s) + if (matchResult != null) { + val (stmt, choiceTypeStr) = matchResult.destructured + return StmtLabel( + StatementWrapper(stmt, scope).instantiate(env), + choiceType = ChoiceType.valueOf(choiceTypeStr), + metadata = metadata, + ) + } else { + return StmtLabel( + StatementWrapper(s, scope).instantiate(env), + choiceType = ChoiceType.NONE, + metadata = metadata, + ) + } } + } } data class ReadLabel( - val local: VarDecl<*>, - val global: VarDecl<*>, - val labels: Set, - override val metadata: MetaData + val local: VarDecl<*>, + val global: VarDecl<*>, + val labels: Set, + override val metadata: MetaData, ) : XcfaLabel(metadata = metadata) { - override fun toString(): String { - return "R[$local <- $global] @$labels" - } + override fun toString(): String { + return "R[$local <- $global] @$labels" + } } -data class WriteLabel constructor( - val local: VarDecl<*>, - val global: VarDecl<*>, - val labels: Set, - override val metadata: MetaData +data class WriteLabel +constructor( + val local: VarDecl<*>, + val global: VarDecl<*>, + val labels: Set, + override val metadata: MetaData, ) : XcfaLabel(metadata = metadata) { - override fun toString(): String { - return "W[$global <- $local] @$labels" - } + override fun toString(): String { + return "W[$global <- $local] @$labels" + } } -data class FenceLabel( - val labels: Set, - override val metadata: MetaData = EmptyMetaData -) : XcfaLabel(metadata = metadata) { +data class FenceLabel(val labels: Set, override val metadata: MetaData = EmptyMetaData) : + XcfaLabel(metadata = metadata) { - override fun toString(): String { - return "F[${labels.joinToString(";")}]" - } + override fun toString(): String { + return "F[${labels.joinToString(";")}]" + } - companion object { + companion object { - fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { - val (labelList) = Regex("F\\[(.*)]").matchEntire(s)!!.destructured - return FenceLabel(labelList.split(";").toSet(), metadata = metadata) - } + fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { + val (labelList) = Regex("^F\\[(.*)]$").matchEntire(s)!!.destructured + return FenceLabel(labelList.split(";").toSet(), metadata = metadata) } + } } -data class SequenceLabel @JvmOverloads constructor( - val labels: List, - override val metadata: MetaData = EmptyMetaData -) : XcfaLabel(metadata = metadata) { +data class SequenceLabel +@JvmOverloads +constructor(val labels: List, override val metadata: MetaData = EmptyMetaData) : + XcfaLabel(metadata = metadata) { - override fun toStmt(): Stmt { - return SequenceStmt(labels.map { it.toStmt() }) - } + override fun toStmt(): Stmt { + return SequenceStmt(labels.map { it.toStmt() }) + } - override fun toString(): String { - val sj = StringJoiner(",", "[", "]") - labels.forEach { sj.add(it.toString()) } - return sj.toString() - } + override fun toString(): String { + val sj = StringJoiner(",", "[", "]") + labels.forEach { sj.add(it.toString()) } + return sj.toString() + } } -data class NondetLabel @JvmOverloads constructor( - val labels: Set, - override val metadata: MetaData = EmptyMetaData -) : XcfaLabel(metadata = metadata) { +data class NondetLabel +@JvmOverloads +constructor(val labels: Set, override val metadata: MetaData = EmptyMetaData) : + XcfaLabel(metadata = metadata) { - override fun toStmt(): Stmt { - return NonDetStmt(labels.map { it.toStmt() }) - } + override fun toStmt(): Stmt { + return NonDetStmt(labels.map { it.toStmt() }) + } - override fun toString(): String { - return "NonDet($labels)" - } + override fun toString(): String { + return "NonDet($labels)" + } } object NopLabel : XcfaLabel(metadata = EmptyMetaData) { - override fun toStmt(): Stmt { - return Skip() - } + override fun toStmt(): Stmt { + return Skip() + } - override fun toString(): String { - return "Nop" - } + override fun toString(): String { + return "Nop" + } } fun getTempLookup(label: XcfaLabel): Map, VarDecl<*>> { - return when (label) { - is InvokeLabel -> { - label.tempLookup - } - - is StartLabel -> { - label.tempLookup - } - - is SequenceLabel -> { - val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() - for (sublabel in label.labels) { - lookup.putAll(getTempLookup(sublabel)) - } - lookup - } - - is NondetLabel -> { - val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() - for (sublabel in label.labels) { - lookup.putAll(getTempLookup(sublabel)) - } - lookup - } - - else -> emptyMap() + return when (label) { + is InvokeLabel -> { + label.tempLookup } -} \ No newline at end of file + + is StartLabel -> { + label.tempLookup + } + + is SequenceLabel -> { + val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() + for (sublabel in label.labels) { + lookup.putAll(getTempLookup(sublabel)) + } + lookup + } + + is NondetLabel -> { + val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() + for (sublabel in label.labels) { + lookup.putAll(getTempLookup(sublabel)) + } + lookup + } + + else -> emptyMap() + } +} diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt index 161f8a4f1a..23235c44a1 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt @@ -106,6 +106,34 @@ class GsonTest { assertEquals(xcfaSource, output) } + @Test + fun testAsyncRoundtrip() { + val xcfaSource = + xcfa("example") { + global { + "x" type Int() init "0" + "thr1" type Int() init "0" + } + procedure("main") { (init to final) { "thr1".start("proc1", "(mod x 0)") } } + procedure("proc1") { (init to final) { assume("true") } } + } + + val symbolTable = XcfaScope(SymbolTable()) + val x_symbol = NamedSymbol("x") + val thr1_symbol = NamedSymbol("thr1") + symbolTable.add(x_symbol) + symbolTable.add(thr1_symbol) + val env = Env() + env.define(x_symbol, xcfaSource.vars.find { it.wrappedVar.name == "x" }!!.wrappedVar) + env.define(thr1_symbol, xcfaSource.vars.find { it.wrappedVar.name == "thr1" }!!.wrappedVar) + val gson = getGson(symbolTable, env, true) + + val output = gson.fromJson(gson.toJson(xcfaSource), XCFA::class.java) + println(xcfaSource) + println(output) + assertEquals(xcfaSource, output) + } + @Test fun testParseContextRoundTrip() { val parseContext = ParseContext()