Skip to content

[clang][dataflow] Teach AnalysisASTVisitor that typeid() can be evaluated. #96731

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 1 commit into from
Jun 26, 2024

Conversation

martinboehme
Copy link
Contributor

We were previously treating the operand of typeid() as being definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic type.

This patch includes a test that fails without the fix.

…valuated.

We were previously treating the operand of `typeid()` as being definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic type.

This patch includes a test that fails without the fix.
@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 Jun 26, 2024
@martinboehme martinboehme requested review from ymand and Xazax-hun June 26, 2024 04:48
@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2024

@llvm/pr-subscribers-clang-analysis

@llvm/pr-subscribers-clang

Author: None (martinboehme)

Changes

We were previously treating the operand of typeid() as being definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic type.

This patch includes a test that fails without the fix.


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

2 Files Affected:

  • (modified) clang/include/clang/Analysis/FlowSensitive/ASTOps.h (+5-1)
  • (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+43)
diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
index 925b99af9141a..f9c923a36ad22 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
@@ -113,7 +113,11 @@ class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
   // 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 TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) {
+    if (TIE->isPotentiallyEvaluated())
+      return RecursiveASTVisitor<Derived>::TraverseCXXTypeidExpr(TIE);
+    return true;
+  }
   bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
     return true;
   }
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 2a74d7fa63fd7..10d7ec9380ab8 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1637,6 +1637,49 @@ TEST(TransferTest, StructModeledFieldsWithAccessor) {
       });
 }
 
+TEST(TransferTest, StructModeledFieldsInTypeid) {
+  // Test that we model fields mentioned inside a `typeid()` expression only if
+  // that expression is potentially evaluated -- i.e. if the expression inside
+  // `typeid()` is a glvalue of polymorphic type (see
+  // `CXXTypeidExpr::isPotentiallyEvaluated()` and [expr.typeid]p3).
+  std::string Code = R"(
+    // Definitions needed for `typeid`.
+    namespace std {
+      class type_info {};
+      class bad_typeid {};
+    }  // namespace std
+
+    struct NonPolymorphic {};
+
+    struct Polymorphic {
+      virtual ~Polymorphic() = default;
+    };
+
+    struct S {
+      NonPolymorphic *NonPoly;
+      Polymorphic *Poly;
+    };
+
+    void target(S &s) {
+      typeid(*s.NonPoly);
+      typeid(*s.Poly);
+      // [[p]]
+    }
+  )";
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+        auto &SLoc = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s");
+        std::vector<const ValueDecl *> Fields;
+        for (auto [Field, _] : SLoc.children())
+          Fields.push_back(Field);
+        EXPECT_THAT(Fields,
+                    UnorderedElementsAre(findValueDecl(ASTCtx, "Poly")));
+      });
+}
+
 TEST(TransferTest, StructModeledFieldsWithComplicatedInheritance) {
   std::string Code = R"(
     struct Base1 {

@martinboehme martinboehme merged commit dfe80a7 into llvm:main Jun 26, 2024
11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 26, 2024

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-sie-ubuntu-fast running on sie-linux-worker while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/913

Here is the relevant piece of the build log for the reference:

Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Clang-Unit :: Analysis/FlowSensitive/./ClangAnalysisFlowSensitiveTests/35/42' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/tools/clang/unittests/Analysis/FlowSensitive/./ClangAnalysisFlowSensitiveTests-Clang-Unit-4189086-35-42.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=42 GTEST_SHARD_INDEX=35 /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/tools/clang/unittests/Analysis/FlowSensitive/./ClangAnalysisFlowSensitiveTests
--

Script:
--
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/tools/clang/unittests/Analysis/FlowSensitive/./ClangAnalysisFlowSensitiveTests --gtest_filter=TransferTest.StructModeledFieldsInTypeid
--
input.cc:20:7: error: use of typeid requires -frtti
   20 |       typeid(*s.NonPoly);
      |       ^
input.cc:21:7: error: use of typeid requires -frtti
   21 |       typeid(*s.Poly);
      |       ^
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp:92: Failure
Value of: llvm::detail::TakeError(checkDataflowWithNoopAnalysis(Code, VerifyResults, Options, Std, TargetFun))
Expected: succeeded
  Actual: failed  (Invalid argument Source file has syntax or type errors, they were printed to the test log)


/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp:92
Value of: llvm::detail::TakeError(checkDataflowWithNoopAnalysis(Code, VerifyResults, Options, Std, TargetFun))
Expected: succeeded
  Actual: failed  (Invalid argument Source file has syntax or type errors, they were printed to the test log)



********************


martinboehme added a commit that referenced this pull request Jun 26, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
arsenm pushed a commit that referenced this pull request Jun 27, 2024
…valuated. (#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
arsenm pushed a commit that referenced this pull request Jun 27, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
arsenm pushed a commit that referenced this pull request Jun 27, 2024
…valuated. (#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
arsenm pushed a commit that referenced this pull request Jun 27, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
arsenm pushed a commit that referenced this pull request Jun 28, 2024
…valuated. (#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
arsenm pushed a commit that referenced this pull request Jun 28, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
arsenm pushed a commit that referenced this pull request Jul 2, 2024
…valuated. (#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
arsenm pushed a commit that referenced this pull request Jul 2, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
arsenm pushed a commit that referenced this pull request Jul 3, 2024
…valuated. (#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
arsenm pushed a commit that referenced this pull request Jul 3, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
…valuated. (llvm#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
arsenm pushed a commit that referenced this pull request Jul 3, 2024
…valuated. (#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
arsenm pushed a commit that referenced this pull request Jul 3, 2024
…can be evaluated." (#96766)

Reverts #96731

It causes CI failures.
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
…valuated. (llvm#96731)

We were previously treating the operand of `typeid()` as being
definitely
unevaluated, but it can be evaluated if it is a glvalue of polymorphic
type.

This patch includes a test that fails without the fix.
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
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.

5 participants