[PATCH] D43477: [CFG] [analyzer] Add MaterializeTemporaryExpr into the construction context.

Xun Li via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 2 22:21:35 PDT 2021


lxfind added a comment.
Herald added subscribers: manas, steakhal, ASDenysPetrov, martong, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, baloghadamsoftware.

Hi! I have a question regarding the implementation of "VisitMaterializeTemporaryExpr". Specifically, I wonder if we should skip visiting the children? Would't visiting the children of MaterializeTemporaryExpr cause the same expression to be visited twice?

I am debugging a crash in ThreadSafetyAnalyzer, which triggers this assertion: https://github.com/llvm/llvm-project/blob/main/clang/lib/Analysis/ThreadSafety.cpp#L534
Basically it's adding the same declaration twice from the same CFG block.
And I found that the redundant declaration is added during CFG construction, when processing cpp source code like this:

  co_return ({ static constexpr mydomain::logdevice::ErrorStacktrace::Frame frame{ __FUNCTION__, "logdevice/common/ZookeeperClientBase.cpp", 103}; mydomain::logdevice::detail::makeUnexpected(&frame, toStatus(result.rc_)); });

which corresponds to the following AST:

  |   `-CompoundStmt 0x227b13f8
  |     `-CoreturnStmt 0x227b13d0
  |       |-CXXBindTemporaryExpr 0x22776218 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>' (CXXTemporary 0x22776218)
  |       | `-StmtExpr 0x227761f0 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>'
  |       |   `-CompoundStmt 0x227761d0
  |       |     |-DeclStmt 0x22771e88
  |       |     | `-VarDecl 0x22771c50  used frame 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame' static constexpr listinit
  |       |     |   |-value: Struct
  |       |     |   | `-fields: LValue <todo>, LValue <todo>, Int 103
  |       |     |   `-InitListExpr 0x22771da8 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame'
  |       |     |     |-ImplicitCastExpr 0x22771e00 'const char *' <ArrayToPointerDecay>
  |       |     |     | `-PredefinedExpr 0x22771cd8 'const char [8]' lvalue __FUNCTION__
  |       |     |     |   `-StringLiteral 0x22771cb8 'const char [8]' lvalue "getData"
  |       |     |     |-ImplicitCastExpr 0x22771e18 'const char *' <ArrayToPointerDecay>
  |       |     |     | `-StringLiteral 0x22771cf0 'const char [41]' lvalue "logdevice/common/ZookeeperClientBase.cpp"
  |       |     |     `-IntegerLiteral 0x22771d30 'int' 103
  |       |     `-ExprWithCleanups 0x227761b8 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>'
  |       |       `-CXXBindTemporaryExpr 0x22776198 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>' (CXXTemporary 0x22776198)
  |       |         `-CallExpr 0x22776160 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>'
  |       |           |-ImplicitCastExpr 0x22776148 'folly::Unexpected<Error> (*)(const class ErrorStacktrace::Frame *, mydomain::logdevice::Status)' <FunctionToPointerDecay>
  |       |           | `-DeclRefExpr 0x227760b8 'folly::Unexpected<Error> (const class ErrorStacktrace::Frame *, mydomain::logdevice::Status)' lvalue Function 0x18b49568 'makeUnexpected' 'folly::Unexpected<Error> (const class ErrorStacktrace::Frame *, mydomain::logdevice::Status)'
  |       |           |-UnaryOperator 0x22771fb8 'const mydomain::logdevice::class ErrorStacktrace::Frame *' prefix '&' cannot overflow
  |       |           | `-DeclRefExpr 0x22771f68 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame' lvalue Var 0x22771c50 'frame' 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame'
  |       |           `-CallExpr 0x227720e0 'mydomain::logdevice::Status':'enum mydomain::logdevice::E'
  |       |             |-ImplicitCastExpr 0x227720c8 'mydomain::logdevice::Status (*)(int)' <FunctionToPointerDecay>
  |       |             | `-DeclRefExpr 0x22771ff8 'mydomain::logdevice::Status (int)' lvalue CXXMethod 0x221cddd0 'toStatus' 'mydomain::logdevice::Status (int)'
  |       |             `-ImplicitCastExpr 0x22772108 'int' <LValueToRValue>
  |       |               `-MemberExpr 0x22772038 'int' lvalue .rc_ 0x21f24480
  |       |                 `-DeclRefExpr 0x22772018 'struct mydomain::logdevice::zk::GetResponse':'struct mydomain::logdevice::zk::GetResponse' lvalue Var 0x22731508 'result' 'struct mydomain::logdevice::zk::GetResponse':'struct mydomain::logdevice::zk::GetResponse'
  |       `-ExprWithCleanups 0x227b13b8 'void'
  |         `-CXXMemberCallExpr 0x227b1378 'void'
  |           |-MemberExpr 0x227b1330 '<bound member function type>' .return_value 0x227b1230
  |           | `-DeclRefExpr 0x22776238 'std::__coroutine_traits_impl<class folly::coro::Task<class folly::Expected<struct mydomain::logdevice::zk::GetResponse, struct mydomain::logdevice::Error> > >::promise_type':'class folly::coro::detail::TaskPromise<class folly::Expected<struct mydomain::logdevice::zk::GetResponse, struct mydomain::logdevice::Error> >' lvalue Var 0x227330a0 '__promise' 'std::__coroutine_traits_impl<class folly::coro::Task<class folly::Expected<struct mydomain::logdevice::zk::GetResponse, struct mydomain::logdevice::Error> > >::promise_type':'class folly::coro::detail::TaskPromise<class folly::Expected<struct mydomain::logdevice::zk::GetResponse, struct mydomain::logdevice::Error> >'
  |           `-MaterializeTemporaryExpr 0x227b13a0 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>' xvalue
  |             `-CXXBindTemporaryExpr 0x22776218 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>' (CXXTemporary 0x22776218)
  |               `-StmtExpr 0x227761f0 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>'
  |                 `-CompoundStmt 0x227761d0
  |                   |-DeclStmt 0x22771e88
  |                   | `-VarDecl 0x22771c50  used frame 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame' static constexpr listinit
  |                   |   |-value: Struct
  |                   |   | `-fields: LValue <todo>, LValue <todo>, Int 103
  |                   |   `-InitListExpr 0x22771da8 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame'
  |                   |     |-ImplicitCastExpr 0x22771e00 'const char *' <ArrayToPointerDecay>
  |                   |     | `-PredefinedExpr 0x22771cd8 'const char [8]' lvalue __FUNCTION__
  |                   |     |   `-StringLiteral 0x22771cb8 'const char [8]' lvalue "getData"
  |                   |     |-ImplicitCastExpr 0x22771e18 'const char *' <ArrayToPointerDecay>
  |                   |     | `-StringLiteral 0x22771cf0 'const char [41]' lvalue "logdevice/common/ZookeeperClientBase.cpp"
  |                   |     `-IntegerLiteral 0x22771d30 'int' 103
  |                   `-ExprWithCleanups 0x227761b8 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>'
  |                     `-CXXBindTemporaryExpr 0x22776198 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>' (CXXTemporary 0x22776198)
  |                       `-CallExpr 0x22776160 'folly::Unexpected<Error>':'class folly::Unexpected<struct mydomain::logdevice::Error>'
  |                         |-ImplicitCastExpr 0x22776148 'folly::Unexpected<Error> (*)(const class ErrorStacktrace::Frame *, mydomain::logdevice::Status)' <FunctionToPointerDecay>
  |                         | `-DeclRefExpr 0x227760b8 'folly::Unexpected<Error> (const class ErrorStacktrace::Frame *, mydomain::logdevice::Status)' lvalue Function 0x18b49568 'makeUnexpected' 'folly::Unexpected<Error> (const class ErrorStacktrace::Frame *, mydomain::logdevice::Status)'
  |                         |-UnaryOperator 0x22771fb8 'const mydomain::logdevice::class ErrorStacktrace::Frame *' prefix '&' cannot overflow
  |                         | `-DeclRefExpr 0x22771f68 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame' lvalue Var 0x22771c50 'frame' 'const mydomain::logdevice::class ErrorStacktrace::Frame':'const struct mydomain::logdevice::ErrorStacktrace::Frame'
  |                         `-CallExpr 0x227720e0 'mydomain::logdevice::Status':'enum mydomain::logdevice::E'
  |                           |-ImplicitCastExpr 0x227720c8 'mydomain::logdevice::Status (*)(int)' <FunctionToPointerDecay>
  |                           | `-DeclRefExpr 0x22771ff8 'mydomain::logdevice::Status (int)' lvalue CXXMethod 0x221cddd0 'toStatus' 'mydomain::logdevice::Status (int)'
  |                           `-ImplicitCastExpr 0x22772108 'int' <LValueToRValue>
  |                             `-MemberExpr 0x22772038 'int' lvalue .rc_ 0x21f24480
  |                               `-DeclRefExpr 0x22772018 'struct mydomain::logdevice::zk::GetResponse':'struct mydomain::logdevice::zk::GetResponse' lvalue Var 0x22731508 'result' 'struct mydomain::logdevice::zk::GetResponse':'struct mydomain::logdevice::zk::GetResponse'

Unfortunately I haven't been able to get a small repro. But I wonder if the problem makes sense to you?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D43477/new/

https://reviews.llvm.org/D43477



More information about the llvm-commits mailing list