@@ -2062,21 +2062,36 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
20622062template <class Emitter >
20632063bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
20642064 const FunctionDecl *FuncDecl,
2065- bool Activate) {
2065+ bool Activate, bool IsOperatorCall ) {
20662066 assert (VarScope->getKind () == ScopeKind::Call);
20672067 llvm::BitVector NonNullArgs;
20682068 if (FuncDecl && FuncDecl->hasAttr <NonNullAttr>())
20692069 NonNullArgs = collectNonNullArgs (FuncDecl, Args);
20702070
2071+ bool ExplicitMemberFn = false ;
2072+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2073+ ExplicitMemberFn = MD->isExplicitObjectMemberFunction ();
2074+
20712075 unsigned ArgIndex = 0 ;
20722076 for (const Expr *Arg : Args) {
20732077 if (canClassify (Arg)) {
20742078 if (!this ->visit (Arg))
20752079 return false ;
20762080 } else {
20772081
2078- std::optional<unsigned > LocalIndex = allocateLocal (
2079- Arg, Arg->getType (), /* ExtendingDecl=*/ nullptr , ScopeKind::Call);
2082+ DeclTy Source = Arg;
2083+ if (FuncDecl) {
2084+ // Try to use the parameter declaration instead of the argument
2085+ // expression as a source.
2086+ unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2087+ if (DeclIndex < FuncDecl->getNumParams ())
2088+ Source = FuncDecl->getParamDecl (ArgIndex - IsOperatorCall +
2089+ ExplicitMemberFn);
2090+ }
2091+
2092+ std::optional<unsigned > LocalIndex =
2093+ allocateLocal (std::move (Source), Arg->getType (),
2094+ /* ExtendingDecl=*/ nullptr , ScopeKind::Call);
20802095 if (!LocalIndex)
20812096 return false ;
20822097
@@ -4489,14 +4504,6 @@ template <class Emitter>
44894504unsigned Compiler<Emitter>::allocateLocalPrimitive(
44904505 DeclTy &&Src, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl,
44914506 ScopeKind SC, bool IsConstexprUnknown) {
4492- // Make sure we don't accidentally register the same decl twice.
4493- if (const auto *VD =
4494- dyn_cast_if_present<ValueDecl>(Src.dyn_cast <const Decl *>())) {
4495- assert (!P.getGlobal (VD));
4496- assert (!Locals.contains (VD));
4497- (void )VD;
4498- }
4499-
45004507 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
45014508 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
45024509 // or isa<MaterializeTemporaryExpr>().
@@ -4518,19 +4525,11 @@ std::optional<unsigned>
45184525Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty,
45194526 const ValueDecl *ExtendingDecl, ScopeKind SC,
45204527 bool IsConstexprUnknown) {
4521- // Make sure we don't accidentally register the same decl twice.
4522- if ([[maybe_unused]] const auto *VD =
4523- dyn_cast_if_present<ValueDecl>(Src.dyn_cast <const Decl *>())) {
4524- assert (!P.getGlobal (VD));
4525- assert (!Locals.contains (VD));
4526- }
4527-
45284528 const ValueDecl *Key = nullptr ;
45294529 const Expr *Init = nullptr ;
45304530 bool IsTemporary = false ;
45314531 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast <const Decl *>())) {
45324532 Key = VD;
4533- Ty = VD->getType ();
45344533
45354534 if (const auto *VarD = dyn_cast<VarDecl>(VD))
45364535 Init = VarD->getInit ();
@@ -5167,7 +5166,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
51675166 return false ;
51685167 }
51695168
5170- if (!this ->visitCallArgs (Args, FuncDecl, IsAssignmentOperatorCall))
5169+ if (!this ->visitCallArgs (Args, FuncDecl, IsAssignmentOperatorCall,
5170+ isa<CXXOperatorCallExpr>(E)))
51715171 return false ;
51725172
51735173 // Undo the argument reversal we did earlier.
0 commit comments