@@ -2062,21 +2062,36 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
2062
2062
template <class Emitter >
2063
2063
bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
2064
2064
const FunctionDecl *FuncDecl,
2065
- bool Activate) {
2065
+ bool Activate, bool IsOperatorCall ) {
2066
2066
assert (VarScope->getKind () == ScopeKind::Call);
2067
2067
llvm::BitVector NonNullArgs;
2068
2068
if (FuncDecl && FuncDecl->hasAttr <NonNullAttr>())
2069
2069
NonNullArgs = collectNonNullArgs (FuncDecl, Args);
2070
2070
2071
+ bool ExplicitMemberFn = false ;
2072
+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2073
+ ExplicitMemberFn = MD->isExplicitObjectMemberFunction ();
2074
+
2071
2075
unsigned ArgIndex = 0 ;
2072
2076
for (const Expr *Arg : Args) {
2073
2077
if (canClassify (Arg)) {
2074
2078
if (!this ->visit (Arg))
2075
2079
return false ;
2076
2080
} else {
2077
2081
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);
2080
2095
if (!LocalIndex)
2081
2096
return false ;
2082
2097
@@ -4489,14 +4504,6 @@ template <class Emitter>
4489
4504
unsigned Compiler<Emitter>::allocateLocalPrimitive(
4490
4505
DeclTy &&Src, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl,
4491
4506
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
-
4500
4507
// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
4501
4508
// (int){12} in C. Consider using Expr::isTemporaryObject() instead
4502
4509
// or isa<MaterializeTemporaryExpr>().
@@ -4518,19 +4525,11 @@ std::optional<unsigned>
4518
4525
Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty,
4519
4526
const ValueDecl *ExtendingDecl, ScopeKind SC,
4520
4527
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
-
4528
4528
const ValueDecl *Key = nullptr ;
4529
4529
const Expr *Init = nullptr ;
4530
4530
bool IsTemporary = false ;
4531
4531
if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast <const Decl *>())) {
4532
4532
Key = VD;
4533
- Ty = VD->getType ();
4534
4533
4535
4534
if (const auto *VarD = dyn_cast<VarDecl>(VD))
4536
4535
Init = VarD->getInit ();
@@ -5167,7 +5166,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
5167
5166
return false ;
5168
5167
}
5169
5168
5170
- if (!this ->visitCallArgs (Args, FuncDecl, IsAssignmentOperatorCall))
5169
+ if (!this ->visitCallArgs (Args, FuncDecl, IsAssignmentOperatorCall,
5170
+ isa<CXXOperatorCallExpr>(E)))
5171
5171
return false ;
5172
5172
5173
5173
// Undo the argument reversal we did earlier.
0 commit comments