https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/152185
Do it only if we will end up skipping the initializer anyway because it's a trivial copy or move constructor. >From 293e92d5f2273d7aedcc0567bda17f46e048ae35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 5 Aug 2025 20:01:57 +0200 Subject: [PATCH] [clang][bytecode] Overrride locs for certain CXXConstructExprs Do it only if we will end up skipping the initializer anyway because it's a trivial copy or move constructor. --- clang/lib/AST/ByteCode/Compiler.cpp | 27 +++++++++++++++------ clang/lib/AST/ByteCode/InterpFrame.cpp | 5 ++++ clang/test/AST/ByteCode/cxx11.cpp | 12 +++++++++ clang/test/SemaCXX/constexpr-value-init.cpp | 1 + 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 4ab4dee5b853c..cc99efa01b83e 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -5997,6 +5997,23 @@ bool Compiler<Emitter>::checkLiteralType(const Expr *E) { return this->emitCheckLiteralType(E->getType().getTypePtr(), E); } +static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init) { + const Expr *InitExpr = Init->getInit(); + + if (!Init->isWritten() && !Init->isInClassMemberInitializer() && + !isa<CXXConstructExpr>(InitExpr)) + return true; + + if (const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) { + const CXXConstructorDecl *Ctor = CE->getConstructor(); + if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() && + Ctor->isTrivial()) + return true; + } + + return false; +} + template <class Emitter> bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) { assert(!ReturnType); @@ -6071,10 +6088,7 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) { const Record::Field *F = R->getField(Member); LocOverrideScope<Emitter> LOS(this, SourceInfo{}, - !Init->isWritten() && - !Init->isInClassMemberInitializer() && - (!isa<CXXConstructExpr>(InitExpr) || - Member->isAnonymousStructOrUnion())); + initNeedsOverridenLoc(Init)); if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion)) return false; } else if (const Type *Base = Init->getBaseClass()) { @@ -6104,10 +6118,7 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) { return false; } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) { LocOverrideScope<Emitter> LOS(this, SourceInfo{}, - !Init->isWritten() && - !Init->isInClassMemberInitializer() && - !isa<CXXConstructExpr>(InitExpr)); - + initNeedsOverridenLoc(Init)); assert(IFD->getChainingSize() >= 2); unsigned NestedFieldOffset = 0; diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp index 14f99c7b76847..93421927d2ea9 100644 --- a/clang/lib/AST/ByteCode/InterpFrame.cpp +++ b/clang/lib/AST/ByteCode/InterpFrame.cpp @@ -133,6 +133,11 @@ static bool shouldSkipInBacktrace(const Function *F) { MD && MD->getParent()->isAnonymousStructOrUnion()) return true; + if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FD); + Ctor && Ctor->isDefaulted() && Ctor->isTrivial() && + Ctor->isCopyOrMoveConstructor() && Ctor->inits().empty()) + return true; + return false; } diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index bb8aca27eb965..7aecf23b0f149 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -318,3 +318,15 @@ namespace PR19010 { }; void test() { constexpr Test t; } } + +namespace ReadMutableInCopyCtor { + struct G { + struct X {}; + union U { X a; }; + mutable U u; // both-note {{declared here}} + }; + constexpr G g1 = {}; + constexpr G g2 = g1; // both-error {{must be initialized by a constant expression}} \ + // both-note {{read of mutable member 'u'}} \ + // both-note {{in call to 'G(g1)'}} +} diff --git a/clang/test/SemaCXX/constexpr-value-init.cpp b/clang/test/SemaCXX/constexpr-value-init.cpp index 3314174a0ea17..18fa9cf0736a6 100644 --- a/clang/test/SemaCXX/constexpr-value-init.cpp +++ b/clang/test/SemaCXX/constexpr-value-init.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -Wno-uninitialized -std=c++17 -fsyntax-only -verify +// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter struct A { constexpr A() : a(b + 1), b(a + 1) {} // expected-note 5{{outside its lifetime}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits