https://github.com/steakhal 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/3] [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/3] 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 >From 4445a7d9bc4c615d589c1b8a80f7291fcb50dd86 Mon Sep 17 00:00:00 2001 From: Balazs Benics <benicsbal...@gmail.com> Date: Thu, 5 Jun 2025 09:47:23 +0200 Subject: [PATCH 3/3] Use the DEFINE directive in LIT tests to simplify the repeated lines --- clang/test/Analysis/pch_macro.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/clang/test/Analysis/pch_macro.cpp b/clang/test/Analysis/pch_macro.cpp index c2eb315418673..afc371d50460f 100644 --- a/clang/test/Analysis/pch_macro.cpp +++ b/clang/test/Analysis/pch_macro.cpp @@ -2,13 +2,18 @@ // 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 -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 +// DEFINE: %{emit-pch-action} = \ +// DEFINE: %clang_cc1 -x c++ -emit-pch -o %t/header.pch %t/header.h + +// DEFINE: %{analyze-action} = \ +// DEFINE: %clang_analyze_cc1 -include-pch %t/header.pch \ +// DEFINE: -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions \ +// DEFINE: -verify %t/main.cpp + +// RUN: %{emit-pch-action} -triple x86_64-apple-macosx10.15.0 +// RUN: %{analyze-action} -triple x86_64-apple-macosx10.15.0 +// RUN: %{emit-pch-action} +// RUN: %{analyze-action} //--- header.h _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits