Skip to content

[clang] Do not diagnose unused deleted operator delete[] #134357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 4, 2025

Conversation

Fznamznon
Copy link
Contributor

For vector deleting dtors support we now also search and save operator delete[]. Avoid diagnosing deleted operator delete[] when doing that because vector deleting dtors are only called when delete[] is present and whenever delete[] is present in the TU it will be diagnosed correctly.

Fixes #134265

For vector deleting dtors support we now also search and save
operator delete[]. Avoid diagnosing deleted operator delete[] when doing that
because vector deleting dtors are only called when delete[] is present and
whenever delete[] is present in the TU it will be diagnosed correctly.

Fixes llvm#134265
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Apr 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 4, 2025

@llvm/pr-subscribers-clang

Author: Mariya Podchishchaeva (Fznamznon)

Changes

For vector deleting dtors support we now also search and save operator delete[]. Avoid diagnosing deleted operator delete[] when doing that because vector deleting dtors are only called when delete[] is present and whenever delete[] is present in the TU it will be diagnosed correctly.

Fixes #134265


Full diff: https://github.com/llvm/llvm-project/pull/134357.diff

6 Files Affected:

  • (modified) clang/include/clang/AST/DeclCXX.h (+1-1)
  • (modified) clang/include/clang/Sema/Sema.h (+2-1)
  • (modified) clang/lib/AST/DeclCXX.cpp (+1-2)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+5-3)
  • (added) clang/test/SemaCXX/gh134265.cpp (+22)
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 764f85b04e6a0..56cec07ec0293 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2878,7 +2878,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
   static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
 
   void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
-  void setOperatorArrayDelete(FunctionDecl *OD, Expr *ThisArg);
+  void setOperatorArrayDelete(FunctionDecl *OD);
 
   const FunctionDecl *getOperatorDelete() const {
     return getCanonicalDecl()->OperatorDelete;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b835697f99670..6bf1caf6bdd18 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8336,7 +8336,8 @@ class Sema final : public SemaBase {
                                               DeclarationName Name);
   FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc,
                                                       CXXRecordDecl *RD,
-                                                      DeclarationName Name);
+                                                      DeclarationName Name,
+                                                      bool Diagnose = true);
 
   /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
   /// @code ::delete ptr; @endcode
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 7aa710ad7309b..fffc50eb0b078 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -3031,8 +3031,7 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) {
   }
 }
 
-void CXXDestructorDecl::setOperatorArrayDelete(FunctionDecl *OD,
-                                               Expr *ThisArg) {
+void CXXDestructorDecl::setOperatorArrayDelete(FunctionDecl *OD) {
   auto *First = cast<CXXDestructorDecl>(getFirstDecl());
   if (OD && !First->OperatorArrayDelete)
     First->OperatorArrayDelete = OD;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 07379c6876731..b86f7118e0b34 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11048,12 +11048,12 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
       // Lookup delete[] too in case we have to emit a vector deleting dtor;
       DeclarationName VDeleteName =
           Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
-      FunctionDecl *ArrOperatorDelete =
-          FindDeallocationFunctionForDestructor(Loc, RD, VDeleteName);
+      FunctionDecl *ArrOperatorDelete = FindDeallocationFunctionForDestructor(
+          Loc, RD, VDeleteName, /*Diagnose=*/false);
       // delete[] in the TU will make sure the operator is referenced and its
       // uses diagnosed, otherwise vector deleting dtor won't be called anyway,
       // so just record it in the destructor.
-      Destructor->setOperatorArrayDelete(ArrOperatorDelete, ThisArg);
+      Destructor->setOperatorArrayDelete(ArrOperatorDelete);
     }
   }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index e43f5e3f75bfe..d5f52cd5853f0 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3265,11 +3265,13 @@ FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
   return Result.FD;
 }
 
-FunctionDecl *Sema::FindDeallocationFunctionForDestructor(
-    SourceLocation Loc, CXXRecordDecl *RD, DeclarationName Name) {
+FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
+                                                          CXXRecordDecl *RD,
+                                                          DeclarationName Name,
+                                                          bool Diagnose) {
 
   FunctionDecl *OperatorDelete = nullptr;
-  if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
+  if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete, Diagnose))
     return nullptr;
   if (OperatorDelete)
     return OperatorDelete;
diff --git a/clang/test/SemaCXX/gh134265.cpp b/clang/test/SemaCXX/gh134265.cpp
new file mode 100644
index 0000000000000..c7bdeb2add0cc
--- /dev/null
+++ b/clang/test/SemaCXX/gh134265.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+struct Foo {
+  virtual ~Foo() {} // expected-error {{attempt to use a deleted function}}
+  static void operator delete(void* ptr) = delete; // expected-note {{explicitly marked deleted here}}
+};
+
+
+struct Bar {
+  virtual ~Bar() {}
+  static void operator delete[](void* ptr) = delete;
+};
+
+struct Baz {
+  virtual ~Baz() {}
+  static void operator delete[](void* ptr) = delete; // expected-note {{explicitly marked deleted here}}
+};
+
+void foobar() {
+  Baz *B = new Baz[10]();
+  delete [] B; // expected-error {{attempt to use a deleted function}}
+}

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but do we need a release note?

@@ -2878,7 +2878,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
void setOperatorArrayDelete(FunctionDecl *OD, Expr *ThisArg);
void setOperatorArrayDelete(FunctionDecl *OD);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like unrelated changes, but the changes themselves are correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is a drive-by removal of unused argument added by a patch that caused the bug this patch is fixing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I do that in a separate commit?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think it's related enough as a drive-by it's fine.

@Fznamznon
Copy link
Contributor Author

Fznamznon commented Apr 4, 2025

LGTM but do we need a release note?

No, it is a fix for a regression caused by a patch committed a couple of days ago.

@AaronBallman
Copy link
Collaborator

LGTM but do we need a release note?

No, it is a fix for a regression caused by a patch committed a couple of days ago.

Excellent, thank you for confirming! LG as-is

@Fznamznon Fznamznon merged commit 16a1d5d into llvm:main Apr 4, 2025
14 checks passed
@zmodem
Copy link
Collaborator

zmodem commented Apr 11, 2025

We're seeing crashes that bisect to this change. Here is a reproducer: https://crbug.com/410001969#comment3

I'll see if I can get something more reduced as well.

@zmodem
Copy link
Collaborator

zmodem commented Apr 11, 2025

Smaller repro:

$ cat /tmp/a.ii
class Trans_NS_cppgc_GarbageCollected {
  void operator delete[](void *);
};

struct ScriptWrappable : Trans_NS_cppgc_GarbageCollected {
  virtual ~ScriptWrappable();
};

struct __declspec(dllexport) ContentIndexEvent : ScriptWrappable {
  ContentIndexEvent();
  ~ContentIndexEvent();
};

ContentIndexEvent::ContentIndexEvent() : ScriptWrappable() {}

ContentIndexEvent::~ContentIndexEvent() = default;


$ build/bin/clang.bad -cc1 -triple x86_64-pc-windows-msvc -emit-obj -fms-extensions /tmp/a.ii
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: build/bin/clang.bad -cc1 -triple x86_64-pc-windows-msvc -emit-obj -fms-extensions /tmp/a.ii
1.      <eof> parser at end of file
2.      Per-file LLVM IR generation
3.      /tmp/a.ii:11:3: Generating code for declaration 'ContentIndexEvent::~ContentIndexEvent'
 #0 0x00005601e55972eb llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (build/bin/clang.bad+0x47392eb)
 #1 0x00005601e55943d6 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x00007f98c8c49e20 (/lib/x86_64-linux-gnu/libc.so.6+0x3fe20)
 #3 0x00005601e591fd10 clang::CodeGen::CodeGenFunction::EmitDeleteCall(clang::FunctionDecl const*, llvm::Value*, clang::QualType, llvm::Value*, clang::CharUnits) (build/bin/clang.bad+0x4ac1d10)
 #4 0x00005601e5e84429 clang::CodeGen::CodeGenFunction::EmitDestructorBody(clang::CodeGen::FunctionArgList&) (build/bin/clang.bad+0x5026429)
 #5 0x00005601e5b09965 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (build/bin/clang.bad+0x4cab965)
 #6 0x00005601e5e33584 clang::CodeGen::CodeGenModule::codegenCXXStructor(clang::GlobalDecl) (build/bin/clang.bad+0x4fd5584)
 #7 0x00005601e5bf86dc (anonymous namespace)::MicrosoftCXXABI::emitCXXStructor(clang::GlobalDecl) MicrosoftCXXABI.cpp:0:0
 #8 0x00005601e5b61d5a clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (build/bin/clang.bad+0x4d03d5a)
 #9 0x00005601e5b6e552 clang::CodeGen::CodeGenModule::EmitDeferred() (build/bin/clang.bad+0x4d10552)
#10 0x00005601e5b6f453 clang::CodeGen::CodeGenModule::Release() (build/bin/clang.bad+0x4d11453)
#11 0x00005601e5f5e87e (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
#12 0x00005601e5f5994d clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (build/bin/clang.bad+0x50fb94d)
#13 0x00005601e7a88ddc clang::ParseAST(clang::Sema&, bool, bool) (build/bin/clang.bad+0x6c2addc)
#14 0x00005601e62948b3 clang::FrontendAction::Execute() (build/bin/clang.bad+0x54368b3)
#15 0x00005601e621395e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (build/bin/clang.bad+0x53b595e)
#16 0x00005601e637be07 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (build/bin/clang.bad+0x551de07)
#17 0x00005601e21737ef cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (build/bin/clang.bad+0x13157ef)
#18 0x00005601e2169b40 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#19 0x00005601e216d360 clang_main(int, char**, llvm::ToolContext const&) (build/bin/clang.bad+0x130f360)
#20 0x00005601e20123b3 main (build/bin/clang.bad+0x11b43b3)
#21 0x00007f98c8c33d68 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#22 0x00007f98c8c33e25 call_init ./csu/../csu/libc-start.c:128:20
#23 0x00007f98c8c33e25 __libc_start_main ./csu/../csu/libc-start.c:347:5
#24 0x00005601e2169171 _start (build/bin/clang.bad+0x130b171)
Segmentation fault (core dumped)

Fznamznon added a commit to Fznamznon/llvm-project that referenced this pull request Apr 14, 2025
zmodem pushed a commit that referenced this pull request Apr 14, 2025
Finding operator delete[] is still problematic, without it the extension
is a security hazard, so reverting until the problem with operator
delete[] is figured out.

This reverts the following PRs:
Reland [MS][clang] Add support for vector deleting destructors (#133451)
[MS][clang] Make sure vector deleting dtor calls correct operator delete (#133950)
[MS][clang] Fix crash on deletion of array of pointers (#134088)
[clang] Do not diagnose unused deleted operator delete[] (#134357)
[MS][clang] Error about ambiguous operator delete[] only when required (#135041)
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
Finding operator delete[] is still problematic, without it the extension
is a security hazard, so reverting until the problem with operator
delete[] is figured out.

This reverts the following PRs:
Reland [MS][clang] Add support for vector deleting destructors (llvm#133451)
[MS][clang] Make sure vector deleting dtor calls correct operator delete (llvm#133950)
[MS][clang] Fix crash on deletion of array of pointers (llvm#134088)
[clang] Do not diagnose unused deleted operator delete[] (llvm#134357)
[MS][clang] Error about ambiguous operator delete[] only when required (llvm#135041)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect error reported for deleted function
4 participants