-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for variable-sized and variable-aligned allocations (#750)
- Loading branch information
1 parent
c828b96
commit c3aa592
Showing
31 changed files
with
1,112 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include <stdint.h> | ||
#include <assert.h> | ||
#include <dat3m.h> | ||
#include <stdlib.h> | ||
|
||
#define SIZE_1 42 | ||
|
||
int main() | ||
{ | ||
int size_int = __VERIFIER_nondet_int(); | ||
int align_int = __VERIFIER_nondet_int(); | ||
__VERIFIER_assume(size_int > 0); | ||
__VERIFIER_assume(align_int > 0); | ||
size_t size = (size_t)size_int; | ||
size_t align = (size_t)align_int; | ||
int *array = malloc(SIZE_1 * sizeof(int)); | ||
int *array_2 = aligned_alloc(align, size * sizeof(int)); | ||
// NOTE: making the first allocation non-det-sized makes the solver extremely slow to verify the | ||
// custom aligned allocation. Even when fixing the alignment to a constant it gets super slow if that constant | ||
// is not a power of two. In other words, aligning variable-sized addresses is very expensive currently, especially | ||
// for non-power-of-two alignments (those don't exist in practice though). | ||
|
||
assert ((size_t)array_2 - (size_t)array >= SIZE_1 * sizeof(int)); | ||
assert (((size_t)array) % 8 == 0); // Default alignment | ||
assert (((size_t)array_2) % align == 0); // Custom alignment | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <stdint.h> | ||
#include <assert.h> | ||
#include <dat3m.h> | ||
|
||
|
||
#define MAX_SIZE 10 | ||
|
||
int main() | ||
{ | ||
int size = __VERIFIER_nondet_int(); | ||
__VERIFIER_assume(size > 0 && size <= MAX_SIZE); | ||
int *array = malloc(size * sizeof(int)); | ||
|
||
__VERIFIER_loop_bound(MAX_SIZE + 1); | ||
for (int i = 0; i < size; i++) { | ||
array[i] = i; | ||
} | ||
|
||
int sum = 0; | ||
__VERIFIER_loop_bound(MAX_SIZE + 1); | ||
for (int i = 0; i < size; i++) { | ||
sum += array[i]; | ||
} | ||
|
||
// Fails if size == MAX_SIZE because then equality holds | ||
assert(sum < (MAX_SIZE * (MAX_SIZE - 1)) / 2); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include <stdint.h> | ||
#include <assert.h> | ||
#include <dat3m.h> | ||
#include <stdlib.h> | ||
|
||
int main() | ||
{ | ||
int size_int = __VERIFIER_nondet_int(); | ||
__VERIFIER_assume(size_int > 0); | ||
// NOTE: Putting the assumption on the below <size> rather than <size_int> gives FAIL. | ||
// This is because the non-det int value is sign-extended to size_t and so negative values are extended | ||
// to very large sizes that can overflow, allowing the addresses of different allocations to overlap! | ||
size_t size = (size_t)size_int; | ||
int *array = malloc(size * sizeof(int)); | ||
int *array_2 = malloc(size * sizeof(int)); | ||
|
||
assert (array != array_2); | ||
assert (((size_t)array) % 8 == 0); | ||
assert (((size_t)array_2) % 8 == 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
dartagnan/src/main/java/com/dat3m/dartagnan/encoding/EncodingHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package com.dat3m.dartagnan.encoding; | ||
|
||
import com.google.common.base.Preconditions; | ||
import org.sosy_lab.java_smt.api.*; | ||
|
||
import java.math.BigInteger; | ||
|
||
public class EncodingHelper { | ||
|
||
private final FormulaManager fmgr; | ||
|
||
public EncodingHelper(FormulaManager fmgr) { | ||
this.fmgr = fmgr; | ||
} | ||
|
||
public BooleanFormula equals(Formula left, Formula right) { | ||
if (left instanceof NumeralFormula.IntegerFormula iLeft && right instanceof NumeralFormula.IntegerFormula iRight) { | ||
return fmgr.getIntegerFormulaManager().equal(iLeft, iRight); | ||
} | ||
|
||
if (left instanceof BitvectorFormula bvLeft && right instanceof BitvectorFormula bvRight) { | ||
final BitvectorFormulaManager bvmgr = fmgr.getBitvectorFormulaManager(); | ||
Preconditions.checkState(bvmgr.getLength(bvLeft) == bvmgr.getLength(bvRight)); | ||
return fmgr.getBitvectorFormulaManager().equal(bvLeft, bvRight); | ||
} | ||
|
||
throw new UnsupportedOperationException("Mismatching types: " + left + " and " + right); | ||
} | ||
|
||
public BooleanFormula greaterThan(Formula left, Formula right, boolean signed) { | ||
if (left instanceof NumeralFormula.IntegerFormula iLeft && right instanceof NumeralFormula.IntegerFormula iRight) { | ||
return fmgr.getIntegerFormulaManager().greaterThan(iLeft, iRight); | ||
} | ||
|
||
if (left instanceof BitvectorFormula bvLeft && right instanceof BitvectorFormula bvRight) { | ||
final BitvectorFormulaManager bvmgr = fmgr.getBitvectorFormulaManager(); | ||
Preconditions.checkState(bvmgr.getLength(bvLeft) == bvmgr.getLength(bvRight)); | ||
return fmgr.getBitvectorFormulaManager().greaterThan(bvLeft, bvRight, signed); | ||
} | ||
|
||
throw new UnsupportedOperationException("Mismatching types: " + left + " and " + right); | ||
} | ||
|
||
public BooleanFormula greaterOrEquals(Formula left, Formula right, boolean signed) { | ||
if (left instanceof NumeralFormula.IntegerFormula iLeft && right instanceof NumeralFormula.IntegerFormula iRight) { | ||
return fmgr.getIntegerFormulaManager().greaterOrEquals(iLeft, iRight); | ||
} | ||
|
||
if (left instanceof BitvectorFormula bvLeft && right instanceof BitvectorFormula bvRight) { | ||
final BitvectorFormulaManager bvmgr = fmgr.getBitvectorFormulaManager(); | ||
Preconditions.checkState(bvmgr.getLength(bvLeft) == bvmgr.getLength(bvRight)); | ||
return fmgr.getBitvectorFormulaManager().greaterOrEquals(bvLeft, bvRight, signed); | ||
} | ||
|
||
throw new UnsupportedOperationException("Mismatching types: " + left + " and " + right); | ||
} | ||
|
||
public Formula add(Formula left, Formula right) { | ||
if (left instanceof NumeralFormula.IntegerFormula iLeft && right instanceof NumeralFormula.IntegerFormula iRight) { | ||
return fmgr.getIntegerFormulaManager().add(iLeft, iRight); | ||
} | ||
|
||
if (left instanceof BitvectorFormula bvLeft && right instanceof BitvectorFormula bvRight) { | ||
final BitvectorFormulaManager bvmgr = fmgr.getBitvectorFormulaManager(); | ||
Preconditions.checkState(bvmgr.getLength(bvLeft) == bvmgr.getLength(bvRight)); | ||
return fmgr.getBitvectorFormulaManager().add(bvLeft, bvRight); | ||
} | ||
|
||
throw new UnsupportedOperationException("Mismatching types: " + left + " and " + right); | ||
} | ||
|
||
public Formula subtract(Formula left, Formula right) { | ||
if (left instanceof NumeralFormula.IntegerFormula iLeft && right instanceof NumeralFormula.IntegerFormula iRight) { | ||
return fmgr.getIntegerFormulaManager().subtract(iLeft, iRight); | ||
} | ||
|
||
if (left instanceof BitvectorFormula bvLeft && right instanceof BitvectorFormula bvRight) { | ||
final BitvectorFormulaManager bvmgr = fmgr.getBitvectorFormulaManager(); | ||
Preconditions.checkState(bvmgr.getLength(bvLeft) == bvmgr.getLength(bvRight)); | ||
return fmgr.getBitvectorFormulaManager().subtract(bvLeft, bvRight); | ||
} | ||
|
||
throw new UnsupportedOperationException("Mismatching types: " + left + " and " + right); | ||
} | ||
|
||
public Formula remainder(Formula left, Formula right) { | ||
//FIXME: integer modulo and BV modulo have different semantics, the former is always positive, the latter | ||
// returns a value whose sign depends on one of the two BVs. | ||
// The results in this implementation will match if the denominator <right> is positive which is the most usual case. | ||
if (left instanceof NumeralFormula.IntegerFormula iLeft && right instanceof NumeralFormula.IntegerFormula iRight) { | ||
return fmgr.getIntegerFormulaManager().modulo(iLeft, iRight); | ||
} | ||
|
||
if (left instanceof BitvectorFormula bvLeft && right instanceof BitvectorFormula bvRight) { | ||
final BitvectorFormulaManager bvmgr = fmgr.getBitvectorFormulaManager(); | ||
Preconditions.checkState(bvmgr.getLength(bvLeft) == bvmgr.getLength(bvRight)); | ||
return fmgr.getBitvectorFormulaManager().smodulo(bvLeft, bvRight); | ||
} | ||
|
||
throw new UnsupportedOperationException("Mismatching types: " + left + " and " + right); | ||
} | ||
|
||
public Formula value(BigInteger value, FormulaType<?> type) { | ||
if (type.isIntegerType()) { | ||
return fmgr.getIntegerFormulaManager().makeNumber(value); | ||
} else if (type.isBitvectorType()) { | ||
int size = getBitSize(type); | ||
return fmgr.getBitvectorFormulaManager().makeBitvector(size, value); | ||
} | ||
throw new UnsupportedOperationException("Cannot generate value of type " + type); | ||
} | ||
|
||
public int getBitSize(FormulaType<?> type) { | ||
if (type.isIntegerType()) { | ||
return -1; | ||
} else if (type.isBitvectorType()) { | ||
return ((FormulaType.BitvectorType)type).getSize(); | ||
} | ||
throw new UnsupportedOperationException("Cannot get bit-size for type " + type); | ||
} | ||
|
||
public FormulaType<?> typeOf(Formula formula) { | ||
return fmgr.getFormulaType(formula); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.