Author: Timm Baeder Date: 2026-01-28T12:59:24+01:00 New Revision: 7c3a2113febd1df48b31c2ada5cbcf1935053807
URL: https://github.com/llvm/llvm-project/commit/7c3a2113febd1df48b31c2ada5cbcf1935053807 DIFF: https://github.com/llvm/llvm-project/commit/7c3a2113febd1df48b31c2ada5cbcf1935053807.diff LOG: [clang][ExprConst] Fix rendering of explicit this parameters (#177551) in compile-time backtraces. The two test cases used to be rendered as `foo(s, 0)` and `foo2(s)`. Added: Modified: clang/lib/AST/ByteCode/InterpFrame.cpp clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/cxx2b-deducing-this.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp index a9f8823613b0a..ef70d9526c194 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,14 +196,12 @@ 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 (const ParmVarDecl *Param : + F->parameters().slice(ExplicitInstanceParam)) { OS << Comma; - QualType Ty = F->getParamDecl(I)->getType(); + QualType Ty = Param->getType(); PrimType PrimTy = S.Ctx.classify(Ty).value_or(PT_Ptr); TYPE_SWITCH(PrimTy, print(OS, stackRef<T>(Off), S.getASTContext(), Ty)); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 857688ed8039d..58748fa5ba49b 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(), @@ -2007,25 +2009,19 @@ void CallStackFrame::describe(raw_ostream &Out) const { } Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(), /*Qualified=*/false); - IsMemberCall = false; } Out << '('; - for (FunctionDecl::param_const_iterator I = Callee->param_begin(), - E = Callee->param_end(); I != E; ++I, ++ArgIndex) { - if (ArgIndex > (unsigned)IsMemberCall) - Out << ", "; - - const ParmVarDecl *Param = *I; - APValue *V = Info.getParamSlot(Arguments, Param); + llvm::ListSeparator Comma; + for (const ParmVarDecl *Param : + Callee->parameters().slice(ExplicitInstanceParam)) { + Out << Comma; + 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
