[clang] 3ea55d3 - [clang][bytecode] Add a source location to destructor calls (#110121)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 26 07:51:01 PDT 2024
Author: Timm Baeder
Date: 2024-09-26T16:50:56+02:00
New Revision: 3ea55d3cb0655c7863596321e132b59158325433
URL: https://github.com/llvm/llvm-project/commit/3ea55d3cb0655c7863596321e132b59158325433
DIFF: https://github.com/llvm/llvm-project/commit/3ea55d3cb0655c7863596321e132b59158325433.diff
LOG: [clang][bytecode] Add a source location to destructor calls (#110121)
The added test case is still diagnosed differently, but I'm not sure
which version is better.
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/lib/AST/ByteCode/Compiler.h
clang/lib/AST/ByteCode/Descriptor.cpp
clang/lib/AST/ByteCode/Descriptor.h
clang/test/AST/ByteCode/cxx23.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 6e3ea6bd070bc1..93008acde65f9d 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5293,7 +5293,7 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
if (!D->isPrimitive() && !D->isPrimitiveArray()) {
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
return false;
- if (!this->emitDestruction(D))
+ if (!this->emitDestruction(D, SourceInfo{}))
return false;
if (!this->emitPopPtr(SourceInfo{}))
return false;
@@ -5307,7 +5307,7 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
return false;
- if (!this->emitRecordDestruction(Base.R))
+ if (!this->emitRecordDestruction(Base.R, {}))
return false;
if (!this->emitPopPtr(SourceInfo{}))
return false;
@@ -6148,7 +6148,7 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
/// on the stack.
/// Emit destruction of record types (or arrays of record types).
template <class Emitter>
-bool Compiler<Emitter>::emitRecordDestruction(const Record *R) {
+bool Compiler<Emitter>::emitRecordDestruction(const Record *R, SourceInfo Loc) {
assert(R);
assert(!R->isAnonymousUnion());
const CXXDestructorDecl *Dtor = R->getDestructor();
@@ -6161,15 +6161,16 @@ bool Compiler<Emitter>::emitRecordDestruction(const Record *R) {
return false;
assert(DtorFunc->hasThisPointer());
assert(DtorFunc->getNumParams() == 1);
- if (!this->emitDupPtr(SourceInfo{}))
+ if (!this->emitDupPtr(Loc))
return false;
- return this->emitCall(DtorFunc, 0, SourceInfo{});
+ return this->emitCall(DtorFunc, 0, Loc);
}
/// When calling this, we have a pointer of the local-to-destroy
/// on the stack.
/// Emit destruction of record types (or arrays of record types).
template <class Emitter>
-bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) {
+bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
+ SourceInfo Loc) {
assert(Desc);
assert(!Desc->isPrimitive());
assert(!Desc->isPrimitiveArray());
@@ -6193,13 +6194,13 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) {
}
for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
- if (!this->emitConstUint64(I, SourceInfo{}))
+ if (!this->emitConstUint64(I, Loc))
return false;
- if (!this->emitArrayElemPtrUint64(SourceInfo{}))
+ if (!this->emitArrayElemPtrUint64(Loc))
return false;
- if (!this->emitDestruction(ElemDesc))
+ if (!this->emitDestruction(ElemDesc, Loc))
return false;
- if (!this->emitPopPtr(SourceInfo{}))
+ if (!this->emitPopPtr(Loc))
return false;
}
return true;
@@ -6209,7 +6210,7 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) {
if (Desc->ElemRecord->isAnonymousUnion())
return true;
- return this->emitRecordDestruction(Desc->ElemRecord);
+ return this->emitRecordDestruction(Desc->ElemRecord, Loc);
}
namespace clang {
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 2dfa187713a803..94c0a5cb295b08 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -364,8 +364,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool emitComplexBoolCast(const Expr *E);
bool emitComplexComparison(const Expr *LHS, const Expr *RHS,
const BinaryOperator *E);
- bool emitRecordDestruction(const Record *R);
- bool emitDestruction(const Descriptor *Desc);
+ bool emitRecordDestruction(const Record *R, SourceInfo Loc);
+ bool emitDestruction(const Descriptor *Desc, SourceInfo Loc);
unsigned collectBaseOffset(const QualType BaseType,
const QualType DerivedType);
bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD);
@@ -540,7 +540,7 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
return false;
- if (!this->Ctx->emitDestruction(Local.Desc))
+ if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
return false;
if (!this->Ctx->emitPopPtr(E))
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp
index 05ece907af42f4..44a7b88b2a1ee9 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -15,6 +15,7 @@
#include "Pointer.h"
#include "PrimType.h"
#include "Record.h"
+#include "Source.h"
using namespace clang;
using namespace clang::interp;
@@ -423,6 +424,14 @@ SourceLocation Descriptor::getLocation() const {
llvm_unreachable("Invalid descriptor type");
}
+SourceInfo Descriptor::getLoc() const {
+ if (const auto *D = Source.dyn_cast<const Decl *>())
+ return SourceInfo(D);
+ if (const auto *E = Source.dyn_cast<const Expr *>())
+ return SourceInfo(E);
+ llvm_unreachable("Invalid descriptor type");
+}
+
bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
InitMap::InitMap(unsigned N)
diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h
index 82f90430f7f4e5..5460199e0e991a 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -21,6 +21,7 @@ namespace clang {
namespace interp {
class Block;
class Record;
+class SourceInfo;
struct InitMap;
struct Descriptor;
enum PrimType : unsigned;
@@ -194,6 +195,7 @@ struct Descriptor final {
QualType getType() const;
QualType getElemQualType() const;
SourceLocation getLocation() const;
+ SourceInfo getLoc() const;
const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); }
const Expr *asExpr() const { return Source.dyn_cast<const Expr *>(); }
diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp
index 9d7e9d753e6d2f..3c50c8927304c0 100644
--- a/clang/test/AST/ByteCode/cxx23.cpp
+++ b/clang/test/AST/ByteCode/cxx23.cpp
@@ -269,3 +269,23 @@ namespace AnonUnionDtor {
void bar() { foo(); }
}
+
+/// FIXME: The two interpreters disagree about there to diagnose the non-constexpr destructor call.
+namespace NonLiteralDtorInParam {
+ class NonLiteral { // all20-note {{is not an aggregate and has no constexpr constructors other than copy or move constructors}}
+ public:
+ NonLiteral() {}
+ ~NonLiteral() {} // all23-note {{declared here}}
+ };
+ constexpr int F2(NonLiteral N) { // all20-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} \
+ // ref23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
+ return 8;
+ }
+
+
+ void test() {
+ NonLiteral L;
+ constexpr auto D = F2(L); // all23-error {{must be initialized by a constant expression}} \
+ // expected23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
+ }
+}
More information about the cfe-commits
mailing list