-
Notifications
You must be signed in to change notification settings - Fork 294
Restore cross checking code, part 1 #1575
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
5ff6192
Revert "Remove cross checking functionality"
ahomescu 7785305
cross-checks: Remove ReMon submodule
ahomescu bf3ff6c
transpile: Push cross-check items to out_items by value
ahomescu 8e6623a
transpile: Update cross-check attribute code to new builder
ahomescu 9731c3a
transpile: Run cargo fmt to clean up some cross-checks code
ahomescu ab05a6f
transpile: Add cross check fields to TranspilerConfig for snapshots
ahomescu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1228,6 +1228,20 @@ fn arrange_header(t: &Translation, is_binary: bool) -> (Vec<syn::Attribute>, Vec | |
| out_attrs.push(attr); | ||
| } | ||
|
|
||
| if t.tcfg.cross_checks { | ||
| let xcheck_plugin_args = t | ||
| .tcfg | ||
| .cross_check_configs | ||
| .iter() | ||
| .map(|config_file| mk().meta_namevalue("config_file", mk().str_lit(config_file))) | ||
| .collect::<Vec<_>>(); | ||
| let xcheck_plugin_item = mk().meta_list("c2rust_xcheck_plugin", xcheck_plugin_args); | ||
| let plugin_args = vec![xcheck_plugin_item]; | ||
| let plugin_item = mk().meta_list("plugin", plugin_args); | ||
| let attr = mk().attribute(AttrStyle::Inner(Default::default()), plugin_item); | ||
| out_attrs.push(attr); | ||
| } | ||
|
|
||
| if t.tcfg.emit_no_std { | ||
| let meta = mk().meta_path("no_std"); | ||
| let attr = mk().attribute(AttrStyle::Inner(Default::default()), meta); | ||
|
|
@@ -1247,6 +1261,24 @@ fn arrange_header(t: &Translation, is_binary: bool) -> (Vec<syn::Attribute>, Vec | |
| } | ||
| } | ||
|
|
||
| if t.tcfg.cross_checks { | ||
| out_items.push( | ||
| mk().single_attr("macro_use") | ||
| .extern_crate_item("c2rust_xcheck_derive", None), | ||
| ); | ||
| out_items.push( | ||
| mk().single_attr("macro_use") | ||
| .extern_crate_item("c2rust_xcheck_runtime", None), | ||
| ); | ||
|
Comment on lines
+1265
to
+1272
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need |
||
| // When cross-checking, always use the system allocator | ||
| let sys_alloc_path = vec!["", "std", "alloc", "System"]; | ||
| out_items.push(mk().single_attr("global_allocator").static_item( | ||
| "C2RUST_ALLOC", | ||
| mk().path_ty(sys_alloc_path.clone()), | ||
| mk().path_expr(sys_alloc_path), | ||
| )); | ||
| } | ||
|
|
||
| // TODO: switch to `#[expect(unused_imports, reason = ...)]` once | ||
| // we upgrade to a newer nightly (Rust 1.81) that supports it. | ||
| out_items.push( | ||
|
|
@@ -1432,6 +1464,10 @@ impl<'c> Translation<'c> { | |
| "unused_assignments", | ||
| ], | ||
| )]; | ||
| if self.tcfg.cross_checks { | ||
| features.append(&mut vec!["plugin"]); | ||
| pragmas.push(("cross_check", vec!["yes"])); | ||
| } | ||
|
|
||
| if self.features.borrow().contains("register_tool") { | ||
| pragmas.push(("register_tool", vec!["c2rust"])); | ||
|
|
@@ -1465,6 +1501,14 @@ impl<'c> Translation<'c> { | |
| )) | ||
| } | ||
|
|
||
| fn mk_cross_check(&self, mk: Builder, args: Vec<&str>) -> Builder { | ||
| if self.tcfg.cross_checks { | ||
| mk.call_attr("cross_check", args) | ||
| } else { | ||
| mk | ||
| } | ||
| } | ||
|
|
||
| fn static_initializer_is_unsafe(&self, expr_id: Option<CExprId>, qty: CQualTypeId) -> bool { | ||
| // SIMD types are always unsafe in statics | ||
| match self.ast_context.resolve_type(qty.ctype).kind { | ||
|
|
@@ -1660,7 +1704,11 @@ impl<'c> Translation<'c> { | |
| let fn_decl = mk().fn_decl(fn_name.clone(), vec![], None, fn_ty.clone()); | ||
| let fn_bare_decl = (vec![], None, fn_ty); | ||
| let fn_block = mk().block(sectioned_static_initializers); | ||
| let fn_item = mk().unsafe_().extern_("C").fn_item(fn_decl, fn_block); | ||
| let fn_attributes = self.mk_cross_check(mk(), vec!["none"]); | ||
| let fn_item = fn_attributes | ||
| .unsafe_() | ||
| .extern_("C") | ||
| .fn_item(fn_decl, fn_block); | ||
|
|
||
| let static_attributes = mk() | ||
| .single_attr("used") | ||
|
|
@@ -2418,7 +2466,10 @@ impl<'c> Translation<'c> { | |
|
|
||
| // Only add linkage attributes if the function is `extern` | ||
| let mut mk_ = if is_main { | ||
| mk() | ||
| // Cross-check this function as if it was called `main` | ||
| // FIXME: pass in a vector of NestedMetaItem elements, | ||
| // but strings have to do for now | ||
| self.mk_cross_check(mk(), vec!["entry(djb2=\"main\")", "exit(djb2=\"main\")"]) | ||
| } else if (is_global && !is_inline) || is_extern_inline { | ||
| mk_linkage(false, new_name, name).extern_("C").pub_() | ||
| } else if self.cur_file.get().is_some() { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| This is the top-level directory for all cross-checking components, and contains the following: | ||
|
|
||
| * A clang plugin that automatically inserts cross-check instrumentation into C code. | ||
|
|
||
| * An equivalent rustc compiler plugin for Rust. | ||
|
|
||
| * The `libfakechecks` cross-checking backend library that prints out all cross-checks to standard output. | ||
| This library is supported by both the C and Rust compiler plugins. | ||
|
|
||
| * Our experimental fork of the `ReMon` MVEE modified for C/Rust side-by-side checking, | ||
| along with the `mvee-configs` directory that contains some MVEE configuration examples. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| cmake_minimum_required(VERSION 3.8) | ||
|
|
||
| find_package(Clang REQUIRED CONFIG) | ||
|
|
||
| add_definitions(${CLANG_DEFINITIONS} ${LLVM_DEFINITIONS}) | ||
| include_directories(${CLANG_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS}) | ||
|
|
||
| find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} | ||
| NO_DEFAULT_PATH) | ||
|
|
||
| # TableGen needs this | ||
| # Find "llvm/Option/OptParser.td" for Options.td, | ||
| # since LLVM_MAIN_INCLUDE_DIR needs to be a single path | ||
| find_path(LLVM_OPT_PARSER_PATH OptParser.td | ||
| PATHS ${LLVM_INCLUDE_DIRS} | ||
| PATH_SUFFIXES llvm/Option | ||
| NO_DEFAULT_PATH | ||
| ) | ||
| get_filename_component(LLVM_INCLUDE_LLVM_DIR | ||
| ${LLVM_OPT_PARSER_PATH} DIRECTORY) | ||
| get_filename_component(LLVM_MAIN_INCLUDE_DIR | ||
| ${LLVM_INCLUDE_LLVM_DIR} DIRECTORY) | ||
| set(CMAKE_INCLUDE_CURRENT_DIR ON) | ||
|
|
||
| # Needed for add_llvm_loadable_module | ||
| list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") | ||
| include(AddLLVM) | ||
| include(TableGen) | ||
| include(HandleLLVMOptions) | ||
|
|
||
| add_subdirectory(plugin) | ||
| add_subdirectory(runtime) | ||
| add_subdirectory(test) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
|
|
||
| TEST_CFLAGS=-g -O2 | ||
|
|
||
| #PLUGIN_PATH := $(shell find . -name CrossChecks.so) | ||
| #RUNTIME_PATH := $(shell find . -name libruntime.a) | ||
| PLUGIN_PATH := $(realpath ../../../build/clang-xcheck-plugin.$(shell uname -n)/plugin/CrossChecks.so) | ||
| RUNTIME_PATH := $(realpath ../../../build/clang-xcheck-plugin.$(shell uname -n)/runtime/libruntime.a) | ||
|
|
||
| # Override this to change the path to the clang binary | ||
| #PLUGIN_CC := clang | ||
| PLUGIN_CC := $(realpath ../../../build/llvm-6.0.0/build.$(shell uname -n)/bin/clang) | ||
|
|
||
| PLUGIN_CC_ARGS := -Xclang -plugin-arg-crosschecks -Xclang -Ctest.c2r | ||
|
|
||
| ifneq ($(filter yes true,$(DUMP_AST)),) | ||
| PLUGIN_CC_ARGS += -Xclang -ast-dump | ||
| endif | ||
|
|
||
| ifneq ($(filter yes true,$(DUMP_LLVM)),) | ||
| PLUGIN_CC_ARGS += -S -emit-llvm | ||
| endif | ||
|
|
||
| FAKECHECKS_PATH=`pwd`/../../libfakechecks | ||
|
|
||
| .PHONY: clean all test.bin | ||
| all: test.bin | ||
|
|
||
| clean: | ||
| rm -f test.bin | ||
|
|
||
| test.bin: test.c | ||
| @echo Building test... | ||
| ./cc_wrapper.sh $(PLUGIN_CC) $(PLUGIN_PATH) $(PLUGIN_CC_ARGS) -ffunction-sections -fuse-ld=gold -Wl,--gc-sections,--icf=safe,-rpath,$(FAKECHECKS_PATH) -L$(FAKECHECKS_PATH) -lfakechecks -std=c11 -Iinclude $(TEST_CFLAGS) -o test.bin $< $(RUNTIME_PATH) | ||
| @echo Running test... | ||
| ./test.bin |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Clang plugin for crosschecking on C programs | ||
|
|
||
| This is a cross-check inserter for C programs implemented as a clang compiler plugin. | ||
|
|
||
| ## Building and running the plugin | ||
|
|
||
| 1. Build `libfakechecks` (optional, useful for testing): | ||
| ```bash | ||
| $ cd ../../libfakechecks | ||
| $ make all | ||
| ``` | ||
|
|
||
| 2. Build the clang plugin using the build script: | ||
| ```bash | ||
| $ ../../../scripts/build_cross_checks.py | ||
| ``` | ||
|
|
||
| 3. To compile code using the plugin, either wrap the compilation command with the `cc_wrapper.sh` script from this directory: | ||
| ```bash | ||
| $ cc_wrapper.sh <path/to/clang> .../CrossChecks.so <rest of command line...> | ||
| ``` | ||
| or add the following arguments manually to the clang command line, e.g., using `CFLAGS`: | ||
| ``` | ||
| -Xclang -load -Xclang .../CrossChecks.so -Xclang -add-plugin -Xclang crosschecks | ||
| ``` | ||
| and link against `libruntime.a`. | ||
| In both cases, the target binary must then be linked against one of the `rb_xcheck` implementation libraries: `libfakechecks.so` or `libclevrbuf.so`. | ||
|
|
||
| ## Testing | ||
|
|
||
| This plugin can be tested in this directory by running `make test`. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, what's the reason for
"*"instead of a specific version?