about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorCristian Cadar <c.cadar@imperial.ac.uk>2023-06-23 22:05:12 +0100
committerMartinNowack <2443641+MartinNowack@users.noreply.github.com>2023-07-12 15:21:56 +0100
commit9cb9fd54846415d0c271cd178d4a9bfe6493ad00 (patch)
treec84895bab9d11fa527168763a68195efbcc6914b
parent8ad9f2aaf4e9e51c3f8b5e24aec56dae4e49e983 (diff)
downloadklee-9cb9fd54846415d0c271cd178d4a9bfe6493ad00.tar.gz
Replaced --suppress-external-warnings and --all-external-warnings with --external-call-warnings=none|once-per-function|all.
This eliminates the ambiguity when both of the old options were set.
Added test for the new option.
-rw-r--r--lib/Core/Executor.cpp37
-rw-r--r--test/Feature/ExtCallWarnings.c26
2 files changed, 49 insertions, 14 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index 906484c6..b4da6a08 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -198,17 +198,27 @@ cl::opt<ExternalCallPolicy> ExternalCalls(
     cl::init(ExternalCallPolicy::Concrete),
     cl::cat(ExtCallsCat));
 
-cl::opt<bool> SuppressExternalWarnings(
-    "suppress-external-warnings",
-    cl::init(false),
-    cl::desc("Supress warnings about calling external functions."),
-    cl::cat(ExtCallsCat));
 
-cl::opt<bool> AllExternalWarnings(
-    "all-external-warnings",
-    cl::init(false),
-    cl::desc("Issue a warning every time an external call is made, "
-             "as opposed to once per function (default=false)"),
+/*** External call warnings options ***/
+
+enum class ExtCallWarnings {
+  None,            // Never warn on external calls
+  OncePerFunction, // Only warn once per function on external calls
+  All,             // Always warn on external calls
+};
+
+cl::opt<ExtCallWarnings> ExternalCallWarnings(
+    "external-call-warnings",
+    cl::desc("Specify when to warn about external calls"),
+    cl::values(
+        clEnumValN(
+            ExtCallWarnings::None, "none",
+            "Never warn"),
+        clEnumValN(ExtCallWarnings::OncePerFunction, "once-per-function",
+                   "Warn once per external function (default)"),
+        clEnumValN(ExternalCallPolicy::All, "all",
+                   "Always warn")),
+    cl::init(ExtCallWarnings::OncePerFunction),
     cl::cat(ExtCallsCat));
 
 cl::opt<std::size_t> ExternalPageThreshold(
@@ -1323,7 +1333,7 @@ Executor::toConstant(ExecutionState &state,
      << " to value " << value << " (" << (*(state.pc)).info->file << ":"
      << (*(state.pc)).info->line << ")";
 
-  if (AllExternalWarnings)
+  if (ExternalCallWarnings == ExtCallWarnings::All)
     klee_warning("%s", os.str().c_str());
   else
     klee_warning_once(reason, "%s", os.str().c_str());
@@ -3966,8 +3976,7 @@ void Executor::callExternalFunction(ExecutionState &state,
       errnoValue->getZExtValue(sizeof(*errno_addr) * 8));
 #endif
 
-  if (!SuppressExternalWarnings) {
-
+  if (ExternalCallWarnings != ExtCallWarnings::None) {
     std::string TmpStr;
     llvm::raw_string_ostream os(TmpStr);
     os << "calling external: " << callable->getName().str() << "(";
@@ -3978,7 +3987,7 @@ void Executor::callExternalFunction(ExecutionState &state,
     }
     os << ") at " << state.pc->getSourceLocation();
     
-    if (AllExternalWarnings)
+    if (ExternalCallWarnings == ExtCallWarnings::All)
       klee_warning("%s", os.str().c_str());
     else
       klee_warning_once(callable->getValue(), "%s", os.str().c_str());
diff --git a/test/Feature/ExtCallWarnings.c b/test/Feature/ExtCallWarnings.c
new file mode 100644
index 00000000..6ee3f371
--- /dev/null
+++ b/test/Feature/ExtCallWarnings.c
@@ -0,0 +1,26 @@
+// RUN: %clang %s -emit-llvm %O0opt -g -c -o %t.bc
+
+// RUN: rm -rf %t.klee-out
+// RUN: %klee --output-dir=%t.klee-out --external-call-warnings=none %t.bc 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+
+// RUN: rm -rf %t.klee-out
+// RUN: %klee --output-dir=%t.klee-out --external-call-warnings=once-per-function %t.bc 2>&1 | FileCheck --check-prefix=CHECK-ONCE %s
+
+// RUN: rm -rf %t.klee-out
+// RUN: %klee --output-dir=%t.klee-out --external-call-warnings=all %t.bc 2>&1 | FileCheck --check-prefix=CHECK-ALL %s
+
+#include "klee/klee.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+  return abs(-5) + abs(6);
+  // CHECK-NONE-NOT: calling external
+
+  // CHECK-ONCE: calling external
+  // CHECK-ONCE-NOT: calling external
+
+  // CHECK-ALL: calling external
+  // CHECK-ALL: calling external
+  // CHECK-ALL-NOT: calling external
+}