diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 06b0491442673..aa7e14329a21b 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1645,11 +1645,22 @@ SourceLocation CallExpr::getBeginLoc() const { if (const auto *OCE = dyn_cast(this)) return OCE->getBeginLoc(); - if (const auto *Method = - dyn_cast_if_present(getCalleeDecl()); - Method && Method->isExplicitObjectMemberFunction()) { - assert(getNumArgs() > 0 && getArg(0)); - return getArg(0)->getBeginLoc(); + // A non-dependent call to a member function with an explicit object parameter + // is modelled with the object expression being the first argument, e.g. in + // `o.f(x)`, the callee will be just `f`, and `o` will be the first argument. + // Since the first argument is written before the callee, the expression's + // begin location should come from the first argument. + // This does not apply to dependent calls, which are modelled with `o.f` + // being the callee. + if (!isTypeDependent()) { + if (const auto *Method = + dyn_cast_if_present(getCalleeDecl()); + Method && Method->isExplicitObjectMemberFunction()) { + bool HasFirstArg = getNumArgs() > 0 && getArg(0); + assert(HasFirstArg); + if (HasFirstArg) + return getArg(0)->getBeginLoc(); + } } SourceLocation begin = getCallee()->getBeginLoc(); diff --git a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp index 854d12b4cdba6..abe9d6a5b5bc6 100644 --- a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp +++ b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp @@ -13,3 +13,16 @@ void main() { // CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)' } } + +namespace GH1269720 { +template +struct S { + void f(this S&); + void g(S s) { + s.f(); + } + // CHECK: CallExpr 0x{{[^ ]*}} '' + // CHECK-NEXT: `-MemberExpr 0x{{[^ ]*}} '' .f + // CHECK-NEXT: `-DeclRefExpr 0x{{[^ ]*}} 'S' lvalue ParmVar 0x{{[^ ]*}} 's' 'S' +}; +}