Skip to content

Fix CFG builder crash when preprocessor directives span across elsif boundaries#3822

Draft
Copilot wants to merge 4 commits intodevelopfrom
copilot/fix-diagnostic-computation-error
Draft

Fix CFG builder crash when preprocessor directives span across elsif boundaries#3822
Copilot wants to merge 4 commits intodevelopfrom
copilot/fix-diagnostic-computation-error

Conversation

Copy link
Contributor

Copilot AI commented Feb 17, 2026

  • Analyze the bug: AllFunctionPathMustHaveReturn crashes when preprocessor #Если/#КонецЕсли wraps ИначеЕсли branches in an If statement
  • Identify root cause: When a statement-level #Если in one elsif branch's codeBlock does not have a matching #КонецЕсли in the same codeBlock (because it spans across elsif boundaries), the CFG builder's block stack becomes unbalanced, leading to NoSuchElementException or FlowGraphLinkException
  • Fix CfgBuildingParseTreeVisitor.visitPreproc_if() to check whether matching #КонецЕсли exists in the same codeBlock before creating graph nodes
  • Add hasMatchingEndIfInSameCodeBlock() helper method to detect unbalanced preprocessor blocks
  • Add comprehensive tests verifying the diagnostic correctly finds missing returns in complex if-expressions with cross-boundary preprocessor directives:
    • No crash on the original bug pattern (return+raise coverage)
    • Detects missing return outside preprocessor block
    • Detects missing return in branches not wrapped by preprocessor
    • No false positives when all branches have returns
    • Handles multiple consecutive preprocessor blocks wrapping elsifs
  • Run all related tests (AllFunctionPathMustHaveReturnDiagnosticTest, ControlFlowGraphBuilderTest, UnreachableCodeDiagnosticTest) - all pass
Original prompt

This section details on the original issue you should resolve

<issue_title>[BUG] Diagnostic computation error при проверке AllFunctionPathMustHaveReturn</issue_title>
<issue_description>## Диагностика
AllFunctionPathMustHaveReturn

Версия

BSLLS v0.28.4 (расширение 1c-syntax.language-1c-bsl для VS Code)

Описание ошибки диагностики

При анализе модуля адаптер_ОбщегоНазначенияСервер/Ext/Module.bsl происходит Diagnostic computation error вместо нормального результата проверки. В Output BSL Language Server:

[ERROR] [diagnostic-computer] [com.github._1c_syntax.bsl.languageserver.context.computer.DiagnosticComputer]: Diagnostic computation error.
File: file:///.../адаптер_ОбщегоНазначенияСервер/Ext/Module.bsl
Diagnostic: Either [
  left = AllFunctionPathMustHaveReturn
  right = null
]

Пример кода

Возможный источник - функция МенеджерОбъектаПоИмени с директивой препроцессора #Если и большой цепочкой ИначеЕсли:

//@skip-warning
Функция МенеджерОбъектаПоИмени(Имя)
	Перем КлассОМ, ИмяОМ, Менеджер;
	
	ЧастиИмени = СтрРазделить(Имя, ".");
	
	Если ЧастиИмени.Количество() > 0 Тогда
		КлассОМ = ВРег(ЧастиИмени[0]);
	КонецЕсли;
	
	Если ЧастиИмени.Количество() > 1 Тогда
		ИмяОМ = ЧастиИмени[1];
	КонецЕсли;
	
	Если      КлассОМ = "ПЛАНОБМЕНА" Или КлассОМ = "ПЛАНЫОБМЕНА" Тогда
		Менеджер = ПланыОбмена;
	ИначеЕсли КлассОМ = "СПРАВОЧНИК" Или КлассОМ = "СПРАВОЧНИКИ" Тогда
		Менеджер = Справочники;
	// ... много ИначеЕсли ...
	#Если НЕ МобильноеПриложениеСервер Тогда
	ИначеЕсли КлассОМ = "ОТЧЕТ" Или КлассОМ = "ОТЧЕТЫ" Тогда
		Менеджер = Отчеты;
	// ... и т.д.
	#КонецЕсли
	КонецЕсли;
	
	Если Менеджер <> Неопределено Тогда
		// ...
		Возврат ...;
	КонецЕсли;
	
	ВызватьИсключение СтрШаблон(...);
	
КонецФункции

Скриншоты

Дополнительная информация

Ошибка воспроизводится в VS Code и в SonarQube (Jenkins pipeline).
Файл: src/cfe/БИТАдаптер/CommonModules/адаптер_ОбщегоНазначенияСервер/Ext/Module.bsl.
Возможные причины: обработка #Если, длинная цепочка ИначеЕсли и сложное управление потоком (return/exception).

Diagnostic error.zip
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 17, 2026 10:03
…sif boundaries

When #Если/#КонецЕсли preprocessor directives wrap ИначеЕсли branches
at the same level as the if statement, the CFG builder's block stack
becomes unbalanced because the preprocessor enter/leave block pairs
span across different codeBlock scopes.

Fix: detect when a statement-level preproc_if does not have a matching
preproc_endif in the same codeBlock, and skip CFG graph manipulation
for those unbalanced preprocessor blocks.

Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com>
Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix diagnostic computation error in AllFunctionPathMustHaveReturn Fix CFG builder crash when preprocessor directives span across elsif boundaries Feb 17, 2026
Copilot AI requested a review from nixel2007 February 17, 2026 10:10
@nixel2007
Copy link
Member

@copilot из фикса не понятно, работает ли теперь функциональность поиска возвратав ветках. Напиши тесты на такие сложные if-выражения, где диагностика корректно находит ветки с пропушенными возвратами как внутри так и снаружи блока с инструкцией препроцессору

…rocessor directives

Tests verify the diagnostic correctly:
- Finds missing returns outside preprocessor blocks
- Finds missing returns in branches not wrapped by preprocessor
- Produces no false positives when all branches have returns
- Handles multiple consecutive preprocessor blocks wrapping elsifs
- Handles the original bug pattern from the issue (return+raise coverage)

Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 17, 2026

@copilot из фикса не понятно, работает ли теперь функциональность поиска возвратав ветках. Напиши тесты на такие ...

Added 5 test methods in commit eafb162 that verify the diagnostic correctly finds missing returns in complex if-expressions with cross-boundary preprocessor directives:

  • testPreprocessorWrappingElsifBranches_NoError — original bug pattern (return+raise), no crash, no diagnostic
  • testPreprocessorWrappingElsifBranches_MissingReturnOutsidePreprocessor — detects missing return outside the preprocessor block (path ends with a statement but no return/raise)
  • testPreprocessorWrappingElsifBranches_MissingReturnInBranchOutsidePreprocessor — detects missing return in an elsif branch not wrapped by preprocessor (branch has statements but no return)
  • testPreprocessorWrappingElsifBranches_AllBranchesReturn — no false positive when all branches (including preprocessor-wrapped) have returns with an else
  • testPreprocessorWrappingElsifBranches_MultiplePreprocessorBlocks — multiple consecutive preprocessor blocks wrapping different elsifs, no crash, no false positive

@github-actions
Copy link
Contributor

Test Results

 2 907 files  ± 0   2 907 suites  ±0   1h 10m 56s ⏱️ + 1m 23s
 1 238 tests + 5   1 238 ✅ + 5  0 💤 ±0  0 ❌ ±0 
11 142 runs  +45  11 142 ✅ +45  0 💤 ±0  0 ❌ ±0 

Results for commit eafb162. ± Comparison against base commit 5aba0f5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Diagnostic computation error при проверке AllFunctionPathMustHaveReturn

2 participants

Comments