Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cargo-vet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
run: echo "${{ runner.tool_cache }}/cargo-vet/bin" >> $GITHUB_PATH

- name: Ensure that the tool cache is populated with the cargo-vet binary
run: cargo install --root ${{ runner.tool_cache }}/cargo-vet --version ${{ env.CARGO_VET_VERSION }} cargo-vet
run: cargo +stable install --root ${{ runner.tool_cache }}/cargo-vet --version ${{ env.CARGO_VET_VERSION }} cargo-vet

- name: Invoke cargo-vet
run: cargo vet --locked
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version = "0.1.0"
description = "Call graph analysis tool for Rust"
repository = "https://github.com/OpenDevicePartnership/cga"
authors = ["Wouter Geraedts <w.geraedts@sarif.n>"]
readme = "README.md"
license = "MIT"
keywords = ["lint", "plugin"]
categories = ["development-tools", "development-tools::cargo-plugins"]
Expand Down
4 changes: 2 additions & 2 deletions bin/cga-driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ fn main() -> ExitCode {
.is_some();

if ignore {
rustc_driver::run_compiler(&args, &mut rustc_driver::TimePassesCallbacks::default());
rustc_driver::compiler_entrypoint(&args, &mut rustc_driver::TimePassesCallbacks::default());
} else {
rustc_driver::run_compiler(&args, &mut Cga)
rustc_driver::compiler_entrypoint(&args, &mut Cga)
}
})
}
6 changes: 3 additions & 3 deletions cga_analysis/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use cga_data::cmd::LintConfig;
use indexmap::{IndexMap, IndexSet};
use itertools::Itertools;
use rustc_attr_ir::lang_items::LangItem;
use rustc_errors::{Diag, MultiSpan};
use rustc_hir::LangItem;
use rustc_lint::Lint;
use rustc_log::tracing::*;
use rustc_middle::ty::TyCtxt;
Expand Down Expand Up @@ -245,7 +245,7 @@ fn decorate_expansion(use_: &Use<'_>, multi_span: &mut MultiSpan) {
}

/// Decorate with extra notes if the leaf node is a panic associated with an async coroutine
fn decorate_leaf(use_: &Use<'_>, diag: &mut Diag<'_, ()>) {
fn decorate_leaf(use_: &Use<'_>, diag: &mut Diag<'_>) {
match use_.kind {
UseKind::AsyncPanic => {
diag.note("an async block can always panic when poll'd after Ready");
Expand All @@ -255,7 +255,7 @@ fn decorate_leaf(use_: &Use<'_>, diag: &mut Diag<'_, ()>) {
}

/// Decorate with extra notes if the boundary is not a straightforward function call
fn decorate_cast(use_: &Use<'_>, diag: &mut Diag<'_, ()>) {
fn decorate_cast(use_: &Use<'_>, diag: &mut Diag<'_>) {
if matches!(use_.kind, UseKind::FnPtrCast(..)) {
diag.note("once a function is cast to a function pointer, cga can no longer tell how it is used");
diag.note("as a precaution, it must assume you will eventually call the function");
Expand Down
4 changes: 3 additions & 1 deletion cga_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(impl_trait_in_assoc_type)]

extern crate rustc_abi;
extern crate rustc_attr_ir;
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_errors;
Expand All @@ -10,6 +11,7 @@ extern crate rustc_index;
extern crate rustc_infer;
extern crate rustc_interface;
extern crate rustc_lint;
extern crate rustc_lint_defs;
extern crate rustc_log;
extern crate rustc_macros;
extern crate rustc_middle;
Expand All @@ -32,11 +34,11 @@ pub mod monomorphize;
pub mod post_mono;

use rustc_hir::{HirId, def_id::DefId};
use rustc_lint_defs::declare_tool_lint;
use rustc_middle::{
mir::{Body, SourceInfo},
ty::{Instance, TyCtxt, print::with_resolve_crate_name},
};
use rustc_session::declare_tool_lint;
use rustc_span::Span;

declare_tool_lint! {
Expand Down
28 changes: 13 additions & 15 deletions cga_analysis/src/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
//!
//! `NoConstOrStatic` has been added, as well as an extra check for the existence of the `no_mangle` and `export_name` attributes.

use rustc_attr_ir::{HasAttrs, InlineAttr, lang_items::LangItem};
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::{
ImplItemId, ItemId, LangItem,
attrs::{HasAttrs, InlineAttr},
ImplItemId, ItemId,
def::DefKind,
def_id::{DefId, LocalDefId},
};
use rustc_middle::{
bug,
middle::codegen_fn_attrs::CodegenFnAttrFlags,
mir::{self},
mono::MonoItem,
Expand All @@ -24,7 +23,7 @@ use rustc_middle::{
ty::GenericArgs,
};
use rustc_session::config::EntryFnType;
use rustc_span::{DUMMY_SP, Span, Spanned, dummy_spanned, respan};
use rustc_span::{DUMMY_SP, Span, Spanned, bug, dummy_spanned, respan};
use rustc_type_ir::TypeVisitableExt;

use rustc_log::tracing::*;
Expand Down Expand Up @@ -155,7 +154,7 @@ impl<'v> RootCollector<'_, 'v> {
// generate a `drop_in_place` instance for it.
if self
.tcx
.instantiate_and_check_impossible_predicates((id.owner_id.to_def_id(), id_args))
.instantiate_and_check_impossible_clauses((id.owner_id.to_def_id(), id_args))
{
return;
}
Expand Down Expand Up @@ -193,7 +192,7 @@ impl<'v> RootCollector<'_, 'v> {
let def_id = id.owner_id.to_def_id();
// Type Consts don't have bodies to evaluate
// nor do they make sense as a static.
if self.tcx.is_type_const(def_id) {
if self.tcx.const_of_item(def_id).is_some() {
// FIXME(mgca): Is this actually what we want? We may want to
// normalize to a ValTree then convert to a const allocation and
// collect that?
Expand Down Expand Up @@ -308,7 +307,7 @@ impl<'v> RootCollector<'_, 'v> {
}

let has_export_link_name = HasAttrs::get_attrs(def_id, &self.tcx).iter().any(|attr| match attr {
rustc_hir::Attribute::Parsed(rustc_hir::attrs::AttributeKind::ExportName { .. }) => true,
rustc_attr_ir::Attribute::Parsed(rustc_attr_ir::AttributeKind::ExportName { .. }) => true,
_ => false,
});
let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
Expand Down Expand Up @@ -428,7 +427,7 @@ fn visit_instance_use<'tcx>(
}

match instance.def {
ty::InstanceKind::Virtual(..) | ty::InstanceKind::Intrinsic(_) => {
ty::InstanceKind::Virtual(..) | ty::InstanceKind::LlvmIntrinsic(_) | ty::InstanceKind::Intrinsic(_) => {
if !is_direct_call {
bug!("{:?} being reified", instance);
}
Expand Down Expand Up @@ -456,7 +455,8 @@ fn visit_instance_use<'tcx>(
| ty::ShimKind::ConstructCoroutineInClosure { .. }
| ty::ShimKind::FnPtr(..)
| ty::ShimKind::Clone(..)
| ty::ShimKind::FnPtrAddr(..),
| ty::ShimKind::FnPtrAsPtr(..)
| ty::ShimKind::FnPtrFromPtr(..),
)
| ty::InstanceKind::Item(..) => {
output.push(create_fn_mono_item(tcx, instance, source));
Expand Down Expand Up @@ -484,11 +484,9 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
let ptrs = alloc.inner().provenance().ptrs();
// avoid `ensure_sufficient_stack` in the common case of "no pointers"
if !ptrs.is_empty() {
rustc_data_structures::stack::ensure_sufficient_stack(move || {
for &prov in ptrs.values() {
collect_alloc(tcx, prov.alloc_id(), output);
}
});
for &prov in ptrs.values() {
collect_alloc(tcx, prov.alloc_id(), output);
}
}
}
GlobalAlloc::Function { instance, .. } => {
Expand Down Expand Up @@ -547,7 +545,7 @@ fn create_mono_items_for_default_impls<'tcx>(tcx: TyCtxt<'tcx>, item: ItemId, ou
// consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to
// be trivially false. We must now check that the impl has no impossible-to-satisfy
// predicates.
if tcx.instantiate_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_args)) {
if tcx.instantiate_and_check_impossible_clauses((item.owner_id.to_def_id(), impl_args)) {
return;
}

Expand Down
3 changes: 1 addition & 2 deletions cga_analysis/src/post_mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ use rustc_hir::{CoroutineDesugaring, CoroutineKind, def_id::DefId};
use rustc_log::tracing::*;
use rustc_middle::mir::{self, Body, CastKind, Location, Rvalue, Terminator, TerminatorKind, visit::Visitor as _};
use rustc_middle::mono::MonoItem;
use rustc_middle::span_bug;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{
self, EarlyBinder, GenericArgsRef, Instance, InstanceKind, ShimKind, TyCtxt, TypeFoldable, TypingEnv,
};
use rustc_span::Span;
use rustc_span::{Span, span_bug};
use rustc_type_ir::CoroutineArgs;

use crate::dyn_object::dyn_object_call_to_impl_methods;
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[toolchain]
channel = "nightly-2026-07-15"
channel = "nightly-2026-10-18"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt", "clippy"]
profile = "minimal"
targets = ["thumbv8m.main-none-eabihf"]
10 changes: 5 additions & 5 deletions tests/ui-cargo/fail-blacklist/Cargo.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ error: call to associated function `std::process::Command::new` which can panic
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: 11 different panics from this location
= note: backtrace (1 of 1863650189):
= note: backtrace (1 of 2021126033):
0: std::rt::panic_fmt (called)
1: alloc::raw_vec::RawVec::<u8>::into_box (called)
2: std::vec::Vec::<u8>::into_boxed_slice (called)
Expand All @@ -24,7 +24,7 @@ error: call to drop of `std::process::Command` which can panic
| ^
|
= note: 11 different panics from this location
= note: backtrace (1 of 1863680573):
= note: backtrace (1 of 2021158477):
0: core::panicking::panic_nounwind_fmt (called)
1: <usize as std::slice::SliceIndex<[T]>>::get_unchecked_mut::precondition_check (called)
2: <usize as std::slice::SliceIndex<[u8]>>::get_unchecked_mut (called)
Expand All @@ -42,7 +42,7 @@ error: call to associated function `std::process::Command::new` which is blackli
7 | let _ = std::process::Command::new("evil");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: 101 different blacklisted functions from this location
= note: 99 different blacklisted functions from this location
= note: backtrace:
0: std::process::Command::new::<&str> (called) <--
1: fail_blacklist::test (called)
Expand All @@ -59,8 +59,8 @@ error: call to drop of `std::process::Command` which can call blacklisted functi
7 | let _ = std::process::Command::new("evil");
| ^
|
= note: 101 different blacklisted functions from this location
= note: backtrace (1 of 20283553):
= note: 99 different blacklisted functions from this location
= note: backtrace (1 of 20629713):
0: std::sys::fs::unix::debug_assert_fd_is_open (called)
1: <std::os::fd::OwnedFd as std::ops::Drop>::drop (called)
2: drop of `std::os::fd::OwnedFd` (called)
Expand Down
17 changes: 9 additions & 8 deletions tests/ui-cargo/fail-embedded/Cargo.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ error: call to method `embassy_executor::Executor::run` which can panic
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expanded from here
|
= note: 10 different panics from this location
= note: backtrace (1 of 16511908):
= note: backtrace (1 of 17414139):
0: core::panicking::panic_fmt (called)
1: core::result::unwrap_failed (called)
2: core::result::Result::<embassy_executor::SpawnToken<{closure@src/main.rs:11:1: 11:26}>, embassy_executor::SpawnError>::unwrap (called)
3: fail_embedded::__cortex_m_rt_main::{closure#0} (called)
4: embassy_executor::Executor::run::<{closure@src/main.rs:11:1: 11:26}> (called) <--
5: fail_embedded::__cortex_m_rt_main (called)
6: fail_embedded::__cortex_m_rt_main_trampoline (entrypoint)
1: core::result::unwrap_failed::unwrap_failed_inner (called)
2: core::result::unwrap_failed::<embassy_executor::SpawnError> (called)
3: core::result::Result::<embassy_executor::SpawnToken<{closure@src/main.rs:11:1: 11:26}>, embassy_executor::SpawnError>::unwrap (called)
4: fail_embedded::__cortex_m_rt_main::{closure#0} (called)
5: embassy_executor::Executor::run::<{closure@src/main.rs:11:1: 11:26}> (called) <--
6: fail_embedded::__cortex_m_rt_main (called)
7: fail_embedded::__cortex_m_rt_main_trampoline (entrypoint)
= note: `#[deny(cga::panics)]` on by default
= note: this error originates in the attribute macro `embassy_executor::main` (in Nightly builds, run with -Z macro-backtrace for more info)

Expand All @@ -25,7 +26,7 @@ error: call to function `embassy_rp::init` which can panic
= note: 7 different panics from this location
= note: backtrace (1 of 721):
0: core::panicking::panic_fmt (called)
1: core::sync::atomic::atomic_store::<u32> (called)
1: core::sync::atomic::atomic_store::<u32, false> (called)
2: core::sync::atomic::Atomic::<u32>::store (called)
3: embassy_rp::clocks::init (called)
4: embassy_rp::init (called) <--
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/large_std_process.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | let _ = std::process::Command::new("evil");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: 11 different panics from this location
= note: backtrace (1 of 1863650189):
= note: backtrace (1 of 2021126033):
0: std::rt::panic_fmt (called)
1: alloc::raw_vec::RawVec::<u8>::into_box (called)
2: std::vec::Vec::<u8>::into_boxed_slice (called)
Expand All @@ -24,7 +24,7 @@ LL | let _ = std::process::Command::new("evil");
| ^
|
= note: 11 different panics from this location
= note: backtrace (1 of 1863680573):
= note: backtrace (1 of 2021158477):
0: core::panicking::panic_nounwind_fmt (called)
1: <usize as std::slice::SliceIndex<[T]>>::get_unchecked_mut::precondition_check (called)
2: <usize as std::slice::SliceIndex<[u8]>>::get_unchecked_mut (called)
Expand Down
Loading