Sitelet https://github.com/starkware-libs/cairo/commit/ac2d27e4fa25926507d2d05188c9235bfb35631f
Skip to content

Commit ac2d27e

Browse files
authored
Preventing infinite inlining of cycle functions. (#9917)
1 parent 80505cc commit ac2d27e

4 files changed

Lines changed: 55 additions & 12 deletions

File tree

‎crates/cairo-lang-lowering/src/inline/mod.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub fn priv_should_inline<'db>(
7272
| ConcreteFunctionWithBodyLongId::Generated(_) => function_id,
7373
ConcreteFunctionWithBodyLongId::Specialized(specialized) => specialized.long(db).base,
7474
};
75-
if db.concrete_in_cycle(base, DependencyType::Call, LoweringStage::Monomorphized)? {
75+
if db.concrete_in_cycle(base, DependencyType::Call, LoweringStage::PreOptimizations)? {
7676
return Ok(false);
7777
}
7878

@@ -357,8 +357,6 @@ where
357357
return Ok(Some((stmt, called_func)));
358358
}
359359

360-
// TODO: Implement better logic to avoid inlining of destructors that call
361-
// themselves.
362360
if called_func != calling_function_id && db.priv_should_inline(called_func)? {
363361
return Ok(Some((stmt, called_func)));
364362
}

‎crates/cairo-lang-lowering/src/test.rs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,18 @@ cairo_lang_test_utils::test_file_test!(
6060
for_: "for",
6161
},
6262
test_function_lowering,
63-
["expect_diagnostics"]
63+
["expect_diagnostics", "no_gas"]
6464
);
6565

6666
fn test_function_lowering(
6767
inputs: &OrderedHashMap<String, String>,
6868
args: &OrderedHashMap<String, String>,
6969
) -> TestRunnerResult {
70-
let db = &mut LoweringDatabaseForTesting::default();
70+
let db = &mut if args.get("no_gas").map(|s| s.trim()) == Some("true") {
71+
LoweringDatabaseForTesting::with_no_gas()
72+
} else {
73+
LoweringDatabaseForTesting::default()
74+
};
7175
let (test_function, semantic_diagnostics) = setup_test_function(db, inputs).split();
7276
let function_id =
7377
ConcreteFunctionWithBodyId::from_semantic(db, test_function.concrete_function_id);

‎crates/cairo-lang-lowering/src/test_data/cycles‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,37 @@ blk0 (root):
170170
Statements:
171171
End:
172172
Return()
173+
174+
//! > ==========================================================================
175+
176+
//! > Test self-referential Destruct impl in no-gas mode does not hang (issue #9894).
177+
178+
//! > test_runner_name
179+
test_function_lowering(expect_diagnostics: false, no_gas: true)
180+
181+
//! > function_code
182+
fn foo() {
183+
let _ = D {};
184+
}
185+
186+
//! > function_name
187+
foo
188+
189+
//! > module_code
190+
struct D {}
191+
impl DDestruct of Destruct<D> {
192+
fn destruct(self: D) nopanic {}
193+
}
194+
195+
//! > semantic_diagnostics
196+
197+
//! > lowering_diagnostics
198+
199+
//! > lowering_flat
200+
Parameters:
201+
blk0 (root):
202+
Statements:
203+
(v0: test::D) <- struct_construct()
204+
() <- test::DDestruct::destruct(v0)
205+
End:
206+
Return()

‎crates/cairo-lang-lowering/src/test_utils.rs‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,25 @@ impl LoweringDatabaseForTesting {
5050
}
5151
}
5252

53-
pub static SHARED_DB: LazyLock<Mutex<LoweringDatabaseForTesting>> =
53+
static SHARED_DB: LazyLock<Mutex<LoweringDatabaseForTesting>> =
5454
LazyLock::new(|| Mutex::new(LoweringDatabaseForTesting::new()));
55-
pub static SHARED_DB_FUTURE_SIERRA: LazyLock<Mutex<LoweringDatabaseForTesting>> =
56-
LazyLock::new(|| {
57-
let mut db = LoweringDatabaseForTesting::new();
58-
db.set_flag(FlagLongId(Flag::FUTURE_SIERRA.into()), Some(Flag::FutureSierra(true)));
59-
Mutex::new(db)
60-
});
55+
static SHARED_DB_NO_GAS: LazyLock<Mutex<LoweringDatabaseForTesting>> = LazyLock::new(|| {
56+
let mut db = LoweringDatabaseForTesting::new();
57+
db.set_flag(FlagLongId(Flag::ADD_WITHDRAW_GAS.into()), Some(Flag::AddWithdrawGas(false)));
58+
Mutex::new(db)
59+
});
60+
static SHARED_DB_FUTURE_SIERRA: LazyLock<Mutex<LoweringDatabaseForTesting>> = LazyLock::new(|| {
61+
let mut db = LoweringDatabaseForTesting::new();
62+
db.set_flag(FlagLongId(Flag::FUTURE_SIERRA.into()), Some(Flag::FutureSierra(true)));
63+
Mutex::new(db)
64+
});
6165
impl LoweringDatabaseForTesting {
6266
pub fn with_future_sierra() -> Self {
6367
SHARED_DB_FUTURE_SIERRA.lock().unwrap().snapshot()
6468
}
69+
pub fn with_no_gas() -> Self {
70+
SHARED_DB_NO_GAS.lock().unwrap().snapshot()
71+
}
6572
}
6673
impl Default for LoweringDatabaseForTesting {
6774
fn default() -> Self {

0 commit comments

Comments
 (0)