-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][dataflow] Fix buggy assertion: Compare an unqualified type to an unqualified type. #71573
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
Includes crash-reproducing test case.
@llvm/pr-subscribers-clang Author: Samira Bazuzi (bazuzi) ChangesIncludes crash-reproducing test case. Full diff: https://github.com/llvm/llvm-project/pull/71573.diff 2 Files Affected:
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 8b2f8ecc5027e8a..839c04c65e39e7c 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -683,11 +683,11 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
assert(
// The types are same, or
Field->getType().getCanonicalType().getUnqualifiedType() ==
- Init->getType().getCanonicalType() ||
+ Init->getType().getCanonicalType().getUnqualifiedType() ||
// The field's type is T&, and initializer is T
(Field->getType()->isReferenceType() &&
- Field->getType().getCanonicalType()->getPointeeType() ==
- Init->getType().getCanonicalType()));
+ Field->getType().getCanonicalType()->getPointeeType() ==
+ Init->getType().getCanonicalType()));
auto& Loc = Env.createObject(Field->getType(), Init);
FieldLocs.insert({Field, &Loc});
}
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index bd9b98178b5d4e3..19136f24d666b66 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3197,6 +3197,26 @@ TEST(TransferTest, AggregateInitialization_NotExplicitlyInitializedField) {
});
}
+TEST(TransferTest, AggregateInitializationFunctionPointer) {
+ // This is a crash repro.
+ // nullptr takes on the type of a const function pointer, but its type was
+ // asserted to be equal to the *unqualified* type of Field, which no longer
+ // included the const.
+ std::string Code = R"(
+ struct S {
+ void (*const Field)();
+ };
+
+ void target() {
+ S s{nullptr};
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {});
+}
+
TEST(TransferTest, AssignToUnionMember) {
std::string Code = R"(
union A {
|
@llvm/pr-subscribers-clang-analysis Author: Samira Bazuzi (bazuzi) ChangesIncludes crash-reproducing test case. Full diff: https://github.com/llvm/llvm-project/pull/71573.diff 2 Files Affected:
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 8b2f8ecc5027e8a..839c04c65e39e7c 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -683,11 +683,11 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
assert(
// The types are same, or
Field->getType().getCanonicalType().getUnqualifiedType() ==
- Init->getType().getCanonicalType() ||
+ Init->getType().getCanonicalType().getUnqualifiedType() ||
// The field's type is T&, and initializer is T
(Field->getType()->isReferenceType() &&
- Field->getType().getCanonicalType()->getPointeeType() ==
- Init->getType().getCanonicalType()));
+ Field->getType().getCanonicalType()->getPointeeType() ==
+ Init->getType().getCanonicalType()));
auto& Loc = Env.createObject(Field->getType(), Init);
FieldLocs.insert({Field, &Loc});
}
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index bd9b98178b5d4e3..19136f24d666b66 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3197,6 +3197,26 @@ TEST(TransferTest, AggregateInitialization_NotExplicitlyInitializedField) {
});
}
+TEST(TransferTest, AggregateInitializationFunctionPointer) {
+ // This is a crash repro.
+ // nullptr takes on the type of a const function pointer, but its type was
+ // asserted to be equal to the *unqualified* type of Field, which no longer
+ // included the const.
+ std::string Code = R"(
+ struct S {
+ void (*const Field)();
+ };
+
+ void target() {
+ S s{nullptr};
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {});
+}
+
TEST(TransferTest, AssignToUnionMember) {
std::string Code = R"(
union A {
|
@martinboehme Could you review? |
Co-authored-by: martinboehme <[email protected]>
Could you merge for me? I don't have write access. |
Done! |
… an unqualified type. (llvm#71573) Includes crash-reproducing test case. --------- Co-authored-by: martinboehme <[email protected]>
Includes crash-reproducing test case.