Skip to content

[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

Merged
merged 2 commits into from
Nov 9, 2023

Conversation

bazuzi
Copy link
Contributor

@bazuzi bazuzi commented Nov 7, 2023

Includes crash-reproducing test case.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:dataflow Clang Dataflow Analysis framework - https://clang.llvm.org/docs/DataFlowAnalysisIntro.html clang:analysis labels Nov 7, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2023

@llvm/pr-subscribers-clang

Author: Samira Bazuzi (bazuzi)

Changes

Includes crash-reproducing test case.


Full diff: https://github.com/llvm/llvm-project/pull/71573.diff

2 Files Affected:

  • (modified) clang/lib/Analysis/FlowSensitive/Transfer.cpp (+3-3)
  • (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+20)
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 {

@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2023

@llvm/pr-subscribers-clang-analysis

Author: Samira Bazuzi (bazuzi)

Changes

Includes crash-reproducing test case.


Full diff: https://github.com/llvm/llvm-project/pull/71573.diff

2 Files Affected:

  • (modified) clang/lib/Analysis/FlowSensitive/Transfer.cpp (+3-3)
  • (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+20)
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 {

@bazuzi
Copy link
Contributor Author

bazuzi commented Nov 7, 2023

@martinboehme Could you review?

@martinboehme martinboehme self-requested a review November 8, 2023 09:54
@martinboehme martinboehme changed the title [clang][dataflow] Compare an unqualified type to an unqualified type. [clang][dataflow] Fix buggy assertion: Compare an unqualified type to an unqualified type. Nov 8, 2023
Co-authored-by: martinboehme <[email protected]>
@bazuzi
Copy link
Contributor Author

bazuzi commented Nov 9, 2023

Could you merge for me? I don't have write access.

@martinboehme martinboehme merged commit 3001d6d into llvm:main Nov 9, 2023
@martinboehme
Copy link
Contributor

Could you merge for me? I don't have write access.

Done!

zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
… an unqualified type. (llvm#71573)

Includes crash-reproducing test case.

---------

Co-authored-by: martinboehme <[email protected]>
@bazuzi bazuzi deleted the piper_export_cl_580226384 branch November 30, 2023 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:analysis clang:dataflow Clang Dataflow Analysis framework - https://clang.llvm.org/docs/DataFlowAnalysisIntro.html clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants