Skip to content

[StaticAnalyzer] Fix tryExpandAsInteger's failures on PCH macros #142722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 5, 2025

Conversation

ziqingluo-90
Copy link
Contributor

The function tryExpandAsInteger attempts to extract an integer from a macro definition. Previously, the attempt would fail when the macro is from a PCH, because the function tried to access the text buffer of the source file, which does not exist in case of PCHs. The fix uses Preprocessor::getSpelling, which works in either cases.

rdar://151403070

The function `tryExpandAsInteger` attempts to extract an integer from
a macro definition.  Previously, the attempt would fail when the macro
is from a PCH, because the function tried to access the text buffer of
the source file, which does not exist in case of PCHs.  The fix uses
`Preprocessor::getSpelling`, which works in either cases.

rdar://151403070
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer labels Jun 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 4, 2025

@llvm/pr-subscribers-clang

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

Author: Ziqing Luo (ziqingluo-90)

Changes

The function tryExpandAsInteger attempts to extract an integer from a macro definition. Previously, the attempt would fail when the macro is from a PCH, because the function tried to access the text buffer of the source file, which does not exist in case of PCHs. The fix uses Preprocessor::getSpelling, which works in either cases.

rdar://151403070


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

3 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp (+12-4)
  • (removed) clang/test/Analysis/pch_crash.cpp (-28)
  • (added) clang/test/Analysis/pch_macro.cpp (+39)
diff --git a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
index 4ed4113919c1d..111af35806dda 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
@@ -129,11 +129,19 @@ std::optional<int> tryExpandAsInteger(StringRef Macro, const Preprocessor &PP) {
 
   // Parse an integer at the end of the macro definition.
   const Token &T = FilteredTokens.back();
-  // FIXME: EOF macro token coming from a PCH file on macOS while marked as
-  //        literal, doesn't contain any literal data
-  if (!T.isLiteral() || !T.getLiteralData())
+
+  if (!T.isLiteral())
     return std::nullopt;
-  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+
+  bool InvalidSpelling = false;
+  // `Preprocessor::getSpelling` can get the spelling of the token regardless of
+  // whether the macro is defined in a PCH or not:
+  std::string Spelling = PP.getSpelling(T, &InvalidSpelling);
+
+  if (InvalidSpelling)
+    return std::nullopt;
+
+  StringRef ValueStr(Spelling);
   llvm::APInt IntValue;
   constexpr unsigned AutoSenseRadix = 0;
   if (ValueStr.getAsInteger(AutoSenseRadix, IntValue))
diff --git a/clang/test/Analysis/pch_crash.cpp b/clang/test/Analysis/pch_crash.cpp
deleted file mode 100644
index 7ad2cb2d2ab57..0000000000000
--- a/clang/test/Analysis/pch_crash.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.15.0 -emit-pch -o %t %s
-// RUN: %clang_analyze_cc1 -triple x86_64-apple-macosx10.15.0 -include-pch %t \
-// RUN:   -analyzer-checker=core,apiModeling -verify %s
-//
-// RUN: %clang_cc1 -emit-pch -o %t %s
-// RUN: %clang_analyze_cc1 -include-pch %t \
-// RUN:   -analyzer-checker=core,apiModeling -verify %s
-
-// expected-no-diagnostics
-
-#ifndef HEADER
-#define HEADER
-// Pre-compiled header
-
-int foo();
-
-// Literal data for this macro value will be null
-#define EOF -1
-
-#else
-// Source file
-
-int test() {
-  // we need a function call here to initiate erroneous routine
-  return foo(); // no-crash
-}
-
-#endif
diff --git a/clang/test/Analysis/pch_macro.cpp b/clang/test/Analysis/pch_macro.cpp
new file mode 100644
index 0000000000000..0cc00cfe0cc17
--- /dev/null
+++ b/clang/test/Analysis/pch_macro.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.15.0 -emit-pch -o %t %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-macosx10.15.0 -include-pch %t \
+// RUN:   -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify %s
+//
+// RUN: %clang_cc1 -emit-pch -o %t %s
+// RUN: %clang_analyze_cc1 -include-pch %t \
+// RUN:   -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+// Pre-compiled header
+
+int foo();
+
+// Literal data for macro values will be null as they are defined in a PCH
+#define EOF -1
+#define AT_FDCWD -2
+
+#else
+// Source file
+
+int test() {
+  // we need a function call here to initiate erroneous routine
+  return foo(); // no-crash
+}
+
+// Test that StdLibraryFunctionsChecker can obtain the definition of
+// AT_FDCWD even if it is from a PCH:
+int faccessat(int, const char *, int, int);
+
+void test_faccessat() {
+  char fileSystemPath[10] = { 0 };
+
+  if (0 != faccessat(AT_FDCWD, fileSystemPath, 2, 0x0030)) {}
+}
+
+#endif

Copy link
Contributor

@steakhal steakhal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the patch.

@ziqingluo-90
Copy link
Contributor Author

CC @dtarditi

Copy link
Contributor

@steakhal steakhal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Much cleaner this way.
Thank you!

FYI: I also proposed a slight declarative simplification to the RUN lines, I hope you like it.

@ziqingluo-90
Copy link
Contributor Author

Thank you for reviewing steakhal!

@steakhal
Copy link
Contributor

steakhal commented Jun 5, 2025

FYI the CI checks are red, I don't think its related to this PR.
It had this line:

2025-06-05T08:01:02.4802924Z PASS: Clang :: Analysis/pch_macro.cpp (1263 of 21496)

So we should be good to merge, any time you want.

@steakhal steakhal merged commit 8094454 into llvm:main Jun 5, 2025
12 of 14 checks passed
@steakhal
Copy link
Contributor

steakhal commented Jun 5, 2025

Hmm, I only checked now that you probably already had commit access. I should have left this up to you to merge.

@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 5, 2025

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building clang at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/23912

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Python/Crashlog/text.test (2980 of 2991)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test (2981 of 2991)
UNSUPPORTED: lldb-shell :: Process/Windows/process_load.cpp (2982 of 2991)
UNSUPPORTED: lldb-shell :: SymbolFile/PDB/compilands.test (2983 of 2991)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Lua/lua-python.test (2984 of 2991)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test (2985 of 2991)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Lua/watchpoint_callback.test (2986 of 2991)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Python/Crashlog/no_threadState.test (2987 of 2991)
PASS: lldb-api :: terminal/TestEditlineCompletions.py (2988 of 2991)
UNRESOLVED: lldb-api :: tools/lldb-dap/launch/TestDAP_launch.py (2989 of 2991)
******************** TEST 'lldb-api :: tools/lldb-dap/launch/TestDAP_launch.py' FAILED ********************
Script:
--
/usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --arch x86_64 --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib --cmake-build-type Release -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/launch -p TestDAP_launch.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 8094454ea1cbe2530a06f44443e08f923ab9de40)
  clang revision 8094454ea1cbe2530a06f44443e08f923ab9de40
  llvm revision 8094454ea1cbe2530a06f44443e08f923ab9de40
Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
Change dir to: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/launch
runCmd: settings clear --all

output: 

runCmd: settings set symbols.enable-external-lookup false

output: 

runCmd: settings set target.inherit-tcc true

output: 

runCmd: settings set target.disable-aslr false

output: 

runCmd: settings set target.detach-on-error false

output: 

runCmd: settings set target.auto-apply-fixits false

@ziqingluo-90
Copy link
Contributor Author

Thanks for merging it for me. Buildbots failures seems irrelevant:

TEST 'lldb-api :: tools/lldb-dap/launch/TestDAP_launch.py' FAILED
or
FAILED: libc/src/math/amdgpu/CMakeFiles/libc.src.math.amdgpu.acosh.dir/acosh.cpp.o

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.

4 participants