diff --git a/src/main/scala/viper/gobra/backend/ViperBackends.scala b/src/main/scala/viper/gobra/backend/ViperBackends.scala index 7746255ec..e4b0308f8 100644 --- a/src/main/scala/viper/gobra/backend/ViperBackends.scala +++ b/src/main/scala/viper/gobra/backend/ViperBackends.scala @@ -31,6 +31,9 @@ object ViperBackends { if (config.z3APIMode) { options = options ++ Vector(s"--prover=${Z3ProverAPI.name}") } + if (config.disableNL) { + options = options ++ Vector(s"--disableNL") + } val mceSiliconOpt = config.mceMode match { case MCE.Disabled => "0" case MCE.Enabled => "1" diff --git a/src/main/scala/viper/gobra/frontend/Config.scala b/src/main/scala/viper/gobra/frontend/Config.scala index 29d92a022..42ae527e9 100644 --- a/src/main/scala/viper/gobra/frontend/Config.scala +++ b/src/main/scala/viper/gobra/frontend/Config.scala @@ -66,6 +66,7 @@ object ConfigDefaults { lazy val DefaultParallelizeBranches: Boolean = false lazy val DefaultConditionalizePermissions: Boolean = false lazy val DefaultZ3APIMode: Boolean = false + lazy val DefaultDisableNL: Boolean = false lazy val DefaultMCEMode: MCE.Mode = MCE.Enabled lazy val DefaultEnableLazyImports: Boolean = false lazy val DefaultNoVerify: Boolean = false @@ -130,6 +131,7 @@ case class Config( parallelizeBranches: Boolean = ConfigDefaults.DefaultParallelizeBranches, conditionalizePermissions: Boolean = ConfigDefaults.DefaultConditionalizePermissions, z3APIMode: Boolean = ConfigDefaults.DefaultZ3APIMode, + disableNL: Boolean = ConfigDefaults.DefaultDisableNL, mceMode: MCE.Mode = ConfigDefaults.DefaultMCEMode, enableLazyImports: Boolean = ConfigDefaults.DefaultEnableLazyImports, noVerify: Boolean = ConfigDefaults.DefaultNoVerify, @@ -180,6 +182,7 @@ case class Config( parallelizeBranches = parallelizeBranches, conditionalizePermissions = conditionalizePermissions, z3APIMode = z3APIMode || other.z3APIMode, + disableNL = disableNL || other.disableNL, mceMode = mceMode, enableLazyImports = enableLazyImports || other.enableLazyImports, noVerify = noVerify || other.noVerify, @@ -233,6 +236,7 @@ case class BaseConfig(gobraDirectory: Path = ConfigDefaults.DefaultGobraDirector parallelizeBranches: Boolean = ConfigDefaults.DefaultParallelizeBranches, conditionalizePermissions: Boolean = ConfigDefaults.DefaultConditionalizePermissions, z3APIMode: Boolean = ConfigDefaults.DefaultZ3APIMode, + disableNL: Boolean = ConfigDefaults.DefaultDisableNL, mceMode: MCE.Mode = ConfigDefaults.DefaultMCEMode, enableLazyImports: Boolean = ConfigDefaults.DefaultEnableLazyImports, noVerify: Boolean = ConfigDefaults.DefaultNoVerify, @@ -290,6 +294,7 @@ trait RawConfig { parallelizeBranches = baseConfig.parallelizeBranches, conditionalizePermissions = baseConfig.conditionalizePermissions, z3APIMode = baseConfig.z3APIMode, + disableNL = baseConfig.disableNL, mceMode = baseConfig.mceMode, enableLazyImports = baseConfig.enableLazyImports, noVerify = baseConfig.noVerify, @@ -561,6 +566,7 @@ class ScallopGobraConfig(arguments: Seq[String], isInputOptional: Boolean = fals default = None, noshort = true ) + lazy val packageTimeoutDuration: Duration = packageTimeout.toOption match { case Some(d) => Duration(d) case _ => Duration.Inf @@ -646,6 +652,13 @@ class ScallopGobraConfig(arguments: Seq[String], isInputOptional: Boolean = fals noshort = true, ) + val disableNL: ScallopOption[Boolean] = opt[Boolean]( + name = "disableNL", + descr = "Disable non-linear integer arithmetics. Non compatible with Carbon", + default = Some(ConfigDefaults.DefaultDisableNL), + noshort = true, + ) + val mceMode: ScallopOption[MCE.Mode] = { val on = "on" val off = "off" @@ -770,6 +783,14 @@ class ScallopGobraConfig(arguments: Seq[String], isInputOptional: Boolean = fals } } + addValidation { + if (!disableNL.toOption.contains(true) || isSiliconBasedBackend) { + Right(()) + } else { + Left("--disableNL is not compatible with Carbon") + } + } + /** File Validation */ validateFilesExist(cutInput) @@ -857,6 +878,7 @@ class ScallopGobraConfig(arguments: Seq[String], isInputOptional: Boolean = fals parallelizeBranches = parallelizeBranches(), conditionalizePermissions = conditionalizePermissions(), z3APIMode = z3APIMode(), + disableNL = disableNL(), mceMode = mceMode(), enableLazyImports = enableLazyImports(), noVerify = noVerify(), diff --git a/src/test/resources/regressions/examples/disableNL.gobra b/src/test/resources/regressions/examples/disableNL.gobra new file mode 100644 index 000000000..53e144e85 --- /dev/null +++ b/src/test/resources/regressions/examples/disableNL.gobra @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ + +// ##(--disableNL) +package pkg + +requires 0 <= x && x <= 10 +requires 0 <= y && y <= 10 +//:: ExpectedOutput(postcondition_error:assertion_error) +ensures 0 <= res && res <= 100 +func f(x, y int) (res int) { + return x * y +} diff --git a/src/test/resources/regressions/examples/disableNL_success.gobra b/src/test/resources/regressions/examples/disableNL_success.gobra new file mode 100644 index 000000000..f2ca41718 --- /dev/null +++ b/src/test/resources/regressions/examples/disableNL_success.gobra @@ -0,0 +1,11 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ + +package pkg + +requires 0 <= x && x <= 10 +requires 0 <= y && y <= 10 +ensures 0 <= res && res <= 100 +func f(x, y int) (res int) { + return x * y +}