[clang] reland 90438 (PR #91172)
via cfe-commits
cfe-commits at lists.llvm.org
Mon May 6 01:11:54 PDT 2024
https://github.com/martinboehme created https://github.com/llvm/llvm-project/pull/91172
- **Reapply "[clang][dataflow] Don't propagate result objects in unevaluated contexts (#90438)"**
- **fixup! Reapply "[clang][dataflow] Don't propagate result objects in unevaluated contexts (#90438)"**
>From af6de532e14c6b3bf89f238533dea197fbc8114a Mon Sep 17 00:00:00 2001
From: Martin Braenne <mboehme at google.com>
Date: Mon, 6 May 2024 06:46:33 +0000
Subject: [PATCH 1/2] Reapply "[clang][dataflow] Don't propagate result objects
in unevaluated contexts (#90438)"
This reverts commit 2252c5c42b95dd12dda0c7fb1b2811f943b21949.
---
.../FlowSensitive/DataflowEnvironment.cpp | 11 ++++
.../Analysis/FlowSensitive/TransferTest.cpp | 52 +++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index d79e734402892a..cb6c8b2ef1072b 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -350,6 +350,17 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
return RecursiveASTVisitor<ResultObjectVisitor>::TraverseDecl(D);
}
+ // Don't traverse expressions in unevaluated contexts, as we don't model
+ // fields that are only used in these.
+ // Note: The operand of the `noexcept` operator is an unevaluated operand, but
+ // nevertheless it appears in the Clang CFG, so we don't exclude it here.
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
+ bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; }
+ bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
+ return true;
+ }
+
bool TraverseBindingDecl(BindingDecl *BD) {
// `RecursiveASTVisitor` doesn't traverse holding variables for
// `BindingDecl`s by itself, so we need to tell it to.
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 0b441faa6c76da..91bd496226caf2 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3400,6 +3400,58 @@ TEST(TransferTest, ResultObjectLocationDontVisitNestedRecordDecl) {
ASTContext &ASTCtx) {});
}
+TEST(TransferTest, ResultObjectLocationDontVisitUnevaluatedContexts) {
+ // This is a crash repro.
+ // We used to crash because when propagating result objects, we would visit
+ // unevaluated contexts, but we don't model fields used only in these.
+
+ auto testFunction = [](llvm::StringRef Code, llvm::StringRef TargetFun) {
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {},
+ LangStandard::lang_gnucxx17,
+ /* ApplyBuiltinTransfer= */ true, TargetFun);
+ };
+
+ std::string Code = R"cc(
+ // Definitions needed for `typeid`.
+ namespace std {
+ class type_info {};
+ class bad_typeid {};
+ } // namespace std
+
+ struct S1 {};
+ struct S2 { S1 s1; };
+
+ // We test each type of unevaluated context from a different target
+ // function. Some types of unevaluated contexts may actually cause the
+ // field `s1` to be modeled, and we don't want this to "pollute" the tests
+ // for the other unevaluated contexts.
+ void decltypeTarget() {
+ decltype(S2{}) Dummy;
+ }
+ void typeofTarget() {
+ typeof(S2{}) Dummy;
+ }
+ void typeidTarget() {
+ typeid(S2{});
+ }
+ void sizeofTarget() {
+ sizeof(S2{});
+ }
+ void noexceptTarget() {
+ noexcept(S2{});
+ }
+ )cc";
+
+ testFunction(Code, "decltypeTarget");
+ testFunction(Code, "typeofTarget");
+ testFunction(Code, "typeidTarget");
+ testFunction(Code, "sizeofTarget");
+ testFunction(Code, "noexceptTarget");
+}
+
TEST(TransferTest, StaticCast) {
std::string Code = R"(
void target(int Foo) {
>From 77222057b948a668aebda9cbd0b6fd41e01a21a2 Mon Sep 17 00:00:00 2001
From: Martin Braenne <mboehme at google.com>
Date: Mon, 6 May 2024 08:11:11 +0000
Subject: [PATCH 2/2] fixup! Reapply "[clang][dataflow] Don't propagate result
objects in unevaluated contexts (#90438)"
---
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 91bd496226caf2..6743e778a2ffeb 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3435,7 +3435,9 @@ TEST(TransferTest, ResultObjectLocationDontVisitUnevaluatedContexts) {
typeof(S2{}) Dummy;
}
void typeidTarget() {
+#if __has_feature(cxx_rtti)
typeid(S2{});
+#endif
}
void sizeofTarget() {
sizeof(S2{});
More information about the cfe-commits
mailing list