https://github.com/ziqingluo-90 updated 
https://github.com/llvm/llvm-project/pull/142722

>From 3bd12ac6bb3c47b5e977cffec019df15a15426fc Mon Sep 17 00:00:00 2001
From: Ziqing Luo <ziq...@udel.edu>
Date: Wed, 4 Jun 2025 12:29:53 +0800
Subject: [PATCH 1/2] [StaticAnalyzer] Fix tryExpandAsInteger's failures on
 macros from PCHs

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
---
 .../StaticAnalyzer/Core/CheckerHelpers.cpp    | 16 ++++++--
 clang/test/Analysis/pch_crash.cpp             | 28 -------------
 clang/test/Analysis/pch_macro.cpp             | 39 +++++++++++++++++++
 3 files changed, 51 insertions(+), 32 deletions(-)
 delete mode 100644 clang/test/Analysis/pch_crash.cpp
 create mode 100644 clang/test/Analysis/pch_macro.cpp

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

>From 8893dd5ae0784821c4c82f1c0ed65e25c832eff0 Mon Sep 17 00:00:00 2001
From: Ziqing Luo <ziq...@udel.edu>
Date: Thu, 5 Jun 2025 13:14:03 +0800
Subject: [PATCH 2/2] address comments

---
 .../StaticAnalyzer/Core/CheckerHelpers.cpp    |  4 +--
 clang/test/Analysis/pch_macro.cpp             | 30 +++++++++++--------
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp 
b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
index 111af35806dda..8b404377186e9 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
@@ -134,14 +134,14 @@ std::optional<int> tryExpandAsInteger(StringRef Macro, 
const Preprocessor &PP) {
     return std::nullopt;
 
   bool InvalidSpelling = false;
+  SmallVector<char> Buffer(T.getLength());
   // `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);
+  StringRef ValueStr = PP.getSpelling(T, Buffer, &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_macro.cpp 
b/clang/test/Analysis/pch_macro.cpp
index 0cc00cfe0cc17..c2eb315418673 100644
--- a/clang/test/Analysis/pch_macro.cpp
+++ b/clang/test/Analysis/pch_macro.cpp
@@ -1,15 +1,19 @@
-// 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: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-macosx10.15.0 -emit-pch -o 
%t/header.pch %t/header.h
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-macosx10.15.0 -include-pch 
%t/header.pch \
+// RUN:   -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify 
%t/main.cpp
 //
-// RUN: %clang_cc1 -emit-pch -o %t %s
-// RUN: %clang_analyze_cc1 -include-pch %t \
-// RUN:   -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify 
%s
+// RUN: %clang_cc1 -x c++ -emit-pch -o %t/header.pch %t/header.h
+// RUN: %clang_analyze_cc1 -include-pch %t/header.pch \
+// RUN:   -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify 
%t/main.cpp
+
+
+//--- header.h
 
-// expected-no-diagnostics
 
-#ifndef HEADER
-#define HEADER
 // Pre-compiled header
 
 int foo();
@@ -18,9 +22,12 @@ int foo();
 #define EOF -1
 #define AT_FDCWD -2
 
-#else
-// Source file
 
+//--- main.cpp
+
+
+// Source file
+// expected-no-diagnostics
 int test() {
   // we need a function call here to initiate erroneous routine
   return foo(); // no-crash
@@ -36,4 +43,3 @@ void test_faccessat() {
   if (0 != faccessat(AT_FDCWD, fileSystemPath, 2, 0x0030)) {}
 }
 
-#endif

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to