Skip to content

Conversation

steakhal
Copy link
Contributor

@steakhal steakhal commented Oct 2, 2025

Previously, when using -analyze-function to target a specific function, the analyzer would incorrectly report "Every top-level function was skipped" even when the function was successfully analyzed by syntax-only checkers.

This happened because NumFunctionsAnalyzed only counted path-sensitive analysis, not syntax-only analysis. The misuse detection logic would see 0 functions analyzed and incorrectly conclude the function wasn't found.

…checkers

Previously, when using -analyze-function to target a specific function,
the analyzer would incorrectly report "Every top-level function was skipped"
even when the function was successfully analyzed by syntax-only checkers.

This happened because NumFunctionsAnalyzed only counted path-sensitive analysis,
not syntax-only analysis. The misuse detection logic would see 0 functions
analyzed and incorrectly conclude the function wasn't found.
@steakhal steakhal requested review from necto and NagyDonat October 2, 2025 13:25
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Balazs Benics (steakhal)

Changes

Previously, when using -analyze-function to target a specific function, the analyzer would incorrectly report "Every top-level function was skipped" even when the function was successfully analyzed by syntax-only checkers.

This happened because NumFunctionsAnalyzed only counted path-sensitive analysis, not syntax-only analysis. The misuse detection logic would see 0 functions analyzed and incorrectly conclude the function wasn't found.


Full diff: https://github.com/llvm/llvm-project/pull/161664.diff

2 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (+7-3)
  • (modified) clang/test/Analysis/analyze-function-guide.cpp (+11-8)
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 53466e7a75b0f..5906e876aa311 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -51,6 +51,9 @@ STAT_COUNTER(NumFunctionTopLevel, "The # of functions at top level.");
 ALWAYS_ENABLED_STATISTIC(NumFunctionsAnalyzed,
                          "The # of functions and blocks analyzed (as top level "
                          "with inlining turned on).");
+ALWAYS_ENABLED_STATISTIC(
+    NumFunctionsAnalyzedSyntaxOnly,
+    "The # of functions analyzed by syntax checkers only.");
 ALWAYS_ENABLED_STATISTIC(NumBlocksInAnalyzedFunctions,
                          "The # of basic blocks in the analyzed functions.");
 ALWAYS_ENABLED_STATISTIC(
@@ -588,10 +591,10 @@ void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
   // If the user wanted to analyze a specific function and the number of basic
   // blocks analyzed is zero, than the user might not specified the function
   // name correctly.
-  // FIXME: The user might have analyzed the requested function in Syntax mode,
-  // but we are unaware of that.
-  if (!Opts.AnalyzeSpecificFunction.empty() && NumFunctionsAnalyzed == 0)
+  if (!Opts.AnalyzeSpecificFunction.empty() && NumFunctionsAnalyzed == 0 &&
+      NumFunctionsAnalyzedSyntaxOnly == 0) {
     reportAnalyzerFunctionMisuse(Opts, *Ctx);
+  }
 }
 
 void AnalysisConsumer::reportAnalyzerProgress(StringRef S) {
@@ -723,6 +726,7 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
       SyntaxCheckTimer->startTimer();
     }
     checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
+    ++NumFunctionsAnalyzedSyntaxOnly;
     if (SyntaxCheckTimer) {
       SyntaxCheckTimer->stopTimer();
       llvm::TimeRecord CheckerEndTime = SyntaxCheckTimer->getTotalTime();
diff --git a/clang/test/Analysis/analyze-function-guide.cpp b/clang/test/Analysis/analyze-function-guide.cpp
index 96f1001057eb6..e260fc43a666a 100644
--- a/clang/test/Analysis/analyze-function-guide.cpp
+++ b/clang/test/Analysis/analyze-function-guide.cpp
@@ -46,14 +46,17 @@ int fizzbuzz(int x, bool y) {
 // CHECK-ADVOCATE-DISPLAY-PROGRESS-NEXT: Pass the -analyzer-display-progress for tracking which functions are analyzed.
 // CHECK-ADVOCATE-DISPLAY-PROGRESS-NOT:  For analyzing
 
-// Same as the previous but syntax mode only.
-// FIXME: This should have empty standard output.
+// The user only enables syntax-only analysis, like `debug.DumpDominators`.
+// `-analyze-function` should only match the given function.
 //
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config ipa=none \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpDominators -analyzer-config ipa=none \
 // RUN:   -analyze-function='fizzbuzz(int, _Bool)' -x c++ \
 // RUN:   -triple x86_64-pc-linux-gnu 2>&1 %s \
-// RUN: | FileCheck %s -check-prefix=CHECK-EMPTY3 --allow-empty
-//
-// FIXME: This should have empty standard output.
-// CHECK-EMPTY3:      Every top-level function was skipped.
-// CHECK-EMPTY3-NEXT: Pass the -analyzer-display-progress for tracking which functions are analyzed.
+// RUN: | FileCheck %s -check-prefix=CHECK-SYNTAX-ONLY --allow-empty
+//
+// With syntax-only analysis, the function is found and analyzed, so no error message.
+// CHECK-SYNTAX-ONLY:      Immediate dominance tree (Node#,IDom#):
+// CHECK-SYNTAX-ONLY-NEXT: (0,1)
+// CHECK-SYNTAX-ONLY-NEXT: (1,2)
+// CHECK-SYNTAX-ONLY-NEXT: (2,2)
+// CHECK-SYNTAX-ONLY-NOT: Every top-level function was skipped.

@steakhal steakhal merged commit c75ae01 into llvm:main Oct 3, 2025
10 of 12 checks passed
@steakhal steakhal deleted the analyze-fn-fix branch October 3, 2025 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants