Skip to content

Commit 3bd12ac

Browse files
committed
[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
1 parent dc513fa commit 3bd12ac

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,19 @@ std::optional<int> tryExpandAsInteger(StringRef Macro, const Preprocessor &PP) {
129129

130130
// Parse an integer at the end of the macro definition.
131131
const Token &T = FilteredTokens.back();
132-
// FIXME: EOF macro token coming from a PCH file on macOS while marked as
133-
// literal, doesn't contain any literal data
134-
if (!T.isLiteral() || !T.getLiteralData())
132+
133+
if (!T.isLiteral())
135134
return std::nullopt;
136-
StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
135+
136+
bool InvalidSpelling = false;
137+
// `Preprocessor::getSpelling` can get the spelling of the token regardless of
138+
// whether the macro is defined in a PCH or not:
139+
std::string Spelling = PP.getSpelling(T, &InvalidSpelling);
140+
141+
if (InvalidSpelling)
142+
return std::nullopt;
143+
144+
StringRef ValueStr(Spelling);
137145
llvm::APInt IntValue;
138146
constexpr unsigned AutoSenseRadix = 0;
139147
if (ValueStr.getAsInteger(AutoSenseRadix, IntValue))

clang/test/Analysis/pch_crash.cpp

Lines changed: 0 additions & 28 deletions
This file was deleted.

clang/test/Analysis/pch_macro.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.15.0 -emit-pch -o %t %s
2+
// RUN: %clang_analyze_cc1 -triple x86_64-apple-macosx10.15.0 -include-pch %t \
3+
// RUN: -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify %s
4+
//
5+
// RUN: %clang_cc1 -emit-pch -o %t %s
6+
// RUN: %clang_analyze_cc1 -include-pch %t \
7+
// RUN: -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions -verify %s
8+
9+
// expected-no-diagnostics
10+
11+
#ifndef HEADER
12+
#define HEADER
13+
// Pre-compiled header
14+
15+
int foo();
16+
17+
// Literal data for macro values will be null as they are defined in a PCH
18+
#define EOF -1
19+
#define AT_FDCWD -2
20+
21+
#else
22+
// Source file
23+
24+
int test() {
25+
// we need a function call here to initiate erroneous routine
26+
return foo(); // no-crash
27+
}
28+
29+
// Test that StdLibraryFunctionsChecker can obtain the definition of
30+
// AT_FDCWD even if it is from a PCH:
31+
int faccessat(int, const char *, int, int);
32+
33+
void test_faccessat() {
34+
char fileSystemPath[10] = { 0 };
35+
36+
if (0 != faccessat(AT_FDCWD, fileSystemPath, 2, 0x0030)) {}
37+
}
38+
39+
#endif

0 commit comments

Comments
 (0)