Integrate LLVM analysis with infer script.

master
Rohan Jacob-Rao 9 years ago
parent 6f51b8c54b
commit f192b02f01

@ -88,6 +88,8 @@ base_group.add_argument('-nf', '--no-filtering', action='store_true',
help='''Also show the results from the experimental
checks. Warning: some checks may contain many false
alarms''')
base_group.add_argument('-l', '--llvm', action='store_true',
help='Analyze C or C++ file using LLVM translation')
base_group.add_argument('--log_to_stderr', action='store_true',
help='''When set, all logging will go to stderr instead

@ -140,6 +140,8 @@ def get_clang_frontend_envvars(args):
env_vars['FCP_DEBUG_MODE'] = '1'
if args.no_failures_allowed:
env_vars['FCP_REPORT_FRONTEND_FAILURE'] = '1'
if args.llvm:
env_vars['LLVM_MODE'] = '1'
# export an env variable with all the arguments to pass to InferClang
env_vars['FCP_INFER_FRONTEND_ARGS'] = ' '.join(frontend_args)

@ -117,8 +117,11 @@ then
else
ADD_PLUGIN_FLAG="-add-plugin"
fi
if [ -z "$LLVM_MODE" ]; then
ATTACH_PLUGIN="1"
fi
IFS=$'\n'
if [ -n "$ATTACH_PLUGIN" ]; then
EXTRA_ARGS=("-Xclang" "-load"
"-Xclang" "${PLUGIN_PATH}"
"-Xclang" "$ADD_PLUGIN_FLAG"
@ -127,11 +130,16 @@ then
"-Xclang" "-"
"-Xclang" "-plugin-arg-${PLUGIN_NAME}"
"-Xclang" "PREPEND_CURRENT_DIR=1")
fi
if [ -n "$SYNTAX_ONLY" ]; then
EXTRA_ARGS+=("-fsyntax-only")
fi
unset IFS
if [ -n "$LLVM_MODE" ]; then
EXTRA_ARGS+=("-o" "-" "-g" "-S" "-emit-llvm")
fi
# using always the original clang command for several reasons:
# - to avoid handling the presence/absence of -Xclang if the standard command is used
# - to emit the same command that was captured by this wrapper
@ -140,7 +148,7 @@ then
fi
fi
if [ -n "$ATTACH_PLUGIN" ]; then
if [ -n "$ATTACH_PLUGIN" ] || [ -n "$LLVM_MODE" ]; then
FOBJC_ARC_FLAG=$(has_flag "-fobjc-arc" "${INPUT_ARGUMENTS[@]}")
LANGUAGE=$(get_option_argument "-x" "${INPUT_ARGUMENTS[@]}")
@ -148,37 +156,43 @@ if [ -n "$ATTACH_PLUGIN" ]; then
if [ "$FOBJC_ARC_FLAG" == 0 ]; then INFER_FRONTEND_ARGS+=("-fobjc-arc"); fi
[[ "$SOURCE_FILE" = /* ]] || { SOURCE_FILE="${CWD}/$SOURCE_FILE"; }
INFERCLANG_CMD=(
if [ -n "$LLVM_MODE" ]; then
INFER_FRONTEND_CMD=("${BIN_DIR}/InferLLVM")
INFER_FRONTEND_LOG_FILE="/dev/stdout"
else
INFER_FRONTEND_CMD=(
"${BIN_DIR}/InferClang"
"-c" "$SOURCE_FILE"
"-results_dir" "$RESULTS_DIR"
"${INFER_FRONTEND_ARGS[@]}")
INFERCLANG_LOG_FILE="/dev/null"
if [ -n "$DEBUG_MODE" ]; then
# Emit the clang command with the extra args piped to InferClang
echo "${CLANG_CMD[@]} " \
"| tee ${OBJECT_FILENAME}.biniou " \
"| ${INFERCLANG_CMD[@]}" \
"| ${INFER_FRONTEND_CMD[@]}" \
> "${OBJECT_FILENAME}${CMD_FILE_EXT}"
echo "bdump -x -d ${ETC_DIR}/clang_ast.dict -w '!!DUMMY!!' ${OBJECT_FILENAME}.biniou " \
"> ${OBJECT_FILENAME}.bdump" \
>> "${OBJECT_FILENAME}${CMD_FILE_EXT}"
# Emit the InferClang cmd used to run the frontend
INFERCLANG_LOG_FILE="${OBJECT_FILENAME}${INFERCLANG_LOG_FILE_EXT}"
echo "${INFERCLANG_CMD[@]}" > "$INFERCLANG_LOG_FILE"
INFER_FRONTEND_LOG_FILE="${OBJECT_FILENAME}${INFERCLANG_LOG_FILE_EXT}"
echo "${INFER_FRONTEND_CMD[@]}" > "$INFER_FRONTEND_LOG_FILE"
else
INFER_FRONTEND_LOG_FILE="/dev/null"
fi
fi
# run clang and pipe its output to InferClang, or flush it in case the latter crashes
"${CLANG_CMD[@]}" | ("${INFERCLANG_CMD[@]}" || { EC=$?; cat > /dev/null; exit $EC; }) >> "$INFERCLANG_LOG_FILE" 2>&1
# run clang and pipe its output to InferClang/InferLLVM, or flush it in case the latter crashes
"${CLANG_CMD[@]}" | ("${INFER_FRONTEND_CMD[@]}" || { EC=$?; cat > /dev/null; exit $EC; }) >> "$INFER_FRONTEND_LOG_FILE" 2>&1
STATUSES=("${PIPESTATUS[@]}")
STATUS="${STATUSES[0]}"
INFERCLANG_STATUS="${STATUSES[1]}"
INFER_STATUS="${STATUSES[1]}"
# if clang fails, then fail, otherwise, fail with the frontend's exitcode if required
if [ "$STATUS" == 0 ] && [ -n "$REPORT_FRONTEND_FAILURE" ]; then
STATUS="$INFERCLANG_STATUS"
STATUS="$INFER_STATUS"
fi
else
"${CLANG_CMD[@]}"

@ -41,15 +41,17 @@ let store_tenv tenv =
Sil.store_tenv_to_file tenv_filename tenv
let () = try
let (input, filename) =
if Array.length Sys.argv < 2 then
raise (UsageError ("Missing source file as first command line argument."))
(stdin, "stdin") (* need a file name for output files *)
else
let filename = Sys.argv.(1) in
let fname = Sys.argv.(1) in
(open_in fname, fname)
in
let source_file = DB.abs_source_file_from_path filename in
let () = init_global_state source_file in
let lexbuf = Lexing.from_channel (open_in filename) in
let lexbuf = Lexing.from_channel input in
let prog = LParser.program LLexer.token lexbuf in
(* let pretty = LPretty.pretty_prog prog in *)
let (cfg, cg, tenv) = LTrans.trans_program prog in
store_icfg tenv cg cfg source_file; store_tenv tenv
with

Loading…
Cancel
Save