https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/177551
in compile-time backtraces. The two test cases used to be rendered as `foo(s, 0) and `foo2(s)`. >From 90b980dded80a8525700f7eef4e4e0f98fd4f7ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Fri, 23 Jan 2026 10:16:49 +0100 Subject: [PATCH] [clang][ExprConst] Fix rendering of explicit this parameters in compile-time backtraces. The two test cases used to be rendered as `foo(s, 0) and `foo2(s)`. --- clang/lib/AST/ByteCode/InterpFrame.cpp | 17 +++++++----- clang/lib/AST/ExprConstant.cpp | 25 +++++++++--------- clang/test/SemaCXX/cxx2b-deducing-this.cpp | 30 ++++++++++++++++++++++ 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp index a9f8823613b0a..5a103e5af38f8 100644 --- a/clang/lib/AST/ByteCode/InterpFrame.cpp +++ b/clang/lib/AST/ByteCode/InterpFrame.cpp @@ -158,8 +158,14 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const { const Expr *CallExpr = Caller->getExpr(getRetPC()); const FunctionDecl *F = getCallee(); - bool IsMemberCall = isa<CXXMethodDecl>(F) && !isa<CXXConstructorDecl>(F) && - cast<CXXMethodDecl>(F)->isImplicitObjectMemberFunction(); + + bool IsMemberCall = false; + bool ExplicitInstanceParam = false; + if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) { + IsMemberCall = !isa<CXXConstructorDecl>(MD) && !MD->isStatic(); + ExplicitInstanceParam = MD->isExplicitObjectMemberFunction(); + } + if (Func->hasThisPointer() && IsMemberCall) { if (const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) { const Expr *Object = MCE->getImplicitObjectArgument(); @@ -190,12 +196,9 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const { unsigned Off = 0; Off += Func->hasRVO() ? primSize(PT_Ptr) : 0; - Off += (Func->hasThisPointer() && !Func->isThisPointerExplicit()) - ? primSize(PT_Ptr) - : 0; - + Off += Func->hasThisPointer() ? primSize(PT_Ptr) : 0; llvm::ListSeparator Comma; - for (unsigned I = 0, N = F->getNumParams(); I < N; ++I) { + for (unsigned I = ExplicitInstanceParam, N = F->getNumParams(); I != N; ++I) { OS << Comma; QualType Ty = F->getParamDecl(I)->getType(); PrimType PrimTy = S.Ctx.classify(Ty).value_or(PT_Ptr); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 857688ed8039d..deb08d4bddb19 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1973,10 +1973,12 @@ APValue *EvalInfo::createHeapAlloc(const Expr *E, QualType T, LValue &LV) { /// Produce a string describing the given constexpr call. void CallStackFrame::describe(raw_ostream &Out) const { - unsigned ArgIndex = 0; - bool IsMemberCall = - isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) && - cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction(); + bool IsMemberCall = false; + bool ExplicitInstanceParam = false; + if (const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) { + IsMemberCall = !isa<CXXConstructorDecl>(MD) && !MD->isStatic(); + ExplicitInstanceParam = MD->isExplicitObjectMemberFunction(); + } if (!IsMemberCall) Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(), @@ -2012,20 +2014,17 @@ void CallStackFrame::describe(raw_ostream &Out) const { Out << '('; - for (FunctionDecl::param_const_iterator I = Callee->param_begin(), - E = Callee->param_end(); I != E; ++I, ++ArgIndex) { - if (ArgIndex > (unsigned)IsMemberCall) - Out << ", "; + llvm::ListSeparator Comma; + for (unsigned ArgIndex = ExplicitInstanceParam, N = Callee->getNumParams(); + ArgIndex != N; ++ArgIndex) { + Out << Comma; - const ParmVarDecl *Param = *I; - APValue *V = Info.getParamSlot(Arguments, Param); + const ParmVarDecl *Param = Callee->getParamDecl(ArgIndex); + const APValue *V = Info.getParamSlot(Arguments, Param); if (V) V->printPretty(Out, Info.Ctx, Param->getType()); else Out << "<...>"; - - if (ArgIndex == 0 && IsMemberCall) - Out << "->" << *Callee << '('; } Out << ')'; diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index a9e31c3d06676..7b4924a1e5285 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -1400,3 +1400,33 @@ a void Bar(this int) { // expected-note {{candidate function}} } } + +namespace ConstexprBacktrace { + struct S { + constexpr int foo(this const S& self, int b) { + (void)(1/b); // expected-note {{division by zero}} + return 0; + } + constexpr int foo2(this const S& self) { + (void)(1/0); // expected-note {{division by zero}} \ + // expected-warning {{division by zero is undefined}} + return 0; + } + }; + + constexpr bool test() { + S s; + s.foo(0); // expected-note {{in call to 's.foo(0)'}} + return true; + } + static_assert(test()); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} + + constexpr bool test2() { + S s; + s.foo2(); // expected-note {{in call to 's.foo2()'}} + return true; + } + static_assert(test2()); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
