diff options
Diffstat (limited to 'clang/lib/Analysis/ThreadSafetyCommon.cpp')
| -rw-r--r-- | clang/lib/Analysis/ThreadSafetyCommon.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index cbcfefdc5254..050daee1168d 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -135,14 +135,30 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, Ctx.NumArgs = CE->getNumArgs(); Ctx.FunArgs = CE->getArgs(); } else if (const auto *CE = dyn_cast<CallExpr>(DeclExp)) { - Ctx.NumArgs = CE->getNumArgs(); - Ctx.FunArgs = CE->getArgs(); + // Calls to operators that are members need to be treated like member calls. + if (isa<CXXOperatorCallExpr>(CE) && isa<CXXMethodDecl>(D)) { + Ctx.SelfArg = CE->getArg(0); + Ctx.SelfArrow = false; + Ctx.NumArgs = CE->getNumArgs() - 1; + Ctx.FunArgs = CE->getArgs() + 1; + } else { + Ctx.NumArgs = CE->getNumArgs(); + Ctx.FunArgs = CE->getArgs(); + } } else if (const auto *CE = dyn_cast<CXXConstructExpr>(DeclExp)) { Ctx.SelfArg = nullptr; // Will be set below Ctx.NumArgs = CE->getNumArgs(); Ctx.FunArgs = CE->getArgs(); } + // Usually we want to substitute the self-argument for "this", but lambdas + // are an exception: "this" on or in a lambda call operator doesn't refer + // to the lambda, but to captured "this" in the context it was created in. + // This can happen for operator calls and member calls, so fix it up here. + if (const auto *CMD = dyn_cast<CXXMethodDecl>(D)) + if (CMD->getParent()->isLambda()) + Ctx.SelfArg = nullptr; + if (Self) { assert(!Ctx.SelfArg && "Ambiguous self argument"); assert(isa<FunctionDecl>(D) && "Self argument requires function"); @@ -326,7 +342,7 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE, } assert(I == 0); - return Ctx->FunArgs.get<til::SExpr *>(); + return cast<til::SExpr *>(Ctx->FunArgs); } } // Map the param back to the param of the original function declaration |
