From 35ca9fca118b8d8f72aa3ad643ca99cb21b05eab Mon Sep 17 00:00:00 2001 From: Natalia Gavrilenko Date: Tue, 10 Dec 2024 11:55:16 +0100 Subject: [PATCH 01/36] Alloc-free verification prototype --- benchmarks/alloc/test1_err_address.c | 26 ++++ benchmarks/alloc/test1_err_double_free_1.c | 27 ++++ benchmarks/alloc/test1_err_double_free_2.c | 28 ++++ benchmarks/alloc/test1_err_no_alloc_1.c | 23 ++++ benchmarks/alloc/test1_err_no_alloc_2.c | 26 ++++ benchmarks/alloc/test1_err_no_free.c | 24 ++++ benchmarks/alloc/test1_err_race.c | 26 ++++ benchmarks/alloc/test1_err_use_after_free.c | 25 ++++ benchmarks/alloc/test1_err_use_before_alloc.c | 27 ++++ benchmarks/alloc/test1_ok_1.c | 26 ++++ benchmarks/alloc/test1_ok_2.c | 26 ++++ cat/rc11.cat | 17 ++- .../dartagnan/encoding/LazyEncodeSets.java | 10 ++ .../dat3m/dartagnan/encoding/WmmEncoder.java | 40 +++++- .../dartagnan/program/event/EventFactory.java | 4 + .../dat3m/dartagnan/program/event/Tag.java | 2 + .../dartagnan/program/event/core/Alloc.java | 11 +- .../dartagnan/program/event/core/MemFree.java | 50 +++++++ .../processing/CoreCodeVerification.java | 2 +- .../program/processing/Intrinsics.java | 8 +- .../program/processing/ThreadCreation.java | 1 + .../com/dat3m/dartagnan/wmm/Constraint.java | 2 + .../dartagnan/wmm/RelationNameRepository.java | 2 + .../java/com/dat3m/dartagnan/wmm/Wmm.java | 2 + .../wmm/analysis/LazyRelationAnalysis.java | 23 ++++ .../wmm/analysis/NativeRelationAnalysis.java | 36 +++++ .../dartagnan/wmm/definition/AllocMem.java | 17 +++ .../dartagnan/wmm/definition/AllocPtr.java | 18 +++ .../dartagnan/wmm/utils/ConstraintCopier.java | 10 ++ .../dat3m/dartagnan/llvm/AllocFreeTest.java | 81 ++++++++++++ .../test/resources/alloc/test1_err_address.ll | 122 +++++++++++++++++ .../alloc/test1_err_double_free_1.ll | 125 ++++++++++++++++++ .../alloc/test1_err_double_free_2.ll | 125 ++++++++++++++++++ .../resources/alloc/test1_err_no_alloc_1.ll | 103 +++++++++++++++ .../resources/alloc/test1_err_no_alloc_2.ll | 113 ++++++++++++++++ .../test/resources/alloc/test1_err_no_free.ll | 112 ++++++++++++++++ .../test/resources/alloc/test1_err_race.ll | 116 ++++++++++++++++ .../alloc/test1_err_use_after_free.ll | 120 +++++++++++++++++ .../alloc/test1_err_use_before_alloc.ll | 121 +++++++++++++++++ .../src/test/resources/alloc/test1_ok_1.ll | 120 +++++++++++++++++ .../src/test/resources/alloc/test1_ok_2.ll | 120 +++++++++++++++++ 41 files changed, 1906 insertions(+), 11 deletions(-) create mode 100644 benchmarks/alloc/test1_err_address.c create mode 100644 benchmarks/alloc/test1_err_double_free_1.c create mode 100644 benchmarks/alloc/test1_err_double_free_2.c create mode 100644 benchmarks/alloc/test1_err_no_alloc_1.c create mode 100644 benchmarks/alloc/test1_err_no_alloc_2.c create mode 100644 benchmarks/alloc/test1_err_no_free.c create mode 100644 benchmarks/alloc/test1_err_race.c create mode 100644 benchmarks/alloc/test1_err_use_after_free.c create mode 100644 benchmarks/alloc/test1_err_use_before_alloc.c create mode 100644 benchmarks/alloc/test1_ok_1.c create mode 100644 benchmarks/alloc/test1_ok_2.c create mode 100644 dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java create mode 100644 dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java create mode 100644 dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java create mode 100644 dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java create mode 100644 dartagnan/src/test/resources/alloc/test1_err_address.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_no_free.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_race.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_ok_1.ll create mode 100644 dartagnan/src/test/resources/alloc/test1_ok_2.ll diff --git a/benchmarks/alloc/test1_err_address.c b/benchmarks/alloc/test1_err_address.c new file mode 100644 index 0000000000..ea5b731048 --- /dev/null +++ b/benchmarks/alloc/test1_err_address.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + free(arr + sizeof(int)); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_double_free_1.c b/benchmarks/alloc/test1_err_double_free_1.c new file mode 100644 index 0000000000..0553eeb598 --- /dev/null +++ b/benchmarks/alloc/test1_err_double_free_1.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + free(arr); + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_double_free_2.c b/benchmarks/alloc/test1_err_double_free_2.c new file mode 100644 index 0000000000..2f93d8100b --- /dev/null +++ b/benchmarks/alloc/test1_err_double_free_2.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_no_alloc_1.c b/benchmarks/alloc/test1_err_no_alloc_1.c new file mode 100644 index 0000000000..c94ca22be0 --- /dev/null +++ b/benchmarks/alloc/test1_err_no_alloc_1.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_no_alloc_2.c b/benchmarks/alloc/test1_err_no_alloc_2.c new file mode 100644 index 0000000000..43b8f10fe8 --- /dev/null +++ b/benchmarks/alloc/test1_err_no_alloc_2.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_no_free.c b/benchmarks/alloc/test1_err_no_free.c new file mode 100644 index 0000000000..4fcad2463d --- /dev/null +++ b/benchmarks/alloc/test1_err_no_free.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_race.c b/benchmarks/alloc/test1_err_race.c new file mode 100644 index 0000000000..cacea9c79b --- /dev/null +++ b/benchmarks/alloc/test1_err_race.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)arr); + arr = malloc(2 * sizeof(int)); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_use_after_free.c b/benchmarks/alloc/test1_err_use_after_free.c new file mode 100644 index 0000000000..d434f69f7c --- /dev/null +++ b/benchmarks/alloc/test1_err_use_after_free.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + free(arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/alloc/test1_err_use_before_alloc.c b/benchmarks/alloc/test1_err_use_before_alloc.c new file mode 100644 index 0000000000..c8a9837065 --- /dev/null +++ b/benchmarks/alloc/test1_err_use_before_alloc.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)arr); + arr = malloc(2 * sizeof(int)); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test1_ok_1.c b/benchmarks/alloc/test1_ok_1.c new file mode 100644 index 0000000000..e7281a4043 --- /dev/null +++ b/benchmarks/alloc/test1_ok_1.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test1_ok_2.c b/benchmarks/alloc/test1_ok_2.c new file mode 100644 index 0000000000..3e904c19a8 --- /dev/null +++ b/benchmarks/alloc/test1_ok_2.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = (int*)arg; + arr[0] = 0; + arr[1] = 1; + + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/cat/rc11.cat b/cat/rc11.cat index d144fd7d35..3572d40c63 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -36,4 +36,19 @@ acyclic (po | rf) as no-thin-air let conflict = ext & ((((W * _) | (_ * W)) & loc) \ ((IW * _) | (_ * IW))) let race = conflict \ (A * A) \ hb \ (hb^-1) -flag ~empty race as racy \ No newline at end of file +flag ~empty race as racy + +(* + * Heap memory safety. + * Base relations: + * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer + * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event + *) +flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race +flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free +flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc +flag ~empty (allocmem \ hb) as use-before-alloc +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free + +// TODO: Non-monotonic! (see ThreadCreation class) +flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java index 454b1947b7..ae5108abec 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java @@ -91,6 +91,16 @@ public Boolean visitCASDependency(CASDependency definition) { return doUpdateSelf(definition); } + @Override + public Boolean visitAllocPtr(AllocPtr definition) { + return doUpdateSelf(definition); + } + + @Override + public Boolean visitAllocMem(AllocMem definition) { + return doUpdateSelf(definition); + } + @Override public Boolean visitLinuxCriticalSections(LinuxCriticalSections definition) { return doUpdateSelf(definition); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java index 753071a769..4b890a11ea 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java @@ -5,10 +5,7 @@ import com.dat3m.dartagnan.program.Program; import com.dat3m.dartagnan.program.analysis.ReachingDefinitionsAnalysis; import com.dat3m.dartagnan.program.event.*; -import com.dat3m.dartagnan.program.event.core.Load; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; -import com.dat3m.dartagnan.program.event.core.NamedBarrier; -import com.dat3m.dartagnan.program.event.core.RMWStoreExclusive; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.utils.Utils; import com.dat3m.dartagnan.utils.dependable.DependencyGraph; import com.dat3m.dartagnan.wmm.Constraint; @@ -670,6 +667,41 @@ public Void visitCoherence(Coherence coDef) { return null; } + @Override + public Void visitAllocPtr(AllocPtr def) { + final Relation rel = def.getDefinedRelation(); + EncodingContext.EdgeEncoder edge = context.edge(rel); + encodeSets.get(rel).apply((e1, e2) -> { + Formula ptr1 = (e1 instanceof Alloc alloc) + ? context.result(alloc) + : context.encodeExpressionAt(((MemFree)e1).getAddress(), e1); + Formula ptr2 = context.encodeExpressionAt(((MemFree) e2).getAddress(), e2); + enc.add(bmgr.equivalence(edge.encode(e1, e2), bmgr.and( + execution(e1, e2), + context.equal(ptr1, ptr2)))); + }); + return null; + } + + @Override + public Void visitAllocMem(AllocMem def) { + final Relation rel = def.getDefinedRelation(); + final EncodingHelper helper = new EncodingHelper(context.getFormulaManager()); + EncodingContext.EdgeEncoder edge = context.edge(rel); + encodeSets.get(rel).apply((e1, e2) -> { + Formula minAddress = context.result((Alloc)e1); + Formula size = context.encodeExpressionAt(((Alloc) e1).getAllocationSize(), e1); + Formula maxAddress = helper.add(minAddress, size); + Formula address = context.address((MemoryEvent) e2); + enc.add(bmgr.equivalence(edge.encode(e1, e2), bmgr.and( + execution(e1, e2), + helper.greaterOrEquals(address, minAddress, false), + helper.greaterThan(maxAddress, address, false) + ))); + }); + return null; + } + @Override public Void visitSyncBarrier(SyncBar syncBar) { final Relation rel = syncBar.getDefinedRelation(); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java index f7523f2a0d..b2a9c2559c 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java @@ -124,6 +124,10 @@ public static Alloc newAlignedAlloc(Register register, Type allocType, Expressio return new Alloc(register, allocType, arraySize, alignment, isHeapAlloc, doesZeroOutMemory); } + public static MemFree newFree(Expression address) { + return new MemFree(address); + } + public static Load newLoad(Register register, Expression address) { return new Load(register, address); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java index 2fcf9bfe2d..52ad820751 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java @@ -22,6 +22,8 @@ private Tag() { } public static final String FENCE = "F"; public static final String STRONG = "STRONG"; // TODO: Maybe move to C11 or IMM? public static final String RMW = "RMW"; + public static final String ALLOC = "ALLOC"; + public static final String FREE = "FREE"; // ---------- Internally used tags (not referenced in CAT) ---------- public static final String EXCL = "__EXCL"; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java index 4ada179a8e..fbce967798 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java @@ -9,10 +9,7 @@ import com.dat3m.dartagnan.expression.type.IntegerType; import com.dat3m.dartagnan.expression.type.TypeFactory; import com.dat3m.dartagnan.program.Register; -import com.dat3m.dartagnan.program.event.AbstractEvent; -import com.dat3m.dartagnan.program.event.EventVisitor; -import com.dat3m.dartagnan.program.event.RegReader; -import com.dat3m.dartagnan.program.event.RegWriter; +import com.dat3m.dartagnan.program.event.*; import com.dat3m.dartagnan.program.memory.MemoryObject; import com.google.common.base.Preconditions; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -47,6 +44,9 @@ public Alloc(Register resultRegister, Type allocType, Expression arraySize, Expr this.allocationType = allocType; this.isHeapAllocation = isHeapAllocation; this.doesZeroOutMemory = doesZeroOutMemory; + if (isHeapAllocation) { + addTags(Tag.VISIBLE, Tag.ALLOC); + } } private Alloc(Alloc other) { @@ -59,6 +59,9 @@ private Alloc(Alloc other) { this.alignment = other.alignment; this.isHeapAllocation = other.isHeapAllocation; this.doesZeroOutMemory = other.doesZeroOutMemory; + if (isHeapAllocation) { + addTags(Tag.VISIBLE, Tag.ALLOC); + } } @Override diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java new file mode 100644 index 0000000000..d0afa6937e --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java @@ -0,0 +1,50 @@ +package com.dat3m.dartagnan.program.event.core; + +import com.dat3m.dartagnan.expression.Expression; +import com.dat3m.dartagnan.expression.ExpressionVisitor; +import com.dat3m.dartagnan.program.Register; +import com.dat3m.dartagnan.program.event.AbstractEvent; +import com.dat3m.dartagnan.program.event.Event; +import com.dat3m.dartagnan.program.event.RegReader; +import com.dat3m.dartagnan.program.event.Tag; + +import java.util.HashSet; +import java.util.Set; + +// TODO: Consistent naming. Should we rename relation 'Free' into FreeRel? +// Or event Alloc into 'MemAlloc'? +public class MemFree extends AbstractEvent implements RegReader { + + private Expression addr; + + public MemFree(Expression addr) { + this.addr = addr; + addTags(Tag.VISIBLE, Tag.FREE); + } + + public Expression getAddress() { + return addr; + } + + @Override + protected String defaultString() { + return String.format("free(%s)", addr); + } + + @Override + public Event getCopy() { + MemFree other = new MemFree(addr); + other.setFunction(this.getFunction()); + return other; + } + + @Override + public Set getRegisterReads() { + return Register.collectRegisterReads(addr, Register.UsageType.ADDR, new HashSet<>()); + } + + @Override + public void transformExpressions(ExpressionVisitor exprTransformer) { + addr = addr.accept(exprTransformer); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java index ebb7f6348f..4830cfab9f 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java @@ -33,7 +33,7 @@ public static CoreCodeVerification fromConfig(Configuration config) { private static final Set> CORE_CLASSES = new HashSet<>(Arrays.asList( Load.class, Store.class, Init.class, GenericMemoryEvent.class, GenericVisibleEvent.class, CondJump.class, IfAsJump.class, ExecutionStatus.class, Label.class, Local.class, - Skip.class, RMWStore.class, RMWStoreExclusive.class, Alloc.class, + Skip.class, RMWStore.class, RMWStoreExclusive.class, Alloc.class, MemFree.class, Assume.class, Assert.class, ThreadCreate.class, ThreadJoin.class, ThreadArgument.class, ThreadStart.class, ThreadReturn.class, ControlBarrier.class, NamedBarrier.class, diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java index e879cbdc54..d55e823c05 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java @@ -221,7 +221,7 @@ public enum Info { STD_MALLOC("malloc", false, false, true, true, Intrinsics::inlineMalloc), STD_CALLOC("calloc", false, false, true, true, Intrinsics::inlineCalloc), STD_ALIGNED_ALLOC("aligned_alloc", false, false, true, true, Intrinsics::inlineAlignedAlloc), - STD_FREE("free", true, false, true, true, Intrinsics::inlineAsZero),//TODO support free + STD_FREE("free", true, false, true, true, Intrinsics::inlineFree), STD_ASSERT(List.of("__assert_fail", "__assert_rtn"), false, false, false, true, Intrinsics::inlineUserAssert), STD_EXIT("exit", false, false, false, true, Intrinsics::inlineExit), STD_ABORT("abort", false, false, false, true, Intrinsics::inlineExit), @@ -965,6 +965,12 @@ private List inlinePthreadRwlockAttr(FunctionCall call) { ); } + private List inlineFree(FunctionCall call) { + return List.of( + EventFactory.newFree(call.getArguments().get(0)) + ); + } + private List inlineMalloc(FunctionCall call) { final Register resultRegister = getResultRegisterAndCheckArguments(1, call); final Type allocType = types.getByteType(); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java index a50033e4a3..fa07fd539e 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java @@ -13,6 +13,7 @@ import com.dat3m.dartagnan.program.Thread; import com.dat3m.dartagnan.program.*; import com.dat3m.dartagnan.program.event.*; +import com.dat3m.dartagnan.program.event.core.Assume; import com.dat3m.dartagnan.program.event.core.Label; import com.dat3m.dartagnan.program.event.core.Local; import com.dat3m.dartagnan.program.event.core.threading.ThreadCreate; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java index f549444074..0cea4c0fc3 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java @@ -85,6 +85,8 @@ default T visitConstraint(Constraint constraint) { default T visitCoherence(Coherence co) { return visitDefinition(co); } default T visitSameLocation(SameLocation loc) { return visitDefinition(loc); } default T visitReadFrom(ReadFrom rf) { return visitDefinition(rf); } + default T visitAllocPtr(AllocPtr aPtr) { return visitDefinition(aPtr); } + default T visitAllocMem(AllocMem aMem) { return visitDefinition(aMem); } // --- Target-specific definitions default T visitCASDependency(CASDependency casDep) { return visitDefinition(casDep); } // IMM default T visitLinuxCriticalSections(LinuxCriticalSections rscs) { return visitDefinition(rscs); } // Linux diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java index a06c0bfa2a..fe3d919185 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java @@ -20,6 +20,8 @@ public class RelationNameRepository { public static final String ADDR = "addr"; public static final String CTRL = "ctrl"; public static final String CASDEP = "casdep"; + public static final String ALLOCPTR = "allocptr"; + public static final String ALLOCMEM = "allocmem"; public static final String SR = "sr"; public static final String SCTA = "scta"; // same-cta, the same as same_block_r in alloy public static final String SSG = "ssg"; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java index 61127ea495..d6df2828e5 100755 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java @@ -220,6 +220,8 @@ private Relation makePredefinedRelation(String name) { Relation mv = addDefinition(product(newRelation(), Tag.MEMORY, Tag.VISIBLE)); yield intersection(r, comp, mv); } + case ALLOCPTR -> new AllocPtr(r); + case ALLOCMEM -> new AllocMem(r); case SR -> new SameScope(r); case SCTA -> new SameScope(r, Tag.PTX.CTA); case SSG -> new SameScope(r, Tag.Vulkan.SUB_GROUP); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java index 0f90a763e7..c5a1f0e1b4 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java @@ -269,6 +269,29 @@ public RelationAnalysis.Knowledge visitCASDependency(CASDependency definition) { return new RelationAnalysis.Knowledge(must, must); } + @Override + public RelationAnalysis.Knowledge visitAllocPtr(AllocPtr definition) { + long start = System.currentTimeMillis(); + RelationAnalysis.Knowledge base = nativeInitializer.visitAllocPtr(definition); + EventGraph may = ImmutableMapEventGraph.from(base.getMaySet()); + EventGraph must = ImmutableMapEventGraph.from(base.getMustSet()); + time(definition, start, System.currentTimeMillis()); + return new RelationAnalysis.Knowledge(may, must); + } + + @Override + // TODO: May and must sets of AllocMem can become very large for some programs. + // Consider using a more efficient representation. A LazyEventGraph can be a good option + // if alias analysis for alloc will be thread-safe. + public RelationAnalysis.Knowledge visitAllocMem(AllocMem definition) { + long start = System.currentTimeMillis(); + RelationAnalysis.Knowledge base = nativeInitializer.visitAllocMem(definition); + EventGraph may = ImmutableMapEventGraph.from(base.getMaySet()); + EventGraph must = ImmutableMapEventGraph.from(base.getMustSet()); + time(definition, start, System.currentTimeMillis()); + return new RelationAnalysis.Knowledge(may, must); + } + @Override public RelationAnalysis.Knowledge visitLinuxCriticalSections(LinuxCriticalSections definition) { long start = System.currentTimeMillis(); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java index 52e63d54e2..83ad6fff9f 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java @@ -773,6 +773,42 @@ public MutableKnowledge visitCoherence(Coherence co) { return new MutableKnowledge(may, must); } + @Override + // TODO: Alias analysis for alloc-free pointers + public MutableKnowledge visitAllocPtr(AllocPtr aref) { + MutableEventGraph may = new MapEventGraph(); + MutableEventGraph must = new MapEventGraph(); + for (Alloc e1 : program.getThreadEvents(Alloc.class)) { + if (e1.isHeapAllocation()) { + for (Event e2 : program.getThreadEvents(MemFree.class)) { + may.add(e1, e2); + } + } + } + for (Event e1 : program.getThreadEvents(MemFree.class)) { + for (Event e2 : program.getThreadEvents(MemFree.class)) { + may.add(e1, e2); + } + } + return new MutableKnowledge(may, must); + } + + @Override + // TODO: Alias analysis for alloc and memory accesses + // (note that we should consider the whole allocated region, not only the pointer) + public MutableKnowledge visitAllocMem(AllocMem aloc) { + MutableEventGraph may = new MapEventGraph(); + MutableEventGraph must = new MapEventGraph(); + for (Alloc e1 : program.getThreadEvents(Alloc.class)) { + if (e1.isHeapAllocation()) { + for (Event e2 : program.getThreadEvents(MemoryEvent.class)) { + may.add(e1, e2); + } + } + } + return new MutableKnowledge(may, must); + } + @Override public MutableKnowledge visitReadFrom(ReadFrom rf) { logger.trace("Computing knowledge about read-from"); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java new file mode 100644 index 0000000000..46c8fe60dc --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java @@ -0,0 +1,17 @@ +package com.dat3m.dartagnan.wmm.definition; + +import com.dat3m.dartagnan.wmm.Definition; +import com.dat3m.dartagnan.wmm.Relation; + +import static com.dat3m.dartagnan.wmm.RelationNameRepository.ALLOCMEM; + +public class AllocMem extends Definition { + public AllocMem(Relation r) { + super(r, ALLOCMEM); + } + + @Override + public T accept(Visitor v) { + return v.visitAllocMem(this); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java new file mode 100644 index 0000000000..5af69c9570 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java @@ -0,0 +1,18 @@ +package com.dat3m.dartagnan.wmm.definition; + +import com.dat3m.dartagnan.wmm.Definition; +import com.dat3m.dartagnan.wmm.Relation; + +import static com.dat3m.dartagnan.wmm.RelationNameRepository.ALLOCPTR; + +public class AllocPtr extends Definition { + + public AllocPtr(Relation r) { + super(r, ALLOCPTR); + } + + @Override + public T accept(Visitor v) { + return v.visitAllocPtr(this); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java index bfc999dbba..172af24bae 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java @@ -186,6 +186,16 @@ public CASDependency visitCASDependency(CASDependency casDep) { return new CASDependency(translate(casDep.getDefinedRelation())); } + @Override + public AllocPtr visitAllocPtr(AllocPtr aPtr) { + return new AllocPtr(translate(aPtr.getDefinedRelation())); + } + + @Override + public AllocMem visitAllocMem(AllocMem aMem) { + return new AllocMem(translate(aMem.getDefinedRelation())); + } + @Override public LinuxCriticalSections visitLinuxCriticalSections(LinuxCriticalSections rscs) { return new LinuxCriticalSections(translate(rscs.getDefinedRelation())); diff --git a/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java new file mode 100644 index 0000000000..609958b0cf --- /dev/null +++ b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java @@ -0,0 +1,81 @@ +package com.dat3m.dartagnan.c; + +import com.dat3m.dartagnan.configuration.Arch; +import com.dat3m.dartagnan.configuration.Property; +import com.dat3m.dartagnan.utils.Result; +import com.dat3m.dartagnan.utils.rules.Provider; +import com.dat3m.dartagnan.utils.rules.Providers; +import com.dat3m.dartagnan.verification.solving.AssumeSolver; +import com.dat3m.dartagnan.verification.solving.RefinementSolver; +import com.dat3m.dartagnan.wmm.Wmm; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.io.IOException; +import java.util.Arrays; +import java.util.EnumSet; + +import static com.dat3m.dartagnan.configuration.Arch.C11; +import static com.dat3m.dartagnan.utils.ResourceHelper.getTestResourcePath; +import static com.dat3m.dartagnan.utils.Result.FAIL; +import static com.dat3m.dartagnan.utils.Result.PASS; +import static org.junit.Assert.assertEquals; + +@RunWith(Parameterized.class) +public class AllocFreeTest extends AbstractCTest { + + public AllocFreeTest(String name, Arch target, Result expected) { + super(name, target, expected); + } + + @Parameterized.Parameters(name = "{index}: {0}, target={1}") + public static Iterable data() throws IOException { + return Arrays.asList(new Object[][]{ + {"test1_ok_1", C11, PASS}, + {"test1_ok_2", C11, PASS}, + {"test1_err_address", C11, FAIL}, + {"test1_err_race", C11, FAIL}, + {"test1_err_double_free_1", C11, FAIL}, + {"test1_err_double_free_2", C11, FAIL}, + {"test1_err_no_free", C11, FAIL}, + {"test1_err_no_alloc_1", C11, FAIL}, + {"test1_err_no_alloc_2", C11, FAIL}, + {"test1_err_use_before_alloc", C11, FAIL}, + {"test1_err_use_after_free", C11, FAIL}, + }); + } + + @Override + protected Provider getProgramPathProvider() { + return () -> getTestResourcePath("alloc/" + name + ".ll"); + } + + @Override + protected long getTimeout() { + return 60000; + } + + @Override + protected Provider getWmmProvider() { + return Providers.createWmmFromName(() -> "rc11"); + } + + @Override + protected Provider> getPropertyProvider() { + return Provider.fromSupplier(() -> EnumSet.of(Property.CAT_SPEC)); + } + + @Test + public void testAssume() throws Exception { + AssumeSolver s = AssumeSolver.run(contextProvider.get(), proverProvider.get(), taskProvider.get()); + assertEquals(expected, s.getResult()); + } + + // TODO: Implement missing definitions (domain) + //@Test + public void testRefinement() throws Exception { + RefinementSolver s = RefinementSolver.run(contextProvider.get(), proverProvider.get(), taskProvider.get()); + assertEquals(expected, s.getResult()); + } +} \ No newline at end of file diff --git a/dartagnan/src/test/resources/alloc/test1_err_address.ll b/dartagnan/src/test/resources/alloc/test1_err_address.ll new file mode 100644 index 0000000000..45c3c72b28 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_address.ll @@ -0,0 +1,122 @@ +; ModuleID = 'benchmarks/alloc/test1_err_address.c' +source_filename = "benchmarks/alloc/test1_err_address.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 + %5 = bitcast i8* %4 to i32*, !dbg !39 + store i32* %5, i32** %3, align 8, !dbg !38 + %6 = load i32*, i32** %3, align 8, !dbg !40 + %7 = bitcast i32* %6 to i8*, !dbg !41 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 + %9 = load i64, i64* %2, align 8, !dbg !43 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 + %11 = load i32*, i32** %3, align 8, !dbg !45 + %12 = getelementptr inbounds i32, i32* %11, i64 4, !dbg !46 + %13 = bitcast i32* %12 to i8*, !dbg !45 + call void @free(i8* noundef %13) #4, !dbg !47 + ret i32 0, !dbg !48 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_address.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "8114dea52686034471751189f8970f2e") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 18, column: 16, scope: !29) +!40 = !DILocation(line: 20, column: 48, scope: !29) +!41 = !DILocation(line: 20, column: 41, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 21, column: 18, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 23, column: 10, scope: !29) +!46 = !DILocation(line: 23, column: 14, scope: !29) +!47 = !DILocation(line: 23, column: 5, scope: !29) +!48 = !DILocation(line: 25, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll b/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll new file mode 100644 index 0000000000..d57221bfb8 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll @@ -0,0 +1,125 @@ +; ModuleID = 'benchmarks/alloc/test1_err_double_free_1.c' +source_filename = "benchmarks/alloc/test1_err_double_free_1.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 + %5 = bitcast i8* %4 to i32*, !dbg !39 + store i32* %5, i32** %3, align 8, !dbg !38 + %6 = load i32*, i32** %3, align 8, !dbg !40 + %7 = bitcast i32* %6 to i8*, !dbg !41 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 + %9 = load i64, i64* %2, align 8, !dbg !43 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 + %11 = load i32*, i32** %3, align 8, !dbg !45 + %12 = bitcast i32* %11 to i8*, !dbg !45 + call void @free(i8* noundef %12) #4, !dbg !46 + %13 = load i32*, i32** %3, align 8, !dbg !47 + %14 = bitcast i32* %13 to i8*, !dbg !47 + call void @free(i8* noundef %14) #4, !dbg !48 + ret i32 0, !dbg !49 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_1.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "d1a66eb11b37ac16370db18220b39a39") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 18, column: 16, scope: !29) +!40 = !DILocation(line: 20, column: 48, scope: !29) +!41 = !DILocation(line: 20, column: 41, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 21, column: 18, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 23, column: 10, scope: !29) +!46 = !DILocation(line: 23, column: 5, scope: !29) +!47 = !DILocation(line: 24, column: 10, scope: !29) +!48 = !DILocation(line: 24, column: 5, scope: !29) +!49 = !DILocation(line: 26, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll b/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll new file mode 100644 index 0000000000..7163262b5d --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll @@ -0,0 +1,125 @@ +; ModuleID = 'benchmarks/alloc/test1_err_double_free_2.c' +source_filename = "benchmarks/alloc/test1_err_double_free_2.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + %10 = load i32*, i32** %3, align 8, !dbg !28 + %11 = bitcast i32* %10 to i8*, !dbg !28 + call void @free(i8* noundef %11) #4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = load i32*, i32** %3, align 8, !dbg !42 + %7 = bitcast i32* %6 to i8*, !dbg !43 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !44 + %9 = load i64, i64* %2, align 8, !dbg !45 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !46 + %11 = load i32*, i32** %3, align 8, !dbg !47 + %12 = bitcast i32* %11 to i8*, !dbg !47 + call void @free(i8* noundef %12) #4, !dbg !48 + ret i32 0, !dbg !49 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_2.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "1db5a6a9c67fb4a0d9e5f2e82df61fa8") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 10, scope: !14) +!29 = !DILocation(line: 12, column: 5, scope: !14) +!30 = !DILocation(line: 14, column: 2, scope: !14) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !32, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!32 = !DISubroutineType(types: !33) +!33 = !{!4} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 19, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 19, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 20, type: !3) +!40 = !DILocation(line: 20, column: 10, scope: !31) +!41 = !DILocation(line: 20, column: 16, scope: !31) +!42 = !DILocation(line: 22, column: 48, scope: !31) +!43 = !DILocation(line: 22, column: 41, scope: !31) +!44 = !DILocation(line: 22, column: 5, scope: !31) +!45 = !DILocation(line: 23, column: 18, scope: !31) +!46 = !DILocation(line: 23, column: 5, scope: !31) +!47 = !DILocation(line: 25, column: 10, scope: !31) +!48 = !DILocation(line: 25, column: 5, scope: !31) +!49 = !DILocation(line: 27, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll new file mode 100644 index 0000000000..7acd79671c --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll @@ -0,0 +1,103 @@ +; ModuleID = 'benchmarks/alloc/test1_err_no_alloc_1.c' +source_filename = "benchmarks/alloc/test1_err_no_alloc_1.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = bitcast i32* %6 to i8*, !dbg !24 + call void @free(i8* noundef %7) #4, !dbg !25 + ret i8* null, !dbg !26 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !27 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !30, metadata !DIExpression()), !dbg !34 + call void @llvm.dbg.declare(metadata i32** %3, metadata !35, metadata !DIExpression()), !dbg !36 + %4 = load i32*, i32** %3, align 8, !dbg !37 + %5 = bitcast i32* %4 to i8*, !dbg !38 + %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !39 + %7 = load i64, i64* %2, align 8, !dbg !40 + %8 = call i32 @pthread_join(i64 noundef %7, i8** noundef null), !dbg !41 + ret i32 0, !dbg !42 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_1.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "a285c25fa1749241c92f70edcd885f7d") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 10, scope: !14) +!25 = !DILocation(line: 9, column: 5, scope: !14) +!26 = !DILocation(line: 11, column: 2, scope: !14) +!27 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !28, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!28 = !DISubroutineType(types: !29) +!29 = !{!4} +!30 = !DILocalVariable(name: "t1", scope: !27, file: !1, line: 16, type: !31) +!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !32, line: 27, baseType: !33) +!32 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!33 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!34 = !DILocation(line: 16, column: 15, scope: !27) +!35 = !DILocalVariable(name: "arr", scope: !27, file: !1, line: 17, type: !3) +!36 = !DILocation(line: 17, column: 10, scope: !27) +!37 = !DILocation(line: 19, column: 48, scope: !27) +!38 = !DILocation(line: 19, column: 41, scope: !27) +!39 = !DILocation(line: 19, column: 5, scope: !27) +!40 = !DILocation(line: 20, column: 18, scope: !27) +!41 = !DILocation(line: 20, column: 5, scope: !27) +!42 = !DILocation(line: 22, column: 2, scope: !27) diff --git a/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll new file mode 100644 index 0000000000..e1e2fd274e --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll @@ -0,0 +1,113 @@ +; ModuleID = 'benchmarks/alloc/test1_err_no_alloc_2.c' +source_filename = "benchmarks/alloc/test1_err_no_alloc_2.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = load i32*, i32** %3, align 8, !dbg !39 + %5 = bitcast i32* %4 to i8*, !dbg !40 + %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !41 + %7 = load i64, i64* %2, align 8, !dbg !42 + %8 = call i32 @pthread_join(i64 noundef %7, i8** noundef null), !dbg !43 + %9 = load i32*, i32** %3, align 8, !dbg !44 + %10 = bitcast i32* %9 to i8*, !dbg !44 + call void @free(i8* noundef %10) #4, !dbg !45 + ret i32 0, !dbg !46 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_2.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "4df5fa623115f5e27fc352d3b4bca11a") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 20, column: 48, scope: !29) +!40 = !DILocation(line: 20, column: 41, scope: !29) +!41 = !DILocation(line: 20, column: 5, scope: !29) +!42 = !DILocation(line: 21, column: 18, scope: !29) +!43 = !DILocation(line: 21, column: 5, scope: !29) +!44 = !DILocation(line: 23, column: 10, scope: !29) +!45 = !DILocation(line: 23, column: 5, scope: !29) +!46 = !DILocation(line: 25, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_no_free.ll b/dartagnan/src/test/resources/alloc/test1_err_no_free.ll new file mode 100644 index 0000000000..59c76a7988 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_no_free.ll @@ -0,0 +1,112 @@ +; ModuleID = 'benchmarks/alloc/test1_err_no_free.c' +source_filename = "benchmarks/alloc/test1_err_no_free.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 + %5 = bitcast i8* %4 to i32*, !dbg !39 + store i32* %5, i32** %3, align 8, !dbg !38 + %6 = load i32*, i32** %3, align 8, !dbg !40 + %7 = bitcast i32* %6 to i8*, !dbg !41 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 + %9 = load i64, i64* %2, align 8, !dbg !43 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 + ret i32 0, !dbg !45 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_free.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "c459aaed4dde8b107e0a8f2a7207c29c") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 18, column: 16, scope: !29) +!40 = !DILocation(line: 20, column: 48, scope: !29) +!41 = !DILocation(line: 20, column: 41, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 21, column: 18, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 23, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_race.ll b/dartagnan/src/test/resources/alloc/test1_err_race.ll new file mode 100644 index 0000000000..a2aaca04eb --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_race.ll @@ -0,0 +1,116 @@ +; ModuleID = 'benchmarks/alloc/test1_err_race.c' +source_filename = "benchmarks/alloc/test1_err_race.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = bitcast i32* %6 to i8*, !dbg !24 + call void @free(i8* noundef %7) #4, !dbg !25 + ret i8* null, !dbg !26 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !27 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !30, metadata !DIExpression()), !dbg !34 + call void @llvm.dbg.declare(metadata i32** %3, metadata !35, metadata !DIExpression()), !dbg !36 + %4 = load i32*, i32** %3, align 8, !dbg !37 + %5 = bitcast i32* %4 to i8*, !dbg !38 + %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !39 + %7 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !40 + %8 = bitcast i8* %7 to i32*, !dbg !40 + store i32* %8, i32** %3, align 8, !dbg !41 + %9 = load i64, i64* %2, align 8, !dbg !42 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !43 + %11 = load i32*, i32** %3, align 8, !dbg !44 + %12 = bitcast i32* %11 to i8*, !dbg !44 + call void @free(i8* noundef %12) #4, !dbg !45 + ret i32 0, !dbg !46 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_race.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "0c175e83c7b7bcb8fa51479a3fec40a3") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 10, scope: !14) +!25 = !DILocation(line: 9, column: 5, scope: !14) +!26 = !DILocation(line: 11, column: 2, scope: !14) +!27 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !28, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!28 = !DISubroutineType(types: !29) +!29 = !{!4} +!30 = !DILocalVariable(name: "t1", scope: !27, file: !1, line: 16, type: !31) +!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !32, line: 27, baseType: !33) +!32 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!33 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!34 = !DILocation(line: 16, column: 15, scope: !27) +!35 = !DILocalVariable(name: "arr", scope: !27, file: !1, line: 17, type: !3) +!36 = !DILocation(line: 17, column: 10, scope: !27) +!37 = !DILocation(line: 19, column: 48, scope: !27) +!38 = !DILocation(line: 19, column: 41, scope: !27) +!39 = !DILocation(line: 19, column: 5, scope: !27) +!40 = !DILocation(line: 20, column: 11, scope: !27) +!41 = !DILocation(line: 20, column: 9, scope: !27) +!42 = !DILocation(line: 21, column: 18, scope: !27) +!43 = !DILocation(line: 21, column: 5, scope: !27) +!44 = !DILocation(line: 23, column: 10, scope: !27) +!45 = !DILocation(line: 23, column: 5, scope: !27) +!46 = !DILocation(line: 25, column: 2, scope: !27) diff --git a/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll b/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll new file mode 100644 index 0000000000..31cffd9e56 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll @@ -0,0 +1,120 @@ +; ModuleID = 'benchmarks/alloc/test1_err_use_after_free.c' +source_filename = "benchmarks/alloc/test1_err_use_after_free.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 + %5 = bitcast i8* %4 to i32*, !dbg !39 + store i32* %5, i32** %3, align 8, !dbg !38 + %6 = load i32*, i32** %3, align 8, !dbg !40 + %7 = bitcast i32* %6 to i8*, !dbg !41 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 + %9 = load i32*, i32** %3, align 8, !dbg !43 + %10 = bitcast i32* %9 to i8*, !dbg !43 + call void @free(i8* noundef %10) #4, !dbg !44 + %11 = load i64, i64* %2, align 8, !dbg !45 + %12 = call i32 @pthread_join(i64 noundef %11, i8** noundef null), !dbg !46 + ret i32 0, !dbg !47 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_after_free.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "8d642581889818962a50078c6ebe4f0e") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 18, column: 16, scope: !29) +!40 = !DILocation(line: 20, column: 48, scope: !29) +!41 = !DILocation(line: 20, column: 41, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 21, column: 10, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 22, column: 18, scope: !29) +!46 = !DILocation(line: 22, column: 5, scope: !29) +!47 = !DILocation(line: 24, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll b/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll new file mode 100644 index 0000000000..e82132f98b --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll @@ -0,0 +1,121 @@ +; ModuleID = 'benchmarks/alloc/test1_err_use_before_alloc.c' +source_filename = "benchmarks/alloc/test1_err_use_before_alloc.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = load i32*, i32** %3, align 8, !dbg !39 + %5 = bitcast i32* %4 to i8*, !dbg !40 + %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !41 + %7 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !42 + %8 = bitcast i8* %7 to i32*, !dbg !42 + store i32* %8, i32** %3, align 8, !dbg !43 + %9 = load i64, i64* %2, align 8, !dbg !44 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !45 + %11 = load i32*, i32** %3, align 8, !dbg !46 + %12 = bitcast i32* %11 to i8*, !dbg !46 + call void @free(i8* noundef %12) #4, !dbg !47 + ret i32 0, !dbg !48 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_before_alloc.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "5c311e095b3edb7094e54502edfcdbc7") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 20, column: 48, scope: !29) +!40 = !DILocation(line: 20, column: 41, scope: !29) +!41 = !DILocation(line: 20, column: 5, scope: !29) +!42 = !DILocation(line: 21, column: 11, scope: !29) +!43 = !DILocation(line: 21, column: 9, scope: !29) +!44 = !DILocation(line: 22, column: 18, scope: !29) +!45 = !DILocation(line: 22, column: 5, scope: !29) +!46 = !DILocation(line: 24, column: 10, scope: !29) +!47 = !DILocation(line: 24, column: 5, scope: !29) +!48 = !DILocation(line: 26, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_ok_1.ll b/dartagnan/src/test/resources/alloc/test1_ok_1.ll new file mode 100644 index 0000000000..ec6407db97 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_ok_1.ll @@ -0,0 +1,120 @@ +; ModuleID = 'benchmarks/alloc/test1_ok_1.c' +source_filename = "benchmarks/alloc/test1_ok_1.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 + %5 = bitcast i8* %4 to i32*, !dbg !39 + store i32* %5, i32** %3, align 8, !dbg !38 + %6 = load i32*, i32** %3, align 8, !dbg !40 + %7 = bitcast i32* %6 to i8*, !dbg !41 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 + %9 = load i64, i64* %2, align 8, !dbg !43 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 + %11 = load i32*, i32** %3, align 8, !dbg !45 + %12 = bitcast i32* %11 to i8*, !dbg !45 + call void @free(i8* noundef %12) #4, !dbg !46 + ret i32 0, !dbg !47 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_1.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "6736e84db76ebdcaab435efe3c94d890") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 2, scope: !14) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!30 = !DISubroutineType(types: !31) +!31 = !{!4} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 17, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) +!38 = !DILocation(line: 18, column: 10, scope: !29) +!39 = !DILocation(line: 18, column: 16, scope: !29) +!40 = !DILocation(line: 20, column: 48, scope: !29) +!41 = !DILocation(line: 20, column: 41, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 21, column: 18, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 23, column: 10, scope: !29) +!46 = !DILocation(line: 23, column: 5, scope: !29) +!47 = !DILocation(line: 25, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_ok_2.ll b/dartagnan/src/test/resources/alloc/test1_ok_2.ll new file mode 100644 index 0000000000..25dcb6aeb0 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test1_ok_2.ll @@ -0,0 +1,120 @@ +; ModuleID = 'benchmarks/alloc/test1_ok_2.c' +source_filename = "benchmarks/alloc/test1_ok_2.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 + call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 + %4 = load i8*, i8** %2, align 8, !dbg !22 + %5 = bitcast i8* %4 to i32*, !dbg !23 + store i32* %5, i32** %3, align 8, !dbg !21 + %6 = load i32*, i32** %3, align 8, !dbg !24 + %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 + store i32 0, i32* %7, align 4, !dbg !25 + %8 = load i32*, i32** %3, align 8, !dbg !26 + %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 + store i32 1, i32* %9, align 4, !dbg !27 + %10 = load i32*, i32** %3, align 8, !dbg !28 + %11 = bitcast i32* %10 to i8*, !dbg !28 + call void @free(i8* noundef %11) #4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = load i32*, i32** %3, align 8, !dbg !42 + %7 = bitcast i32* %6 to i8*, !dbg !43 + %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !44 + %9 = load i64, i64* %2, align 8, !dbg !45 + %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !46 + ret i32 0, !dbg !47 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_2.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "9d341cbb939552f914c1c2ac6d9de86c") +!2 = !{!3, !5} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 7, !"PIC Level", i32 2} +!10 = !{i32 7, !"PIE Level", i32 2} +!11 = !{i32 7, !"uwtable", i32 1} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!5, !5} +!17 = !{} +!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) +!19 = !DILocation(line: 6, column: 22, scope: !14) +!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) +!21 = !DILocation(line: 8, column: 10, scope: !14) +!22 = !DILocation(line: 8, column: 22, scope: !14) +!23 = !DILocation(line: 8, column: 16, scope: !14) +!24 = !DILocation(line: 9, column: 5, scope: !14) +!25 = !DILocation(line: 9, column: 12, scope: !14) +!26 = !DILocation(line: 10, column: 5, scope: !14) +!27 = !DILocation(line: 10, column: 12, scope: !14) +!28 = !DILocation(line: 12, column: 10, scope: !14) +!29 = !DILocation(line: 12, column: 5, scope: !14) +!30 = !DILocation(line: 14, column: 2, scope: !14) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !32, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) +!32 = !DISubroutineType(types: !33) +!33 = !{!4} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 19, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 19, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 20, type: !3) +!40 = !DILocation(line: 20, column: 10, scope: !31) +!41 = !DILocation(line: 20, column: 16, scope: !31) +!42 = !DILocation(line: 22, column: 48, scope: !31) +!43 = !DILocation(line: 22, column: 41, scope: !31) +!44 = !DILocation(line: 22, column: 5, scope: !31) +!45 = !DILocation(line: 23, column: 18, scope: !31) +!46 = !DILocation(line: 23, column: 5, scope: !31) +!47 = !DILocation(line: 25, column: 2, scope: !31) From 3940bb8ec996f242b3caf56c0168f197aadbffbd Mon Sep 17 00:00:00 2001 From: Natalia Gavrilenko Date: Mon, 20 Jan 2025 22:41:57 +0100 Subject: [PATCH 02/36] Using stack pointer in alloc tests --- benchmarks/alloc/test1_err_address.c | 4 +- benchmarks/alloc/test1_err_double_free_1.c | 4 +- benchmarks/alloc/test1_err_double_free_2.c | 4 +- benchmarks/alloc/test1_err_no_alloc_1.c | 4 +- benchmarks/alloc/test1_err_no_alloc_2.c | 4 +- benchmarks/alloc/test1_err_no_free.c | 4 +- benchmarks/alloc/test1_err_race.c | 4 +- benchmarks/alloc/test1_err_use_after_free.c | 4 +- benchmarks/alloc/test1_err_use_before_alloc.c | 4 +- benchmarks/alloc/test1_ok_1.c | 4 +- benchmarks/alloc/test1_ok_2.c | 4 +- .../dat3m/dartagnan/llvm/AllocFreeTest.java | 88 +++++++--- .../test/resources/alloc/test1_err_address.ll | 157 ++++++++--------- .../alloc/test1_err_double_free_1.ll | 163 +++++++++--------- .../alloc/test1_err_double_free_2.ll | 163 +++++++++--------- .../resources/alloc/test1_err_no_alloc_1.ll | 125 +++++++------- .../resources/alloc/test1_err_no_alloc_2.ll | 145 ++++++++-------- .../test/resources/alloc/test1_err_no_free.ll | 143 +++++++-------- .../test/resources/alloc/test1_err_race.ll | 145 ++++++++-------- .../alloc/test1_err_use_after_free.ll | 153 ++++++++-------- .../alloc/test1_err_use_before_alloc.ll | 155 ++++++++--------- .../src/test/resources/alloc/test1_ok_1.ll | 153 ++++++++-------- .../src/test/resources/alloc/test1_ok_2.ll | 153 ++++++++-------- 23 files changed, 917 insertions(+), 870 deletions(-) diff --git a/benchmarks/alloc/test1_err_address.c b/benchmarks/alloc/test1_err_address.c index ea5b731048..f13de6fa99 100644 --- a/benchmarks/alloc/test1_err_address.c +++ b/benchmarks/alloc/test1_err_address.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); free(arr + sizeof(int)); diff --git a/benchmarks/alloc/test1_err_double_free_1.c b/benchmarks/alloc/test1_err_double_free_1.c index 0553eeb598..8b14f5c334 100644 --- a/benchmarks/alloc/test1_err_double_free_1.c +++ b/benchmarks/alloc/test1_err_double_free_1.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); free(arr); diff --git a/benchmarks/alloc/test1_err_double_free_2.c b/benchmarks/alloc/test1_err_double_free_2.c index 2f93d8100b..6ef22015ea 100644 --- a/benchmarks/alloc/test1_err_double_free_2.c +++ b/benchmarks/alloc/test1_err_double_free_2.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -19,7 +19,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); free(arr); diff --git a/benchmarks/alloc/test1_err_no_alloc_1.c b/benchmarks/alloc/test1_err_no_alloc_1.c index c94ca22be0..f2e0628854 100644 --- a/benchmarks/alloc/test1_err_no_alloc_1.c +++ b/benchmarks/alloc/test1_err_no_alloc_1.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); free(arr); return NULL; @@ -16,7 +16,7 @@ int main() pthread_t t1; int *arr; - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); return 0; diff --git a/benchmarks/alloc/test1_err_no_alloc_2.c b/benchmarks/alloc/test1_err_no_alloc_2.c index 43b8f10fe8..5182ba09f0 100644 --- a/benchmarks/alloc/test1_err_no_alloc_2.c +++ b/benchmarks/alloc/test1_err_no_alloc_2.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr; - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); free(arr); diff --git a/benchmarks/alloc/test1_err_no_free.c b/benchmarks/alloc/test1_err_no_free.c index 4fcad2463d..d60b0f082b 100644 --- a/benchmarks/alloc/test1_err_no_free.c +++ b/benchmarks/alloc/test1_err_no_free.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); return 0; diff --git a/benchmarks/alloc/test1_err_race.c b/benchmarks/alloc/test1_err_race.c index cacea9c79b..26c5d5f220 100644 --- a/benchmarks/alloc/test1_err_race.c +++ b/benchmarks/alloc/test1_err_race.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); free(arr); return NULL; @@ -16,7 +16,7 @@ int main() pthread_t t1; int *arr; - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); arr = malloc(2 * sizeof(int)); pthread_join(t1, NULL); diff --git a/benchmarks/alloc/test1_err_use_after_free.c b/benchmarks/alloc/test1_err_use_after_free.c index d434f69f7c..4461e48722 100644 --- a/benchmarks/alloc/test1_err_use_after_free.c +++ b/benchmarks/alloc/test1_err_use_after_free.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); free(arr); pthread_join(t1, NULL); diff --git a/benchmarks/alloc/test1_err_use_before_alloc.c b/benchmarks/alloc/test1_err_use_before_alloc.c index c8a9837065..3ff99e914e 100644 --- a/benchmarks/alloc/test1_err_use_before_alloc.c +++ b/benchmarks/alloc/test1_err_use_before_alloc.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr; - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); arr = malloc(2 * sizeof(int)); pthread_join(t1, NULL); diff --git a/benchmarks/alloc/test1_ok_1.c b/benchmarks/alloc/test1_ok_1.c index e7281a4043..336a5345de 100644 --- a/benchmarks/alloc/test1_ok_1.c +++ b/benchmarks/alloc/test1_ok_1.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -17,7 +17,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); free(arr); diff --git a/benchmarks/alloc/test1_ok_2.c b/benchmarks/alloc/test1_ok_2.c index 3e904c19a8..753600aeb7 100644 --- a/benchmarks/alloc/test1_ok_2.c +++ b/benchmarks/alloc/test1_ok_2.c @@ -5,7 +5,7 @@ void *thread_1(void *arg) { - int *arr = (int*)arg; + int *arr = *((int**)arg); arr[0] = 0; arr[1] = 1; @@ -19,7 +19,7 @@ int main() pthread_t t1; int *arr = malloc(2 * sizeof(int)); - pthread_create(&t1, NULL, thread_1, (void*)arr); + pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); return 0; diff --git a/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java index 609958b0cf..15397673d0 100644 --- a/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java +++ b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java @@ -1,32 +1,53 @@ package com.dat3m.dartagnan.c; +import com.dat3m.dartagnan.configuration.Alias; import com.dat3m.dartagnan.configuration.Arch; -import com.dat3m.dartagnan.configuration.Property; +import com.dat3m.dartagnan.configuration.OptionNames; +import com.dat3m.dartagnan.encoding.ProverWithTracker; +import com.dat3m.dartagnan.parsers.cat.ParserCat; +import com.dat3m.dartagnan.parsers.program.ProgramParser; +import com.dat3m.dartagnan.program.Program; import com.dat3m.dartagnan.utils.Result; -import com.dat3m.dartagnan.utils.rules.Provider; -import com.dat3m.dartagnan.utils.rules.Providers; +import com.dat3m.dartagnan.verification.VerificationTask; import com.dat3m.dartagnan.verification.solving.AssumeSolver; import com.dat3m.dartagnan.verification.solving.RefinementSolver; import com.dat3m.dartagnan.wmm.Wmm; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.sosy_lab.common.ShutdownManager; +import org.sosy_lab.common.configuration.Configuration; +import org.sosy_lab.common.configuration.InvalidConfigurationException; +import org.sosy_lab.common.log.BasicLogManager; +import org.sosy_lab.java_smt.SolverContextFactory; +import org.sosy_lab.java_smt.api.SolverContext; +import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.EnumSet; +import java.util.List; +import static com.dat3m.dartagnan.configuration.Alias.*; import static com.dat3m.dartagnan.configuration.Arch.C11; +import static com.dat3m.dartagnan.configuration.Property.CAT_SPEC; +import static com.dat3m.dartagnan.utils.ResourceHelper.getRootPath; import static com.dat3m.dartagnan.utils.ResourceHelper.getTestResourcePath; import static com.dat3m.dartagnan.utils.Result.FAIL; import static com.dat3m.dartagnan.utils.Result.PASS; import static org.junit.Assert.assertEquals; @RunWith(Parameterized.class) -public class AllocFreeTest extends AbstractCTest { +public class AllocFreeTest { + + private final String name; + private final Arch target; + private final Result expected; public AllocFreeTest(String name, Arch target, Result expected) { - super(name, target, expected); + this.name = name; + this.target = target; + this.expected = expected; } @Parameterized.Parameters(name = "{index}: {0}, target={1}") @@ -46,36 +67,51 @@ public static Iterable data() throws IOException { }); } - @Override - protected Provider getProgramPathProvider() { - return () -> getTestResourcePath("alloc/" + name + ".ll"); + @Test + public void testAssume() throws Exception { + for (Alias aliasMethod : List.of(FIELD_INSENSITIVE , FIELD_SENSITIVE, FULL)) { + Configuration cfg = mkConfiguration(aliasMethod); + SolverContext ctx = mkCtx(cfg); + AssumeSolver s = AssumeSolver.run(ctx, mkProver(ctx), mkTask(cfg)); + assertEquals(expected, s.getResult()); + } } - @Override - protected long getTimeout() { - return 60000; + @Test + public void testRefinement() throws Exception { + for (Alias aliasMethod : List.of(FIELD_INSENSITIVE , FIELD_SENSITIVE, FULL)) { + Configuration cfg = mkConfiguration(aliasMethod); + SolverContext ctx = mkCtx(cfg); + RefinementSolver s = RefinementSolver.run(ctx, mkProver(ctx), mkTask(cfg)); + assertEquals(expected, s.getResult()); + } } - @Override - protected Provider getWmmProvider() { - return Providers.createWmmFromName(() -> "rc11"); + private SolverContext mkCtx(Configuration cfg) throws InvalidConfigurationException { + return SolverContextFactory.createSolverContext( + cfg, + BasicLogManager.create(cfg), + ShutdownManager.create().getNotifier(), + SolverContextFactory.Solvers.Z3); } - @Override - protected Provider> getPropertyProvider() { - return Provider.fromSupplier(() -> EnumSet.of(Property.CAT_SPEC)); + private ProverWithTracker mkProver(SolverContext ctx) { + return new ProverWithTracker(ctx, "", SolverContext.ProverOptions.GENERATE_MODELS); } - @Test - public void testAssume() throws Exception { - AssumeSolver s = AssumeSolver.run(contextProvider.get(), proverProvider.get(), taskProvider.get()); - assertEquals(expected, s.getResult()); + private VerificationTask mkTask(Configuration configuration) throws Exception { + VerificationTask.VerificationTaskBuilder builder = VerificationTask.builder() + .withConfig(configuration) + .withTarget(target); + Program program = new ProgramParser().parse(new File(getTestResourcePath("alloc/" + name + ".ll"))); + Wmm mcm = new ParserCat().parse(new File(getRootPath("cat/rc11.cat"))); + return builder.build(program, mcm, EnumSet.of(CAT_SPEC)); } - // TODO: Implement missing definitions (domain) - //@Test - public void testRefinement() throws Exception { - RefinementSolver s = RefinementSolver.run(contextProvider.get(), proverProvider.get(), taskProvider.get()); - assertEquals(expected, s.getResult()); + private Configuration mkConfiguration(Alias aliasMethod) throws InvalidConfigurationException { + return Configuration.builder() + .setOption(OptionNames.USE_INTEGERS, "true") + .setOption(OptionNames.ALIAS_METHOD, aliasMethod.asStringOption()) + .build(); } } \ No newline at end of file diff --git a/dartagnan/src/test/resources/alloc/test1_err_address.ll b/dartagnan/src/test/resources/alloc/test1_err_address.ll index 45c3c72b28..472487495c 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_address.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_address.ll @@ -6,48 +6,48 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 - %5 = bitcast i8* %4 to i32*, !dbg !39 - store i32* %5, i32** %3, align 8, !dbg !38 - %6 = load i32*, i32** %3, align 8, !dbg !40 - %7 = bitcast i32* %6 to i8*, !dbg !41 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 - %9 = load i64, i64* %2, align 8, !dbg !43 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 - %11 = load i32*, i32** %3, align 8, !dbg !45 - %12 = getelementptr inbounds i32, i32* %11, i64 4, !dbg !46 - %13 = bitcast i32* %12 to i8*, !dbg !45 - call void @free(i8* noundef %13) #4, !dbg !47 - ret i32 0, !dbg !48 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + %10 = load i32*, i32** %3, align 8, !dbg !46 + %11 = getelementptr inbounds i32, i32* %10, i64 4, !dbg !47 + %12 = bitcast i32* %11 to i8*, !dbg !46 + call void @free(i8* noundef %12) #4, !dbg !48 + ret i32 0, !dbg !49 } ; Function Attrs: nounwind @@ -68,55 +68,56 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_address.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "8114dea52686034471751189f8970f2e") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_address.c", directory: "", checksumkind: CSK_MD5, checksum: "10f0e4c5d76d57d15b440887b3a1fd9f") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 18, column: 16, scope: !29) -!40 = !DILocation(line: 20, column: 48, scope: !29) -!41 = !DILocation(line: 20, column: 41, scope: !29) -!42 = !DILocation(line: 20, column: 5, scope: !29) -!43 = !DILocation(line: 21, column: 18, scope: !29) -!44 = !DILocation(line: 21, column: 5, scope: !29) -!45 = !DILocation(line: 23, column: 10, scope: !29) -!46 = !DILocation(line: 23, column: 14, scope: !29) -!47 = !DILocation(line: 23, column: 5, scope: !29) -!48 = !DILocation(line: 25, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 10, scope: !31) +!47 = !DILocation(line: 23, column: 14, scope: !31) +!48 = !DILocation(line: 23, column: 5, scope: !31) +!49 = !DILocation(line: 25, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll b/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll index d57221bfb8..2d8bc4b507 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_double_free_1.ll @@ -6,50 +6,50 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 - %5 = bitcast i8* %4 to i32*, !dbg !39 - store i32* %5, i32** %3, align 8, !dbg !38 - %6 = load i32*, i32** %3, align 8, !dbg !40 - %7 = bitcast i32* %6 to i8*, !dbg !41 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 - %9 = load i64, i64* %2, align 8, !dbg !43 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 - %11 = load i32*, i32** %3, align 8, !dbg !45 - %12 = bitcast i32* %11 to i8*, !dbg !45 - call void @free(i8* noundef %12) #4, !dbg !46 - %13 = load i32*, i32** %3, align 8, !dbg !47 - %14 = bitcast i32* %13 to i8*, !dbg !47 - call void @free(i8* noundef %14) #4, !dbg !48 - ret i32 0, !dbg !49 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + %10 = load i32*, i32** %3, align 8, !dbg !46 + %11 = bitcast i32* %10 to i8*, !dbg !46 + call void @free(i8* noundef %11) #4, !dbg !47 + %12 = load i32*, i32** %3, align 8, !dbg !48 + %13 = bitcast i32* %12 to i8*, !dbg !48 + call void @free(i8* noundef %13) #4, !dbg !49 + ret i32 0, !dbg !50 } ; Function Attrs: nounwind @@ -70,56 +70,57 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_1.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "d1a66eb11b37ac16370db18220b39a39") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_1.c", directory: "", checksumkind: CSK_MD5, checksum: "000dddf7e9b0673f5f3e4f8212feb516") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 18, column: 16, scope: !29) -!40 = !DILocation(line: 20, column: 48, scope: !29) -!41 = !DILocation(line: 20, column: 41, scope: !29) -!42 = !DILocation(line: 20, column: 5, scope: !29) -!43 = !DILocation(line: 21, column: 18, scope: !29) -!44 = !DILocation(line: 21, column: 5, scope: !29) -!45 = !DILocation(line: 23, column: 10, scope: !29) -!46 = !DILocation(line: 23, column: 5, scope: !29) -!47 = !DILocation(line: 24, column: 10, scope: !29) -!48 = !DILocation(line: 24, column: 5, scope: !29) -!49 = !DILocation(line: 26, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 10, scope: !31) +!47 = !DILocation(line: 23, column: 5, scope: !31) +!48 = !DILocation(line: 24, column: 10, scope: !31) +!49 = !DILocation(line: 24, column: 5, scope: !31) +!50 = !DILocation(line: 26, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll b/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll index 7163262b5d..b2c310951f 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_double_free_2.ll @@ -6,25 +6,26 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - %10 = load i32*, i32** %3, align 8, !dbg !28 - %11 = bitcast i32* %10 to i8*, !dbg !28 - call void @free(i8* noundef %11) #4, !dbg !29 - ret i8* null, !dbg !30 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + %11 = load i32*, i32** %3, align 8, !dbg !30 + %12 = bitcast i32* %11 to i8*, !dbg !30 + call void @free(i8* noundef %12) #4, !dbg !31 + ret i8* null, !dbg !32 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn @@ -34,25 +35,24 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 declare void @free(i8* noundef) #2 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !31 { +define dso_local i32 @main() #0 !dbg !33 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 - call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 - %5 = bitcast i8* %4 to i32*, !dbg !41 - store i32* %5, i32** %3, align 8, !dbg !40 - %6 = load i32*, i32** %3, align 8, !dbg !42 - %7 = bitcast i32* %6 to i8*, !dbg !43 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !44 - %9 = load i64, i64* %2, align 8, !dbg !45 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !46 - %11 = load i32*, i32** %3, align 8, !dbg !47 - %12 = bitcast i32* %11 to i8*, !dbg !47 - call void @free(i8* noundef %12) #4, !dbg !48 - ret i32 0, !dbg !49 + call void @llvm.dbg.declare(metadata i64* %2, metadata !36, metadata !DIExpression()), !dbg !40 + call void @llvm.dbg.declare(metadata i32** %3, metadata !41, metadata !DIExpression()), !dbg !42 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !43 + %5 = bitcast i8* %4 to i32*, !dbg !43 + store i32* %5, i32** %3, align 8, !dbg !42 + %6 = bitcast i32** %3 to i8*, !dbg !44 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !45 + %8 = load i64, i64* %2, align 8, !dbg !46 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !47 + %10 = load i32*, i32** %3, align 8, !dbg !48 + %11 = bitcast i32* %10 to i8*, !dbg !48 + call void @free(i8* noundef %11) #4, !dbg !49 + ret i32 0, !dbg !50 } ; Function Attrs: nounwind @@ -70,56 +70,57 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_2.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "1db5a6a9c67fb4a0d9e5f2e82df61fa8") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_2.c", directory: "", checksumkind: CSK_MD5, checksum: "45c24eb667d393b0b91a33073899f35b") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 10, scope: !14) -!29 = !DILocation(line: 12, column: 5, scope: !14) -!30 = !DILocation(line: 14, column: 2, scope: !14) -!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !32, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!32 = !DISubroutineType(types: !33) -!33 = !{!4} -!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 19, type: !35) -!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) -!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!38 = !DILocation(line: 19, column: 15, scope: !31) -!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 20, type: !3) -!40 = !DILocation(line: 20, column: 10, scope: !31) -!41 = !DILocation(line: 20, column: 16, scope: !31) -!42 = !DILocation(line: 22, column: 48, scope: !31) -!43 = !DILocation(line: 22, column: 41, scope: !31) -!44 = !DILocation(line: 22, column: 5, scope: !31) -!45 = !DILocation(line: 23, column: 18, scope: !31) -!46 = !DILocation(line: 23, column: 5, scope: !31) -!47 = !DILocation(line: 25, column: 10, scope: !31) -!48 = !DILocation(line: 25, column: 5, scope: !31) -!49 = !DILocation(line: 27, column: 2, scope: !31) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 10, scope: !15) +!31 = !DILocation(line: 12, column: 5, scope: !15) +!32 = !DILocation(line: 14, column: 2, scope: !15) +!33 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !34, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!34 = !DISubroutineType(types: !35) +!35 = !{!5} +!36 = !DILocalVariable(name: "t1", scope: !33, file: !1, line: 19, type: !37) +!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !38, line: 27, baseType: !39) +!38 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!39 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!40 = !DILocation(line: 19, column: 15, scope: !33) +!41 = !DILocalVariable(name: "arr", scope: !33, file: !1, line: 20, type: !4) +!42 = !DILocation(line: 20, column: 10, scope: !33) +!43 = !DILocation(line: 20, column: 16, scope: !33) +!44 = !DILocation(line: 22, column: 41, scope: !33) +!45 = !DILocation(line: 22, column: 5, scope: !33) +!46 = !DILocation(line: 23, column: 18, scope: !33) +!47 = !DILocation(line: 23, column: 5, scope: !33) +!48 = !DILocation(line: 25, column: 10, scope: !33) +!49 = !DILocation(line: 25, column: 5, scope: !33) +!50 = !DILocation(line: 27, column: 2, scope: !33) diff --git a/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll index 7acd79671c..1831e5eb48 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_1.ll @@ -6,19 +6,20 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = bitcast i32* %6 to i8*, !dbg !24 - call void @free(i8* noundef %7) #4, !dbg !25 - ret i8* null, !dbg !26 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = bitcast i32* %7 to i8*, !dbg !26 + call void @free(i8* noundef %8) #4, !dbg !27 + ret i8* null, !dbg !28 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn @@ -28,19 +29,18 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 declare void @free(i8* noundef) #2 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !27 { +define dso_local i32 @main() #0 !dbg !29 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !30, metadata !DIExpression()), !dbg !34 - call void @llvm.dbg.declare(metadata i32** %3, metadata !35, metadata !DIExpression()), !dbg !36 - %4 = load i32*, i32** %3, align 8, !dbg !37 - %5 = bitcast i32* %4 to i8*, !dbg !38 - %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !39 - %7 = load i64, i64* %2, align 8, !dbg !40 - %8 = call i32 @pthread_join(i64 noundef %7, i8** noundef null), !dbg !41 - ret i32 0, !dbg !42 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = bitcast i32** %3 to i8*, !dbg !39 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !40 + %6 = load i64, i64* %2, align 8, !dbg !41 + %7 = call i32 @pthread_join(i64 noundef %6, i8** noundef null), !dbg !42 + ret i32 0, !dbg !43 } ; Function Attrs: nounwind @@ -55,49 +55,50 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_1.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "a285c25fa1749241c92f70edcd885f7d") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_1.c", directory: "", checksumkind: CSK_MD5, checksum: "14a6148e31a552c09a9972943a522fc6") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 10, scope: !14) -!25 = !DILocation(line: 9, column: 5, scope: !14) -!26 = !DILocation(line: 11, column: 2, scope: !14) -!27 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !28, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!28 = !DISubroutineType(types: !29) -!29 = !{!4} -!30 = !DILocalVariable(name: "t1", scope: !27, file: !1, line: 16, type: !31) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !32, line: 27, baseType: !33) -!32 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!33 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!34 = !DILocation(line: 16, column: 15, scope: !27) -!35 = !DILocalVariable(name: "arr", scope: !27, file: !1, line: 17, type: !3) -!36 = !DILocation(line: 17, column: 10, scope: !27) -!37 = !DILocation(line: 19, column: 48, scope: !27) -!38 = !DILocation(line: 19, column: 41, scope: !27) -!39 = !DILocation(line: 19, column: 5, scope: !27) -!40 = !DILocation(line: 20, column: 18, scope: !27) -!41 = !DILocation(line: 20, column: 5, scope: !27) -!42 = !DILocation(line: 22, column: 2, scope: !27) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 10, scope: !15) +!27 = !DILocation(line: 9, column: 5, scope: !15) +!28 = !DILocation(line: 11, column: 2, scope: !15) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !30, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!30 = !DISubroutineType(types: !31) +!31 = !{!5} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 16, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 16, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 17, type: !4) +!38 = !DILocation(line: 17, column: 10, scope: !29) +!39 = !DILocation(line: 19, column: 41, scope: !29) +!40 = !DILocation(line: 19, column: 5, scope: !29) +!41 = !DILocation(line: 20, column: 18, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 22, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll index e1e2fd274e..3d123e6cfd 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_no_alloc_2.ll @@ -6,44 +6,44 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = load i32*, i32** %3, align 8, !dbg !39 - %5 = bitcast i32* %4 to i8*, !dbg !40 - %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !41 - %7 = load i64, i64* %2, align 8, !dbg !42 - %8 = call i32 @pthread_join(i64 noundef %7, i8** noundef null), !dbg !43 - %9 = load i32*, i32** %3, align 8, !dbg !44 - %10 = bitcast i32* %9 to i8*, !dbg !44 - call void @free(i8* noundef %10) #4, !dbg !45 - ret i32 0, !dbg !46 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = bitcast i32** %3 to i8*, !dbg !41 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !42 + %6 = load i64, i64* %2, align 8, !dbg !43 + %7 = call i32 @pthread_join(i64 noundef %6, i8** noundef null), !dbg !44 + %8 = load i32*, i32** %3, align 8, !dbg !45 + %9 = bitcast i32* %8 to i8*, !dbg !45 + call void @free(i8* noundef %9) #4, !dbg !46 + ret i32 0, !dbg !47 } ; Function Attrs: nounwind @@ -61,53 +61,54 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_2.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "4df5fa623115f5e27fc352d3b4bca11a") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_2.c", directory: "", checksumkind: CSK_MD5, checksum: "b2bf37e36390289c32a839b496955f74") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 20, column: 48, scope: !29) -!40 = !DILocation(line: 20, column: 41, scope: !29) -!41 = !DILocation(line: 20, column: 5, scope: !29) -!42 = !DILocation(line: 21, column: 18, scope: !29) -!43 = !DILocation(line: 21, column: 5, scope: !29) -!44 = !DILocation(line: 23, column: 10, scope: !29) -!45 = !DILocation(line: 23, column: 5, scope: !29) -!46 = !DILocation(line: 25, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 20, column: 41, scope: !31) +!42 = !DILocation(line: 20, column: 5, scope: !31) +!43 = !DILocation(line: 21, column: 18, scope: !31) +!44 = !DILocation(line: 21, column: 5, scope: !31) +!45 = !DILocation(line: 23, column: 10, scope: !31) +!46 = !DILocation(line: 23, column: 5, scope: !31) +!47 = !DILocation(line: 25, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_err_no_free.ll b/dartagnan/src/test/resources/alloc/test1_err_no_free.ll index 59c76a7988..3dbe6fb7e3 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_no_free.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_no_free.ll @@ -6,44 +6,44 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 - %5 = bitcast i8* %4 to i32*, !dbg !39 - store i32* %5, i32** %3, align 8, !dbg !38 - %6 = load i32*, i32** %3, align 8, !dbg !40 - %7 = bitcast i32* %6 to i8*, !dbg !41 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 - %9 = load i64, i64* %2, align 8, !dbg !43 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 - ret i32 0, !dbg !45 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + ret i32 0, !dbg !46 } ; Function Attrs: nounwind @@ -61,52 +61,53 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_free.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "c459aaed4dde8b107e0a8f2a7207c29c") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_free.c", directory: "", checksumkind: CSK_MD5, checksum: "e081113a88e49dfdea0e036a989897e2") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 18, column: 16, scope: !29) -!40 = !DILocation(line: 20, column: 48, scope: !29) -!41 = !DILocation(line: 20, column: 41, scope: !29) -!42 = !DILocation(line: 20, column: 5, scope: !29) -!43 = !DILocation(line: 21, column: 18, scope: !29) -!44 = !DILocation(line: 21, column: 5, scope: !29) -!45 = !DILocation(line: 23, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_err_race.ll b/dartagnan/src/test/resources/alloc/test1_err_race.ll index a2aaca04eb..b0e1c08a51 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_race.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_race.ll @@ -6,19 +6,20 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = bitcast i32* %6 to i8*, !dbg !24 - call void @free(i8* noundef %7) #4, !dbg !25 - ret i8* null, !dbg !26 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = bitcast i32* %7 to i8*, !dbg !26 + call void @free(i8* noundef %8) #4, !dbg !27 + ret i8* null, !dbg !28 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn @@ -28,25 +29,24 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 declare void @free(i8* noundef) #2 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !27 { +define dso_local i32 @main() #0 !dbg !29 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !30, metadata !DIExpression()), !dbg !34 - call void @llvm.dbg.declare(metadata i32** %3, metadata !35, metadata !DIExpression()), !dbg !36 - %4 = load i32*, i32** %3, align 8, !dbg !37 - %5 = bitcast i32* %4 to i8*, !dbg !38 - %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !39 - %7 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !40 - %8 = bitcast i8* %7 to i32*, !dbg !40 - store i32* %8, i32** %3, align 8, !dbg !41 - %9 = load i64, i64* %2, align 8, !dbg !42 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !43 - %11 = load i32*, i32** %3, align 8, !dbg !44 - %12 = bitcast i32* %11 to i8*, !dbg !44 - call void @free(i8* noundef %12) #4, !dbg !45 - ret i32 0, !dbg !46 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = bitcast i32** %3 to i8*, !dbg !39 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !40 + %6 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %7 = bitcast i8* %6 to i32*, !dbg !41 + store i32* %7, i32** %3, align 8, !dbg !42 + %8 = load i64, i64* %2, align 8, !dbg !43 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !44 + %10 = load i32*, i32** %3, align 8, !dbg !45 + %11 = bitcast i32* %10 to i8*, !dbg !45 + call void @free(i8* noundef %11) #4, !dbg !46 + ret i32 0, !dbg !47 } ; Function Attrs: nounwind @@ -64,53 +64,54 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_race.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "0c175e83c7b7bcb8fa51479a3fec40a3") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_race.c", directory: "", checksumkind: CSK_MD5, checksum: "5b343c7c5b5f3d29b761dd3f4bb442b1") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 10, scope: !14) -!25 = !DILocation(line: 9, column: 5, scope: !14) -!26 = !DILocation(line: 11, column: 2, scope: !14) -!27 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !28, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!28 = !DISubroutineType(types: !29) -!29 = !{!4} -!30 = !DILocalVariable(name: "t1", scope: !27, file: !1, line: 16, type: !31) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !32, line: 27, baseType: !33) -!32 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!33 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!34 = !DILocation(line: 16, column: 15, scope: !27) -!35 = !DILocalVariable(name: "arr", scope: !27, file: !1, line: 17, type: !3) -!36 = !DILocation(line: 17, column: 10, scope: !27) -!37 = !DILocation(line: 19, column: 48, scope: !27) -!38 = !DILocation(line: 19, column: 41, scope: !27) -!39 = !DILocation(line: 19, column: 5, scope: !27) -!40 = !DILocation(line: 20, column: 11, scope: !27) -!41 = !DILocation(line: 20, column: 9, scope: !27) -!42 = !DILocation(line: 21, column: 18, scope: !27) -!43 = !DILocation(line: 21, column: 5, scope: !27) -!44 = !DILocation(line: 23, column: 10, scope: !27) -!45 = !DILocation(line: 23, column: 5, scope: !27) -!46 = !DILocation(line: 25, column: 2, scope: !27) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 10, scope: !15) +!27 = !DILocation(line: 9, column: 5, scope: !15) +!28 = !DILocation(line: 11, column: 2, scope: !15) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !30, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!30 = !DISubroutineType(types: !31) +!31 = !{!5} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 16, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 16, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 17, type: !4) +!38 = !DILocation(line: 17, column: 10, scope: !29) +!39 = !DILocation(line: 19, column: 41, scope: !29) +!40 = !DILocation(line: 19, column: 5, scope: !29) +!41 = !DILocation(line: 20, column: 11, scope: !29) +!42 = !DILocation(line: 20, column: 9, scope: !29) +!43 = !DILocation(line: 21, column: 18, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 23, column: 10, scope: !29) +!46 = !DILocation(line: 23, column: 5, scope: !29) +!47 = !DILocation(line: 25, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll b/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll index 31cffd9e56..341923add3 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_use_after_free.ll @@ -6,47 +6,47 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 - %5 = bitcast i8* %4 to i32*, !dbg !39 - store i32* %5, i32** %3, align 8, !dbg !38 - %6 = load i32*, i32** %3, align 8, !dbg !40 - %7 = bitcast i32* %6 to i8*, !dbg !41 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 - %9 = load i32*, i32** %3, align 8, !dbg !43 - %10 = bitcast i32* %9 to i8*, !dbg !43 - call void @free(i8* noundef %10) #4, !dbg !44 - %11 = load i64, i64* %2, align 8, !dbg !45 - %12 = call i32 @pthread_join(i64 noundef %11, i8** noundef null), !dbg !46 - ret i32 0, !dbg !47 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i32*, i32** %3, align 8, !dbg !44 + %9 = bitcast i32* %8 to i8*, !dbg !44 + call void @free(i8* noundef %9) #4, !dbg !45 + %10 = load i64, i64* %2, align 8, !dbg !46 + %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !47 + ret i32 0, !dbg !48 } ; Function Attrs: nounwind @@ -67,54 +67,55 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_after_free.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "8d642581889818962a50078c6ebe4f0e") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_after_free.c", directory: "", checksumkind: CSK_MD5, checksum: "b7f8e5ba08709850a328a9a7557694f9") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 18, column: 16, scope: !29) -!40 = !DILocation(line: 20, column: 48, scope: !29) -!41 = !DILocation(line: 20, column: 41, scope: !29) -!42 = !DILocation(line: 20, column: 5, scope: !29) -!43 = !DILocation(line: 21, column: 10, scope: !29) -!44 = !DILocation(line: 21, column: 5, scope: !29) -!45 = !DILocation(line: 22, column: 18, scope: !29) -!46 = !DILocation(line: 22, column: 5, scope: !29) -!47 = !DILocation(line: 24, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 10, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 22, column: 18, scope: !31) +!47 = !DILocation(line: 22, column: 5, scope: !31) +!48 = !DILocation(line: 24, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll b/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll index e82132f98b..d3023a7635 100644 --- a/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll +++ b/dartagnan/src/test/resources/alloc/test1_err_use_before_alloc.ll @@ -6,47 +6,47 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = load i32*, i32** %3, align 8, !dbg !39 - %5 = bitcast i32* %4 to i8*, !dbg !40 - %6 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %5) #4, !dbg !41 - %7 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !42 - %8 = bitcast i8* %7 to i32*, !dbg !42 - store i32* %8, i32** %3, align 8, !dbg !43 - %9 = load i64, i64* %2, align 8, !dbg !44 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !45 - %11 = load i32*, i32** %3, align 8, !dbg !46 - %12 = bitcast i32* %11 to i8*, !dbg !46 - call void @free(i8* noundef %12) #4, !dbg !47 - ret i32 0, !dbg !48 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = bitcast i32** %3 to i8*, !dbg !41 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !42 + %6 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !43 + %7 = bitcast i8* %6 to i32*, !dbg !43 + store i32* %7, i32** %3, align 8, !dbg !44 + %8 = load i64, i64* %2, align 8, !dbg !45 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !46 + %10 = load i32*, i32** %3, align 8, !dbg !47 + %11 = bitcast i32* %10 to i8*, !dbg !47 + call void @free(i8* noundef %11) #4, !dbg !48 + ret i32 0, !dbg !49 } ; Function Attrs: nounwind @@ -67,55 +67,56 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_before_alloc.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "5c311e095b3edb7094e54502edfcdbc7") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_before_alloc.c", directory: "", checksumkind: CSK_MD5, checksum: "38394d88843694d48c1b381d56bd1b78") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 20, column: 48, scope: !29) -!40 = !DILocation(line: 20, column: 41, scope: !29) -!41 = !DILocation(line: 20, column: 5, scope: !29) -!42 = !DILocation(line: 21, column: 11, scope: !29) -!43 = !DILocation(line: 21, column: 9, scope: !29) -!44 = !DILocation(line: 22, column: 18, scope: !29) -!45 = !DILocation(line: 22, column: 5, scope: !29) -!46 = !DILocation(line: 24, column: 10, scope: !29) -!47 = !DILocation(line: 24, column: 5, scope: !29) -!48 = !DILocation(line: 26, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 20, column: 41, scope: !31) +!42 = !DILocation(line: 20, column: 5, scope: !31) +!43 = !DILocation(line: 21, column: 11, scope: !31) +!44 = !DILocation(line: 21, column: 9, scope: !31) +!45 = !DILocation(line: 22, column: 18, scope: !31) +!46 = !DILocation(line: 22, column: 5, scope: !31) +!47 = !DILocation(line: 24, column: 10, scope: !31) +!48 = !DILocation(line: 24, column: 5, scope: !31) +!49 = !DILocation(line: 26, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_ok_1.ll b/dartagnan/src/test/resources/alloc/test1_ok_1.ll index ec6407db97..070835dcba 100644 --- a/dartagnan/src/test/resources/alloc/test1_ok_1.ll +++ b/dartagnan/src/test/resources/alloc/test1_ok_1.ll @@ -6,47 +6,47 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - ret i8* null, !dbg !28 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !29 { +define dso_local i32 @main() #0 !dbg !31 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 - call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !39 - %5 = bitcast i8* %4 to i32*, !dbg !39 - store i32* %5, i32** %3, align 8, !dbg !38 - %6 = load i32*, i32** %3, align 8, !dbg !40 - %7 = bitcast i32* %6 to i8*, !dbg !41 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !42 - %9 = load i64, i64* %2, align 8, !dbg !43 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !44 - %11 = load i32*, i32** %3, align 8, !dbg !45 - %12 = bitcast i32* %11 to i8*, !dbg !45 - call void @free(i8* noundef %12) #4, !dbg !46 - ret i32 0, !dbg !47 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + %10 = load i32*, i32** %3, align 8, !dbg !46 + %11 = bitcast i32* %10 to i8*, !dbg !46 + call void @free(i8* noundef %11) #4, !dbg !47 + ret i32 0, !dbg !48 } ; Function Attrs: nounwind @@ -67,54 +67,55 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_1.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "6736e84db76ebdcaab435efe3c94d890") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_1.c", directory: "", checksumkind: CSK_MD5, checksum: "2e590941d7651d3df54b809725038357") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 2, scope: !14) -!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !30, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!30 = !DISubroutineType(types: !31) -!31 = !{!4} -!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 17, type: !33) -!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) -!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!36 = !DILocation(line: 17, column: 15, scope: !29) -!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 18, type: !3) -!38 = !DILocation(line: 18, column: 10, scope: !29) -!39 = !DILocation(line: 18, column: 16, scope: !29) -!40 = !DILocation(line: 20, column: 48, scope: !29) -!41 = !DILocation(line: 20, column: 41, scope: !29) -!42 = !DILocation(line: 20, column: 5, scope: !29) -!43 = !DILocation(line: 21, column: 18, scope: !29) -!44 = !DILocation(line: 21, column: 5, scope: !29) -!45 = !DILocation(line: 23, column: 10, scope: !29) -!46 = !DILocation(line: 23, column: 5, scope: !29) -!47 = !DILocation(line: 25, column: 2, scope: !29) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 10, scope: !31) +!47 = !DILocation(line: 23, column: 5, scope: !31) +!48 = !DILocation(line: 25, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test1_ok_2.ll b/dartagnan/src/test/resources/alloc/test1_ok_2.ll index 25dcb6aeb0..3a010d9984 100644 --- a/dartagnan/src/test/resources/alloc/test1_ok_2.ll +++ b/dartagnan/src/test/resources/alloc/test1_ok_2.ll @@ -6,25 +6,26 @@ target triple = "x86_64-pc-linux-gnu" %union.pthread_attr_t = type { i64, [48 x i8] } ; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !14 { +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { %2 = alloca i8*, align 8 %3 = alloca i32*, align 8 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !18, metadata !DIExpression()), !dbg !19 - call void @llvm.dbg.declare(metadata i32** %3, metadata !20, metadata !DIExpression()), !dbg !21 - %4 = load i8*, i8** %2, align 8, !dbg !22 - %5 = bitcast i8* %4 to i32*, !dbg !23 - store i32* %5, i32** %3, align 8, !dbg !21 - %6 = load i32*, i32** %3, align 8, !dbg !24 - %7 = getelementptr inbounds i32, i32* %6, i64 0, !dbg !24 - store i32 0, i32* %7, align 4, !dbg !25 - %8 = load i32*, i32** %3, align 8, !dbg !26 - %9 = getelementptr inbounds i32, i32* %8, i64 1, !dbg !26 - store i32 1, i32* %9, align 4, !dbg !27 - %10 = load i32*, i32** %3, align 8, !dbg !28 - %11 = bitcast i32* %10 to i8*, !dbg !28 - call void @free(i8* noundef %11) #4, !dbg !29 - ret i8* null, !dbg !30 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + %11 = load i32*, i32** %3, align 8, !dbg !30 + %12 = bitcast i32* %11 to i8*, !dbg !30 + call void @free(i8* noundef %12) #4, !dbg !31 + ret i8* null, !dbg !32 } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn @@ -34,22 +35,21 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 declare void @free(i8* noundef) #2 ; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !31 { +define dso_local i32 @main() #0 !dbg !33 { %1 = alloca i32, align 4 %2 = alloca i64, align 8 %3 = alloca i32*, align 8 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 - call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 - %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 - %5 = bitcast i8* %4 to i32*, !dbg !41 - store i32* %5, i32** %3, align 8, !dbg !40 - %6 = load i32*, i32** %3, align 8, !dbg !42 - %7 = bitcast i32* %6 to i8*, !dbg !43 - %8 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %7) #4, !dbg !44 - %9 = load i64, i64* %2, align 8, !dbg !45 - %10 = call i32 @pthread_join(i64 noundef %9, i8** noundef null), !dbg !46 - ret i32 0, !dbg !47 + call void @llvm.dbg.declare(metadata i64* %2, metadata !36, metadata !DIExpression()), !dbg !40 + call void @llvm.dbg.declare(metadata i32** %3, metadata !41, metadata !DIExpression()), !dbg !42 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !43 + %5 = bitcast i8* %4 to i32*, !dbg !43 + store i32* %5, i32** %3, align 8, !dbg !42 + %6 = bitcast i32** %3 to i8*, !dbg !44 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !45 + %8 = load i64, i64* %2, align 8, !dbg !46 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !47 + ret i32 0, !dbg !48 } ; Function Attrs: nounwind @@ -67,54 +67,55 @@ attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protect attributes #4 = { nounwind } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12} -!llvm.ident = !{!13} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_2.c", directory: "/home/ubuntu/Desktop/code/temp2/Dat3M", checksumkind: CSK_MD5, checksum: "9d341cbb939552f914c1c2ac6d9de86c") -!2 = !{!3, !5} +!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_2.c", directory: "", checksumkind: CSK_MD5, checksum: "e91d7edb143929cccd1bbe8f9e07c187") +!2 = !{!3, !6} !3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!9 = !{i32 7, !"PIC Level", i32 2} -!10 = !{i32 7, !"PIE Level", i32 2} -!11 = !{i32 7, !"uwtable", i32 1} -!12 = !{i32 7, !"frame-pointer", i32 2} -!13 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!14 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 6, type: !5) -!19 = !DILocation(line: 6, column: 22, scope: !14) -!20 = !DILocalVariable(name: "arr", scope: !14, file: !1, line: 8, type: !3) -!21 = !DILocation(line: 8, column: 10, scope: !14) -!22 = !DILocation(line: 8, column: 22, scope: !14) -!23 = !DILocation(line: 8, column: 16, scope: !14) -!24 = !DILocation(line: 9, column: 5, scope: !14) -!25 = !DILocation(line: 9, column: 12, scope: !14) -!26 = !DILocation(line: 10, column: 5, scope: !14) -!27 = !DILocation(line: 10, column: 12, scope: !14) -!28 = !DILocation(line: 12, column: 10, scope: !14) -!29 = !DILocation(line: 12, column: 5, scope: !14) -!30 = !DILocation(line: 14, column: 2, scope: !14) -!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !32, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17) -!32 = !DISubroutineType(types: !33) -!33 = !{!4} -!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 19, type: !35) -!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) -!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!38 = !DILocation(line: 19, column: 15, scope: !31) -!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 20, type: !3) -!40 = !DILocation(line: 20, column: 10, scope: !31) -!41 = !DILocation(line: 20, column: 16, scope: !31) -!42 = !DILocation(line: 22, column: 48, scope: !31) -!43 = !DILocation(line: 22, column: 41, scope: !31) -!44 = !DILocation(line: 22, column: 5, scope: !31) -!45 = !DILocation(line: 23, column: 18, scope: !31) -!46 = !DILocation(line: 23, column: 5, scope: !31) -!47 = !DILocation(line: 25, column: 2, scope: !31) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 10, scope: !15) +!31 = !DILocation(line: 12, column: 5, scope: !15) +!32 = !DILocation(line: 14, column: 2, scope: !15) +!33 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !34, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!34 = !DISubroutineType(types: !35) +!35 = !{!5} +!36 = !DILocalVariable(name: "t1", scope: !33, file: !1, line: 19, type: !37) +!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !38, line: 27, baseType: !39) +!38 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!39 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!40 = !DILocation(line: 19, column: 15, scope: !33) +!41 = !DILocalVariable(name: "arr", scope: !33, file: !1, line: 20, type: !4) +!42 = !DILocation(line: 20, column: 10, scope: !33) +!43 = !DILocation(line: 20, column: 16, scope: !33) +!44 = !DILocation(line: 22, column: 41, scope: !33) +!45 = !DILocation(line: 22, column: 5, scope: !33) +!46 = !DILocation(line: 23, column: 18, scope: !33) +!47 = !DILocation(line: 23, column: 5, scope: !33) +!48 = !DILocation(line: 25, column: 2, scope: !33) From a4b8f1d4043acdbfe70f2950d22bf2c8ac649f1f Mon Sep 17 00:00:00 2001 From: Tianrui Zheng <107266531+CapZTr@users.noreply.github.com> Date: Tue, 11 Mar 2025 11:42:24 +0100 Subject: [PATCH 03/36] Support alloc-free dev (#794) * init alias analysis for alloc Signed-off-by: Tianrui Zheng * add MemFree events to the test Signed-off-by: Tianrui Zheng * add first test for alias analysis Signed-off-by: Tianrui Zheng * add second test for alias analysis Signed-off-by: Tianrui Zheng * improve field insensitive for alloc Signed-off-by: Tianrui Zheng * add third test for alias analysis Signed-off-by: Tianrui Zheng * add alias analysis for free events Signed-off-by: Tianrui Zheng * use alias analysis for alloc and free in relation analysis Signed-off-by: Tianrui Zheng * change native relation analysis Signed-off-by: Tianrui Zheng * change logic of mustAlias Signed-off-by: Tianrui Zheng * Using stack pointer in alloc tests * change exception type Signed-off-by: Tianrui Zheng * Add full alias analysis Signed-off-by: Tianrui Zheng * Add object alias for alloc -> memory event Signed-off-by: Tianrui Zheng * Add alloc and free to alias graph Signed-off-by: Tianrui Zheng --------- Signed-off-by: Tianrui Zheng Co-authored-by: Tianrui Zheng Co-authored-by: Natalia Gavrilenko --- cat/rc11.cat | 4 +- .../program/analysis/alias/AliasAnalysis.java | 140 +++++-- .../analysis/alias/AndersenAliasAnalysis.java | 68 +++- .../analysis/alias/EqualityAliasAnalysis.java | 37 +- .../alias/FieldSensitiveAndersen.java | 50 ++- .../alias/InclusionBasedPointerAnalysis.java | 65 ++- .../analysis/alias/VirtualAliasAnalysis.java | 26 +- .../wmm/analysis/NativeRelationAnalysis.java | 36 +- .../others/miscellaneous/AnalysisTest.java | 380 +++++++++++++++++- 9 files changed, 715 insertions(+), 91 deletions(-) diff --git a/cat/rc11.cat b/cat/rc11.cat index 3572d40c63..5320da5e12 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -44,11 +44,13 @@ flag ~empty race as racy * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event *) +(* flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +*) // TODO: Non-monotonic! (see ThreadCreation class) -flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file +// flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java index 2330b85306..4d2827902c 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java @@ -3,9 +3,9 @@ import com.dat3m.dartagnan.configuration.Alias; import com.dat3m.dartagnan.configuration.Arch; import com.dat3m.dartagnan.program.Program; -import com.dat3m.dartagnan.program.event.MemoryEvent; -import com.dat3m.dartagnan.program.event.core.Init; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; +import com.dat3m.dartagnan.program.Thread; +import com.dat3m.dartagnan.program.event.Event; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.program.event.metadata.SourceLocation; import com.dat3m.dartagnan.utils.Utils; import com.dat3m.dartagnan.verification.Context; @@ -30,9 +30,13 @@ public interface AliasAnalysis { Logger logger = LogManager.getLogger(AliasAnalysis.class); - boolean mustAlias(MemoryCoreEvent a, MemoryCoreEvent b); + boolean mustAlias(Event a, Event b); - boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b); + boolean mayAlias(Event a, Event b); + + boolean mustObjectAlias(Event a, Event b); + + boolean mayObjectAlias(Event a, Event b); static AliasAnalysis fromConfig(Program program, Context analysisContext, Configuration config) throws InvalidConfigurationException { Config c = new Config(config); @@ -103,15 +107,25 @@ private CombinedAliasAnalysis(AliasAnalysis a1, AliasAnalysis a2) { } @Override - public boolean mustAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + public boolean mustAlias(Event a, Event b) { return a1.mustAlias(a, b) || a2.mustAlias(a, b); } @Override - public boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + public boolean mayAlias(Event a, Event b) { return a1.mayAlias(a, b) && a2.mayAlias(a, b); } + @Override + public boolean mustObjectAlias(Event a, Event b) { + return a1.mustObjectAlias(a, b) || a2.mustObjectAlias(a, b); + } + + @Override + public boolean mayObjectAlias(Event a, Event b) { + return a1.mayObjectAlias(a, b) && a2.mayObjectAlias(a, b); + } + @Override public Graphviz getGraphVisualization() { return a1.getGraphVisualization(); @@ -123,39 +137,106 @@ default Graphviz getGraphVisualization() { return null; } - private Graphviz defaultGraph(Program program, Config configuration) { - // Nodes represent sets of events. - // A solid line marks the existence of events that must alias. - // A dashed line marks the existence of events that may alias. - final Map> mayGraph = new HashMap<>(); - final Map> mustGraph = new HashMap<>(); - final List events = program.getThreadEvents(MemoryCoreEvent.class); - for (final MemoryCoreEvent event1 : events) { + private void populateAddressGraph(Map> may, Map> must, + List list1, List list2, Config configuration) { + for (final Event event1 : list1) { final String node1 = repr(event1, configuration); if (node1 == null) { continue; } - final Set maySet = mayGraph.computeIfAbsent(node1, k -> new HashSet<>()); - final Set mustSet = mustGraph.computeIfAbsent(node1, k -> new HashSet<>()); - for (final MemoryCoreEvent event2 : events) { + final Set maySet = may.computeIfAbsent(node1, k -> new HashSet<>()); + final Set mustSet = must.computeIfAbsent(node1, k -> new HashSet<>()); + for (final Event event2 : list2) { final String node2 = repr(event2, configuration); - if (node2 != null && node1.compareTo(node2) < 0 && mayAlias(event1, event2)) { + if ((event1 instanceof MemoryCoreEvent && event2 instanceof MemoryCoreEvent) + || (event1 instanceof MemFree && event2 instanceof MemFree)) { + if (event1.getGlobalId() - event2.getGlobalId() >= 0) { + continue; + } + } + if (node2 != null && mayAlias(event1, event2)) { (mustAlias(event1, event2) ? mustSet : maySet).add(node2); } } maySet.removeAll(mustSet); } + } + + private void populateObjectGraph(Map> may, Map> must, + List allocs, List events, Config configuration) { + for (final Alloc alloc : allocs) { + final String node1 = repr(alloc, configuration); + final Set maySet = may.computeIfAbsent(node1, k -> new HashSet<>()); + final Set mustSet = must.computeIfAbsent(node1, k -> new HashSet<>()); + for (final MemoryCoreEvent event : events) { + final String node2 = repr(event, configuration); + if (node2 != null && mayObjectAlias(alloc, event)) { + (mustObjectAlias(alloc, event) ? mustSet : maySet).add(node2); + } + } + maySet.removeAll(mustSet); + } + } + + private Graphviz defaultGraph(Program program, Config configuration) { + // Nodes represent sets of events. + // A solid blue line marks the existence of events that must address-alias. + final Map> mustAddressGraph = new HashMap<>(); + // A dashed blue line marks the existence of events that may address-alias. + final Map> mayAddressGraph = new HashMap<>(); + // A solid orange line marks the existence of events that must object-alias. + final Map> mustObjectGraph = new HashMap<>(); + // A dashed orange line marks the existence of events that may object-alias. + final Map> mayObjectGraph = new HashMap<>(); + + final List events = program.getThreadEvents(MemoryCoreEvent.class); + final List allocs = program.getThreadEvents(Alloc.class); + final List frees = program.getThreadEvents(MemFree.class); + + populateAddressGraph(mayAddressGraph, mustAddressGraph, events, events, configuration); + populateAddressGraph(mayAddressGraph, mustAddressGraph, frees, frees, configuration); + populateAddressGraph(mayAddressGraph, mustAddressGraph, allocs, frees, configuration); + + populateObjectGraph(mayObjectGraph, mustObjectGraph, allocs, events, configuration); // Generates the graphs final var graphviz = new Graphviz(); graphviz.beginGraph("alias"); - graphviz.beginSubgraph("may alias"); + // Group events + for (final Thread thread : program.getThreads()) { + graphviz.beginSubgraph("Thread" + thread.getId()); + graphviz.setEdgeAttributes("weight=100", "style=invis"); + final List grouped = new ArrayList<>(); + for (final Event event : thread.getEvents()) { + if (event instanceof MemoryCoreEvent || event instanceof Alloc || event instanceof MemFree) { + if (!configuration.graphvizShowAll && event instanceof Init) { + continue; + } + grouped.add(event); + } + } + for (int i = 1; i < grouped.size(); i++) { + final String node1 = repr(grouped.get(i - 1), configuration); + final String node2 = repr(grouped.get(i), configuration); + graphviz.addEdge(node1, node2); + } + graphviz.end(); + } + graphviz.beginSubgraph("may address alias"); graphviz.setEdgeAttributes("color=mediumslateblue", "style=dashed"); - graphviz.addEdges(mayGraph); + graphviz.addEdges(mayAddressGraph); graphviz.end(); - graphviz.beginSubgraph("must alias"); + graphviz.beginSubgraph("must address alias"); graphviz.setEdgeAttributes("color=mediumslateblue"); - graphviz.addEdges(mustGraph); + graphviz.addEdges(mustAddressGraph); + graphviz.end(); + graphviz.beginSubgraph("may object alias"); + graphviz.setEdgeAttributes("color=orangered", "style=dashed"); + graphviz.addEdges(mayObjectGraph); + graphviz.end(); + graphviz.beginSubgraph("must object alias"); + graphviz.setEdgeAttributes("color=orangered"); + graphviz.addEdges(mustObjectGraph); graphviz.end(); graphviz.end(); return graphviz; @@ -180,16 +261,21 @@ private void generateGraph(Program program, Config configuration) { } } - private static String repr(MemoryEvent event, Config configuration) { + private static String repr(Event event, Config configuration) { if (!configuration.graphvizShowAll && event instanceof Init) { return null; } + final String type = event instanceof Load ? ": R" + : event instanceof Store ? ": W" + : event instanceof Alloc ? ": A" + : event instanceof MemFree ? ": F" + : ""; final SourceLocation location = event.getMetadata(SourceLocation.class); if (configuration.graphvizSplitByThread) { - return location != null ? "\"T" + event.getThread().getId() + esc(location) + "\"" : - "\"T" + event.getThread().getId() + "E" + event.getGlobalId() + "\""; + return location != null ? "\"T" + event.getThread().getId() + esc(location) + type + "\"" : + "\"T" + event.getThread().getId() + "E" + event.getGlobalId() + type + "\""; } - return location != null ? "\"" + esc(location) + "\"" : "\"E" + event.getGlobalId() + "\""; + return location != null ? "\"" + esc(location) + type + "\"" : "\"E" + event.getGlobalId() + type + "\""; } private static String esc(Object object) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java index 3aa76b80fe..51472ebb68 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java @@ -5,11 +5,10 @@ import com.dat3m.dartagnan.expression.integers.IntLiteral; import com.dat3m.dartagnan.program.Program; import com.dat3m.dartagnan.program.Register; +import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.MemoryEvent; import com.dat3m.dartagnan.program.event.RegWriter; -import com.dat3m.dartagnan.program.event.core.Local; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; -import com.dat3m.dartagnan.program.event.core.Store; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.program.memory.MemoryObject; import com.google.common.base.Preconditions; import com.google.common.base.Verify; @@ -34,6 +33,7 @@ * * @author flo * @author xeren + * @author Tianrui Zheng */ public class AndersenAliasAnalysis implements AliasAnalysis { @@ -45,7 +45,7 @@ public class AndersenAliasAnalysis implements AliasAnalysis { private final Map> addresses = new HashMap<>(); private final Map> events = new HashMap<>(); private final Map> targets = new HashMap<>(); - private final Map> eventAddressSpaceMap = new HashMap<>(); + private final Map> eventAddressSpaceMap = new HashMap<>(); // ================================ Construction ================================ @@ -68,24 +68,48 @@ public static AndersenAliasAnalysis fromConfig(Program program, Configuration co // ================================ API ================================ @Override - public boolean mayAlias(MemoryCoreEvent x, MemoryCoreEvent y) { + public boolean mayAlias(Event x, Event y) { return !Sets.intersection(getMaxAddressSet(x), getMaxAddressSet(y)).isEmpty(); } @Override - public boolean mustAlias(MemoryCoreEvent x, MemoryCoreEvent y) { - return getMaxAddressSet(x).size() == 1 && getMaxAddressSet(x).containsAll(getMaxAddressSet(y)); + public boolean mustAlias(Event x, Event y) { + Set lx = getMaxAddressSet(x); + return lx.size() == 1 && lx.equals(getMaxAddressSet(y)); } - private ImmutableSet getMaxAddressSet(MemoryEvent e) { + @Override + public boolean mayObjectAlias(Event a, Event b) { + return !Sets.intersection(getAccessibleObjects(a), getAccessibleObjects(b)).isEmpty(); + } + + @Override + public boolean mustObjectAlias(Event a, Event b) { + Set objsA = getAccessibleObjects(a); + return objsA.size() == 1 && objsA.equals(getAccessibleObjects(b)); + } + + private ImmutableSet getMaxAddressSet(Event e) { return eventAddressSpaceMap.get(e); } + private Set getAccessibleObjects(Event e) { + Set objs = new HashSet<>(); + Set locs = getMaxAddressSet(e); + if (locs != null) { + locs.stream().forEach(l -> objs.add(l.base)); + } + return objs; + } + // ================================ Processing ================================ private void run(Program program) { List memEvents = program.getThreadEvents(MemoryCoreEvent.class); List locals = program.getThreadEvents(Local.class); + for (Alloc a : program.getThreadEvents(Alloc.class)) { + processAllocs(a); + } for (MemoryCoreEvent e : memEvents) { processLocs(e); } @@ -98,10 +122,21 @@ private void run(Program program) { processResults(e); } for (MemoryCoreEvent e : memEvents) { - processResults(e); + eventAddressSpaceMap.put(e, ImmutableSet.copyOf(getAddressSpace(e.getAddress()))); + } + for (MemFree f : program.getThreadEvents(MemFree.class)) { + eventAddressSpaceMap.put(f, ImmutableSet.copyOf(getAddressSpace(f.getAddress()))); } } + private void processAllocs(Alloc a) { + Register r = a.getResultRegister(); + Location base = new Location(a.getAllocatedObject(), 0); + eventAddressSpaceMap.put(a, ImmutableSet.of(base)); + addAddress(r, base); + variables.add(r); + } + private void processLocs(MemoryCoreEvent e) { Expression address = e.getAddress(); // Collect for each v events of form: p = *v, *v = q @@ -236,25 +271,24 @@ private void processResults(Local e) { } } - private void processResults(MemoryCoreEvent e) { - Expression address = e.getAddress(); + private Set getAddressSpace(Expression addrExpr) { Set addresses; - if (address instanceof Register) { - Set target = targets.get(address); - addresses = target != null ? target : getAddresses(address); + if (addrExpr instanceof Register) { + Set target = targets.get(addrExpr); + addresses = target != null ? target : getAddresses(addrExpr); } else { - Constant addressConstant = new Constant(address); + Constant addressConstant = new Constant(addrExpr); if (addressConstant.failed) { addresses = maxAddressSet; } else { - Verify.verify(addressConstant.location != null, "memory event accessing a pure constant address"); + Verify.verify(addressConstant.location != null, "accessing a pure constant address"); addresses = ImmutableSet.of(addressConstant.location); } } if (addresses.isEmpty()) { addresses = maxAddressSet; } - eventAddressSpaceMap.put(e, ImmutableSet.copyOf(addresses)); + return addresses; } private static final class Constant { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java index 9d5a923e78..f6cff75494 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java @@ -1,10 +1,11 @@ package com.dat3m.dartagnan.program.analysis.alias; +import com.dat3m.dartagnan.expression.Expression; import com.dat3m.dartagnan.program.Program; import com.dat3m.dartagnan.program.Register; import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.RegWriter; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.wmm.utils.graph.mutable.MapEventGraph; import com.dat3m.dartagnan.wmm.utils.graph.mutable.MutableEventGraph; import org.sosy_lab.common.configuration.Configuration; @@ -29,17 +30,22 @@ public static EqualityAliasAnalysis fromConfig(Program program, Configuration co } @Override - public boolean mustAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + public boolean mayAlias(Event a, Event b) { + return true; + } - if (a.getFunction() != b.getFunction() - || !a.getAddress().equals(b.getAddress())) { + @Override + public boolean mustAlias(Event a, Event b) { + Expression addrA = getAddress(a); + Expression addrB = getAddress(b); + if (a.getFunction() != b.getFunction() || !addrA.equals(addrB)) { return false; } else if (a == b) { return true; } // Normalize direction if (a.getGlobalId() > b.getGlobalId()) { - MemoryCoreEvent temp = a; + Event temp = a; a = b; b = temp; } @@ -53,7 +59,7 @@ public boolean mustAlias(MemoryCoreEvent a, MemoryCoreEvent b) { } // Establish that address expression evaluates to same value at both events. - Set addrRegs = a.getAddress().getRegs(); + Set addrRegs = addrA.getRegs(); Event e = a.getSuccessor(); while (e != b) { if (e instanceof RegWriter rw && addrRegs.contains(rw.getResultRegister())) { @@ -67,7 +73,24 @@ public boolean mustAlias(MemoryCoreEvent a, MemoryCoreEvent b) { } @Override - public boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + public boolean mayObjectAlias(Event a, Event b) { return true; } + + @Override + public boolean mustObjectAlias(Event a, Event b) { + return false; + } + + private Expression getAddress(Event e) { + if (e instanceof MemoryCoreEvent me) { + return me.getAddress(); + } else if (e instanceof MemFree f) { + return f.getAddress(); + } else if (e instanceof Alloc a) { + return a.getAllocatedObject(); + } else { + throw new UnsupportedOperationException("Event type has no address: " + e.getClass().getSimpleName()); + } + } } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java index 3127715cf8..dcf4e3a5f6 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java @@ -55,7 +55,7 @@ public class FieldSensitiveAndersen implements AliasAnalysis { ///Maps registers to matched value expressions of stores that use the register in their address private final Map>> stores = new HashMap<>(); ///Result sets - private final Map> eventAddressSpaceMap = new HashMap<>(); + private final Map> eventAddressSpaceMap = new HashMap<>(); // ================================ Construction ================================ @@ -70,24 +70,47 @@ private FieldSensitiveAndersen() { } // ================================ API ================================ @Override - public boolean mayAlias(MemoryCoreEvent x, MemoryCoreEvent y) { + public boolean mayAlias(Event x, Event y) { return !Sets.intersection(getMaxAddressSet(x), getMaxAddressSet(y)).isEmpty(); } @Override - public boolean mustAlias(MemoryCoreEvent x, MemoryCoreEvent y) { + public boolean mustAlias(Event x, Event y) { Set a = getMaxAddressSet(x); - return a.size() == 1 && a.containsAll(getMaxAddressSet(y)); + return a.size() == 1 && a.equals(getMaxAddressSet(y)); } - private ImmutableSet getMaxAddressSet(MemoryEvent e) { + @Override + public boolean mayObjectAlias(Event a, Event b) { + return !Sets.intersection(getAccessibleObjects(a), getAccessibleObjects(b)).isEmpty(); + } + + @Override + public boolean mustObjectAlias(Event a, Event b) { + Set objsA = getAccessibleObjects(a); + return objsA.size() == 1 && objsA.equals(getAccessibleObjects(b)); + } + + private ImmutableSet getMaxAddressSet(Event e) { return eventAddressSpaceMap.get(e); } + private Set getAccessibleObjects(Event e) { + Set objs = new HashSet<>(); + Set locs = getMaxAddressSet(e); + if (locs != null) { + locs.stream().forEach(l -> objs.add(l.base)); + } + return objs; + } + // ================================ Processing ================================ private void run(Program program) { checkArgument(program.isCompiled(), "The program must be compiled first."); + for (Alloc a : program.getThreadEvents(Alloc.class)) { + eventAddressSpaceMap.put(a, ImmutableSet.of(new Location(a.getAllocatedObject(), 0))); + } List memEvents = program.getThreadEvents(MemoryCoreEvent.class); for (MemoryCoreEvent e : memEvents) { processLocs(e); @@ -100,7 +123,10 @@ private void run(Program program) { algorithm(variable); } for (MemoryCoreEvent e : memEvents) { - processResults(e); + eventAddressSpaceMap.put(e, getAddressSpace(e.getAddress())); + } + for (MemFree f : program.getThreadEvents(MemFree.class)) { + eventAddressSpaceMap.put(f, getAddressSpace(f.getAddress())); } } @@ -181,14 +207,14 @@ protected void algorithm(Object variable) { } } - protected void processResults(MemoryCoreEvent e) { - ImmutableSet.Builder addresses = ImmutableSet.builder(); - Collector collector = new Collector(e.getAddress()); - addresses.addAll(collector.address()); + protected ImmutableSet getAddressSpace(Expression addrExpr) { + ImmutableSet.Builder builder = new ImmutableSet.Builder<>(); + Collector collector = new Collector(addrExpr); + builder.addAll(collector.address()); for (Offset r : collector.register()) { - addresses.addAll(fields(getAddresses(r.base), r.offset, r.alignment)); + builder.addAll(fields(getAddresses(r.base), r.offset, r.alignment)); } - eventAddressSpaceMap.put(e, addresses.build()); + return builder.build(); } private static final class Offset { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java index 8a13f70d7c..928cfd5da8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java @@ -8,6 +8,7 @@ import com.dat3m.dartagnan.program.Register; import com.dat3m.dartagnan.program.analysis.ReachingDefinitionsAnalysis; import com.dat3m.dartagnan.program.analysis.SyntacticContextAnalysis; +import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.RegReader; import com.dat3m.dartagnan.program.event.RegWriter; import com.dat3m.dartagnan.program.event.core.*; @@ -17,6 +18,7 @@ import com.dat3m.dartagnan.witness.graphviz.Graphviz; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.collect.Sets; import com.google.common.math.IntMath; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -80,8 +82,11 @@ public class InclusionBasedPointerAnalysis implements AliasAnalysis { // For lazy cycle detection, it is grouped by the absolute value of IncludeEdge.modifier.offset. private final TreeMap>> queue = new TreeMap<>(); - // Maps memory events to variables representing their pointer set. - private final Map addressVariables = new HashMap<>(); + // Maps memory events, allocs, and frees to variables representing their pointer set. + private final Map addressVariables = new HashMap<>(); + + // Maps pointer sets to their accessible memory objects. + private final Map> accessibleObjects = new HashMap<>(); // Maps memory objects to variables representing their base address. // These Variables should always have empty includes-sets. @@ -146,7 +151,7 @@ private InclusionBasedPointerAnalysis(Program p, ReachingDefinitionsAnalysis d) // ================================ API ================================ @Override - public boolean mayAlias(MemoryCoreEvent x, MemoryCoreEvent y) { + public boolean mayAlias(Event x, Event y) { final DerivedVariable vx = addressVariables.get(x); final DerivedVariable vy = addressVariables.get(y); if (vx == null || vy == null) { @@ -170,18 +175,47 @@ public boolean mayAlias(MemoryCoreEvent x, MemoryCoreEvent y) { } @Override - public boolean mustAlias(MemoryCoreEvent x, MemoryCoreEvent y) { + public boolean mustAlias(Event x, Event y) { final DerivedVariable vx = addressVariables.get(x); final DerivedVariable vy = addressVariables.get(y); return vx != null && vy != null && vx.base == vy.base && vx.modifier.offset == vy.modifier.offset && isConstant(vx.modifier) && isConstant(vy.modifier); } + @Override + public boolean mayObjectAlias(Event a, Event b) { + final DerivedVariable va = addressVariables.get(a); + final DerivedVariable vb = addressVariables.get(b); + return va == null || vb == null || !Sets.intersection(accessibleObjects.get(va), accessibleObjects.get(vb)).isEmpty(); + } + + @Override + public boolean mustObjectAlias(Event a, Event b) { + final DerivedVariable va = addressVariables.get(a); + final DerivedVariable vb = addressVariables.get(b); + if (va == null || vb == null) { + return false; + } + if (va.base == vb.base) { + return true; + } + final Set objsA = accessibleObjects.get(va); + return objsA.size() == 1 && objsA.equals(accessibleObjects.get(vb)); + } + @Override public Graphviz getGraphVisualization() { return graphviz; } + private Set getAccessibleObjects(DerivedVariable address) { + final Set objs = new HashSet<>(); + objs.add(address.base.object); + address.base.includes.forEach(i -> objs.add(i.source.object)); + objs.remove(null); + return objs; + } + // ================================ Processing ================================ private void run(Program program, AliasAnalysis.Config configuration) { @@ -192,6 +226,9 @@ private void run(Program program, AliasAnalysis.Config configuration) { totalVariables++; objectVariables.put(object, new Variable(object, object.toString())); } + for (final Alloc alloc : program.getThreadEvents(Alloc.class)) { + addressVariables.put(alloc, derive(objectVariables.get(alloc.getAllocatedObject()))); + } // Each expression gets a "res" variable representing its result value set. // Each register writer gets an "out" variable ("ld" for loads) representing its return value set. // If needed, a register gets a "phi" variable representing its phi-node's value set. @@ -202,6 +239,9 @@ private void run(Program program, AliasAnalysis.Config configuration) { for (final MemoryCoreEvent memoryEvent : program.getThreadEvents(MemoryCoreEvent.class)) { processMemoryEvent(memoryEvent); } + for (final MemFree free : program.getThreadEvents(MemFree.class)) { + processFree(free); + } // Fixed-point computation: while (!queue.isEmpty()) { final Map.Entry>> q = queue.pollFirstEntry(); @@ -213,9 +253,12 @@ private void run(Program program, AliasAnalysis.Config configuration) { if (configuration.graphvizInternal) { generateGraph(); } - for (final Map.Entry entry : addressVariables.entrySet()) { + for (final Map.Entry entry : addressVariables.entrySet()) { postProcess(entry); } + for (final DerivedVariable v : addressVariables.values()) { + accessibleObjects.computeIfAbsent(v, k -> getAccessibleObjects(v)); + } objectVariables.clear(); registerVariables.clear(); } @@ -294,6 +337,16 @@ private void processMemoryEvent(MemoryCoreEvent event) { } } + private void processFree(MemFree free) { + logger.trace("{}", free); + final DerivedVariable address = getResultVariable(free.getAddress(), free); + if (address == null) { + logger.warn("null pointer address for {}", synContext.get().getContextInfo(free)); + return; + } + addressVariables.put(free, address); + } + // Propagates the pointer sets and tests for new communications. private void algorithm(Variable variable, List edges) { logger.trace("{} includes {}", variable, edges); @@ -372,7 +425,7 @@ private void algorithm(Variable variable, List edges) { // Removes information from the internal graph, which are no longer needed after the algorithm has finished. // This simplifies alias queries and releases memory resources. - private void postProcess(Map.Entry entry) { + private void postProcess(Map.Entry entry) { logger.trace("{}", entry); final DerivedVariable address = entry.getValue(); if (address == null) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java index f9cc3aac21..779a7701f3 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java @@ -1,5 +1,6 @@ package com.dat3m.dartagnan.program.analysis.alias; +import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; import com.dat3m.dartagnan.program.memory.VirtualMemoryObject; @@ -15,12 +16,29 @@ public static AliasAnalysis wrap(AliasAnalysis analysis) { } @Override - public boolean mayAlias(MemoryCoreEvent e1, MemoryCoreEvent e2) { - return samePhysicalAddress(e1, e2) || wrappedAnalysis.mayAlias(e1, e2); + public boolean mayAlias(Event e1, Event e2) { + if (e1 instanceof MemoryCoreEvent me1 && e2 instanceof MemoryCoreEvent me2) { + return samePhysicalAddress(me1, me2) || wrappedAnalysis.mayAlias(me1, me2); + } + return true; + } + + @Override + public boolean mustAlias(Event e1, Event e2) { + if (e1 instanceof MemoryCoreEvent me1 && e2 instanceof MemoryCoreEvent me2) { + return samePhysicalAddress(me1, me2) || wrappedAnalysis.mustAlias(me1, me2); + } + return false; } + + @Override + public boolean mayObjectAlias(Event a, Event b) { + return true; + } + @Override - public boolean mustAlias(MemoryCoreEvent e1, MemoryCoreEvent e2) { - return samePhysicalAddress(e1, e2) || wrappedAnalysis.mustAlias(e1, e2); + public boolean mustObjectAlias(Event a, Event b) { + return false; } // GPU memory models make use of virtual addresses. diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java index 83ad6fff9f..964300ec33 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java @@ -774,35 +774,39 @@ public MutableKnowledge visitCoherence(Coherence co) { } @Override - // TODO: Alias analysis for alloc-free pointers - public MutableKnowledge visitAllocPtr(AllocPtr aref) { + public MutableKnowledge visitAllocPtr(AllocPtr allocPtr) { MutableEventGraph may = new MapEventGraph(); MutableEventGraph must = new MapEventGraph(); - for (Alloc e1 : program.getThreadEvents(Alloc.class)) { - if (e1.isHeapAllocation()) { - for (Event e2 : program.getThreadEvents(MemFree.class)) { + List allocs = program.getThreadEventsWithAllTags(ALLOC); + List frees = program.getThreadEvents(MemFree.class); + List allocAndFrees = Stream.concat(allocs.stream(), frees.stream()).toList(); + for (Event e1 : allocAndFrees) { + for (MemFree e2 : frees) { + if (alias.mayAlias(e1, e2)) { may.add(e1, e2); + if (alias.mustAlias(e1, e2)) { + must.add(e1, e2); + } } } } - for (Event e1 : program.getThreadEvents(MemFree.class)) { - for (Event e2 : program.getThreadEvents(MemFree.class)) { - may.add(e1, e2); - } - } return new MutableKnowledge(may, must); } @Override - // TODO: Alias analysis for alloc and memory accesses - // (note that we should consider the whole allocated region, not only the pointer) - public MutableKnowledge visitAllocMem(AllocMem aloc) { + public MutableKnowledge visitAllocMem(AllocMem allocMem) { MutableEventGraph may = new MapEventGraph(); MutableEventGraph must = new MapEventGraph(); - for (Alloc e1 : program.getThreadEvents(Alloc.class)) { - if (e1.isHeapAllocation()) { - for (Event e2 : program.getThreadEvents(MemoryEvent.class)) { + List memEvents = program.getThreadEvents(MemoryCoreEvent.class); + List allocs = program.getThreadEventsWithAllTags(ALLOC); + for (Event e1 : allocs) { + for (MemoryCoreEvent e2 : memEvents) { + if (e2 instanceof Init) { continue; } + if (alias.mayObjectAlias(e1, e2)) { may.add(e1, e2); + if (alias.mustObjectAlias(e1, e2)) { + must.add(e1, e2); + } } } } diff --git a/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java b/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java index 07cbd927d3..bce35b68f0 100644 --- a/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java +++ b/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java @@ -620,6 +620,363 @@ public void fullPropagation1() throws InvalidConfigurationException { assertAlias(MAY, a, me3, me4); } + @Test + public void fieldsensitive6() throws InvalidConfigurationException { + program6(FIELD_SENSITIVE, MUST, NONE, MUST, MUST); + } + + @Test + public void fieldinsensitive6() throws InvalidConfigurationException { + program6(FIELD_INSENSITIVE, MUST, NONE, MAY, MUST); + } + + @Test + public void full6() throws InvalidConfigurationException { + program6(FULL, MUST, NONE, MUST, MUST); + } + + private void program6(Alias method, Result... expect) throws InvalidConfigurationException { + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + MemoryObject x = b.newMemoryObject("x", 1); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + Alloc a = newHeapAlloc(r0, 2); // r0 = malloc(2) + b.addChild(0, a); + Store e0 = newStore(r0, value(2)); // *r0 = 2 + b.addChild(0, e0); + Register r1 = b.getOrNewRegister(0, "r1"); + Load e1 = newLoad(r1, x); // r1 = x + b.addChild(0, e1); + Store e2 = newStore(plus(r0, 1), r1); // *(r0 + 1) = r1 + b.addChild(0, e2); + MemFree f = newFree(r0); // free(r0) + b.addChild(0, f); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + Alloc al = (Alloc) findMatchingEventAfterProcessing(program, a); + MemoryCoreEvent me0 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e0); + MemoryCoreEvent me1 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e1); + MemoryCoreEvent me2 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e2); + MemFree fr = (MemFree) findMatchingEventAfterProcessing(program, f); + + assertObjectAlias(expect[0], aa, al, me0); + assertObjectAlias(expect[1], aa, al, me1); + assertObjectAlias(expect[2], aa, al, me2); + assertAlias(expect[3], aa, al, fr); + } + + @Test + public void fieldsensitive7() throws InvalidConfigurationException { + program7(FIELD_SENSITIVE, MUST, NONE, MUST, NONE, MAY, NONE, MUST, NONE, MUST, MAY, MUST, NONE, NONE, MUST, NONE); + } + + @Test + public void fieldinsensitive7() throws InvalidConfigurationException { + program7(FIELD_INSENSITIVE, MUST, NONE, MAY, MAY, MAY, NONE, MUST, MAY, MAY, MAY, MUST, NONE, NONE, MUST, NONE); + } + + @Test + public void full7() throws InvalidConfigurationException { + program7(FULL, MUST, NONE, MUST, NONE, NONE, NONE, MUST, NONE, MUST, MUST, MUST, NONE, NONE, MUST, NONE); + } + + private void program7(Alias method, Result... expect) throws InvalidConfigurationException{ + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + Alloc a0 = newHeapAlloc(r0, 3); // r0 = malloc(3) + b.addChild(0, a0); + Register r1 = b.getOrNewRegister(0, "r1"); + Alloc a1 = newHeapAlloc(r1, 4); // r1 = malloc(4) + b.addChild(0, a1); + Store e0 = newStore(r0, r1); // *r0 = r1 + b.addChild(0, e0); + Store e1 = newStore(r1, r0); // *r1 = r0 + b.addChild(0, e1); + Register r2 = b.getOrNewRegister(0, "r2"); + b.addChild(0, newLocal(r2, r0)); // r2 = r0 + Store e2 = newStore(plus(r2, 2), value(1)); // *(r2 + 2) = 1 + b.addChild(0, e2); + Register r3 = b.getOrNewRegister(0, "r3"); + b.addChild(0, newLocal(r3, r1)); // r3 = r1 + Store e3 = newStore(plus(r3, 3), value(1)); // *(r3 + 3) = 1 + b.addChild(0, e3); + Register r4 = b.getOrNewRegister(0, "r4"); + b.addChild(0, newLocal(r4, r0)); // r4 = r0 + b.addChild(0, newLocal(r4, r1)); // r4 = r1 + Store e4 = newStore(r4, value(1)); // *r4 = 1 + b.addChild(0, e4); + MemFree f0 = newFree(r0); // free(r0) + b.addChild(0, f0); + MemFree f1 = newFree(r1); // free(r1) + b.addChild(0, f1); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + Alloc al0 = (Alloc) findMatchingEventAfterProcessing(program, a0); + Alloc al1 = (Alloc) findMatchingEventAfterProcessing(program, a1); + MemoryCoreEvent me0 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e0); + MemoryCoreEvent me1 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e1); + MemoryCoreEvent me2 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e2); + MemoryCoreEvent me3 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e3); + MemoryCoreEvent me4 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e4); + MemFree fr0 = (MemFree) findMatchingEventAfterProcessing(program, f0); + MemFree fr1 = (MemFree) findMatchingEventAfterProcessing(program, f1); + + assertObjectAlias(expect[0], aa, al0, me0); + assertObjectAlias(expect[1], aa, al0, me1); + assertObjectAlias(expect[2], aa, al0, me2); + assertObjectAlias(expect[3], aa, al0, me3); + assertObjectAlias(expect[4], aa, al0, me4); + assertObjectAlias(expect[5], aa, al1, me0); + assertObjectAlias(expect[6], aa, al1, me1); + assertObjectAlias(expect[7], aa, al1, me2); + assertObjectAlias(expect[8], aa, al1, me3); + assertObjectAlias(expect[9], aa, al1, me4); + assertAlias(expect[10], aa, al0, fr0); + assertAlias(expect[11], aa, al0, fr1); + assertAlias(expect[12], aa, al1, fr0); + assertAlias(expect[13], aa, al1, fr1); + assertAlias(expect[14], aa, fr0, fr1); + } + + @Test + public void fieldsensitive8() throws InvalidConfigurationException { + program8(FIELD_SENSITIVE, MUST, MUST, MUST, MUST, MUST, NONE, MUST); + } + + @Test + public void fieldinsensitive8() throws InvalidConfigurationException { + program8(FIELD_INSENSITIVE, MUST, MAY, MAY, MUST, MAY, NONE, MUST); + } + + @Test + public void full8() throws InvalidConfigurationException { + program8(FULL, MUST, MUST, MUST, MUST, MUST, NONE, MUST); + } + + private void program8(Alias method, Result... expect) throws InvalidConfigurationException { + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + MemoryObject x = b.newMemoryObject("x", 1); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + Alloc a0 = newHeapAlloc(r0, 4); // r0 = malloc(4) + b.addChild(0, a0); + Store e0 = newStore(r0, value(1)); // *r0 = 1 + b.addChild(0, e0); + Register r1 = b.getOrNewRegister(0, "r1"); + b.addChild(0, newLocal(r1, plus(r0, 2))); // r1 = r0 + 2 + Store e1 = newStore(r1, value(1)); // *r1 = 1 + b.addChild(0, e1); + Register r2 = b.getOrNewRegister(0, "r2"); + b.addChild(0, newLocal(r2, plus(r0, 3))); // r2 = r0 + 3 + Store e2 = newStore(r2, value(1)); // *r2 = 1 + b.addChild(0, e2); + Register r3 = b.getOrNewRegister(0, "r3"); + b.addChild(0, newLocal(r3, r0)); // r3 = r0 + Store e3 = newStore(r3, value(1)); // *r3 = 1 + b.addChild(0, e3); + Register r4 = b.getOrNewRegister(0, "r4"); + b.addChild(0, newLocal(r4, r1)); // r4 = r1 + Store e4 = newStore(r4, value(1)); // *r4 = 1 + b.addChild(0, e4); + Store e5 = newStore(x, value(1)); // x = 1 + b.addChild(0, e5); + MemFree f0 = newFree(r3); // free(r3) + b.addChild(0, f0); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + Alloc al0 = (Alloc) findMatchingEventAfterProcessing(program, a0); + MemoryCoreEvent me0 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e0); + MemoryCoreEvent me1 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e1); + MemoryCoreEvent me2 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e2); + MemoryCoreEvent me3 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e3); + MemoryCoreEvent me4 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e4); + MemoryCoreEvent me5 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e5); + MemFree fr0 = (MemFree) findMatchingEventAfterProcessing(program, f0); + + assertObjectAlias(expect[0], aa, al0, me0); + assertObjectAlias(expect[1], aa, al0, me1); + assertObjectAlias(expect[2], aa, al0, me2); + assertObjectAlias(expect[3], aa, al0, me3); + assertObjectAlias(expect[4], aa, al0, me4); + assertObjectAlias(expect[5], aa, al0, me5); + assertAlias(expect[6], aa, al0, fr0); + } + + @Test + public void fieldsensitive9() throws InvalidConfigurationException { + program9(FIELD_SENSITIVE, MUST, NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, + NONE, NONE, NONE, + NONE, NONE, + NONE); + } + + @Test + public void fieldinsensitive9() throws InvalidConfigurationException { + program9(FIELD_INSENSITIVE, MUST, NONE, MUST, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, MUST, NONE, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, MUST, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, MAY, NONE, MAY, MAY, MAY, + MAY, MUST, MAY, MAY, MAY, + MAY, MAY, MAY, MAY, + MAY, MAY, MAY, + MAY, MAY, + MAY); + } + + @Test + public void full9() throws InvalidConfigurationException { + program9(FULL, MUST, NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, + NONE, NONE, NONE, + NONE, NONE, + NONE); + } + + // This program is wrong because it frees the same memory multiple times. + // But it is suitable to test the alias analysis. + private void program9(Alias method, Result... expect) throws InvalidConfigurationException { + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + MemoryObject x = b.newMemoryObject("x", 2); + x.setInitialValue(0, x); + MemoryObject y = b.newMemoryObject("y", 2); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + Alloc a0 = newHeapAlloc(r0, 2); // r0 = malloc(2) + b.addChild(0, a0); + Register r1 = b.getOrNewRegister(0, "r1"); + Alloc a1 = newHeapAlloc(r1, 3); // r1 = malloc(3) + b.addChild(0, a1); + Register r2 = b.getOrNewRegister(0, "r2"); + b.addChild(0, newLocal(r2, r0)); // r2 = r0 + Register r3 = b.getOrNewRegister(0, "r3"); + b.addChild(0, newLoad(r3, x)); // r3 = x + Register r4 = b.getOrNewRegister(0, "r4"); + b.addChild(0, newLocal(r4, plus(r3, 1))); // r4 = r3 + 1 + MemFree f0 = newFree(r0); // free(r0) + b.addChild(0, f0); + MemFree f1 = newFree(r1); // free(r1) + b.addChild(0, f1); + MemFree f2 = newFree(r2); // free(r2) + b.addChild(0, f2); + MemFree f3 = newFree(r3); // free(r3) + b.addChild(0, f3); + MemFree f4 = newFree(r4); // free(r4) + b.addChild(0, f4); + MemFree f5 = newFree(x); // free(x) + b.addChild(0, f5); + Register r5 = b.getOrNewRegister(0, "r5"); + b.addChild(0, newLocal(r5, plus(r0, 1))); // r5 = r0 + 1 + MemFree f6 = newFree(r5); // free(r5) + b.addChild(0, f6); + MemFree f7 = newFree(plus(r1, 2)); // free(r1 + 2) + b.addChild(0, f7); + Register r6 = b.getOrNewRegister(0, "r6"); + b.addChild(0, newLoad(r6, y)); // r6 = y + MemFree f8 = newFree(r6); // free(r6) + b.addChild(0, f8); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + Alloc al0 = (Alloc) findMatchingEventAfterProcessing(program, a0); + Alloc al1 = (Alloc) findMatchingEventAfterProcessing(program, a1); + MemFree fr0 = (MemFree) findMatchingEventAfterProcessing(program, f0); + MemFree fr1 = (MemFree) findMatchingEventAfterProcessing(program, f1); + MemFree fr2 = (MemFree) findMatchingEventAfterProcessing(program, f2); + MemFree fr3 = (MemFree) findMatchingEventAfterProcessing(program, f3); + MemFree fr4 = (MemFree) findMatchingEventAfterProcessing(program, f4); + MemFree fr5 = (MemFree) findMatchingEventAfterProcessing(program, f5); + MemFree fr6 = (MemFree) findMatchingEventAfterProcessing(program, f6); + MemFree fr7 = (MemFree) findMatchingEventAfterProcessing(program, f7); + MemFree fr8 = (MemFree) findMatchingEventAfterProcessing(program, f8); + + assertAlias(expect[0], aa, al0, fr0); + assertAlias(expect[1], aa, al0, fr1); + assertAlias(expect[2], aa, al0, fr2); + assertAlias(expect[3], aa, al0, fr3); + assertAlias(expect[4], aa, al0, fr4); + assertAlias(expect[5], aa, al0, fr5); + assertAlias(expect[6], aa, al0, fr6); + assertAlias(expect[7], aa, al0, fr7); + assertAlias(expect[8], aa, al0, fr8); + + assertAlias(expect[9], aa, al1, fr0); + assertAlias(expect[10], aa, al1, fr1); + assertAlias(expect[11], aa, al1, fr2); + assertAlias(expect[12], aa, al1, fr3); + assertAlias(expect[13], aa, al1, fr4); + assertAlias(expect[14], aa, al1, fr5); + assertAlias(expect[15], aa, al1, fr6); + assertAlias(expect[16], aa, al1, fr7); + assertAlias(expect[17], aa, al1, fr8); + + assertAlias(expect[18], aa, fr0, fr1); + assertAlias(expect[19], aa, fr0, fr2); + assertAlias(expect[20], aa, fr0, fr3); + assertAlias(expect[21], aa, fr0, fr4); + assertAlias(expect[22], aa, fr0, fr5); + assertAlias(expect[23], aa, fr0, fr6); + assertAlias(expect[24], aa, fr0, fr7); + assertAlias(expect[25], aa, fr0, fr8); + + assertAlias(expect[26], aa, fr1, fr2); + assertAlias(expect[27], aa, fr1, fr3); + assertAlias(expect[28], aa, fr1, fr4); + assertAlias(expect[29], aa, fr1, fr5); + assertAlias(expect[30], aa, fr1, fr6); + assertAlias(expect[31], aa, fr1, fr7); + assertAlias(expect[32], aa, fr1, fr8); + + assertAlias(expect[33], aa, fr2, fr3); + assertAlias(expect[34], aa, fr2, fr4); + assertAlias(expect[35], aa, fr2, fr5); + assertAlias(expect[36], aa, fr2, fr6); + assertAlias(expect[37], aa, fr2, fr7); + assertAlias(expect[38], aa, fr2, fr8); + + assertAlias(expect[39], aa, fr3, fr4); + assertAlias(expect[40], aa, fr3, fr5); + assertAlias(expect[41], aa, fr3, fr6); + assertAlias(expect[42], aa, fr3, fr7); + assertAlias(expect[43], aa, fr3, fr8); + + assertAlias(expect[44], aa, fr4, fr5); + assertAlias(expect[45], aa, fr4, fr6); + assertAlias(expect[46], aa, fr4, fr7); + assertAlias(expect[47], aa, fr4, fr8); + + assertAlias(expect[48], aa, fr5, fr6); + assertAlias(expect[49], aa, fr5, fr7); + assertAlias(expect[50], aa, fr5, fr8); + + assertAlias(expect[51], aa, fr6, fr7); + assertAlias(expect[52], aa, fr6, fr8); + + assertAlias(expect[53], aa, fr7, fr8); + } + private Load newLoad(Register value, Expression address) { return EventFactory.newLoad(value, address); } @@ -632,6 +989,10 @@ private Store newStore(Expression address, Expression value) { return EventFactory.newStore(address, value); } + private Alloc newHeapAlloc(Register resultReg, int size) { + return EventFactory.newAlloc(resultReg, types.getByteType(), value(size), true, true); + } + private Expression value(long v) { return expressions.makeValue(v, types.getArchType()); } @@ -656,7 +1017,7 @@ private AliasAnalysis analyze(Program program, Alias method) throws InvalidConfi return AliasAnalysis.fromConfig(program, analysisContext, configuration); } - private void assertAlias(Result expect, AliasAnalysis a, MemoryCoreEvent x, MemoryCoreEvent y) { + private void assertAlias(Result expect, AliasAnalysis a, Event x, Event y) { switch (expect) { case NONE: assertFalse(a.mayAlias(x, y)); @@ -673,6 +1034,23 @@ private void assertAlias(Result expect, AliasAnalysis a, MemoryCoreEvent x, Memo } } + private void assertObjectAlias(Result expect, AliasAnalysis a, Event x, Event y) { + switch (expect) { + case NONE: + assertFalse(a.mayObjectAlias(x, y)); + assertFalse(a.mustObjectAlias(x, y)); + break; + case MAY: + assertTrue(a.mayObjectAlias(x, y)); + assertFalse(a.mustObjectAlias(x, y)); + break; + case MUST: + assertTrue(a.mayObjectAlias(x, y)); + assertTrue(a.mustObjectAlias(x, y)); + break; + } + } + /* * This test may fail to show the presence of an error immediately. * When it fails during a merge, consider repeating it on the head of the target branch. From 20e84e48c8cca3f5eeb0869bc55806edbf7b9ca4 Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Thu, 10 Apr 2025 14:16:24 +0200 Subject: [PATCH 04/36] Init setup Signed-off-by: Tianrui Zheng --- cat/c11.cat | 17 ++++++++++++++++- cat/rc11.cat | 4 +--- cat/vmm.cat | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/cat/c11.cat b/cat/c11.cat index 1abd41f349..359e869dde 100644 --- a/cat/c11.cat +++ b/cat/c11.cat @@ -103,4 +103,19 @@ flag ~empty dr as unsequenced_race // This SC semantics is proposed in the paper "Overhauling SC atomics in C11 and OpenCL" section 3.2 // The proposal simplifies the Spartial and provide stronger guarantees let scp = ((SC * SC) & (fsb?; (mo | fr | hb); sbf?)) \ id -acyclic scp as Ssimp \ No newline at end of file +acyclic scp as Ssimp + +(* + * Heap memory safety. + * Base relations: + * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer + * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event + *) +flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race +flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free +flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc +flag ~empty (allocmem \ hb) as use-before-alloc +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free + +// TODO: Non-monotonic! (see ThreadCreation class) +flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/rc11.cat b/cat/rc11.cat index 5320da5e12..3572d40c63 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -44,13 +44,11 @@ flag ~empty race as racy * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event *) -(* flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free -*) // TODO: Non-monotonic! (see ThreadCreation class) -// flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file +flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/vmm.cat b/cat/vmm.cat index ca3b50a2bd..0efadfe1cd 100644 --- a/cat/vmm.cat +++ b/cat/vmm.cat @@ -147,4 +147,19 @@ let r-racy = [domain(r-race)] | [range(r-race)] As long as the value is not observed in this manner, r-race is well-defined behavior. *) let obs-dep = ctrl | addr | data;rfe -flag ~empty [domain(obs-dep)] & r-racy as r-data-race \ No newline at end of file +flag ~empty [domain(obs-dep)] & r-racy as r-data-race + +(* + * Heap memory safety. + * Base relations: + * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer + * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event + *) +flag ~empty (((ALLOC * FREE) & allocptr) \ hb+) as alloc-race +flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free +flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc +flag ~empty (allocmem \ hb+) as use-before-alloc +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb+) as use-after-free + +// TODO: Non-monotonic! (see ThreadCreation class) +flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file From ddc0e11e07402ffdb9ebe999d3b9c6fb938a00ad Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Thu, 10 Apr 2025 16:49:47 +0200 Subject: [PATCH 05/36] Add Alloc and MemFree to witness for debugging Signed-off-by: Tianrui Zheng --- .../verification/model/ExecutionModelManager.java | 8 +++++++- .../verification/model/event/AllocModel.java | 11 +++++++++++ .../verification/model/event/MemFreeModel.java | 11 +++++++++++ .../witness/graphviz/ExecutionGraphVisualizer.java | 4 +++- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/AllocModel.java create mode 100644 dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java index 6c679f2f81..47a26c9dd8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java @@ -142,6 +142,10 @@ assrt, tm, id, isTrue(context.encodeExpressionAsBooleanAt(assrt.getExpression(), em = new LocalModel(local, tm, id, value); } else if (e instanceof CondJump cj) { em = new CondJumpModel(cj, tm, id); + } else if (e instanceof Alloc alloc) { + em = new AllocModel(alloc, tm, id); + } else if (e instanceof MemFree free) { + em = new MemFreeModel(free, tm, id); } else { // Should never happen. throw new IllegalArgumentException(String.format("Event %s should not be extracted", e)); @@ -157,7 +161,9 @@ private boolean toExtract(Event e) { || e instanceof GenericVisibleEvent || e instanceof Local || e instanceof Assert - || e instanceof CondJump; + || e instanceof CondJump + || e instanceof Alloc + || e instanceof MemFree; } private void extractMemoryLayout() { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/AllocModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/AllocModel.java new file mode 100644 index 0000000000..37cb58fe20 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/AllocModel.java @@ -0,0 +1,11 @@ +package com.dat3m.dartagnan.verification.model.event; + +import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.verification.model.ThreadModel; + + +public class AllocModel extends DefaultEventModel implements RegReaderModel, RegWriterModel { + public AllocModel(Alloc event, ThreadModel thread, int id) { + super(event, thread, id); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java new file mode 100644 index 0000000000..226c4b23e8 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java @@ -0,0 +1,11 @@ +package com.dat3m.dartagnan.verification.model.event; + +import com.dat3m.dartagnan.program.event.core.MemFree; +import com.dat3m.dartagnan.verification.model.ThreadModel; + + +public class MemFreeModel extends DefaultEventModel implements RegReaderModel { + public MemFreeModel(MemFree event, ThreadModel thread, int id) { + super(event, thread, id); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java b/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java index 771958386f..ea229c3f6e 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java @@ -101,7 +101,9 @@ private List getEventModelsToShow(ThreadModel tm) { .filter(e -> e instanceof MemoryEventModel || e instanceof GenericVisibleEventModel || e instanceof LocalModel - || e instanceof AssertModel) + || e instanceof AssertModel + || e instanceof AllocModel + || e instanceof MemFreeModel) .toList(); } From 8631ddc31d5efb1380ee5fabcc79a2858bc4a51b Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Wed, 30 Apr 2025 15:20:12 +0200 Subject: [PATCH 06/36] Modified some memory models and tests Signed-off-by: Tianrui Zheng --- benchmarks/alloc/test1_ok_2.c | 8 +++++-- cat/c11.cat | 4 +++- cat/rc11.cat | 6 ++++- cat/vmm.cat | 21 +++++++++++----- .../encoding/NonTerminationEncoder.java | 6 ++--- .../dartagnan/encoding/PropertyEncoder.java | 15 ++++++++---- .../program/processing/ProcessingManager.java | 7 +++--- .../java/com/dat3m/dartagnan/wmm/Wmm.java | 24 +++++++++++++------ .../dat3m/dartagnan/llvm/AllocFreeTest.java | 2 +- 9 files changed, 65 insertions(+), 28 deletions(-) diff --git a/benchmarks/alloc/test1_ok_2.c b/benchmarks/alloc/test1_ok_2.c index 753600aeb7..845253bf43 100644 --- a/benchmarks/alloc/test1_ok_2.c +++ b/benchmarks/alloc/test1_ok_2.c @@ -7,9 +7,9 @@ void *thread_1(void *arg) { int *arr = *((int**)arg); arr[0] = 0; - arr[1] = 1; + // arr[1] = 1; - free(arr); + // free(arr); return NULL; } @@ -18,9 +18,13 @@ int main() { pthread_t t1; int *arr = malloc(2 * sizeof(int)); + arr[1] = 1; pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); + free(arr); + + while (1) {} return 0; } diff --git a/cat/c11.cat b/cat/c11.cat index 359e869dde..05719856f9 100644 --- a/cat/c11.cat +++ b/cat/c11.cat @@ -115,7 +115,9 @@ flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc -flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +let uaf = (allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb +flag ~empty uaf as use-after-free +// flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free // TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/rc11.cat b/cat/rc11.cat index 3572d40c63..e769125144 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -48,7 +48,11 @@ flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc -flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +// flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +let memfree = allocmem^-1 ; (allocptr & (ALLOC * FREE)) +let uaf = memfree \ hb +// flag ~empty (memfree \ hb) as use-after-free +flag ~empty uaf as use-after-free // TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/vmm.cat b/cat/vmm.cat index 0efadfe1cd..012690aa69 100644 --- a/cat/vmm.cat +++ b/cat/vmm.cat @@ -96,7 +96,8 @@ let dep = ctrl | addr | data let bob = [Acq];po | po;[Rel] | [SC];po;[SC] | po;[SC & F];po | [R];po;[Acq & F];po | po;[Rel & F];po;[W & Marked] (* Preserved Program-Order: these are never visibly reordered by compiler and hardware. Includes both barrier ordering, and dependency ordering + same-address ordering *) -let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] +// let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | [ALLOC];(addr | data) | addr;[FREE] +let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | [ALLOC];(addr | data) (* Important: these relations satisfy ppo ; [~Marked] ; po <= ppo @@ -118,10 +119,12 @@ let WRF-ppo = po;[Rel & F];po;[W & Plain] | [Marked];(ctrl | addr);[W & Plain] let hb = ppo | WRF-ppo | rfe | fre | coe acyclic hb +let hbp = hb+ (** Data Races **) -let w-race-fix = ([Marked] | ppo);hb+;([Marked] | ppo) +// let w-race-fix = ([Marked] | ppo);hb+;([Marked] | ppo) +let w-race-fix = ([Marked] | ppo);hbp;([Marked] | ppo) let w-race = coe \ w-race-fix let w-racy = [domain(w-race)] | [range(w-race)] @@ -138,7 +141,8 @@ flag ~empty w-racy as w-data-race It is not relevant for rfe & r-race, since there the plain store would be in the range (but WRF-ppo only orders stores in the domain); and reading from it without proper synchronization is a data race too anyways. *) -let r-race-fix = ([Marked] | ppo);hb+; WRF-ppo +// let r-race-fix = ([Marked] | ppo);hb+; WRF-ppo +let r-race-fix = ([Marked] | ppo);hbp; WRF-ppo let r-race = ((fre \ r-race-fix) | rfe) \ w-race-fix let r-racy = [domain(r-race)] | [range(r-race)] @@ -155,11 +159,16 @@ flag ~empty [domain(obs-dep)] & r-racy as r-data-race * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event *) -flag ~empty (((ALLOC * FREE) & allocptr) \ hb+) as alloc-race +flag ~empty (((ALLOC * FREE) & allocptr) \ hbp) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc -flag ~empty (allocmem \ hb+) as use-before-alloc -flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb+) as use-after-free +flag ~empty (allocmem \ hbp) as use-before-alloc + +// flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb+) as use-after-free +let memfree = allocmem^-1 ; (allocptr & (ALLOC * FREE)) +let uaf = memfree \ hbp +// flag ~empty (memfree \ hb+) as use-after-free +flag ~empty uaf as use-after-free // TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java index 6e732bede3..ff6f34416f 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java @@ -422,7 +422,7 @@ private BooleanFormula areEquivalent(Event x, Event y) { - Side-effectful non-termination requires at least one infix iteration - Side-effect-free non-termination causes exactly one suffix iteration. */ - private BooleanFormula encodeInfixSuffixDecomposition() { + public BooleanFormula encodeInfixSuffixDecomposition() { final BooleanFormulaManager bmgr = context.getBooleanFormulaManager(); final List totalEnc = new ArrayList<>(); @@ -492,7 +492,7 @@ private BooleanFormula encodeInfixSuffixDecomposition() { // (2) co/rf-edges within the infix have equivalent co/rf-edges in the suffix // NOTE: We rely on a matching relation between iterations of infix and suffix to implement (1) and (2) - private BooleanFormula encodeInfixSuffixEquivalence() { + public BooleanFormula encodeInfixSuffixEquivalence() { final List totalEnc = new ArrayList<>(); // Encode matching relation for (Loop loop : allLoops) { @@ -650,7 +650,7 @@ private BooleanFormula isSuffixReadable(Store store) { return bmgr.or(bmgr.not(isInPrefix(store)), context.lastCoVar(store)); } - private BooleanFormula encodeStrongSuffixExtension() { + public BooleanFormula encodeStrongSuffixExtension() { final Wmm memoryModel = task.getMemoryModel(); final RelationAnalysis ra = context.getAnalysisContext().requires(RelationAnalysis.class); final BooleanFormulaManager bmgr = context.getBooleanFormulaManager(); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java index d63497317c..8128f5f117 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java @@ -114,13 +114,13 @@ public BooleanFormula encodeProperties(EnumSet properties) { BooleanFormula encoding = (specType == Property.Type.SAFETY) ? encodePropertyViolations(properties) : encodePropertyWitnesses(properties); - if (!program.getFormat().equals(LLVM) || properties.contains(TERMINATION)) { + // if (!program.getFormat().equals(LLVM) || properties.contains(TERMINATION)) { // Both litmus assertions and termination need to identify // the final stores to addresses. // TODO Optimization: This encoding can be restricted to only those addresses // that are relevant for the specification (e.g., only variables that are used in loops). - encoding = context.getBooleanFormulaManager().and(encoding, encodeLastCoConstraints()); - } + encoding = context.getBooleanFormulaManager().and(encoding, encodeLastCoConstraints()); + // } return encoding; } @@ -148,7 +148,14 @@ private BooleanFormula encodePropertyViolations(EnumSet properties) { final BooleanFormula atLeastOneViolation = bmgr.or(Lists.transform(trackableViolationEncodings, vio -> vio.trackingLiteral)); - return bmgr.and(atLeastOneViolation, trackedViolationEnc); + NonTerminationEncoder encoder = new NonTerminationEncoder(context.getTask(), context); + BooleanFormula spinloops = bmgr.and( + encoder.encodeInfixSuffixDecomposition(), + encoder.encodeInfixSuffixEquivalence(), + encoder.encodeStrongSuffixExtension() + ); + // return bmgr.and(atLeastOneViolation, trackedViolationEnc); + return bmgr.and(spinloops, atLeastOneViolation, trackedViolationEnc); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java index eb3eff0317..aa5549532a 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java @@ -100,7 +100,7 @@ private ProcessingManager(Configuration config) throws InvalidConfigurationExcep Compilation.fromConfig(config), // We keep compilation global for now LoopFormVerification.fromConfig(config), printAfterCompilation ? DebugPrint.withHeader("After compilation", Printer.Mode.ALL) : null, - ProgramProcessor.fromFunctionProcessor(MemToReg.fromConfig(config), Target.FUNCTIONS, true), + // ProgramProcessor.fromFunctionProcessor(MemToReg.fromConfig(config), Target.FUNCTIONS, true), ProgramProcessor.fromFunctionProcessor(sccp, Target.FUNCTIONS, false), dynamicSpinLoopDetection ? DynamicSpinLoopDetection.fromConfig(config) : null, ProgramProcessor.fromFunctionProcessor(NaiveLoopBoundAnnotation.fromConfig(config), Target.FUNCTIONS, true), @@ -120,8 +120,9 @@ private ProcessingManager(Configuration config) throws InvalidConfigurationExcep intrinsics.lateInliningPass(), ProgramProcessor.fromFunctionProcessor( FunctionProcessor.chain( - RemoveDeadNullChecks.newInstance(), - MemToReg.fromConfig(config) + RemoveDeadNullChecks.newInstance() + // RemoveDeadNullChecks.newInstance(), + // MemToReg.fromConfig(config) ), Target.THREADS, true ), ProgramProcessor.fromFunctionProcessor( diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java index d6df2828e5..6e0e94bc4e 100755 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java @@ -203,16 +203,26 @@ private Relation makePredefinedRelation(String name) { case CTRLDIRECT -> new DirectControlDependency(r); case EMPTY -> new Empty(r); case IDDTRANS -> new TransitiveClosure(r, getOrCreatePredefinedRelation(IDD)); - case DATA -> intersection(r, - getOrCreatePredefinedRelation(IDDTRANS), - addDefinition(product(newRelation(), Tag.MEMORY, Tag.MEMORY)) - ); + // case DATA -> intersection(r, + // getOrCreatePredefinedRelation(IDDTRANS), + // addDefinition(product(newRelation(), Tag.MEMORY, Tag.MEMORY)) + // ); + case DATA -> { + Relation mm = addDefinition(product(newRelation(), Tag.MEMORY, Tag.MEMORY)); + Relation am = addDefinition(product(newRelation(), Tag.ALLOC, Tag.MEMORY)); + Relation productUnion = addDefinition(union(newRelation(), am, mm)); + yield intersection(r, getOrCreatePredefinedRelation(IDDTRANS), productUnion); + } case ADDR -> { Relation addrdirect = getOrCreatePredefinedRelation(ADDRDIRECT); Relation comp = addDefinition(composition(newRelation(), getOrCreatePredefinedRelation(IDDTRANS), addrdirect)); Relation union = addDefinition(union(newRelation(), addrdirect, comp)); Relation mm = addDefinition(product(newRelation(), Tag.MEMORY, Tag.MEMORY)); - yield intersection(r, union, mm); + Relation am = addDefinition(product(newRelation(), Tag.ALLOC, Tag.MEMORY)); + Relation mf = addDefinition(product(newRelation(), Tag.MEMORY, Tag.FREE)); + Relation af = addDefinition(product(newRelation(), Tag.ALLOC, Tag.FREE)); + Relation productUnion = addDefinition(union(newRelation(), mm, mf, af)); + yield intersection(r, union, productUnion); } case CTRL -> { Relation comp = addDefinition(composition(newRelation(), getOrCreatePredefinedRelation(IDDTRANS), @@ -238,8 +248,8 @@ private Relation makePredefinedRelation(String name) { return addDefinition(def); } - private Definition union(Relation r0, Relation r1, Relation r2) { - return new Union(r0, r1, r2); + private Definition union(Relation r0, Relation... others) { + return new Union(r0, others); } private Definition intersection(Relation r0, Relation r1, Relation r2) { diff --git a/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java index 15397673d0..de048a3400 100644 --- a/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java +++ b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java @@ -104,7 +104,7 @@ private VerificationTask mkTask(Configuration configuration) throws Exception { .withConfig(configuration) .withTarget(target); Program program = new ProgramParser().parse(new File(getTestResourcePath("alloc/" + name + ".ll"))); - Wmm mcm = new ParserCat().parse(new File(getRootPath("cat/rc11.cat"))); + Wmm mcm = new ParserCat().parse(new File(getRootPath("cat/vmm.cat"))); return builder.build(program, mcm, EnumSet.of(CAT_SPEC)); } From 44ead61d37c1ca72b930caafe4a4b6e2e9ac8626 Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Wed, 7 May 2025 11:08:38 +0200 Subject: [PATCH 07/36] Fix event and relation extraction of alloc-free for witness Signed-off-by: Tianrui Zheng --- .../verification/model/ExecutionModelManager.java | 4 +++- .../verification/model/ExecutionModelNext.java | 7 ++++--- .../dartagnan/verification/model/ThreadModel.java | 11 +++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java index 47a26c9dd8..0bd74bef97 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java @@ -162,7 +162,7 @@ private boolean toExtract(Event e) { || e instanceof Local || e instanceof Assert || e instanceof CondJump - || e instanceof Alloc + || (e instanceof Alloc alloc && alloc.isHeapAllocation()) || e instanceof MemFree; } @@ -221,6 +221,7 @@ private void extractRelations() { // Populate graph of relations unsupported by the visitor using default relation analysis. graphPopulator.populateDynamicDefaultGraph(r); } + // graphPopulator.populateDynamicDefaultGraph(r); } // Do the computation. @@ -236,6 +237,7 @@ private void extractRelations() { } for (Relation r : relsToExtract) { + System.out.println(r + " : " + relModelCache.get(r).getEdgeModels().size()); executionModel.addRelation(r, relModelCache.get(r)); } } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java index 3bb6fceaa4..53d306b563 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java @@ -69,9 +69,10 @@ public List getEventModels() { } public List getVisibleEventModels() { - return eventList.stream() - .filter(e -> e instanceof MemoryEventModel || e instanceof GenericVisibleEventModel) - .toList(); + return eventList.stream().filter(e -> e instanceof MemoryEventModel || + e instanceof GenericVisibleEventModel || + e instanceof AllocModel || + e instanceof MemFreeModel).toList(); } public List getEventModelsByFilter(Filter filter) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java index e49a427bc8..44998d1343 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java @@ -2,9 +2,7 @@ import com.dat3m.dartagnan.program.event.Tag; import com.dat3m.dartagnan.program.Thread; -import com.dat3m.dartagnan.verification.model.event.EventModel; -import com.dat3m.dartagnan.verification.model.event.GenericVisibleEventModel; -import com.dat3m.dartagnan.verification.model.event.MemoryEventModel; +import com.dat3m.dartagnan.verification.model.event.*; import java.util.Collections; import java.util.List; @@ -41,8 +39,9 @@ public List getEventModels() { } public List getVisibleEventModels() { - return eventList.stream() - .filter(e -> e instanceof MemoryEventModel || e instanceof GenericVisibleEventModel) - .toList(); + return eventList.stream().filter(e -> e instanceof MemoryEventModel || + e instanceof GenericVisibleEventModel || + e instanceof AllocModel || + e instanceof MemFreeModel).toList(); } } \ No newline at end of file From e5d6a286a1cebaefbe0d9a9e5ec1c09209491bf8 Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Tue, 13 May 2025 14:25:37 +0200 Subject: [PATCH 08/36] Modify some relation and constraint definitions Signed-off-by: Tianrui Zheng --- benchmarks/alloc/test1_ok_2.c | 8 ++--- cat/vmm.cat | 35 ++++++++----------- .../program/processing/ProcessingManager.java | 7 ++-- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/benchmarks/alloc/test1_ok_2.c b/benchmarks/alloc/test1_ok_2.c index 845253bf43..753600aeb7 100644 --- a/benchmarks/alloc/test1_ok_2.c +++ b/benchmarks/alloc/test1_ok_2.c @@ -7,9 +7,9 @@ void *thread_1(void *arg) { int *arr = *((int**)arg); arr[0] = 0; - // arr[1] = 1; + arr[1] = 1; - // free(arr); + free(arr); return NULL; } @@ -18,13 +18,9 @@ int main() { pthread_t t1; int *arr = malloc(2 * sizeof(int)); - arr[1] = 1; pthread_create(&t1, NULL, thread_1, (void*)&arr); pthread_join(t1, NULL); - free(arr); - - while (1) {} return 0; } diff --git a/cat/vmm.cat b/cat/vmm.cat index 012690aa69..16264214a4 100644 --- a/cat/vmm.cat +++ b/cat/vmm.cat @@ -73,6 +73,13 @@ let Plain = ~Marked let Acq = (ACQ | SC) & (R | F) let Rel = (REL | SC) & (W | F) +(* + * Base relations for heap memory safety: + * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer + * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event +*) +let memfree = allocmem^-1 ; (allocptr & (ALLOC * FREE)) + (** Ordering **) (* In our model, dependencies only order stores: r1 = x_rlx; @@ -96,8 +103,7 @@ let dep = ctrl | addr | data let bob = [Acq];po | po;[Rel] | [SC];po;[SC] | po;[SC & F];po | [R];po;[Acq & F];po | po;[Rel & F];po;[W & Marked] (* Preserved Program-Order: these are never visibly reordered by compiler and hardware. Includes both barrier ordering, and dependency ordering + same-address ordering *) -// let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | [ALLOC];(addr | data) | addr;[FREE] -let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | [ALLOC];(addr | data) +let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | [ALLOC];(addr | data) | addr;[FREE] | (memfree & po) (* Important: these relations satisfy ppo ; [~Marked] ; po <= ppo @@ -119,12 +125,10 @@ let WRF-ppo = po;[Rel & F];po;[W & Plain] | [Marked];(ctrl | addr);[W & Plain] let hb = ppo | WRF-ppo | rfe | fre | coe acyclic hb -let hbp = hb+ (** Data Races **) -// let w-race-fix = ([Marked] | ppo);hb+;([Marked] | ppo) -let w-race-fix = ([Marked] | ppo);hbp;([Marked] | ppo) +let w-race-fix = ([Marked] | ppo);hb+;([Marked] | ppo) let w-race = coe \ w-race-fix let w-racy = [domain(w-race)] | [range(w-race)] @@ -141,8 +145,7 @@ flag ~empty w-racy as w-data-race It is not relevant for rfe & r-race, since there the plain store would be in the range (but WRF-ppo only orders stores in the domain); and reading from it without proper synchronization is a data race too anyways. *) -// let r-race-fix = ([Marked] | ppo);hb+; WRF-ppo -let r-race-fix = ([Marked] | ppo);hbp; WRF-ppo +let r-race-fix = ([Marked] | ppo);hb+; WRF-ppo let r-race = ((fre \ r-race-fix) | rfe) \ w-race-fix let r-racy = [domain(r-race)] | [range(r-race)] @@ -153,22 +156,12 @@ let r-racy = [domain(r-race)] | [range(r-race)] let obs-dep = ctrl | addr | data;rfe flag ~empty [domain(obs-dep)] & r-racy as r-data-race -(* - * Heap memory safety. - * Base relations: - * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer - * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event - *) -flag ~empty (((ALLOC * FREE) & allocptr) \ hbp) as alloc-race +(** Axioms for heap memory safety **) +flag ~empty (((ALLOC * FREE) & allocptr) \ hb+) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc -flag ~empty (allocmem \ hbp) as use-before-alloc - -// flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb+) as use-after-free -let memfree = allocmem^-1 ; (allocptr & (ALLOC * FREE)) -let uaf = memfree \ hbp -// flag ~empty (memfree \ hb+) as use-after-free -flag ~empty uaf as use-after-free +flag ~empty (allocmem \ hb+) as use-before-alloc +flag ~empty (memfree \ hb+) as use-after-free // TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java index aa5549532a..eb3eff0317 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java @@ -100,7 +100,7 @@ private ProcessingManager(Configuration config) throws InvalidConfigurationExcep Compilation.fromConfig(config), // We keep compilation global for now LoopFormVerification.fromConfig(config), printAfterCompilation ? DebugPrint.withHeader("After compilation", Printer.Mode.ALL) : null, - // ProgramProcessor.fromFunctionProcessor(MemToReg.fromConfig(config), Target.FUNCTIONS, true), + ProgramProcessor.fromFunctionProcessor(MemToReg.fromConfig(config), Target.FUNCTIONS, true), ProgramProcessor.fromFunctionProcessor(sccp, Target.FUNCTIONS, false), dynamicSpinLoopDetection ? DynamicSpinLoopDetection.fromConfig(config) : null, ProgramProcessor.fromFunctionProcessor(NaiveLoopBoundAnnotation.fromConfig(config), Target.FUNCTIONS, true), @@ -120,9 +120,8 @@ private ProcessingManager(Configuration config) throws InvalidConfigurationExcep intrinsics.lateInliningPass(), ProgramProcessor.fromFunctionProcessor( FunctionProcessor.chain( - RemoveDeadNullChecks.newInstance() - // RemoveDeadNullChecks.newInstance(), - // MemToReg.fromConfig(config) + RemoveDeadNullChecks.newInstance(), + MemToReg.fromConfig(config) ), Target.THREADS, true ), ProgramProcessor.fromFunctionProcessor( From 8ff67e22d2e2a9a76b9b2cb315fa2c9def56c030 Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Tue, 13 May 2025 14:33:34 +0200 Subject: [PATCH 09/36] Merge development into this branch Signed-off-by: Tianrui Zheng --- .../com/dat3m/dartagnan/encoding/PropertyEncoder.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java index 8128f5f117..20d9c16fe8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java @@ -148,14 +148,7 @@ private BooleanFormula encodePropertyViolations(EnumSet properties) { final BooleanFormula atLeastOneViolation = bmgr.or(Lists.transform(trackableViolationEncodings, vio -> vio.trackingLiteral)); - NonTerminationEncoder encoder = new NonTerminationEncoder(context.getTask(), context); - BooleanFormula spinloops = bmgr.and( - encoder.encodeInfixSuffixDecomposition(), - encoder.encodeInfixSuffixEquivalence(), - encoder.encodeStrongSuffixExtension() - ); - // return bmgr.and(atLeastOneViolation, trackedViolationEnc); - return bmgr.and(spinloops, atLeastOneViolation, trackedViolationEnc); + return bmgr.and(atLeastOneViolation, trackedViolationEnc); } From 5f7440f0dd30d503f61d13390ced1498614bddb8 Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Tue, 13 May 2025 16:29:33 +0200 Subject: [PATCH 10/36] Remove unnecessary definition Signed-off-by: Tianrui Zheng --- cat/vmm.cat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cat/vmm.cat b/cat/vmm.cat index 16264214a4..4ba655294c 100644 --- a/cat/vmm.cat +++ b/cat/vmm.cat @@ -103,7 +103,7 @@ let dep = ctrl | addr | data let bob = [Acq];po | po;[Rel] | [SC];po;[SC] | po;[SC & F];po | [R];po;[Acq & F];po | po;[Rel & F];po;[W & Marked] (* Preserved Program-Order: these are never visibly reordered by compiler and hardware. Includes both barrier ordering, and dependency ordering + same-address ordering *) -let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | [ALLOC];(addr | data) | addr;[FREE] | (memfree & po) +let ppo = bob | [Marked];(dep | coi | fri);[W & Marked] | (memfree & po) | (allocmem & po) (* Important: these relations satisfy ppo ; [~Marked] ; po <= ppo From 9803e52b040c7dc09f0f31e1d4a034ad3b0bc45c Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Wed, 14 May 2025 10:53:13 +0200 Subject: [PATCH 11/36] Clean c11 and rc11 Signed-off-by: Tianrui Zheng --- cat/c11.cat | 4 +--- cat/rc11.cat | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/cat/c11.cat b/cat/c11.cat index 05719856f9..359e869dde 100644 --- a/cat/c11.cat +++ b/cat/c11.cat @@ -115,9 +115,7 @@ flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc -let uaf = (allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb -flag ~empty uaf as use-after-free -// flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free // TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/rc11.cat b/cat/rc11.cat index e769125144..3572d40c63 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -48,11 +48,7 @@ flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc -// flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free -let memfree = allocmem^-1 ; (allocptr & (ALLOC * FREE)) -let uaf = memfree \ hb -// flag ~empty (memfree \ hb) as use-after-free -flag ~empty uaf as use-after-free +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free // TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file From 0659c5e5e56492cc5745cd603747d6ecea4c49b4 Mon Sep 17 00:00:00 2001 From: Tianrui Zheng Date: Wed, 14 May 2025 17:05:50 +0200 Subject: [PATCH 12/36] Modify as comments Signed-off-by: Tianrui Zheng --- cat/c11.cat | 2 -- cat/rc11.cat | 2 -- cat/vmm.cat | 2 -- .../encoding/NonTerminationEncoder.java | 6 ++-- .../dartagnan/encoding/ProgramEncoder.java | 2 +- .../dartagnan/encoding/PropertyEncoder.java | 6 ++-- .../dat3m/dartagnan/encoding/WmmEncoder.java | 6 ++-- .../program/analysis/alias/AliasAnalysis.java | 10 +++---- .../analysis/alias/AndersenAliasAnalysis.java | 4 +-- .../analysis/alias/EqualityAliasAnalysis.java | 2 +- .../alias/FieldSensitiveAndersen.java | 6 ++-- .../alias/InclusionBasedPointerAnalysis.java | 4 +-- .../dartagnan/program/event/EventFactory.java | 6 ++-- .../dartagnan/program/event/EventVisitor.java | 2 +- .../event/core/{Alloc.java => MemAlloc.java} | 12 ++++---- .../dartagnan/program/event/core/MemFree.java | 2 -- .../dartagnan/program/memory/Memory.java | 4 +-- .../program/memory/MemoryObject.java | 8 ++--- .../processing/CoreCodeVerification.java | 2 +- .../processing/DeadAssignmentElimination.java | 4 +-- .../program/processing/MemToReg.java | 8 ++--- .../program/processing/MemoryAllocation.java | 6 ++-- .../processing/RemoveDeadNullChecks.java | 4 +-- .../program/processing/ThreadCreation.java | 1 - .../verification/model/ExecutionModel.java | 2 +- .../model/ExecutionModelManager.java | 4 +-- .../verification/model/event/AllocModel.java | 4 +-- .../dat3m/dartagnan/llvm/AllocFreeTest.java | 30 +++++++++++-------- .../others/miscellaneous/AnalysisTest.java | 26 ++++++++-------- 29 files changed, 86 insertions(+), 91 deletions(-) rename dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/{Alloc.java => MemAlloc.java} (91%) diff --git a/cat/c11.cat b/cat/c11.cat index 359e869dde..f555799e44 100644 --- a/cat/c11.cat +++ b/cat/c11.cat @@ -116,6 +116,4 @@ flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free - -// TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/rc11.cat b/cat/rc11.cat index 3572d40c63..2f28f27e41 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -49,6 +49,4 @@ flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb) as use-before-alloc flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free - -// TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/cat/vmm.cat b/cat/vmm.cat index 4ba655294c..e339327c62 100644 --- a/cat/vmm.cat +++ b/cat/vmm.cat @@ -162,6 +162,4 @@ flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc flag ~empty (allocmem \ hb+) as use-before-alloc flag ~empty (memfree \ hb+) as use-after-free - -// TODO: Non-monotonic! (see ThreadCreation class) flag ~empty ([ALLOC] \ [domain(allocptr)]) as alloc-without-free \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java index ff6f34416f..6e732bede3 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/NonTerminationEncoder.java @@ -422,7 +422,7 @@ private BooleanFormula areEquivalent(Event x, Event y) { - Side-effectful non-termination requires at least one infix iteration - Side-effect-free non-termination causes exactly one suffix iteration. */ - public BooleanFormula encodeInfixSuffixDecomposition() { + private BooleanFormula encodeInfixSuffixDecomposition() { final BooleanFormulaManager bmgr = context.getBooleanFormulaManager(); final List totalEnc = new ArrayList<>(); @@ -492,7 +492,7 @@ public BooleanFormula encodeInfixSuffixDecomposition() { // (2) co/rf-edges within the infix have equivalent co/rf-edges in the suffix // NOTE: We rely on a matching relation between iterations of infix and suffix to implement (1) and (2) - public BooleanFormula encodeInfixSuffixEquivalence() { + private BooleanFormula encodeInfixSuffixEquivalence() { final List totalEnc = new ArrayList<>(); // Encode matching relation for (Loop loop : allLoops) { @@ -650,7 +650,7 @@ private BooleanFormula isSuffixReadable(Store store) { return bmgr.or(bmgr.not(isInPrefix(store)), context.lastCoVar(store)); } - public BooleanFormula encodeStrongSuffixExtension() { + private BooleanFormula encodeStrongSuffixExtension() { final Wmm memoryModel = task.getMemoryModel(); final RelationAnalysis ra = context.getAnalysisContext().requires(RelationAnalysis.class); final BooleanFormulaManager bmgr = context.getBooleanFormulaManager(); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java index 792780935c..6e64fadb46 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java @@ -430,7 +430,7 @@ private BooleanFormula encodeMemoryLayout(Memory memory) { enc.add(helper.equals(size, context.encodeFinalExpression(cur.size()))); alignment = context.encodeFinalExpression(cur.alignment()); } else { - // Non-allocated objects, i.e. objects whose Alloc event was not executed, get size 0 + // Non-allocated objects, i.e. objects whose MemAlloc event was not executed, get size 0 enc.add(helper.equals(size, bmgr.ifThenElse(context.execution(cur.getAllocationSite()), context.encodeExpressionAt(cur.size(), cur.getAllocationSite()), diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java index 20d9c16fe8..d63497317c 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java @@ -114,13 +114,13 @@ public BooleanFormula encodeProperties(EnumSet properties) { BooleanFormula encoding = (specType == Property.Type.SAFETY) ? encodePropertyViolations(properties) : encodePropertyWitnesses(properties); - // if (!program.getFormat().equals(LLVM) || properties.contains(TERMINATION)) { + if (!program.getFormat().equals(LLVM) || properties.contains(TERMINATION)) { // Both litmus assertions and termination need to identify // the final stores to addresses. // TODO Optimization: This encoding can be restricted to only those addresses // that are relevant for the specification (e.g., only variables that are used in loops). - encoding = context.getBooleanFormulaManager().and(encoding, encodeLastCoConstraints()); - // } + encoding = context.getBooleanFormulaManager().and(encoding, encodeLastCoConstraints()); + } return encoding; } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java index 4b890a11ea..41e8774c94 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java @@ -672,7 +672,7 @@ public Void visitAllocPtr(AllocPtr def) { final Relation rel = def.getDefinedRelation(); EncodingContext.EdgeEncoder edge = context.edge(rel); encodeSets.get(rel).apply((e1, e2) -> { - Formula ptr1 = (e1 instanceof Alloc alloc) + Formula ptr1 = (e1 instanceof MemAlloc alloc) ? context.result(alloc) : context.encodeExpressionAt(((MemFree)e1).getAddress(), e1); Formula ptr2 = context.encodeExpressionAt(((MemFree) e2).getAddress(), e2); @@ -689,8 +689,8 @@ public Void visitAllocMem(AllocMem def) { final EncodingHelper helper = new EncodingHelper(context.getFormulaManager()); EncodingContext.EdgeEncoder edge = context.edge(rel); encodeSets.get(rel).apply((e1, e2) -> { - Formula minAddress = context.result((Alloc)e1); - Formula size = context.encodeExpressionAt(((Alloc) e1).getAllocationSize(), e1); + Formula minAddress = context.result((MemAlloc)e1); + Formula size = context.encodeExpressionAt(((MemAlloc) e1).getAllocationSize(), e1); Formula maxAddress = helper.add(minAddress, size); Formula address = context.address((MemoryEvent) e2); enc.add(bmgr.equivalence(edge.encode(e1, e2), bmgr.and( diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java index 4d2827902c..07944cea47 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java @@ -163,8 +163,8 @@ private void populateAddressGraph(Map> may, Map> may, Map> must, - List allocs, List events, Config configuration) { - for (final Alloc alloc : allocs) { + List allocs, List events, Config configuration) { + for (final MemAlloc alloc : allocs) { final String node1 = repr(alloc, configuration); final Set maySet = may.computeIfAbsent(node1, k -> new HashSet<>()); final Set mustSet = must.computeIfAbsent(node1, k -> new HashSet<>()); @@ -190,7 +190,7 @@ private Graphviz defaultGraph(Program program, Config configuration) { final Map> mayObjectGraph = new HashMap<>(); final List events = program.getThreadEvents(MemoryCoreEvent.class); - final List allocs = program.getThreadEvents(Alloc.class); + final List allocs = program.getThreadEvents(MemAlloc.class); final List frees = program.getThreadEvents(MemFree.class); populateAddressGraph(mayAddressGraph, mustAddressGraph, events, events, configuration); @@ -208,7 +208,7 @@ private Graphviz defaultGraph(Program program, Config configuration) { graphviz.setEdgeAttributes("weight=100", "style=invis"); final List grouped = new ArrayList<>(); for (final Event event : thread.getEvents()) { - if (event instanceof MemoryCoreEvent || event instanceof Alloc || event instanceof MemFree) { + if (event instanceof MemoryCoreEvent || event instanceof MemAlloc || event instanceof MemFree) { if (!configuration.graphvizShowAll && event instanceof Init) { continue; } @@ -267,7 +267,7 @@ private static String repr(Event event, Config configuration) { } final String type = event instanceof Load ? ": R" : event instanceof Store ? ": W" - : event instanceof Alloc ? ": A" + : event instanceof MemAlloc ? ": A" : event instanceof MemFree ? ": F" : ""; final SourceLocation location = event.getMetadata(SourceLocation.class); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java index 51472ebb68..1b2ef5a40b 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java @@ -107,7 +107,7 @@ private Set getAccessibleObjects(Event e) { private void run(Program program) { List memEvents = program.getThreadEvents(MemoryCoreEvent.class); List locals = program.getThreadEvents(Local.class); - for (Alloc a : program.getThreadEvents(Alloc.class)) { + for (MemAlloc a : program.getThreadEvents(MemAlloc.class)) { processAllocs(a); } for (MemoryCoreEvent e : memEvents) { @@ -129,7 +129,7 @@ private void run(Program program) { } } - private void processAllocs(Alloc a) { + private void processAllocs(MemAlloc a) { Register r = a.getResultRegister(); Location base = new Location(a.getAllocatedObject(), 0); eventAddressSpaceMap.put(a, ImmutableSet.of(base)); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java index f6cff75494..0dcec9972b 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java @@ -87,7 +87,7 @@ private Expression getAddress(Event e) { return me.getAddress(); } else if (e instanceof MemFree f) { return f.getAddress(); - } else if (e instanceof Alloc a) { + } else if (e instanceof MemAlloc a) { return a.getAllocatedObject(); } else { throw new UnsupportedOperationException("Event type has no address: " + e.getClass().getSimpleName()); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java index dcf4e3a5f6..5f1bbc3f78 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java @@ -108,7 +108,7 @@ private Set getAccessibleObjects(Event e) { private void run(Program program) { checkArgument(program.isCompiled(), "The program must be compiled first."); - for (Alloc a : program.getThreadEvents(Alloc.class)) { + for (MemAlloc a : program.getThreadEvents(MemAlloc.class)) { eventAddressSpaceMap.put(a, ImmutableSet.of(new Location(a.getAllocatedObject(), 0))); } List memEvents = program.getThreadEvents(MemoryCoreEvent.class); @@ -158,7 +158,7 @@ protected void processLocs(MemoryCoreEvent e) { protected void processRegs(Event e) { - if (!(e instanceof Local || e instanceof ThreadArgument || e instanceof Alloc)) { + if (!(e instanceof Local || e instanceof ThreadArgument || e instanceof MemAlloc)) { return; } assert e instanceof RegWriter; @@ -166,7 +166,7 @@ protected void processRegs(Event e) { final Expression expr; if (e instanceof Local local) { expr = local.getExpr(); - } else if (e instanceof Alloc alloc) { + } else if (e instanceof MemAlloc alloc) { expr = alloc.getAllocatedObject(); } else { final ThreadArgument arg = (ThreadArgument) e; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java index 928cfd5da8..7e120a8284 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java @@ -226,7 +226,7 @@ private void run(Program program, AliasAnalysis.Config configuration) { totalVariables++; objectVariables.put(object, new Variable(object, object.toString())); } - for (final Alloc alloc : program.getThreadEvents(Alloc.class)) { + for (final MemAlloc alloc : program.getThreadEvents(MemAlloc.class)) { addressVariables.put(alloc, derive(objectVariables.get(alloc.getAllocatedObject()))); } // Each expression gets a "res" variable representing its result value set. @@ -269,7 +269,7 @@ private void processWriter(RegWriter event) { logger.trace("{}", event); final Expression expr = event instanceof Local local ? local.getExpr() : event instanceof ThreadArgument arg ? arg.getCreator().getArguments().get(arg.getIndex()) : - event instanceof Alloc alloc ? alloc.getAllocatedObject() : null; + event instanceof MemAlloc alloc ? alloc.getAllocatedObject() : null; final DerivedVariable value; if (expr != null) { final RegReader reader = event instanceof ThreadArgument arg ? arg.getCreator() : (RegReader) event; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java index b2a9c2559c..b5f3ad66a8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java @@ -111,17 +111,17 @@ public static Event newTerminator(Function function, String... tags) { // ------------------------------------------ Memory events ------------------------------------------ - public static Alloc newAlloc(Register register, Type allocType, Expression arraySize, + public static MemAlloc newAlloc(Register register, Type allocType, Expression arraySize, boolean isHeapAlloc, boolean doesZeroOutMemory) { final Expression defaultAlignment = expressions.makeValue(8, types.getArchType()); return newAlignedAlloc(register, allocType, arraySize, defaultAlignment, isHeapAlloc, doesZeroOutMemory); } - public static Alloc newAlignedAlloc(Register register, Type allocType, Expression arraySize, Expression alignment, + public static MemAlloc newAlignedAlloc(Register register, Type allocType, Expression arraySize, Expression alignment, boolean isHeapAlloc, boolean doesZeroOutMemory) { arraySize = expressions.makeCast(arraySize, types.getArchType(), false); alignment = expressions.makeCast(alignment, types.getArchType(), false); - return new Alloc(register, allocType, arraySize, alignment, isHeapAlloc, doesZeroOutMemory); + return new MemAlloc(register, allocType, arraySize, alignment, isHeapAlloc, doesZeroOutMemory); } public static MemFree newFree(Expression address) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java index 0a8ec356f1..df0c3dea9d 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java @@ -46,7 +46,7 @@ public interface EventVisitor { default T visitLoad(Load e) { return visitMemCoreEvent(e); } default T visitStore(Store e) { return visitMemCoreEvent(e); } default T visitInit(Init e) { return visitStore(e); } - default T visitAlloc(Alloc e) { return visitEvent(e); } + default T visitAlloc(MemAlloc e) { return visitEvent(e); } // RMW core events default T visitRMWStore(RMWStore e) { return visitStore(e); } default T visitRMWStoreExclusive(RMWStoreExclusive e) { return visitStore(e); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemAlloc.java similarity index 91% rename from dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java rename to dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemAlloc.java index fbce967798..2b19c6c9ff 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemAlloc.java @@ -19,10 +19,10 @@ import java.util.Set; /* - Alloc represents any dynamic allocation performed in the program, i.e., both heap and stack allocations. + MemAlloc represents any dynamic allocation performed in the program, i.e., both heap and stack allocations. Each allocation has a type and an array size (equals 1 for simple allocations). */ -public final class Alloc extends AbstractEvent implements RegReader, RegWriter { +public final class MemAlloc extends AbstractEvent implements RegReader, RegWriter { private Register resultRegister; private Type allocationType; private Expression arraySize; @@ -33,7 +33,7 @@ public final class Alloc extends AbstractEvent implements RegReader, RegWriter { // This will be set at the end of the program processing. private transient MemoryObject allocatedObject; - public Alloc(Register resultRegister, Type allocType, Expression arraySize, Expression alignment, boolean isHeapAllocation, + public MemAlloc(Register resultRegister, Type allocType, Expression arraySize, Expression alignment, boolean isHeapAllocation, boolean doesZeroOutMemory) { Preconditions.checkArgument(resultRegister.getType() == TypeFactory.getInstance().getPointerType()); Preconditions.checkArgument(arraySize.getType() instanceof IntegerType); @@ -49,10 +49,10 @@ public Alloc(Register resultRegister, Type allocType, Expression arraySize, Expr } } - private Alloc(Alloc other) { + private MemAlloc(MemAlloc other) { super(other); Preconditions.checkState(other.allocatedObject == null, - "Cannot copy Alloc events after memory allocation was performed."); + "Cannot copy MemAlloc events after memory allocation was performed."); this.resultRegister = other.resultRegister; this.allocationType = other.allocationType; this.arraySize = other.arraySize; @@ -125,7 +125,7 @@ protected String defaultString() { } @Override - public Alloc getCopy() { return new Alloc(this); } + public MemAlloc getCopy() { return new MemAlloc(this); } @Override public T accept(EventVisitor visitor) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java index d0afa6937e..ede0f9c958 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java @@ -11,8 +11,6 @@ import java.util.HashSet; import java.util.Set; -// TODO: Consistent naming. Should we rename relation 'Free' into FreeRel? -// Or event Alloc into 'MemAlloc'? public class MemFree extends AbstractEvent implements RegReader { private Expression addr; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java index f891b25eed..5a33aed173 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java @@ -5,7 +5,7 @@ import com.dat3m.dartagnan.expression.Type; import com.dat3m.dartagnan.expression.type.IntegerType; import com.dat3m.dartagnan.expression.type.TypeFactory; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; @@ -30,7 +30,7 @@ public MemoryObject allocate(int size) { } // Generates a new, dynamically allocated memory object. - public MemoryObject allocate(Alloc allocationSite) { + public MemoryObject allocate(MemAlloc allocationSite) { Preconditions.checkNotNull(allocationSite); final MemoryObject memoryObject = new MemoryObject(nextIndex++, allocationSite.getAllocationSize(), allocationSite.getAlignment(), allocationSite, ptrType); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java index ca80d38814..5e3bd78e03 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java @@ -8,7 +8,7 @@ import com.dat3m.dartagnan.expression.base.LeafExpressionBase; import com.dat3m.dartagnan.expression.integers.IntLiteral; import com.dat3m.dartagnan.expression.type.*; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.google.common.base.Preconditions; import java.util.*; @@ -26,7 +26,7 @@ public class MemoryObject extends LeafExpressionBase { private final int id; private final Expression size; private final Expression alignment; - private final Alloc allocationSite; + private final MemAlloc allocationSite; private String name = null; private boolean isThreadLocal = false; @@ -34,7 +34,7 @@ public class MemoryObject extends LeafExpressionBase { private final Map initialValues = new TreeMap<>(); - MemoryObject(int id, Expression size, Expression alignment, Alloc allocationSite, Type ptrType) { + MemoryObject(int id, Expression size, Expression alignment, MemAlloc allocationSite, Type ptrType) { super(ptrType); final TypeFactory types = TypeFactory.getInstance(); Preconditions.checkArgument(size.getType() instanceof IntegerType, "Size %s must be of integer type.", size); @@ -54,7 +54,7 @@ public class MemoryObject extends LeafExpressionBase { public boolean isStaticallyAllocated() { return allocationSite == null; } public boolean isDynamicallyAllocated() { return !isStaticallyAllocated(); } - public Alloc getAllocationSite() { return allocationSite; } + public MemAlloc getAllocationSite() { return allocationSite; } public boolean isThreadLocal() { return this.isThreadLocal; } public void setIsThreadLocal(boolean value) { this.isThreadLocal = value;} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java index 4830cfab9f..001f73b252 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java @@ -33,7 +33,7 @@ public static CoreCodeVerification fromConfig(Configuration config) { private static final Set> CORE_CLASSES = new HashSet<>(Arrays.asList( Load.class, Store.class, Init.class, GenericMemoryEvent.class, GenericVisibleEvent.class, CondJump.class, IfAsJump.class, ExecutionStatus.class, Label.class, Local.class, - Skip.class, RMWStore.class, RMWStoreExclusive.class, Alloc.class, MemFree.class, + Skip.class, RMWStore.class, RMWStoreExclusive.class, MemAlloc.class, MemFree.class, Assume.class, Assert.class, ThreadCreate.class, ThreadJoin.class, ThreadArgument.class, ThreadStart.class, ThreadReturn.class, ControlBarrier.class, NamedBarrier.class, diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java index e1d50e9589..24f2fbcd18 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java @@ -6,7 +6,7 @@ import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.RegReader; import com.dat3m.dartagnan.program.event.RegWriter; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.dat3m.dartagnan.program.event.core.Local; import com.google.common.collect.Lists; import org.sosy_lab.common.configuration.Configuration; @@ -69,6 +69,6 @@ private void eliminateDeadAssignments(Function function) { } private boolean isSideEffectFree(Event event) { - return !event.hasTag(VISIBLE) && (event instanceof Local || event instanceof Alloc); + return !event.hasTag(VISIBLE) && (event instanceof Local || event instanceof MemAlloc); } } \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java index 65423661b5..08d18c36ee 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java @@ -55,7 +55,7 @@ public void run(Function function) { private Matcher analyze(Function function) { final var matcher = new Matcher(); // Initially, all locally-allocated addresses are potentially promotable. - for (final Alloc allocation : function.getEvents(Alloc.class)) { + for (final MemAlloc allocation : function.getEvents(MemAlloc.class)) { final Map fields = getPrimitiveReplacementTypes(allocation); // Allocations will usually not have users. Otherwise, their object is not promotable. if (fields == null || allocation.getUsers().isEmpty()) { @@ -76,7 +76,7 @@ private void promoteAll(Function function, Matcher matcher) { final ExpressionFactory expressions = ExpressionFactory.getInstance(); // Replace every unmarked address. final HashMap> replacingRegisters = new HashMap<>(); - for (final Alloc allocation : function.getEvents(Alloc.class)) { + for (final MemAlloc allocation : function.getEvents(MemAlloc.class)) { if (matcher.reachabilityGraph.containsKey(allocation)) { final Map registerTypes = getPrimitiveReplacementTypes(allocation); if (registerTypes != null) { @@ -121,7 +121,7 @@ private void promoteAll(Function function, Matcher matcher) { } } - private Map getPrimitiveReplacementTypes(Alloc allocation) { + private Map getPrimitiveReplacementTypes(MemAlloc allocation) { if (!(allocation.getArraySize() instanceof IntLiteral sizeExpression)) { return null; } @@ -146,7 +146,7 @@ private static final class Matcher implements EventVisitor