From 27041e74d65b53f1b2d785ab8d0874aa04459a3c Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sun, 8 Mar 2026 00:28:28 +0100 Subject: [PATCH 1/3] * add 'Block that isn't BBJ_RETURN should not contain GT_RETURN node.' * add 'If the block contains a GT_RETURN node it should be last.' --- src/coreclr/jit/fgdiagnostic.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 275d0775045cab..3e8cb8a13c83f0 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -3064,6 +3064,28 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef assert(succBlock->bbTraversalStamp == curTraversalStamp); } + // Block that isn't BBJ_RETURN should not contain GT_RETURN node. + if (!block->KindIs(BBJ_RETURN)) + { + for (Statement* const stmt : block->Statements()) + { + GenTree* tree = stmt->GetRootNode(); + assert(!tree->OperIs(GT_RETURN)); + } + } + + // If the block contains a GT_RETURN node it should be last. + if (block->KindIs(BBJ_RETURN)) + { + for (Statement* const stmt : block->Statements()) + { + GenTree* tree = stmt->GetRootNode(); + bool isReturn = tree->OperIs(GT_RETURN); + bool isLastStmt = stmt->GetNextStmt() == nullptr; + assert(!(isReturn && !isLastStmt)); + } + } + // If the block is a BBJ_COND, a BBJ_SWITCH or a // lowered GT_SWITCH_TABLE node then make sure it // ends with a conditional jump or a GT_SWITCH From cf451bbc38c79c838a0815047e1c75eb6fa181d7 Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sun, 8 Mar 2026 01:01:25 +0100 Subject: [PATCH 2/3] * move from fgDebugCheckBBlist to fgDebugCheckStmtsList --- src/coreclr/jit/fgdiagnostic.cpp | 39 ++++++++++++++------------------ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 3e8cb8a13c83f0..8e25a6118016d5 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -3064,28 +3064,6 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef assert(succBlock->bbTraversalStamp == curTraversalStamp); } - // Block that isn't BBJ_RETURN should not contain GT_RETURN node. - if (!block->KindIs(BBJ_RETURN)) - { - for (Statement* const stmt : block->Statements()) - { - GenTree* tree = stmt->GetRootNode(); - assert(!tree->OperIs(GT_RETURN)); - } - } - - // If the block contains a GT_RETURN node it should be last. - if (block->KindIs(BBJ_RETURN)) - { - for (Statement* const stmt : block->Statements()) - { - GenTree* tree = stmt->GetRootNode(); - bool isReturn = tree->OperIs(GT_RETURN); - bool isLastStmt = stmt->GetNextStmt() == nullptr; - assert(!(isReturn && !isLastStmt)); - } - } - // If the block is a BBJ_COND, a BBJ_SWITCH or a // lowered GT_SWITCH_TABLE node then make sure it // ends with a conditional jump or a GT_SWITCH @@ -3951,6 +3929,7 @@ void Compiler::fgDebugCheckLinks(bool morphTrees) // - all statements in the block are linked correctly // - check statements flags // - check nodes gtNext and gtPrev values, if the node list is threaded +// - no invalid statements given the block kind // // Arguments: // block - the block to check statements in @@ -3987,6 +3966,22 @@ void Compiler::fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees) noway_assert(block->lastStmt() == stmt); } + // Block that isn't BBJ_RETURN should not contain GT_RETURN node. + if (!block->KindIs(BBJ_RETURN)) + { + GenTree* tree = stmt->GetRootNode(); + assert(!tree->OperIs(GT_RETURN)); + } + + // If the block contains a GT_RETURN node it should be last. + if (block->KindIs(BBJ_RETURN)) + { + GenTree* tree = stmt->GetRootNode(); + bool isReturn = tree->OperIs(GT_RETURN); + bool isNotLastStmt = stmt->GetNextStmt() != nullptr; + assert(!(isReturn && isNotLastStmt)); + } + // For each statement check that the exception flags are properly set noway_assert(stmt->GetRootNode()); From 9f61468edf1417890bfb590e0ba9c48e9bc3f188 Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sun, 8 Mar 2026 01:10:08 +0100 Subject: [PATCH 3/3] * add description to assert --- src/coreclr/jit/fgdiagnostic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 8e25a6118016d5..8a8cb8b8eae203 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -3970,7 +3970,7 @@ void Compiler::fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees) if (!block->KindIs(BBJ_RETURN)) { GenTree* tree = stmt->GetRootNode(); - assert(!tree->OperIs(GT_RETURN)); + assert(!tree->OperIs(GT_RETURN) && "GT_RETURN node found in a block that isn't BBJ_RETURN"); } // If the block contains a GT_RETURN node it should be last. @@ -3979,7 +3979,7 @@ void Compiler::fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees) GenTree* tree = stmt->GetRootNode(); bool isReturn = tree->OperIs(GT_RETURN); bool isNotLastStmt = stmt->GetNextStmt() != nullptr; - assert(!(isReturn && isNotLastStmt)); + assert(!(isReturn && isNotLastStmt) && "GT_RETURN node found that is not the last statement in the block"); } // For each statement check that the exception flags are properly set