[clang] [clang][bytecode] Diagnose delete with non-virtual dtor (PR #114373)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 31 01:13:06 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
... in the base class.
---
Full diff: https://github.com/llvm/llvm-project/pull/114373.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+18)
- (modified) clang/test/AST/ByteCode/new-delete.cpp (+10)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 513d4512b45cff..3094d7986f9986 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1002,6 +1002,13 @@ static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
return runRecordDestructor(S, OpPC, Pointer(const_cast<Block *>(B)), Desc);
}
+static bool hasVirtualDestructor(QualType T) {
+ if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
+ if (const CXXDestructorDecl *DD = RD->getDestructor())
+ return DD->isVirtual();
+ return false;
+}
+
bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
bool IsGlobalDelete) {
if (!CheckDynamicMemoryAllocation(S, OpPC))
@@ -1019,9 +1026,20 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
return true;
// Remove base casts.
+ QualType InitialType = Ptr.getType();
while (Ptr.isBaseClass())
Ptr = Ptr.getBase();
+ // For the non-array case, the types must match if the static type
+ // does not have a virtual destructor.
+ if (!DeleteIsArrayForm && Ptr.getType() != InitialType &&
+ !hasVirtualDestructor(InitialType)) {
+ S.FFDiag(S.Current->getSource(OpPC),
+ diag::note_constexpr_delete_base_nonvirt_dtor)
+ << InitialType << Ptr.getType();
+ return false;
+ }
+
if (!Ptr.isRoot() || Ptr.isOnePastEnd() || Ptr.isArrayElement()) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_delete_subobject)
diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp
index 94fe2d4497df6a..31c8da93a3a643 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -569,6 +569,16 @@ namespace CastedDelete {
return a;
}
static_assert(vdtor_1() == 1);
+
+ constexpr int foo() { // both-error {{never produces a constant expression}}
+ struct S {};
+ struct T : S {};
+ S *p = new T();
+ delete p; // both-note 2{{delete of object with dynamic type 'T' through pointer to base class type 'S' with non-virtual destructor}}
+ return 1;
+ }
+ static_assert(foo() == 1); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
}
constexpr void use_after_free_2() { // both-error {{never produces a constant expression}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/114373
More information about the cfe-commits
mailing list