Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bool/Int type coercion #1170

Draft
wants to merge 7 commits into
base: dev
Choose a base branch
from
13 changes: 13 additions & 0 deletions examples/technical/intBoolCoercion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

//@ requires i;
void check(int i) {
if(!i) {
//@ assert false;
}
}

void main() {
check(5==5);
int *p;
if(!p) return;
}
3 changes: 3 additions & 0 deletions src/col/vct/col/ast/Node.scala
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@ final case class CoerceCIntCFloat[G](target: Type[G])(implicit val o: Origin) ex
final case class CoerceCIntInt[G]()(implicit val o: Origin) extends Coercion[G] with CoerceCIntIntImpl[G]
final case class CoerceCFloatFloat[G](source: Type[G], target: Type[G])(implicit val o: Origin) extends Coercion[G] with CoerceCFloatFloatImpl[G]
final case class CoerceIntRat[G]()(implicit val o: Origin) extends Coercion[G] with CoerceIntRatImpl[G]
final case class CoerceBoolCInt[G]()(implicit val o: Origin) extends Coercion[G] with CoerceBoolCIntImpl[G]
final case class CoerceCIntBool[G]()(implicit val o: Origin) extends Coercion[G] with CoerceCIntBoolImpl[G]
final case class CoercePointerBool[G]()(implicit val o: Origin) extends Coercion[G] with CoercePointerBoolImpl[G]

final case class CoerceIncreasePrecision[G](source: Type[G], target: Type[G])(implicit val o: Origin) extends Coercion[G] with CoerceIncreasePrecisionImpl[G]
final case class CoerceDecreasePrecision[G](source: Type[G], target: Type[G])(implicit val o: Origin) extends Coercion[G] with CoerceDecreasePrecisionImpl[G]
Expand Down
9 changes: 9 additions & 0 deletions src/col/vct/col/ast/family/coercion/CoerceBoolCIntImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vct.col.ast.family.coercion

import vct.col.ast.{CoerceBoolCInt, TBool}
import vct.col.ast.ops.CoerceBoolCIntOps

trait CoerceBoolCIntImpl[G] extends CoerceBoolCIntOps[G] { this: CoerceBoolCInt[G] =>
override def target: TBool[G] = TBool()

}
9 changes: 9 additions & 0 deletions src/col/vct/col/ast/family/coercion/CoerceCIntBoolImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vct.col.ast.family.coercion

import vct.col.ast.{CoerceCIntBool, TBool}
import vct.col.ast.ops.CoerceCIntBoolOps

trait CoerceCIntBoolImpl[G] extends CoerceCIntBoolOps[G] { this: CoerceCIntBool[G] =>
override def target: TBool[G] = TBool()

}
10 changes: 10 additions & 0 deletions src/col/vct/col/ast/family/coercion/CoercePointerBoolImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package vct.col.ast.family.coercion

import vct.col.ast.ops.CoercePointerBoolOps
import vct.col.ast.{CoercePointerBool, TBool}

trait CoercePointerBoolImpl[G] extends CoercePointerBoolOps[G] {
this: CoercePointerBool[G] =>
// override def layout(implicit ctx: Ctx): Doc = ???
override def target: TBool[G] = TBool()
}
7 changes: 5 additions & 2 deletions src/col/vct/col/ast/family/coercion/CoercionImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ trait CoercionImpl[G] extends CoercionFamilyOps[G] { this: Coercion[G] =>
case CoerceDecreasePrecision(_, _) => false
case CoerceCFloatCInt(_) => false
case CoercionSequence(coercions) => coercions.forall(_.isCPromoting)
case CoerceJoinUnion(inner, _, _) => inner.forall(_.isPromoting)
case CoerceSelectUnion(inner, _, _, _) => inner.isPromoting
case CoerceJoinUnion(inner, _, _) => inner.forall(_.isCPromoting)
case CoerceSelectUnion(inner, _, _, _) => inner.isCPromoting
case CoerceMapOption(inner, _, _) => inner.isCPromoting
case CoerceMapTuple(inner, _, _) => inner.forall(_.isCPromoting)
case CoerceMapEither(inner, _, _) => inner._1.isCPromoting && inner._2.isCPromoting
Expand Down Expand Up @@ -79,5 +79,8 @@ trait CoercionImpl[G] extends CoercionFamilyOps[G] { this: Coercion[G] =>
case CoerceCFloatFloat(_, _) => true
case CoerceDecreasePrecision(_, _) => false
case CoerceCFloatCInt(_) => false
case CoerceBoolCInt() => true
case CoerceCIntBool() => false
case CoercePointerBool() => false
}
}
3 changes: 3 additions & 0 deletions src/col/vct/col/feature/FeatureRainbow.scala
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ class FeatureRainbow[G] {
case node: CoerceIdentity[G] => Coercions
case node: CoerceIncreasePrecision[G] => Coercions
case node: CoerceIntRat[G] => Coercions
case node: CoerceBoolCInt[G] => Coercions
case node: CoerceCIntBool[G] => Coercions
case node: CoercePointerBool[G] => Coercions
case node: CoerceJavaClassAnyClass[G] => Coercions
case node: CoerceJavaSupports[G] => Coercions
case node: CoerceJoinUnion[G] => Coercions
Expand Down
2 changes: 1 addition & 1 deletion src/col/vct/col/resolve/lang/C.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ case object C {
case Seq(CFloat()) => C_ieee754_32bit()
case Seq(CDouble()) => C_ieee754_64bit()
case Seq(CLong(), CDouble()) => C_ieee754_64bit()
case Seq(CBool()) => TBool()
case Seq(CBool()) => TCInt()
case Seq(defn @ CTypedefName(_)) => Types.notAValue(defn.ref.get)
case Seq(CSpecificationType(typ)) => typ
case Seq(defn @ CStructSpecifier(_)) => CTStruct(defn.ref.get.decl.ref)
Expand Down
3 changes: 3 additions & 0 deletions src/col/vct/col/typerules/CoercingRewriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ abstract class CoercingRewriter[Pre <: Generation]() extends BaseCoercingRewrite
case CoerceRatZFrac() => e
case CoerceZFracFrac() => e

case CoerceBoolCInt() => e
case CoerceCIntBool() => e
case CoercePointerBool() => e
case CoerceDecreasePrecision(_, _) => e
case CoerceCFloatCInt(_) => e
case CoerceCIntCFloat(_) => e
Expand Down
5 changes: 5 additions & 0 deletions src/col/vct/col/typerules/CoercionUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ case object CoercionUtils {
case (TFraction(), TRational()) => CoercionSequence(Seq(CoerceFracZFrac(), CoerceZFracRat()))
case (TZFraction(), TRational()) => CoerceZFracRat()
case (source: FloatType[G], TRational()) => CoerceFloatRat(source)
case (TBool(), TCInt()) => CoerceBoolCInt()
case (TCInt(), TBool()) => CoerceCIntBool()
case (TCInt(), TResource()) => CoercionSequence(Seq(CoerceCIntBool(), CoerceBoolResource()))
case (TPointer(_), TBool()) => CoercePointerBool()
case (CTPointer(_), TBool()) => CoercePointerBool()

case (source @ TFloat(exponentL, mantissaL), target @ TFloat(exponentR, mantissaR)) if exponentL <= exponentR && mantissaL <= mantissaR =>
CoerceIncreasePrecision(source, target)
Expand Down
1 change: 1 addition & 0 deletions src/main/vct/main/stages/Transformation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ case class SilverTransformation
) extends Transformation(onBeforePassKey, onAfterPassKey, Seq(
// Replace leftover SYCL types
ReplaceSYCLTypes,
CIntBoolCoercion,
CFloatIntCoercion,

ComputeBipGlue,
Expand Down
27 changes: 27 additions & 0 deletions src/rewrite/vct/rewrite/CIntBoolCoercion.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package vct.col.rewrite

import vct.col.ast._
import vct.col.origin.Origin
import vct.col.typerules.CoercingRewriter

case object CIntBoolCoercion extends RewriterBuilder {
override def key: String = "CIntBool"
override def desc: String = "Introduce an explicit node to convert integers to boolean and vice versa for C."
}

case class CIntBoolCoercion[Pre <: Generation]() extends CoercingRewriter[Pre] {
override def applyCoercion(e: => Expr[Post], coercion: Coercion[Pre])(implicit o: Origin): Expr[Post] = coercion match {
case CoerceBoolCInt() =>
val zero = new CIntegerValue[Post](0)
val one = new CIntegerValue[Post](1)
new Select[Post](e, one, zero)
case CoerceCIntBool() =>
val zero = new CIntegerValue[Post](0)
new Neq[Post](e, zero)
case CoercePointerBool() =>
val ptr = new Null[Post]()
new Neq[Post](e, ptr)
case other => super.applyCoercion(e, other)
}

}
7 changes: 7 additions & 0 deletions src/rewrite/vct/rewrite/lang/LangCToCol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,13 @@ case class LangCToCol[Pre <: Generation](rw: LangSpecificToCol[Pre]) extends Laz
NewPointerArray(rw.dispatch(t1), size)(ArrayMallocFailed(inv))(c.o)
case CCast(CInvocation(CLocal("__vercors_malloc"), _, _, _), _) => throw UnsupportedMalloc(c)
case CCast(n@Null(), t) if t.asPointer.isDefined => rw.dispatch(n)
case CCast(e, t) if getBaseType(e.t)==TBool[Pre]() && getBaseType(t)==TCInt[Pre]() =>
val zero = new CIntegerValue[Post](0)(e.o)
val one = new CIntegerValue[Post](1)(e.o)
new Select[Post](rw.dispatch(e), one, zero)(e.o)
case CCast(e, t) if getBaseType(t)==TBool[Pre]() && getBaseType(e.t)==TCInt[Pre]() =>
val zero = new CIntegerValue[Post](0)(e.o)
new Neq[Post](rw.dispatch(e), zero)(e.o)
case _ => throw UnsupportedCast(c)
}

Expand Down
2 changes: 2 additions & 0 deletions test/main/vct/test/integration/examples/TechnicalSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,8 @@ vercors should verify using silicon in "example using string primitive" pvl

vercors should verify using anyBackend example "technical/labeledEmbeddedStatement.c"

vercors should verify using anyBackend example "technical/intBoolCoercion.c"
sakehl marked this conversation as resolved.
Show resolved Hide resolved

vercors should verify using anyBackend in "usage of given/yields in C" c """
/*@
given int x;
Expand Down
Loading