-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[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
Conversation
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
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-static-analyzer-1 Author: Ziqing Luo (ziqingluo-90) ChangesThe function rdar://151403070 Full diff: https://github.com/llvm/llvm-project/pull/142722.diff 3 Files Affected:
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
|
There was a problem hiding this 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.
CC @dtarditi |
There was a problem hiding this 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.
Thank you for reviewing steakhal! |
FYI the CI checks are red, I don't think its related to this PR.
So we should be good to merge, any time you want. |
Hmm, I only checked now that you probably already had commit access. I should have left this up to you to merge. |
LLVM Buildbot has detected a new failure on builder 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
|
Thanks for merging it for me. Buildbots failures seems irrelevant:
|
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 usesPreprocessor::getSpelling
, which works in either cases.rdar://151403070