[llvm] delete llvm frontend

Summary: This frontend is not supported.

Reviewed By: sblackshear

Differential Revision: D3981323

fbshipit-source-id: 82b7422
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent b736f672e7
commit eb391d7875

5
.gitignore vendored

@ -65,7 +65,6 @@ buck-out/
/infer/bin/InferAnalyze
/infer/bin/InferClang
/infer/bin/InferJava
/infer/bin/InferLLVM
/infer/bin/InferPrint
/infer/bin/InferStatsAggregator
/infer/bin/InferBuckCompilationDatabase
@ -111,10 +110,6 @@ buck-out/
/infer/src/clang/clang_ast_visit.ml
/infer/src/clang/clang_ast_main.ml
# copied over by make
/infer/src/llvm/lLexer.ml
/infer/src/llvm/lParser.ml
/infer/annotations/annot_classes/
/infer/annotations/annotations.jar
/infer/annotations/processor_classes/

@ -86,7 +86,7 @@ test_oss_build: clang_plugin
ifeq ($(IS_FACEBOOK_TREE),yes)
$(MAKE) -C facebook clean
endif
$(MAKE) -C $(SRC_DIR) EXTRA_DEPS=opensource LLVM_BUILD_DIR=$(BUILD_DIR)/llvm_opensource TEST_BUILD_DIR=$(BUILD_DIR)/opensource test_build
$(MAKE) -C $(SRC_DIR) EXTRA_DEPS=opensource TEST_BUILD_DIR=$(BUILD_DIR)/opensource test_build
test_build: test_this_build
ifeq ($(IS_FACEBOOK_TREE),yes)

@ -13,7 +13,6 @@ ATDGEN = @ATDGEN@
bindir = @bindir@
BUILD_C_ANALYZERS = @BUILD_C_ANALYZERS@
BUILD_JAVA_ANALYZERS = @BUILD_JAVA_ANALYZERS@
BUILD_LLVM_ANALYZERS = @BUILD_LLVM_ANALYZERS@
CC = @CC@
CFLAGS = @CFLAGS@
CLANG_INCLUDES = @CLANG_INCLUDES@
@ -83,7 +82,6 @@ SRC_DIR = $(INFER_DIR)/src
ANNOT_DIR = $(SRC_DIR)/_build
INFER_BUILD_DIR = $(BUILD_DIR)/infer
LLVM_BUILD_DIR = $(BUILD_DIR)/llvm
TEST_BUILD_DIR = $(BUILD_DIR)/test
JAVA_LIB_DIR = $(LIB_DIR)/java

@ -72,14 +72,6 @@ AC_ARG_ENABLE(java-analyzers,
BUILD_JAVA_ANALYZERS=$enable_java_analyzers
AC_SUBST([BUILD_JAVA_ANALYZERS])
AC_ARG_ENABLE(llvm-analyzers,
AS_HELP_STRING([--enable-llvm-analyzers],
[build the LLVM experimental analyzers (default is not to build them)]),
,
enable_llvm_analyzers=no)
BUILD_LLVM_ANALYZERS=$enable_llvm_analyzers
AC_SUBST([BUILD_LLVM_ANALYZERS])
AC_ARG_WITH(fcp-clang,
AS_HELP_STRING([--without-fcp-clang],
[do not use $CLANG_PREFIX/bin/clang to override the default compiler (default is to override if in an infer release)]),

@ -102,10 +102,6 @@ CLANG_CMD+=(
"-plugin-arg-${PLUGIN_NAME}"
"PREPEND_CURRENT_DIR=1")
if [ -n "$LLVM_MODE" ]; then
CLANG_CMD+=("-o" "-" "-g" "-S" "-emit-llvm")
fi
# add the remaining arguments
CLANG_CMD+=("$@")
@ -121,27 +117,19 @@ if [ -n "$SYNTAX_ONLY" ]; then
CLANG_CMD+=("-fsyntax-only")
fi
if [ -n "$LLVM_MODE" ]; then
INFER_FRONTEND_CMD=(
"${BIN_DIR}/InferLLVM"
"-c" "$SOURCE_FILENAME"
"-results_dir" "$RESULTS_DIR"
"${INFER_FRONTEND_ARGS[@]}")
INFER_FRONTEND_LOG_FILE="/dev/stdout"
else
LANGUAGE=$(get_option_argument "-x" "${INPUT_ARGUMENTS[@]}")
if [ -n "$LANGUAGE" ]; then INFER_FRONTEND_ARGS+=("-x" "$LANGUAGE"); fi
if has_flag "-fobjc-arc" "${INPUT_ARGUMENTS[@]}"; then
LANGUAGE=$(get_option_argument "-x" "${INPUT_ARGUMENTS[@]}")
if [ -n "$LANGUAGE" ]; then INFER_FRONTEND_ARGS+=("-x" "$LANGUAGE"); fi
if has_flag "-fobjc-arc" "${INPUT_ARGUMENTS[@]}"; then
INFER_FRONTEND_ARGS+=("-fobjc-arc");
fi
fi
INFER_FRONTEND_CMD=(
INFER_FRONTEND_CMD=(
"${BIN_DIR}/InferClang"
"-c" "$SOURCE_FILENAME"
"-results_dir" "$RESULTS_DIR"
"${INFER_FRONTEND_ARGS[@]}")
if [ -n "$DEBUG_MODE" ]; then
if [ -n "$DEBUG_MODE" ]; then
OBJECT_FILENAME="$(get_option_argument "-o" "${INPUT_ARGUMENTS[@]}")"
# Emit the clang command with the extra args piped to InferClang
echo "${CLANG_CMD[@]} " \
@ -151,10 +139,9 @@ else
echo "bdump -x -d ${ETC_DIR}/clang_ast.dict -w '!!DUMMY!!' ${OBJECT_FILENAME}.biniou " \
"> ${OBJECT_FILENAME}.bdump" \
>> "${OBJECT_FILENAME}${CMD_FILE_EXT}"
fi
fi
# run clang and pipe its output to InferClang/InferLLVM, or flush it in case the latter crashes
# run clang and pipe its output to InferClang, or flush it in case the latter crashes
"${CLANG_CMD[@]}" | \
("${INFER_FRONTEND_CMD[@]}" || \
{ EC=$?; cat > /dev/null; exit $EC; }) 2>&1

@ -108,10 +108,6 @@ base_group.add_argument('--android-harness', action='store_true',
help='''[experimental] Create harness to detect bugs
involving the Android lifecycle''')
base_group.add_argument('--llvm', action='store_true',
help='''[experimental] Analyze C or C++ file using the
experimental LLVM frontend''')
base_parser.add_argument('-v', '--version',
help='''Print the version of Infer and exit''',
action=VersionAction)

@ -148,8 +148,6 @@ 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)

@ -11,7 +11,6 @@ include $(ROOT_DIR)/Makefile.config
#### Global declarations ####
INFER_BUILD_DIR = $(BUILD_DIR)/infer
LLVM_BUILD_DIR = $(BUILD_DIR)/llvm
ANNOT_DIR = $(SRC_DIR)/_build
ETC_DIR = $(INFER_DIR)/etc
@ -110,13 +109,6 @@ INFER_CLANG_FCP_MIRRORED_FILES = $(addprefix $(CLANG_SOURCES)/, $(notdir $(FCP_F
CLANG_BINIOU_DICT = $(ETC_DIR)/clang_ast.dict
#### LLVM declarations ####
LLVM_SOURCES = llvm
MENHIR_SOURCES = menhir
INFERLLVM_MAIN = $(LLVM_SOURCES)/lMain
INFERLLVM_BIN = $(BIN_DIR)/InferLLVM
#### scripts declarations ####
SCRIPT_SOURCES = scripts
@ -159,8 +151,6 @@ INFER_BASE_TARGETS = \
INFER_ALL_TARGETS = $(INFER_BASE_TARGETS) \
$(INFERJAVA_MAIN).native \
$(INFERCLANG_MAIN).native \
$(CLANGWRAPPER_MAIN).native \
$(INFERLLVM_MAIN).native \
$(BUCK_COMPILATION_DATABASE_MAIN).native
# configure-aware ocamlbuild commands and targets
@ -177,10 +167,6 @@ INFER_CONFIG_TARGETS += $(INFERCLANG_MAIN).native $(CLANGWRAPPER_MAIN).native
INFER_CONFIG_TARGETS += $(BUCK_COMPILATION_DATABASE_MAIN).native
DEPENDENCIES += clang
endif
ifeq ($(BUILD_LLVM_ANALYZERS),yes)
INFER_CONFIG_TARGETS += $(INFERLLVM_MAIN).native
DEPENDENCIES += llvm
endif
.PHONY: all infer init version sanitize clean toplevel
@ -194,9 +180,6 @@ infer: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS)
$(COPY) $(INFER_BUILD_DIR)/$(CHECKCOPYRIGHT_MAIN).native $(CHECKCOPYRIGHT_BIN)
$(COPY) $(INFER_BUILD_DIR)/$(STATSAGGREGATOR_MAIN).native $(STATSAGGREGATOR_BIN)
$(COPY) $(INFER_BUILD_DIR)/$(INFERUNIT_MAIN).native $(INFERUNIT_BIN)
ifeq ($(BUILD_LLVM_ANALYZERS),yes)
$(COPY) $(INFER_BUILD_DIR)/$(INFERLLVM_MAIN).native $(INFERLLVM_BIN)
endif
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
$(COPY) $(INFER_BUILD_DIR)/$(INFERJAVA_MAIN).native $(INFERJAVA_BIN)
endif
@ -212,21 +195,8 @@ endif
ifeq ($(BUILD_C_ANALYZERS),yes)
infer: $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) $(CLANG_BINIOU_DICT)
endif
ifeq ($(BUILD_LLVM_ANALYZERS),yes)
infer: $(LLVM_SOURCES)/lLexer.ml $(LLVM_SOURCES)/lParser.ml
endif
$(LLVM_SOURCES)/lLexer.ml $(LLVM_SOURCES)/lParser.ml: init
$(OCAMLBUILD_BASE) -build-dir $(LLVM_BUILD_DIR) -I $(LLVM_SOURCES) -use-menhir $(MENHIR_SOURCES)/$(@F)
$(COPY) $(LLVM_BUILD_DIR)/$(MENHIR_SOURCES)/$(@F) $@
$(LLVM_SOURCES)/lLexer.ml: $(MENHIR_SOURCES)/lLexer.mll
# avoid race condition between concurrently running ocamlbuild instances by making the parser depend
# on the lexer
$(LLVM_SOURCES)/lParser.ml: $(MENHIR_SOURCES)/lParser.mly $(LLVM_SOURCES)/lLexer.ml
byte: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) \
$(LLVM_SOURCES)/lLexer.ml $(LLVM_SOURCES)/lParser.ml
byte: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES)
$(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) $(INFER_ALL_TARGETS:.native=.byte)
# to build only the single module <Module> (and its dependencies) with extra flags execute:
@ -236,14 +206,12 @@ byte: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_S
M=
MFLAGS=
module: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) \
$(LLVM_SOURCES)/lLexer.ml $(LLVM_SOURCES)/lParser.ml
module: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES)
$(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) \
$(MFLAGS) \
$(M)
test_build: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) \
$(LLVM_SOURCES)/lLexer.ml $(LLVM_SOURCES)/lParser.ml
test_build: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES)
$(OCAMLBUILD_ALL) -build-dir $(TEST_BUILD_DIR) \
-cflags -warn-error,$(OCAML_FATAL_WARNINGS) \
$(INFER_ALL_TARGETS:.native=.byte)
@ -281,7 +249,7 @@ toplevel: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDG
# 5. filter out root modules since they run code when loading the module.
find . \( -name "*.ml" -o -name "*.mly" -o -name "*.mll" -o -name "*.re" \) \
\( $(dirs_find_regex) -false \) \
-not \( -path "./unit/*" -o -path "./llvm/*" -o -path "./facebook/scripts/eradicate_stats.ml" -o -name ".#*" \) \
-not \( -path "./unit/*" -o -path "./facebook/scripts/eradicate_stats.ml" -o -name ".#*" \) \
| cut -c 3- \
| rev | cut -f 2- -d '.' | rev \
| awk 'BEGIN { FS = "/"; OFS = "/" } ; {$$NF=toupper(substr($$NF,1,1))substr($$NF,2); print $$0}' \
@ -366,16 +334,13 @@ clean:
$(REMOVE) $(ETC_DIR)/clang_ast.dict
ifeq ($(ENABLE_OCAML_ANNOT),yes)
$(REMOVE_DIR) $(ANNOT_DIR)
endif
ifeq ($(BUILD_LLVM_ANALYZERS),yes)
$(REMOVE) $(LLVM_SOURCES)/lLexer.ml $(LLVM_SOURCES)/lParser.ml
endif
$(REMOVE) base/Version.ml
$(REMOVE) base/Version.ml.tmp.*
$(REMOVE) backend/jsonbug_{j,t}.ml{,i}
$(REMOVE) checkers/stacktree_{j,t}.ml{,i}
$(REMOVE) $(INFER_BIN) $(INFERANALYZE_BIN) $(INFERPRINT_BIN) $(STATSAGGREGATOR_BIN)
$(REMOVE) $(INFERJAVA_BIN) $(INFERCLANG_BIN) $(CLANGWRAPPER_BIN) $(INFERLLVM_BIN)
$(REMOVE) $(INFERJAVA_BIN) $(INFERCLANG_BIN)
$(REMOVE) $(INFERUNIT_BIN) $(CHECKCOPYRIGHT_BIN) $(INFER_BUCK_COMPILATION_DATABASE_BIN)
$(REMOVE) $(CLANG_ATDGEN_STUBS)
$(REMOVE) $(INFER_CLANG_FCP_MIRRORED_FILES)

@ -22,8 +22,7 @@ let set_env_for_clang_wrapper () =
Unix.putenv "FCP_DEBUG_MODE" "1" ;
if not Config.failures_allowed then
Unix.putenv "FCP_REPORT_FRONTEND_FAILURE" "1" ;
if Config.llvm then
Unix.putenv "LLVM_MODE" "1"
()
(** as the Config.fail_on_bug flag mandates, exit with error when an issue is reported *)
let fail_on_issue_epilogue () =

@ -17,8 +17,8 @@ module YBU = Yojson.Basic.Util
(** Each command line option may appear in the --help list of any executable, these tags are used to
specify which executables for which an option will be documented. *)
type exe = Analyze | BuckCompilationDatabase | Clang | ClangWrapper | Interactive | Java | Llvm
| Print | StatsAggregator | Toplevel
type exe = Analyze | BuckCompilationDatabase | Clang | ClangWrapper | Interactive | Java | Print
| StatsAggregator | Toplevel
let exes = [
@ -27,7 +27,6 @@ let exes = [
("InferClang", Clang);
("InferClangWrapper", ClangWrapper);
("InferJava", Java);
("InferLLVM", Llvm);
("InferPrint", Print);
("InferStatsAggregator", StatsAggregator);
("infer", Toplevel);
@ -36,7 +35,7 @@ let exes = [
let all_exes = IList.map snd exes
let frontend_exes = [Clang; Java; Llvm]
let frontend_exes = [Clang; Java]
let current_exe =
if !Sys.interactive then Interactive
@ -564,7 +563,7 @@ let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var exe_u
let exe_name = Sys.executable_name in
let should_parse_cl_args = match current_exe with
| ClangWrapper | Interactive -> false
| Analyze | BuckCompilationDatabase | Clang | Java | Llvm | Print | StatsAggregator
| Analyze | BuckCompilationDatabase | Clang | Java | Print | StatsAggregator
| Toplevel -> true in
let env_cl_args =
if should_parse_cl_args then prepend_to_argv env_args

@ -11,8 +11,8 @@
open! Utils
type exe = Analyze | BuckCompilationDatabase | Clang | ClangWrapper | Interactive | Java | Llvm
| Print | StatsAggregator | Toplevel
type exe = Analyze | BuckCompilationDatabase | Clang | ClangWrapper | Interactive | Java | Print
| StatsAggregator | Toplevel
val current_exe : exe

@ -411,7 +411,7 @@ and project_root =
?default:CLOpt.(match current_exe with Print | Toplevel | StatsAggregator ->
Some (Sys.getcwd ()) | _ -> None)
~f:resolve
~exes:CLOpt.[Analyze;Clang;Java;Llvm;Print;Toplevel]
~exes:CLOpt.[Analyze;Clang;Java;Print;Toplevel]
~meta:"dir" "Specify the root directory of the project"
(* Parse the phase 1 options, ignoring the rest *)
@ -833,9 +833,6 @@ and load_results =
~exes:CLOpt.[Print]
~meta:"file.iar" "Load analysis results from Infer Analysis Results file file.iar"
and llvm =
CLOpt.mk_bool ~long:"llvm" "Analyze C or C++ using the experimental LLVM frontend"
(** name of the makefile to create with clusters and dependencies *)
and makefile =
CLOpt.mk_string ~deprecated:["makefile"] ~long:"makefile" ~default:""
@ -974,7 +971,7 @@ and reports_include_ml_loc =
and results_dir =
CLOpt.mk_string ~deprecated:["results_dir"; "-out"] ~long:"results-dir" ~short:"o"
~default:(init_work_dir // "infer-out")
~exes:CLOpt.[Analyze;Clang;Java;Llvm;Print;StatsAggregator]
~exes:CLOpt.[Analyze;Clang;Java;Print;StatsAggregator]
~meta:"dir" "Write results and internal files in the specified directory"
and save_results =
@ -1138,11 +1135,11 @@ and verbose_out =
and version =
CLOpt.mk_bool ~deprecated:["version"] ~long:"version"
~exes:CLOpt.[Analyze;Clang;Java;Llvm;Print] "Print version information and exit"
~exes:CLOpt.[Analyze;Clang;Java;Print] "Print version information and exit"
and version_json =
CLOpt.mk_bool ~deprecated:["version_json"] ~long:"version-json"
~exes:CLOpt.[Analyze;Clang;Java;Llvm;Print]
~exes:CLOpt.[Analyze;Clang;Java;Print]
"Print version json formatted"
and whole_seconds =
@ -1237,9 +1234,6 @@ let exe_usage (exe : CLOpt.exe) =
| Java ->
"Usage: InferJava [options]\n\
Translate the given files using javac into infer internal representation for later analysis."
| Llvm ->
"Usage: InferLLVM -c <c file> [options]\n\
Translate the given files using llvm into infer internal representation for later analysis."
| Print ->
"Usage: InferPrint [options] name1.specs ... namen.specs\n\
Read, convert, and print .specs files. \
@ -1437,7 +1431,6 @@ and join_cond = !join_cond
and latex = !latex
and load_average = !load_average
and load_analysis_results = !load_results
and llvm = !llvm
and makefile_cmdline = !makefile
and merge = !merge
and ml_buckets = !ml_buckets

@ -203,7 +203,6 @@ val jobs : int
val join_cond : int
val latex : outfile option
val load_analysis_results : string option
val llvm : bool
val makefile_cmdline : string
val merge : bool
val ml_buckets :

@ -24,7 +24,6 @@ let log_dir_of_current_exe =
| ClangWrapper -> "clang_wrapper"
| Interactive -> "interactive"
| Java -> "java"
| Llvm -> "llvm"
| Print -> "print"
| StatsAggregator -> "stats_agregator"
| Toplevel -> "top_level"

@ -1,3 +0,0 @@
REC
S *
B ../../_build/llvm/**

@ -1,82 +0,0 @@
(*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! Utils
(** Representation of LLVM constructs *)
module MetadataMap = IntMap;;
type variable_id =
| Name of string
| Number of int
type variable =
| Global of variable_id
| Local of variable_id
type constant =
| Cint of int
| Cnull
type operand =
| Var of variable
| Const of constant
type typ =
| Tint of int
| Tfloat (* just one type for now *)
| Tptr of typ
| Tvector of int * typ
| Tarray of int * typ
| Tfunc of typ option * typ list
| Tlabel
| Tmetadata
type metadata_value =
| MetadataVar of int
| MetadataString of string
| MetadataNode of metadata_component list
and metadata_component =
| TypOperand of typ option * operand
| MetadataVal of metadata_value
type metadata_location = { line : int; col : int; scope : metadata_value }
type metadata_aggregate =
| Components of metadata_component list
| Location of metadata_location
type instruction =
| Ret of (typ * operand) option
| UncondBranch of variable
| CondBranch of operand * variable * variable
| Load of variable * typ * variable
| Store of operand * typ * variable
| Alloc of variable * typ * int (* return variable, element type, number of elements *)
| Call of variable * variable * (typ * operand) list (* return variable, function pointer, arguments *)
| Binop
type annotation = Annotation of int
type annotated_instruction = instruction * annotation option
type function_def = FunctionDef of variable * typ option * (typ * string) list * annotated_instruction list
type metadata_map = metadata_aggregate MetadataMap.t
type program = Program of function_def list * metadata_map
let string_of_variable : variable -> string = function
| Global var_id | Local var_id ->
begin match var_id with
| Name str -> str
| Number i -> string_of_int i
end

@ -1,60 +0,0 @@
(*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! Utils
let register_perf_stats_report source_file =
let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name in
let abbrev_source_file = DB.source_file_encoding source_file in
let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json" in
create_dir Config.results_dir ;
create_dir stats_dir ;
PerfStats.register_report_at_exit (Filename.concat stats_dir stats_file)
let init_global_state source_file =
Config.curr_language := Config.Clang;
register_perf_stats_report source_file;
DB.Results_dir.init source_file;
Ident.NameGenerator.reset ();
Config.nLOC := FileLOC.file_get_loc (DB.source_file_to_string source_file)
let store_icfg source_file cg cfg =
let source_dir = DB.source_dir_from_source_file source_file in
let get_internal_file = DB.source_dir_get_internal_file source_dir in
let cg_file = get_internal_file ".cg" in
let cfg_file = get_internal_file ".cfg" in
Cg.store_to_file cg_file cg;
Cfg.store_cfg_to_file ~source_file cfg_file cfg;
if Config.debug_mode || Config.frontend_tests then
begin
Dotty.print_icfg_dotty source_file cfg;
Cg.save_call_graph_dotty source_file Specs.get_specs cg
end
let store_tenv tenv =
if DB.file_exists DB.global_tenv_fname then DB.file_remove DB.global_tenv_fname;
Tenv.store_to_file DB.global_tenv_fname tenv
let () =
let source_file = match Config.source_file with
| None ->
Config.print_usage_exit ()
| Some source_file ->
begin match Config.project_root with
| None ->
DB.abs_source_file_from_path source_file
| Some project_root ->
DB.rel_source_file_from_abs_path project_root (filename_to_absolute source_file)
end in
init_global_state source_file;
let lexbuf = Lexing.from_channel stdin in
let prog = LParser.program LLexer.token lexbuf in
let (cfg, cg, tenv) = LTrans.trans_program source_file prog in
store_icfg source_file cg cfg;
store_tenv tenv

@ -1,59 +0,0 @@
(*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! Utils
open LAst
let concatmap (sep : string) (f : 'a -> string) (l : 'a list) : string =
String.concat sep (List.map f l)
let pretty_variable : variable -> string = function
| Global id -> "@" ^ id
| Local id -> "%" ^ id
let pretty_constant : constant -> string = function
| Cint i -> string_of_int i
| Cnull -> "null"
let pretty_operand : operand -> string = function
| Var var -> pretty_variable var
| Const const -> pretty_constant const
let rec pretty_typ : typ -> string = function
| Tint width -> "i" ^ string_of_int width
| Tfloat (* just one type for now *) -> "float"
| Tptr tp -> pretty_typ tp ^ "*"
| Tvector (sz, tp) -> "<" ^ string_of_int sz ^ " x " ^ pretty_typ tp ^ ">"
| Tlabel -> "label"
| Tmetadata -> "metadata"
| Tarray (sz, tp) -> "[" ^ string_of_int sz ^ " x " ^ pretty_typ tp ^ "]"
let pretty_ret_typ : typ option -> string = function
| None -> "void"
| Some tp -> pretty_typ tp
let pretty_instr : instr -> string = function
| Ret None -> "ret void"
| Ret (Some (tp, op)) -> "ret " ^ pretty_typ tp ^ " " ^ pretty_operand op
| UncondBranch label -> "br label " ^ pretty_variable label
| CondBranch (op, label1, label2) ->
"br i1 " ^ pretty_operand op ^ ", label " ^ pretty_variable label1 ^
", label " ^ pretty_variable label2
let pretty_instr_ln (i : instr) : string = pretty_instr i ^ "\n"
let pretty_func_def : func_def -> string = function
FuncDef (name, ret_tp, params, instrs) ->
"define " ^ pretty_ret_typ ret_tp ^ " " ^ pretty_variable name ^ "(" ^
concatmap ", " (fun (tp, id) -> pretty_typ tp ^ " " ^ id) params ^ ") {\n" ^
concatmap "" pretty_instr_ln instrs ^ "}\n"
let pretty_prog : prog -> string = function
Prog func_defs -> concatmap "" pretty_func_def func_defs

@ -1,175 +0,0 @@
(*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! Utils
open LAst
exception ImproperTypeError of string
exception MalformedMetadata of string
exception Unimplemented of string
let source_only_location source_file : Location.t =
let open Location in { line = -1; col = -1; file = source_file; nLOC = !Config.nLOC }
let ident_of_variable (var : LAst.variable) : Ident.t = (* TODO: use unique stamps *)
Ident.create_normal (Ident.string_to_name (LAst.string_of_variable var)) 0
let trans_variable (var : LAst.variable) : Exp.t = Exp.Var (ident_of_variable var)
let trans_constant : LAst.constant -> Exp.t = function
| Cint i -> Exp.Const (Const.Cint (IntLit.of_int i))
| Cnull -> Exp.null
let trans_operand : LAst.operand -> Exp.t = function
| Var var -> trans_variable var
| Const const -> trans_constant const
let rec trans_typ : LAst.typ -> Typ.t = function
| Tint _i -> Typ.Tint Typ.IInt (* TODO: check what size int is needed here *)
| Tfloat -> Typ.Tfloat Typ.FFloat
| Tptr tp -> Typ.Tptr (trans_typ tp, Typ.Pk_pointer)
| Tvector (i, tp)
| Tarray (i, tp) -> Typ.Tarray (trans_typ tp, Some (IntLit.of_int i))
| Tfunc _ -> Typ.Tfun false
| Tlabel -> raise (ImproperTypeError "Tried to generate Sil type from LLVM label type.")
| Tmetadata -> raise (ImproperTypeError "Tried to generate Sil type from LLVM metadata type.")
let location_of_annotation_option source_file (metadata : LAst.metadata_map)
: LAst.annotation option -> Location.t = function
| None -> source_only_location source_file (* no source line/column numbers *)
| Some (Annotation i) ->
begin match MetadataMap.find i metadata with
| Components (TypOperand (_, Const (Cint line_num)) :: _) ->
let open Location in
{ line = line_num; col = -1; file = source_file; nLOC = !Config.nLOC }
| Location loc ->
let open Location in
{ line = loc.line; col = loc.col; file = source_file; nLOC = !Config.nLOC }
| _ -> raise (MalformedMetadata ("Instruction annotation refers to metadata node " ^
"without line number as first component."))
end
let procname_of_function_variable (func_var : LAst.variable) : Procname.t =
Procname.from_string_c_fun (LAst.string_of_variable func_var)
(* Generate list of SIL instructions and list of local variables *)
let rec trans_annotated_instructions
source_file
(cfg : Cfg.cfg) (procdesc : Cfg.Procdesc.t) (metadata : LAst.metadata_map)
: LAst.annotated_instruction list -> Sil.instr list * (Mangled.t * Typ.t) list = function
| [] -> ([], [])
| (instr, anno) :: t ->
let (sil_instrs, locals) = trans_annotated_instructions source_file cfg procdesc metadata t in
let location = location_of_annotation_option source_file metadata anno in
begin match instr with
| Ret None -> (sil_instrs, locals)
| Ret (Some (tp, exp)) ->
let procname = Cfg.Procdesc.get_proc_name procdesc in
let ret_var = Pvar.get_ret_pvar procname in
let new_sil_instr =
Sil.Store (Exp.Lvar ret_var, trans_typ tp, trans_operand exp, location) in
(new_sil_instr :: sil_instrs, locals)
| Load (var, tp, ptr) ->
let new_sil_instr =
Sil.Load (ident_of_variable var, trans_variable ptr, trans_typ tp, location) in
(new_sil_instr :: sil_instrs, locals)
| Store (op, tp, var) ->
let new_sil_instr =
Sil.Store (trans_variable var, trans_typ tp, trans_operand op, location) in
(new_sil_instr :: sil_instrs, locals)
| Alloc (var, tp, _num_elems) ->
(* num_elems currently ignored *)
begin match var with
| Global (Name var_name) | Local (Name var_name) ->
let new_local = (Mangled.from_string var_name, trans_typ (Tptr tp)) in
(sil_instrs, new_local :: locals)
| _ ->
raise
(ImproperTypeError
"Not expecting alloca instruction to a numbered variable.")
end
| Call (ret_var, func_var, typed_args) ->
let new_sil_instr = Sil.Call (
(* TODO: translate type of ret_var *)
Some (ident_of_variable ret_var, Tvoid),
Exp.Const (Const.Cfun (procname_of_function_variable func_var)),
IList.map (fun (tp, arg) -> (trans_operand arg, trans_typ tp)) typed_args,
location, CallFlags.default) in
(new_sil_instr :: sil_instrs, locals)
| _ -> raise (Unimplemented "Need to translate instruction to SIL.")
end
let callees_of_function_def : LAst.function_def -> Procname.t list = function
FunctionDef (_, _, _, annotated_instrs) ->
let callee_of_instruction : LAst.instruction -> Procname.t option = begin function
| Call (_, func_var, _) -> Some (procname_of_function_variable func_var)
| _ -> None
end in
IList.flatten_options (
IList.map
(fun annotated_instr -> callee_of_instruction (fst annotated_instr))
annotated_instrs)
(* Update CFG and call graph with new function definition *)
let trans_function_def source_file (cfg : Cfg.cfg) (cg: Cg.t) (metadata : LAst.metadata_map)
(func_def : LAst.function_def) : unit =
(* each procedure has different scope: start names from id 0 *)
Ident.NameGenerator.reset ();
match func_def with
FunctionDef (func_name, ret_tp_opt, params, annotated_instrs) ->
let proc_name = procname_of_function_variable func_name in
let ret_type =
match ret_tp_opt with
| None -> Typ.Tvoid
| Some ret_tp -> trans_typ ret_tp in
let (proc_attrs : ProcAttributes.t) =
{ (ProcAttributes.default proc_name Config.Clang) with
ProcAttributes.formals =
IList.map (fun (tp, name) -> (Mangled.from_string name, trans_typ tp)) params;
is_defined = true; (* is defined and not just declared *)
loc = source_only_location source_file;
locals = []; (* TODO *)
ret_type;
} in
let procdesc = Cfg.Procdesc.create cfg proc_attrs in
let start_kind = Cfg.Node.Start_node procdesc in
let start_node =
Cfg.Node.create cfg (source_only_location source_file) start_kind [] procdesc in
let exit_kind = Cfg.Node.Exit_node procdesc in
let exit_node =
Cfg.Node.create cfg (source_only_location source_file) exit_kind [] procdesc in
let node_of_sil_instr cfg procdesc sil_instr =
Cfg.Node.create cfg (Sil.instr_get_loc sil_instr) (Cfg.Node.Stmt_node "method_body")
[sil_instr] procdesc in
let rec link_nodes (start_node : Cfg.Node.t) : Cfg.Node.t list -> unit = function
(* link all nodes in a chain for now *)
| [] ->
Cfg.Node.set_succs_exn cfg start_node [exit_node] [exit_node]
| nd :: nds ->
Cfg.Node.set_succs_exn cfg start_node [nd] [exit_node]; link_nodes nd nds in
let (sil_instrs, locals) =
trans_annotated_instructions source_file cfg procdesc metadata annotated_instrs in
let nodes = IList.map (node_of_sil_instr cfg procdesc) sil_instrs in
Cfg.Procdesc.set_start_node procdesc start_node;
Cfg.Procdesc.set_exit_node procdesc exit_node;
link_nodes start_node nodes;
Cfg.Node.add_locals_ret_declaration start_node locals;
Cg.add_defined_node cg proc_name;
IList.iter (Cg.add_edge cg proc_name) (callees_of_function_def func_def)
let trans_program source_file : LAst.program -> Cfg.cfg * Cg.t * Tenv.t = function
Program (func_defs, metadata) ->
let cfg = Cfg.Node.create_cfg () in
let cg = Cg.create (Some source_file) in
let tenv = Tenv.create () in
IList.iter (trans_function_def source_file cfg cg metadata) func_defs;
(cfg, cg, tenv)

@ -1,187 +0,0 @@
(*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
{
open LParser
exception LexingError of string
}
let space = [' ' '\t']
let newline = '\n'
let comment = ';' [^ '\n']*
let nonzero_digit = ['1'-'9']
let digit = ['0'-'9']
let pos_int = nonzero_digit digit*
let nonneg_int = '0' | pos_int
let intlit = '-'? digit+
let lower = ['a'-'z']
let upper = ['A'-'Z']
let id_special_char = ['-' '$' '.' '_']
let id_char = lower | upper | id_special_char
let id = id_char (id_char | digit)*
(* some top level constructs currently ignored *)
let declaration = "declare " [^ '\n']*
let attribute_group = "attributes " [^ '\n']*
let string_content = [^ '"']*
rule token = parse
| space | comment { token lexbuf }
| newline { token lexbuf }
(* keywords *)
| "target" { TARGET }
| "datalayout" { DATALAYOUT }
| "triple" { TRIPLE }
| "define" { DEFINE }
(* delimiters *)
| ',' { COMMA }
| '(' { LPAREN }
| ')' { RPAREN }
| '{' { LBRACE }
| '}' { RBRACE }
| '<' { LANGLE }
| '>' { RANGLE }
| '[' { LSQBRACK }
| ']' { RSQBRACK }
| ':' { COLON }
(* symbols *)
| '=' { EQUALS }
| '*' { STAR }
| ['x' 'X'] { X }
(* TYPES *)
| "void" { VOID }
| 'i' (pos_int as width) { INT (int_of_string width) }
| "half" { HALF }
| "float" { FLOAT }
| "double" { DOUBLE }
| "fp128" { FP128 }
| "x86_fp80" { X86_FP80 }
| "ppc_fp128" { PPC_FP128 }
(*| "x86_mmx" { X86_MMX }*)
| "label" { LABEL }
| "metadata" { METADATA }
| '"' (string_content as str) '"' { CONSTANT_STRING str }
(* CONSTANTS *)
| "true" { CONSTANT_INT 1 }
| "false" { CONSTANT_INT 0 }
| intlit as i { CONSTANT_INT (int_of_string i) }
(* floating point constants *)
| "null" { NULL }
(* INSTRUCTIONS *)
(* terminator instructions *)
| "ret" { RET }
| "br" { BR }
(*| "switch" { SWITCH }
| "indirectbr" { INDIRECTBR }
| "invoke" { INVOKE }
| "resume" { RESUME }
| "unreachable" { UNREACHABLE }*)
(* binary operations *)
| "add" { ADD }
| "fadd" { FADD }
| "sub" { SUB }
| "fsub" { FSUB }
| "mul" { MUL }
| "fmul" { FMUL }
| "udiv" { UDIV }
| "sdiv" { SDIV }
| "fdiv" { FDIV }
| "urem" { UREM }
| "srem" { SREM }
| "frem" { FREM }
(* arithmetic options *)
| "nuw" { NUW }
| "nsw" { NSW }
| "exact" { EXACT }
(* floating point options *)
| "nnan" { NNAN }
| "ninf" { NINF }
| "nsz" { NSZ }
| "arcp" { ARCP }
| "fast" { FAST }
(* bitwise binary operations *)
| "shl" { SHL }
| "lshr" { LSHR }
| "ashr" { ASHR }
| "and" { AND }
| "or" { OR }
| "xor" { XOR }
(* vector operations *)
| "extractelement" { EXTRACTELEMENT }
| "insertelement" { INSERTELEMENT }
(*| "shufflevector" { SHUFFLEVECTOR }*)
(* aggregate operations *)
(*| "extractvalue" { EXTRACTVALUE }*)
(*| "insertvalue" { INSERTVALUE }*)
(* memory access and addressing operations *)
| "align" { ALIGN }
| "alloca" { ALLOCA }
| "load" { LOAD }
| "store" { STORE }
(*| "fence" { FENCE }*)
(*| "cmpxchg" { CMPXCHG }*)
(*| "atomicrmw" { ATOMICRMW }*)
(*| "getelementptr" { GETELEMENTPTR }*)
(* conversion operations *)
(*| "trunc" { TRUNC }*) (* e.g. trunc ... to ... *)
(*| "zext" { ZEXT }*)
(*| "sext" { SEXT }*)
(*| "fptrunc" { FPTRUNC }*)
(*| "fpext" { FPEXT }*)
(*| "fptoui" { FPTOUI }*)
(*| "fptosi" { FPTOSI }*)
(*| "uitofp" { UITOFP }*)
(*| "sitofp" { SITOFP }*)
(*| "ptrtoint" { PTRTOINT }*)
(*| "inttoptr" { INTTOPTR }*)
(*| "bitcast" { BITCAST }*)
(*| "addrspacecast" { ADDRSPACECAST }*)
(*| "to" { TO }*) (* all conversion operations include this keyword *)
(* other operations *)
(*| "icmp" { ICMP }*)
(*| "fcmp" { FCMP }*)
(*| "phi" { PHI }*)
(*| "select" { SELECT }*)
| "call" { CALL }
(*| "va_arg" { VA_ARG }*)
(*| "landingpad" { LANDINGPAD }*)
(* IDENTIFIERS *)
| "@llvm.dbg.declare" { DBG_DECLARE }
| '@' (id as str) { NAMED_GLOBAL str }
| '%' (id as str) { NAMED_LOCAL str }
| '@' (nonneg_int as i) { NUMBERED_GLOBAL (int_of_string i) }
| '%' (nonneg_int as i) { NUMBERED_LOCAL (int_of_string i) }
| id as str { IDENT str }
(* METADATA *)
| "!dbg" { DEBUG_ANNOTATION }
| "!MDLocation" { METADATA_LOCATION }
| '!' (id as str) { NAMED_METADATA str }
| '!' (nonneg_int as i) { NUMBERED_METADATA (int_of_string i) }
| '!' '"' ([^ '"']* as str) '"' { METADATA_STRING str }
| "!{" { METADATA_NODE_BEGIN }
| declaration { token lexbuf }
(* attribute groups *)
| '#' (nonneg_int as i) { ATTRIBUTE_GROUP (int_of_string i) }
| attribute_group { token lexbuf }
| eof { EOF }

@ -1,335 +0,0 @@
(*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
%{
open LAst
%}
(* keywords *)
%token TARGET
%token DATALAYOUT
%token TRIPLE
%token DEFINE
(* delimiters *)
%token COMMA
%token LPAREN
%token RPAREN
%token LBRACE
%token RBRACE
%token LANGLE
%token RANGLE
%token LSQBRACK
%token RSQBRACK
%token COLON
(* symbols *)
%token EQUALS
%token STAR
%token X
(* TYPES *)
%token VOID
%token <int> INT
%token HALF
%token FLOAT
%token DOUBLE
%token FP128
%token X86_FP80
%token PPC_FP128
(*%token X86_MMX*)
%token LABEL
%token METADATA
%token <string> CONSTANT_STRING
(* CONSTANTS *)
%token <int> CONSTANT_INT
%token NULL
(* INSTRUCTIONS *)
(* terminator instructions *)
%token RET
%token BR
(*%token SWITCH*)
(*%token INDIRECTBR*)
(*%token INVOKE*)
(*%token RESUME*)
(*%token UNREACHABLE*)
(* binary operations *)
%token ADD
%token FADD
%token SUB
%token FSUB
%token MUL
%token FMUL
%token UDIV
%token SDIV
%token FDIV
%token UREM
%token SREM
%token FREM
(* arithmetic options *)
%token NUW
%token NSW
%token EXACT
(* floating point options *)
%token NNAN
%token NINF
%token NSZ
%token ARCP
%token FAST
(* bitwise binary operations *)
%token SHL
%token LSHR
%token ASHR
%token AND
%token OR
%token XOR
(* vector operations *)
%token EXTRACTELEMENT
%token INSERTELEMENT
(*%token SHUFFLEVECTOR*)
(* aggregate operations *)
(*%token EXTRACTVALUE*)
(*%token INSERTVALUE*)
(* memory access and addressing operations *)
%token ALIGN (* argument for below operations *)
%token ALLOCA
%token LOAD
%token STORE
(*%token FENCE*)
(*%token CMPXCHG*)
(*%token ATOMICRMW*)
(*%token GETELEMENTPTR*)
(* conversion operations *)
(*%token TRUNC*)
(*%token ZEXT*)
(*%token SEXT*)
(*%token FPTRUNC*)
(*%token FPEXT*)
(*%token FPTOUI*)
(*%token FPTOSI*)
(*%token UITOFP*)
(*%token SITOFP*)
(*%token PTRTOINT*)
(*%token INTTOPTR*)
(*%token BITCAST*)
(*%token ADDRSPACECAST*)
(*%token TO*)
(* other operations *)
(*%token ICMP*)
(*%token FCMP*)
(*%token PHI*)
(*%token SELECT*)
%token CALL
(*%token VA_ARG*)
(*%token LANDINGPAD*)
%token DBG_DECLARE
%token <string> NAMED_GLOBAL
%token <string> NAMED_LOCAL
%token <int> NUMBERED_GLOBAL
%token <int> NUMBERED_LOCAL
%token <string> IDENT
%token DEBUG_ANNOTATION
%token <string> NAMED_METADATA
%token <int> NUMBERED_METADATA
%token <string> METADATA_STRING
%token METADATA_NODE_BEGIN
%token METADATA_LOCATION
%token <int> ATTRIBUTE_GROUP
%token EOF
%start program
%type <LAst.program> program
%type <LAst.function_def> function_def
%type <LAst.typ option> ret_typ
%type <LAst.typ> typ
%%
program:
| targets func_defs = function_def* opt_mappings = metadata_def* EOF {
let mappings = IList.flatten_options opt_mappings in
let add_mapping map (metadata_id, aggregate) = MetadataMap.add metadata_id aggregate map in
let metadata_map = IList.fold_left add_mapping MetadataMap.empty mappings in
Program (func_defs, metadata_map) }
targets:
| { (None, None) }
| dl = datalayout { (Some dl, None) }
| tt = target_triple { (None, Some tt) }
| dl = datalayout tt = target_triple { (Some dl, Some tt) }
| tt = target_triple dl = datalayout { (Some dl, Some tt) }
datalayout:
| TARGET DATALAYOUT EQUALS str = CONSTANT_STRING { str }
target_triple:
| TARGET TRIPLE EQUALS str = CONSTANT_STRING { str }
metadata_def:
| NAMED_METADATA EQUALS numbered_metadata_node { None }
| metadata_id = NUMBERED_METADATA EQUALS aggregate = metadata_aggregate { Some
(metadata_id, aggregate) }
numbered_metadata_node:
| METADATA_NODE_BEGIN metadata_ids = separated_list(COMMA, NUMBERED_METADATA) RBRACE { metadata_ids }
metadata_aggregate:
| components = metadata_node { Components components }
| location = metadata_location { Location location }
metadata_location:
| METADATA_LOCATION LPAREN IDENT COLON line_num = CONSTANT_INT COMMA
IDENT COLON col_num = CONSTANT_INT COMMA
IDENT COLON i = NUMBERED_METADATA RPAREN
{ { line = line_num; col = col_num; scope = MetadataVar i} }
metadata_node:
| METADATA? METADATA_NODE_BEGIN components = separated_list(COMMA, metadata_component) RBRACE { components }
metadata_component:
| METADATA? tp = typ? op = operand { TypOperand (tp, op) }
| METADATA? value = metadata_value { MetadataVal value }
metadata_value:
| i = NUMBERED_METADATA { MetadataVar i }
| str = METADATA_STRING { MetadataString str }
| components = metadata_node { MetadataNode components }
function_def:
| DEFINE ret_tp = ret_typ name = variable LPAREN
params = separated_list(COMMA, pair(first_class_typ, IDENT)) RPAREN attribute_group*
annotated_instrs = block { FunctionDef (name, ret_tp, params, annotated_instrs) }
attribute_group:
| i = ATTRIBUTE_GROUP { i }
ret_typ:
| VOID { None }
| tp = first_class_typ { Some tp }
typ:
| tp = func_typ { tp }
| tp = first_class_typ { tp }
func_typ:
| ret_tp = ret_typ LPAREN param_tps = separated_list(COMMA, first_class_typ) RPAREN { Tfunc (ret_tp, param_tps) }
first_class_typ:
| tp = element_typ { tp }
(*| X86_MMX { () }*)
| tp = vector_typ { tp }
| LSQBRACK sz = CONSTANT_INT X tp = element_typ RSQBRACK { Tarray (sz, tp) } (* array type *)
| LABEL { Tlabel }
| METADATA { Tmetadata }
(* TODO structs *)
vector_typ:
| LANGLE sz = CONSTANT_INT X tp = element_typ RANGLE { Tvector (sz, tp) }
element_typ:
| width = INT { Tint width }
| floating_typ { Tfloat }
| tp = ptr_typ { Tptr tp }
floating_typ:
| HALF { () }
| FLOAT { () }
| DOUBLE { () }
| FP128 { () }
| X86_FP80 { () }
| PPC_FP128 { () }
ptr_typ:
| tp = typ STAR { tp }
block:
| LBRACE annotated_instrs = annotated_instruction* RBRACE { IList.flatten_options annotated_instrs }
annotated_instruction:
| instr = real_instruction anno = annotation? { Some (instr, anno) }
| debug_instruction annotation? { None }
annotation:
| COMMA DEBUG_ANNOTATION i = NUMBERED_METADATA { Annotation i }
real_instruction:
(* terminator instructions *)
| RET tp = typ op = operand { Ret (Some (tp, op)) }
| RET VOID { Ret None }
| BR LABEL lbl = variable { UncondBranch lbl }
| BR _ = INT op = operand COMMA LABEL lbl1 = variable COMMA LABEL lbl2 = variable
{ CondBranch (op, lbl1, lbl2) }
(* Memory access operations *)
| var = variable EQUALS ALLOCA tp = typ align? { Alloc (var, tp, 1) }
| var = variable EQUALS LOAD tp = ptr_typ ptr = variable align? { Load (var, tp, ptr) }
| STORE val_tp = typ value = operand COMMA _ptr_tp = ptr_typ var = variable align?
{ Store (value, val_tp, var) }
(* don't yet know why val_tp and _ptr_tp would be different *)
(* Function call *)
| ret_var = variable EQUALS CALL ret_typ func_var = variable LPAREN
args = separated_list(COMMA, pair(typ, operand)) RPAREN { Call (ret_var, func_var, args) }
| variable EQUALS binop { Binop }
debug_instruction:
| CALL VOID DBG_DECLARE LPAREN separated_list(COMMA, metadata_component) RPAREN { () }
align:
| COMMA ALIGN width = CONSTANT_INT { width }
binop:
| ADD arith_options binop_args { () }
| FADD fast_math_flags binop_args { () }
| SUB arith_options binop_args { () }
| FSUB fast_math_flags binop_args { () }
| MUL binop_args { () }
| FMUL fast_math_flags binop_args { () }
| UDIV EXACT? binop_args { () }
| SDIV EXACT? binop_args { () }
| FDIV fast_math_flags binop_args { () }
| UREM binop_args { () }
| SREM binop_args { () }
| FREM fast_math_flags binop_args { () }
(* bitwise *)
| SHL arith_options binop_args { () }
| LSHR EXACT? binop_args { () }
| ASHR EXACT? binop_args { () }
| AND binop_args { () }
| OR binop_args { () }
| XOR binop_args { () }
(* vector *)
| EXTRACTELEMENT vector_typ operand COMMA typ operand { () }
| INSERTELEMENT vector_typ operand COMMA typ operand COMMA typ operand { () }
arith_options:
| NUW? NSW? { () }
fast_math_flags:
| NNAN? NINF? NSZ? ARCP? FAST? { () }
binop_args:
| typ operand COMMA operand { () }
operand:
| var = variable { Var var }
| const = constant { Const const }
variable:
| name = NAMED_GLOBAL { Global (Name name) }
| name = NAMED_LOCAL { Local (Name name) }
| num = NUMBERED_GLOBAL { Global (Number num) }
| num = NUMBERED_LOCAL { Local (Number num) }
constant:
| i = CONSTANT_INT { Cint i }
| NULL { Cnull }

@ -1,12 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; Allocate stack variable using alloca instruction
define i32 @main() {
%a = alloca i32
ret i32 0
}

@ -1,15 +0,0 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
int* always_null(void) { return 0; }
void foo(void) {
int* p = always_null();
*p = 42;
}

@ -1,59 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; ModuleID = 'interproc.c'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.10.0"
; Function Attrs: nounwind ssp uwtable
define i32* @always_null() #0 {
ret i32* null, !dbg !16
}
; Function Attrs: nounwind ssp uwtable
define void @foo() #0 {
%p = alloca i32*, align 8
call void @llvm.dbg.declare(metadata !{i32** %p}, metadata !17), !dbg !18
%1 = call i32* @always_null(), !dbg !19
store i32* %1, i32** %p, align 8, !dbg !19
%2 = load i32** %p, align 8, !dbg !20
store i32 42, i32* %2, align 4, !dbg !20
ret void, !dbg !21
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata) #1
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!13, !14}
!llvm.ident = !{!15}
!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit ] [/Users/rohanjr/infer/infer/tests/codetoanalyze/llvm/interproc.c] [DW_LANG_C99]
!1 = metadata !{metadata !"interproc.c", metadata !"/Users/rohanjr/infer/infer/tests/codetoanalyze/llvm"}
!2 = metadata !{}
!3 = metadata !{metadata !4, metadata !10}
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"always_null", metadata !"always_null", metadata !"", i32 10, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32* ()* @always_null, null, null, metadata !2, i32 10} ; [ DW_TAG_subprogram ] [line 10] [def] [always_null]
!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/Users/rohanjr/infer/infer/tests/codetoanalyze/llvm/interproc.c]
!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!7 = metadata !{metadata !8}
!8 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
!9 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
!10 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 14, metadata !11, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void ()* @foo, null, null, metadata !2, i32 14} ; [ DW_TAG_subprogram ] [line 14] [def] [foo]
!11 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!12 = metadata !{null}
!13 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
!14 = metadata !{i32 2, metadata !"Debug Info Version", i32 602053001}
!15 = metadata !{metadata !"Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)"}
!16 = metadata !{i32 11, i32 4, metadata !4, null} ; [ DW_TAG_lexical_block ] [/]
!17 = metadata !{i32 786688, metadata !10, metadata !"p", metadata !5, i32 15, metadata !8, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [p] [line 15]
!18 = metadata !{i32 15, i32 9, metadata !10, null}
!19 = metadata !{i32 15, i32 13, metadata !10, null}
!20 = metadata !{i32 16, i32 4, metadata !10, null}
!21 = metadata !{i32 17, i32 1, metadata !10, null}

@ -1,12 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; Definition of main function
define i32 @main() {
%a = load i32* %b
ret i32 0
}

@ -1,13 +0,0 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
void foo(void) {
int* p = 0;
*p = 42;
}

@ -1,51 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; ModuleID = 'null_deref.c'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.10.0"
; Function Attrs: nounwind ssp uwtable
define void @foo() #0 {
%p = alloca i32*, align 8
call void @llvm.dbg.declare(metadata i32** %p, metadata !12, metadata !15), !dbg !16
store i32* null, i32** %p, align 8, !dbg !16
%1 = load i32** %p, align 8, !dbg !17
store i32 42, i32* %1, align 4, !dbg !18
ret void, !dbg !19
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!8, !9, !10}
!llvm.ident = !{!11}
!0 = !{!"0x11\0012\00clang version 3.6.1 (tags/RELEASE_361/final)\000\00\000\00\001", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/Users/rohanjr/infer/infer/tests/codetoanalyze/llvm/null_deref.c] [DW_LANG_C99]
!1 = !{!"null_deref.c", !"/Users/rohanjr/infer/infer/tests/codetoanalyze/llvm"}
!2 = !{}
!3 = !{!4}
!4 = !{!"0x2e\00foo\00foo\00\0010\000\001\000\000\00256\000\0010", !1, !5, !6, null, void ()* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 10] [def] [foo]
!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/Users/rohanjr/infer/infer/tests/codetoanalyze/llvm/null_deref.c]
!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!7 = !{null}
!8 = !{i32 2, !"Dwarf Version", i32 2}
!9 = !{i32 2, !"Debug Info Version", i32 2}
!10 = !{i32 1, !"PIC Level", i32 2}
!11 = !{!"clang version 3.6.1 (tags/RELEASE_361/final)"}
!12 = !{!"0x100\00p\0011\000", !4, !5, !13} ; [ DW_TAG_auto_variable ] [p] [line 11]
!13 = !{!"0xf\00\000\0064\0064\000\000", null, null, !14} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
!14 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
!15 = !{!"0x102"} ; [ DW_TAG_expression ]
!16 = !MDLocation(line: 11, column: 9, scope: !4)
!17 = !MDLocation(line: 12, column: 5, scope: !4)
!18 = !MDLocation(line: 12, column: 4, scope: !4)
!19 = !MDLocation(line: 13, column: 1, scope: !4)

@ -1,11 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; Definition of main function
define i32 @main() {
ret i32 0
}

@ -1,11 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; Definition of main function
define i32 @main() {
ret i32 %0
}

@ -1,11 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; Definition of main function
define void @main() {
ret void
}

@ -1,12 +0,0 @@
; Copyright (c) 2015 - present Facebook, Inc.
; All rights reserved.
;
; This source code is licensed under the BSD style license found in the
; LICENSE file in the root directory of this source tree. An additional grant
; of patent rights can be found in the PATENTS file in the same directory.
; Function with store instruction
define i32 @main() {
store i32 0, i32* %i
ret i32 0
}
Loading…
Cancel
Save