Skip to content
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

[clang] Enable sized deallocation by default in C++14 onwards #83774

Merged
merged 1 commit into from
Apr 26, 2024

Conversation

wangpc-pp
Copy link
Contributor

@wangpc-pp wangpc-pp commented Mar 4, 2024

Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

Some buildbots failed last time and I hope the owners may help me to
find the causes as I may not have such environments.

Fixes #60061

@wangpc-pp wangpc-pp requested review from Endilll and a team as code owners March 4, 2024 06:47
@llvmbot llvmbot added clang Clang issues not falling into any other category clang-tools-extra libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. backend:SystemZ clangd clang-tidy clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" coroutines C++20 coroutines labels Mar 4, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 4, 2024

@llvm/pr-subscribers-clang-tools-extra
@llvm/pr-subscribers-clangd
@llvm/pr-subscribers-coroutines
@llvm/pr-subscribers-backend-systemz
@llvm/pr-subscribers-clang-tidy
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-libcxx

Author: Wang Pengcheng (wangpc-pp)

Changes

Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

Some buildbots failed last time and I hope the owners may help me to
find the causes as I may not have such environments.


Patch is 53.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83774.diff

41 Files Affected:

  • (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+3-1)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp (-10)
  • (modified) clang/docs/ReleaseNotes.rst (+4)
  • (added) clang/include/clang/Basic/SizedDeallocation.h (+44)
  • (modified) clang/include/clang/Driver/Options.td (+3-2)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+9-4)
  • (modified) clang/lib/Driver/ToolChains/Darwin.cpp (+38-3)
  • (modified) clang/lib/Driver/ToolChains/Darwin.h (+4)
  • (modified) clang/lib/Driver/ToolChains/ZOS.cpp (+6)
  • (modified) clang/test/AST/ast-dump-expr-json.cpp (+1-1)
  • (modified) clang/test/AST/ast-dump-expr.cpp (+1-1)
  • (modified) clang/test/AST/ast-dump-stmt-json.cpp (+241-3)
  • (modified) clang/test/Analysis/cxxnewexpr-callback.cpp (+2-2)
  • (modified) clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp (+1-1)
  • (modified) clang/test/CXX/drs/dr292.cpp (+3-3)
  • (modified) clang/test/CXX/expr/expr.unary/expr.new/p14.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp (+5-5)
  • (modified) clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/delete-two-arg.cpp (+3-1)
  • (modified) clang/test/CodeGenCXX/delete.cpp (+7-5)
  • (modified) clang/test/CodeGenCXX/dllimport.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/new.cpp (+3-3)
  • (modified) clang/test/CodeGenCoroutines/coro-aligned-alloc-2.cpp (-2)
  • (modified) clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp (+4-2)
  • (modified) clang/test/CodeGenCoroutines/coro-alloc.cpp (+4-2)
  • (modified) clang/test/CodeGenCoroutines/coro-cleanup.cpp (+4-2)
  • (modified) clang/test/CodeGenCoroutines/coro-dealloc.cpp (-2)
  • (modified) clang/test/CodeGenCoroutines/coro-gro.cpp (+2-1)
  • (modified) clang/test/CodeGenCoroutines/pr56919.cpp (+6-3)
  • (modified) clang/test/Lexer/cxx-features.cpp (+10-10)
  • (modified) clang/test/PCH/cxx1z-aligned-alloc.cpp (+5-5)
  • (modified) clang/test/SemaCXX/MicrosoftExtensions.cpp (+7-1)
  • (modified) clang/test/SemaCXX/builtin-operator-new-delete.cpp (+1-1)
  • (modified) clang/test/SemaCXX/cxx1y-sized-deallocation.cpp (+1-1)
  • (modified) clang/test/SemaCXX/unavailable_aligned_allocation.cpp (+9-6)
  • (modified) clang/unittests/StaticAnalyzer/CallEventTest.cpp (+1-1)
  • (modified) clang/www/cxx_status.html (+5-6)
  • (modified) libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp (+3)
  • (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp (+5-3)
  • (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp (+5-3)
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 0af6036734ba53..1b7b96281dfaa5 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -839,7 +839,9 @@ TEST_F(TargetDeclTest, OverloadExpr) {
       [[delete]] x;
     }
   )cpp";
-  EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept");
+  // Sized deallocation is enabled by default in C++14 onwards.
+  EXPECT_DECLS("CXXDeleteExpr",
+               "void operator delete(void *, unsigned long) noexcept");
 }
 
 TEST_F(TargetDeclTest, DependentExprs) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp
index 78f021144b2e19..f86fe8a4c5b14f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp
@@ -12,16 +12,6 @@ struct S {
 // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
 void *operator new(size_t size) noexcept(false);
 
-struct T {
-  // Sized deallocations are not enabled by default, and so this new/delete pair
-  // does not match. However, we expect only one warning, for the new, because
-  // the operator delete is a placement delete and we do not warn on mismatching
-  // placement operations.
-  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
-  void *operator new(size_t size) noexcept;
-  void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled
-};
-
 struct U {
   void *operator new(size_t size) noexcept;
   void operator delete(void *ptr) noexcept;
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6f6ce7c68a7a71..fb491a257dc715 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -72,6 +72,10 @@ sections with improvements to Clang's support for those languages.
 C++ Language Changes
 --------------------
 
+C++14 Feature Support
+^^^^^^^^^^^^^^^^^^^^^
+- Sized deallocation is enabled by default in C++14 onwards.
+
 C++20 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/include/clang/Basic/SizedDeallocation.h b/clang/include/clang/Basic/SizedDeallocation.h
new file mode 100644
index 00000000000000..e1a353de3bdfba
--- /dev/null
+++ b/clang/include/clang/Basic/SizedDeallocation.h
@@ -0,0 +1,44 @@
+//===------- SizedDellocation.h - Sized Deallocation ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines a function that returns the minimum OS versions supporting
+/// C++14's sized deallocation functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SIZEDDEALLOCATION_H
+#define LLVM_CLANG_BASIC_SIZEDDEALLOCATION_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace clang {
+inline llvm::VersionTuple sizedDeallocMinVersion(llvm::Triple::OSType OS) {
+  switch (OS) {
+  default:
+    break;
+  case llvm::Triple::Darwin:
+  case llvm::Triple::MacOSX: // Earliest supporting version is 10.12.
+    return llvm::VersionTuple(10U, 12U);
+  case llvm::Triple::IOS:
+  case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0.
+    return llvm::VersionTuple(10U);
+  case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0.
+    return llvm::VersionTuple(3U);
+  case llvm::Triple::ZOS:
+    return llvm::VersionTuple(); // All z/OS versions have no support.
+  }
+
+  llvm_unreachable("Unexpected OS");
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_SIZEDDEALLOCATION_H
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3e857f4e6faf87..9550d679142158 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -603,6 +603,7 @@ class MarshallingInfoVisibility<KeyPathAndMacro kpm, code default>
 // Key paths that are constant during parsing of options with the same key path prefix.
 defvar cplusplus = LangOpts<"CPlusPlus">;
 defvar cpp11 = LangOpts<"CPlusPlus11">;
+defvar cpp14 = LangOpts<"CPlusPlus14">;
 defvar cpp17 = LangOpts<"CPlusPlus17">;
 defvar cpp20 = LangOpts<"CPlusPlus20">;
 defvar c99 = LangOpts<"C99">;
@@ -3327,10 +3328,10 @@ defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-arg
           "Enable C++17 relaxed template template argument matching">,
   NegFlag<SetFalse>>;
 defm sized_deallocation : BoolFOption<"sized-deallocation",
-  LangOpts<"SizedDeallocation">, DefaultFalse,
+  LangOpts<"SizedDeallocation">, Default<cpp14.KeyPath>,
   PosFlag<SetTrue, [], [ClangOption, CC1Option],
           "Enable C++14 sized global deallocation functions">,
-  NegFlag<SetFalse>>;
+  NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
 defm aligned_allocation : BoolFOption<"aligned-allocation",
   LangOpts<"AlignedAllocation">, Default<cpp17.KeyPath>,
   PosFlag<SetTrue, [], [ClangOption], "Enable C++17 aligned allocation functions">,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 858d20fbfac015..ab74f41cbd0a30 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7105,10 +7105,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   Args.addOptInFlag(CmdArgs, options::OPT_frelaxed_template_template_args,
                     options::OPT_fno_relaxed_template_template_args);
 
-  // -fsized-deallocation is off by default, as it is an ABI-breaking change for
-  // most platforms.
-  Args.addOptInFlag(CmdArgs, options::OPT_fsized_deallocation,
-                    options::OPT_fno_sized_deallocation);
+  // -fsized-deallocation is on by default in C++14 onwards and otherwise off
+  // by default.
+  if (Arg *A = Args.getLastArg(options::OPT_fsized_deallocation,
+                               options::OPT_fno_sized_deallocation)) {
+    if (A->getOption().matches(options::OPT_fsized_deallocation))
+      CmdArgs.push_back("-fsized-deallocation");
+    else
+      CmdArgs.push_back("-fno-sized-deallocation");
+  }
 
   // -faligned-allocation is on by default in C++17 onwards and otherwise off
   // by default.
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index c7682c7f1d3379..d3dc07a4408c84 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -12,6 +12,7 @@
 #include "CommonArgs.h"
 #include "clang/Basic/AlignedAllocation.h"
 #include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/SizedDeallocation.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
@@ -2912,9 +2913,36 @@ static bool sdkSupportsBuiltinModules(const Darwin::DarwinPlatformKind &TargetPl
   }
 }
 
-void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                                   llvm::opt::ArgStringList &CC1Args,
-                                   Action::OffloadKind DeviceOffloadKind) const {
+bool Darwin::isSizedDeallocationUnavailable() const {
+  llvm::Triple::OSType OS;
+
+  if (isTargetMacCatalyst())
+    return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX);
+  switch (TargetPlatform) {
+  case MacOS: // Earlier than 10.12.
+    OS = llvm::Triple::MacOSX;
+    break;
+  case IPhoneOS:
+    OS = llvm::Triple::IOS;
+    break;
+  case TvOS: // Earlier than 10.0.
+    OS = llvm::Triple::TvOS;
+    break;
+  case WatchOS: // Earlier than 3.0.
+    OS = llvm::Triple::WatchOS;
+    break;
+  case DriverKit: // Always available.
+    return false;
+  case XROS: // Always available.
+    return false;
+  }
+
+  return TargetVersion < sizedDeallocMinVersion(OS);
+}
+
+void Darwin::addClangTargetOptions(
+    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
+    Action::OffloadKind DeviceOffloadKind) const {
   // Pass "-faligned-alloc-unavailable" only when the user hasn't manually
   // enabled or disabled aligned allocations.
   if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,
@@ -2922,6 +2950,13 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
       isAlignedAllocationUnavailable())
     CC1Args.push_back("-faligned-alloc-unavailable");
 
+  // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
+  // or disabled sized deallocations.
+  if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation,
+                                options::OPT_fno_sized_deallocation) &&
+      isSizedDeallocationUnavailable())
+    CC1Args.push_back("-fno-sized-deallocation");
+
   addClangCC1ASTargetOptions(DriverArgs, CC1Args);
 
   // Enable compatibility mode for NSItemProviderCompletionHandler in
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 10d4b69e5d5f10..b45279ecedeb25 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -511,6 +511,10 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
   /// targeting.
   bool isAlignedAllocationUnavailable() const;
 
+  /// Return true if c++14 sized deallocation functions are not implemented in
+  /// the c++ standard library of the deployment target we are targeting.
+  bool isSizedDeallocationUnavailable() const;
+
   void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
                              llvm::opt::ArgStringList &CC1Args,
                              Action::OffloadKind DeviceOffloadKind) const override;
diff --git a/clang/lib/Driver/ToolChains/ZOS.cpp b/clang/lib/Driver/ToolChains/ZOS.cpp
index d5fc7b8ef562a6..074e0556ecd2ad 100644
--- a/clang/lib/Driver/ToolChains/ZOS.cpp
+++ b/clang/lib/Driver/ToolChains/ZOS.cpp
@@ -36,6 +36,12 @@ void ZOS::addClangTargetOptions(const ArgList &DriverArgs,
   if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation,
                                 options::OPT_fno_aligned_allocation))
     CC1Args.push_back("-faligned-alloc-unavailable");
+
+  // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
+  // or disabled sized deallocations.
+  if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation,
+                                options::OPT_fno_sized_deallocation))
+    CC1Args.push_back("-fno-sized-deallocation");
 }
 
 void zos::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index 0fb07b0b434cc3..bdd5ea19e41835 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -2333,7 +2333,7 @@ void TestNonADLCall3() {
 // CHECK-NEXT:         "kind": "FunctionDecl",
 // CHECK-NEXT:         "name": "operator delete",
 // CHECK-NEXT:         "type": {
-// CHECK-NEXT:          "qualType": "void (void *) noexcept"
+// CHECK-NEXT:          "qualType": "void (void *, unsigned long) noexcept"
 // CHECK-NEXT:         }
 // CHECK-NEXT:        },
 // CHECK-NEXT:        "inner": [
diff --git a/clang/test/AST/ast-dump-expr.cpp b/clang/test/AST/ast-dump-expr.cpp
index 69e65e22d61d0d..de88f29bc4b0a9 100644
--- a/clang/test/AST/ast-dump-expr.cpp
+++ b/clang/test/AST/ast-dump-expr.cpp
@@ -164,7 +164,7 @@ void UnaryExpressions(int *p) {
   // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *'
 
   ::delete p;
-  // CHECK: CXXDeleteExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> 'void' global Function 0x{{[^ ]*}} 'operator delete' 'void (void *) noexcept'
+  // CHECK: CXXDeleteExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> 'void' global Function 0x{{[^ ]*}} 'operator delete' 'void (void *, unsigned long) noexcept'
   // CHECK-NEXT: ImplicitCastExpr
   // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *'
 
diff --git a/clang/test/AST/ast-dump-stmt-json.cpp b/clang/test/AST/ast-dump-stmt-json.cpp
index 667a12a0120244..a473d17da94244 100644
--- a/clang/test/AST/ast-dump-stmt-json.cpp
+++ b/clang/test/AST/ast-dump-stmt-json.cpp
@@ -994,7 +994,7 @@ void TestDependentGenericSelectionExpr(Ty T) {
 // CHECK-NEXT:       "kind": "FunctionDecl",
 // CHECK-NEXT:       "name": "operator delete",
 // CHECK-NEXT:       "type": {
-// CHECK-NEXT:        "qualType": "void (void *) noexcept"
+// CHECK-NEXT:        "qualType": "void (void *, unsigned long) noexcept"
 // CHECK-NEXT:       }
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "inner": [
@@ -1369,7 +1369,7 @@ void TestDependentGenericSelectionExpr(Ty T) {
 // CHECK-NEXT:       "kind": "FunctionDecl",
 // CHECK-NEXT:       "name": "operator delete",
 // CHECK-NEXT:       "type": {
-// CHECK-NEXT:        "qualType": "void (void *) noexcept"
+// CHECK-NEXT:        "qualType": "void (void *, unsigned long) noexcept"
 // CHECK-NEXT:       }
 // CHECK-NEXT:      },
 // CHECK-NEXT:      "inner": [
@@ -1722,7 +1722,6 @@ void TestDependentGenericSelectionExpr(Ty T) {
 // CHECK-NEXT:   "end": {}
 // CHECK-NEXT:  },
 // CHECK-NEXT:  "isImplicit": true,
-// CHECK-NEXT:  "isUsed": true,
 // CHECK-NEXT:  "name": "operator delete",
 // CHECK-NEXT:  "mangledName": "_ZdlPv",
 // CHECK-NEXT:  "type": {
@@ -1810,6 +1809,126 @@ void TestDependentGenericSelectionExpr(Ty T) {
 // CHECK-NEXT: }
 
 
+// CHECK-NOT: {{^}}Dumping
+// CHECK:  "kind": "FunctionDecl",
+// CHECK-NEXT:  "loc": {},
+// CHECK-NEXT:  "range": {
+// CHECK-NEXT:   "begin": {},
+// CHECK-NEXT:   "end": {}
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isImplicit": true,
+// CHECK-NEXT:  "isUsed": true,
+// CHECK-NEXT:  "name": "operator delete",
+// CHECK-NEXT:  "mangledName": "_ZdlPvm",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "void (void *, unsigned long) noexcept"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "void *"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "unsigned long"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "VisibilityAttr",
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "implicit": true,
+// CHECK-NEXT:    "visibility": "default"
+// CHECK-NEXT:   }
+// CHECK-NEXT:  ]
+// CHECK-NEXT: }
+
+// CHECK-NOT: {{^}}Dumping
+// CHECK:  "kind": "FunctionDecl",
+// CHECK-NEXT:  "loc": {},
+// CHECK-NEXT:  "range": {
+// CHECK-NEXT:   "begin": {},
+// CHECK-NEXT:   "end": {}
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isImplicit": true,
+// CHECK-NEXT:  "name": "operator delete",
+// CHECK-NEXT:  "mangledName": "_ZdlPvmSt11align_val_t",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "void (void *, unsigned long, std::align_val_t) noexcept"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "void *"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "unsigned long"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "std::align_val_t"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "VisibilityAttr",
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "implicit": true,
+// CHECK-NEXT:    "visibility": "default"
+// CHECK-NEXT:   }
+// CHECK-NEXT:  ]
+// CHECK-NEXT: }
+
 // CHECK-NOT: {{^}}Dumping
 // CHECK:  "kind": "FunctionDecl",
 // CHECK-NEXT:  "loc": {},
@@ -1906,6 +2025,125 @@ void TestDependentGenericSelectionExpr(Ty T) {
 // CHECK-NEXT: }
 
 
+// CHECK-NOT: {{^}}Dumping
+// CHECK:  "kind": "FunctionDecl",
+// CHECK-NEXT:  "loc": {},
+// CHECK-NEXT:  "range": {
+// CHECK-NEXT:   "begin": {},
+// CHECK-NEXT:   "end": {}
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isImplicit": true,
+// CHECK-NEXT:  "name": "operator delete[]",
+// CHECK-NEXT:  "mangledName": "_ZdaPvm",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "void (void *, unsigned long) noexcept"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "void *"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "unsigned long"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "VisibilityAttr",
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "implicit": true,
+// CHECK-NEXT:    "visibility": "default"
+// CHECK-NEXT:   }
+// CHECK-NEXT:  ]
+// CHECK-NEXT: }
+
+// CHECK-NOT: {{^}}Dumping
+// CHECK:  "kind": "FunctionDecl",
+// CHECK-NEXT:  "loc": {},
+// CHECK-NEXT:  "range": {
+// CHECK-NEXT:   "begin": {},
+// CHECK-NEXT:   "end": {}
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isImplicit": true,
+// CHECK-NEXT:  "name": "operator delete[]",
+// CHECK-NEXT:  "mangledName": "_ZdaPvmSt11align_val_t",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "void (void *, unsigned long, std::align_val_t) noexcept"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:    "loc": {},
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:     "begin": {},
+// CHECK-NEXT:     "end": {}
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "isImplicit": true,
+// CHECK-NEXT:    "type": {
+// CHECK-NEXT:     "qualType": "void *"
+// CHECK-NEXT:    }
+// CHECK-NEXT:   },
+// CHECK-NEXT:   {
+// CHECK-NEXT:    "id": "0x{{.*}}",
+// CHECK-NEXT:    "kind": "ParmVarDecl",
+// CHECK-NEXT:  ...
[truncated]

clang/docs/ReleaseNotes.rst Outdated Show resolved Hide resolved
clang/include/clang/Basic/SizedDeallocation.h Outdated Show resolved Hide resolved
Copy link
Member

@mordante mordante left a comment

Choose a reason for hiding this comment

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

I only looked at the libc++ changes and have some minor comments to update this patch to the latest libc++ style.

@wangpc-pp wangpc-pp requested a review from shafik March 5, 2024 09:42
Copy link
Contributor

@Endilll Endilll left a comment

Choose a reason for hiding this comment

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

I used a different approach for CWG292 test that avoids passing -fsized-deallocation in 98 and 11 modes, as this is not a conforming mode for them. Now changes to DR tests look good :) I hope you don't mind me pushing commits to your PR.

(I'm the author of CWG292 test)

@wangpc-pp
Copy link
Contributor Author

@Endilll Thanks! I don't mind at all. All I wish is that we can push this forward. :-)


It seems that Windows buildbot still fails this time, I just hope someone in charge can help me to figure it out whether we need more code changes, or it's just because Windows environment doesn't support sized-deallocators (failed tests are all about Interpreter).

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

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

This needs sign-off from Apple reviewers whether the version table in Darwin.cpp is correct.

options::OPT_fno_sized_deallocation);
// -fsized-deallocation is on by default in C++14 onwards and otherwise off
// by default.
if (Arg *A = Args.getLastArg(options::OPT_fsized_deallocation,
Copy link
Member

Choose a reason for hiding this comment

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

We only need -fno-sized-deallocation for CC1Option. When neither option is specified, assume implicit -fsized-deallocation.

The code change in Darwin.cpp should be changed to a function that decides whether the default is yes or no.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I may not understand what you mean, can I leave it unchanged as this code is just like -faligned-allocation. We can change it later.

Copy link
Member

Choose a reason for hiding this comment

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

See my other comment. I think this should be fixed.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

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

The version map seems correct to me. I have a comment about z/OS appearing in a place it shouldn't but apart from that LGTM. Heads up @ahatanak you probably want to have a quick look as well since you did a lot of work around aligned allocation on Apple platforms a few years back.

clang/lib/Driver/ToolChains/Darwin.cpp Outdated Show resolved Hide resolved
clang/lib/Driver/ToolChains/Darwin.cpp Show resolved Hide resolved
Copy link
Member

@mordante mordante left a comment

Choose a reason for hiding this comment

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

I have only reviewed the libc++ changes and they LGTM.

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

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

The __cpp_sized_deallocation feature test macro should be set to 201309L

Comment on lines +1230 to +1265
<span id="n3778">(7): The user must supply definitions of the sized deallocation
functions, either by providing them explicitly or by using a C++ standard library
that does. <code>libstdc++</code> added these functions in version 5.0, and
<code>libc++</code> added them in version 3.7. The user can also use the
<code>-fno-sized-deallocation</code> option to disable sized deallocation.
Copy link
Contributor

Choose a reason for hiding this comment

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

@mordante @AaronBallman do we still support either of these? I'm inclined to removing the comment entirely.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not entirely sure what the question is. If the question is do we allow users to provide their own definition of the sized allocation function, then the answer is yes. http://eel.is/c++draft/replacement.functions.

I'm not sure whether we still need to mention the versions of libc++ and libstdc++; I expect when people use Clang 19 they have a somewhat recent std lib. (Especially since building Clang requires C++17.)

@wangpc-pp
Copy link
Contributor Author

The __cpp_sized_deallocation feature test macro should be set to 201309L

This has been done.
https://github.com/llvm/llvm-project/blob/1d900e298449d43547312364751f730b7a0d07d1/clang/lib/Frontend/InitPreprocessor.cpp#L690C1-L692C1

@wangpc-pp
Copy link
Contributor Author

There is a Windows failure that I can't reproduce: https://buildkite.com/llvm-project/github-pull-requests/builds/46331
Can someone help me to figure out what is wrong?

@AaronBallman
Copy link
Collaborator

There is a Windows failure that I can't reproduce: https://buildkite.com/llvm-project/github-pull-requests/builds/46331 Can someone help me to figure out what is wrong?

I'm not certain what's going on yet, but it smells a bit like the interpreter needs to know about sized deallocations now being on by default (this may be exposing an existing bug rather than introducing a new one).

CC @vgvassilev

@wangpc-pp wangpc-pp force-pushed the main-sized-deallocation branch from f84c6c7 to 2ed7367 Compare April 25, 2024 04:34
@wangpc-pp wangpc-pp merged commit cf5a8b4 into llvm:main Apr 26, 2024
20 of 27 checks passed
@vitalybuka
Copy link
Collaborator

This is causing new/delete mismatch https://lab.llvm.org/buildbot/#/builders/168/builds/20063

=================================================================
==2164144==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x5030000035b0 in thread T0:
  object passed to delete has wrong type:
  size of the allocated type:   25 bytes;
  size of the deallocated type: 24 bytes.
    #0 0x555c21886d82 in operator delete(void*, unsigned long) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:155:3
    #1 0x555c21a2d47c in __libcpp_operator_delete<void *, unsigned long> /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/new:279:3
    #2 0x555c21a2d47c in __do_deallocate_handle_size<> /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/new:303:10
    #3 0x555c21a2d47c in __libcpp_deallocate /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/new:316:12
    #4 0x555c21a2d47c in deallocate /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/__memory/allocator.h:133:7
    #5 0x555c21a2d47c in deallocate /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/__memory/allocator_traits.h:312:9
    #6 0x555c21a2d47c in ~basic_string /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/string:1126:7
    #7 0x555c21a2d47c in llvm::TGParser::addDefOne(std::__1::unique_ptr<llvm::Record, std::__1::default_delete<llvm::Record>>) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:545:22
    #8 0x555c21a2bc41 in llvm::TGParser::addEntry(llvm::RecordsEntry) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:416:10
    #9 0x555c21a5948e in llvm::TGParser::ParseDef(llvm::MultiClass*) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:3625:10
    #10 0x555c21a5ccab in llvm::TGParser::ParseObject(llvm::MultiClass*) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:4325:31
    #11 0x555c21a651f1 in ParseObjectList /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:4356:9
    #12 0x555c21a651f1 in llvm::TGParser::ParseFile() /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:4365:7
    #13 0x555c219ba36f in llvm::TableGenMain(char const*, std::__1::function<bool (llvm::raw_ostream&, llvm::RecordKeeper&)>) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/Main.cpp:125:14
    #14 0x555c218986c5 in main /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/utils/TableGen/TableGen.cpp:84:10
    #15 0x7f0373e2814f  (/lib/x86_64-linux-gnu/libc.so.6+0x2814f) (BuildId: 6a981b07a3731293c24c10a21397416d3c3d52ed)
    #16 0x7f0373e28208 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28208) (BuildId: 6a981b07a3731293c24c10a21397416d3c3d52ed)
    #17 0x555c217b2cb4 in _start (/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-min-tblgen+0x134cb4)
0x5030000035b0 is located 0 bytes inside of 25-byte region [0x5030000035b0,0x5030000035c9)
allocated by thread T0 here:
    #0 0x555c2188611d in operator new(unsigned long) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:86:3
    #1 0x555c219f9c45 in __libcpp_operator_new<unsigned long> /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/new:270:10
    #2 0x555c219f9c45 in __libcpp_allocate /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/new:294:10
    #3 0x555c219f9c45 in allocate /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/__memory/allocator.h:119:32
    #4 0x555c219f9c45 in __allocate_at_least<std::__1::allocator<char> > /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/__memory/allocate_at_least.h:41:19
    #5 0x555c219f9c45 in __init /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/string:2228:25
    #6 0x555c219f9c45 in basic_string<llvm::StringRef, 0> /b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_build_asan/include/c++/v1/string:1071:5
    #7 0x555c219f9c45 in llvm::StringInit::getAsUnquotedString() const /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/include/llvm/TableGen/Record.h:736:12
    #8 0x555c21a2d398 in getNameInitAsString /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/include/llvm/TableGen/Record.h:1718:27
    #9 0x555c21a2d398 in llvm::TGParser::addDefOne(std::__1::unique_ptr<llvm::Record, std::__1::default_delete<llvm::Record>>) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:545:42
    #10 0x555c21a2bc41 in llvm::TGParser::addEntry(llvm::RecordsEntry) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:416:10
    #11 0x555c21a5948e in llvm::TGParser::ParseDef(llvm::MultiClass*) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:3625:10
    #12 0x555c21a5ccab in llvm::TGParser::ParseObject(llvm::MultiClass*) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:4325:31
    #13 0x555c21a651f1 in ParseObjectList /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:4356:9
    #14 0x555c21a651f1 in llvm::TGParser::ParseFile() /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/TGParser.cpp:4365:7
    #15 0x555c219ba36f in llvm::TableGenMain(char const*, std::__1::function<bool (llvm::raw_ostream&, llvm::RecordKeeper&)>) /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/lib/TableGen/Main.cpp:125:14
    #16 0x555c218986c5 in main /b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/utils/TableGen/TableGen.cpp:84:10
    #17 0x7f0373e2814f  (/lib/x86_64-linux-gnu/libc.so.6+0x2814f) (BuildId: 6a981b07a3731293c24c10a21397416d3c3d52ed)

@vitalybuka
Copy link
Collaborator

vitalybuka commented Apr 26, 2024

@ldionne looks like a bug in std::string

--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1123,7 +1123,7 @@ public:
   inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
     __annotate_delete();
     if (__is_long())
-      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap() + 1);
   }
 

fixes that place, but breaks others

@vitalybuka
Copy link
Collaborator

Delete uses __get_long_cap()

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_cap(size_type __s) _NOEXCEPT {
    __r_.first().__l.__cap_     = __s / __endian_factor;
    __r_.first().__l.__is_long_ = true;
  }

  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT {
    return __r_.first().__l.__cap_ * __endian_factor;
  }

And if __set_long_cap() provided with odd number, and __endian_factor == 2, __get_long_cap() will be short by 1.

@dyung
Copy link
Collaborator

dyung commented Apr 26, 2024

This change is also causing a failure on our internal Windows builder, and a public Windows bot:
https://lab.llvm.org/buildbot/#/builders/119/builds/17634

88.872 [191/66/4550] Linking CXX executable bin\clang-repl.exe
FAILED: bin/clang-repl.exe 
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=tools\clang\tools\clang-repl\CMakeFiles\clang-repl.dir --rc=C:\PROGRA~2\WINDOW~4\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WINDOW~4\10\bin\100226~1.0\x64\mt.exe --manifests  -- C:\PROGRA~1\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1439~1.335\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\clang-repl.rsp  /out:bin\clang-repl.exe /implib:lib\clang-repl.lib /pdb:bin\clang-repl.pdb /version:0.0 /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console  /EXPORT:??_7type_info@@6B@ /EXPORT:?__type_info_root_node@@3U__type_info_node@@A /EXPORT:?nothrow@std@@3Unothrow_t@1@B /EXPORT:_Init_thread_abort /EXPORT:_Init_thread_epoch /EXPORT:_Init_thread_footer /EXPORT:_Init_thread_header /EXPORT:_tls_index /EXPORT:??2@YAPEAX_K@Z /EXPORT:??3@YAXPEAX@Z /EXPORT:??_U@YAPEAX_K@Z /EXPORT:??_V@YAXPEAX@Z /EXPORT:??3@YAXPEAX_K@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@H@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@M@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@N@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@PEBX@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@D@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@PEBD@Z /EXPORT:?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z  -Wl,--long-plt  && cd ."
LINK: command "C:\PROGRA~1\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1439~1.335\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\clang-repl.rsp /out:bin\clang-repl.exe /implib:lib\clang-repl.lib /pdb:bin\clang-repl.pdb /version:0.0 /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console /EXPORT:??_7type_info@@6B@ /EXPORT:?__type_info_root_node@@3U__type_info_node@@A /EXPORT:?nothrow@std@@3Unothrow_t@1@B /EXPORT:_Init_thread_abort /EXPORT:_Init_thread_epoch /EXPORT:_Init_thread_footer /EXPORT:_Init_thread_header /EXPORT:_tls_index /EXPORT:??2@YAPEAX_K@Z /EXPORT:??3@YAXPEAX@Z /EXPORT:??_U@YAPEAX_K@Z /EXPORT:??_V@YAXPEAX@Z /EXPORT:??3@YAXPEAX_K@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@H@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@M@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@N@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@PEBX@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@D@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@PEBD@Z /EXPORT:?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z -Wl,--long-plt /MANIFEST /MANIFESTFILE:bin\clang-repl.exe.manifest" failed (exit code 1120) with the following output:
LINK : warning LNK4044: unrecognized option '/Wl,--long-plt'; ignored
   Creating library lib\clang-repl.lib and object lib\clang-repl.exp
LIBCMT.lib(initializers.obj) : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4217: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'zlibstatic.lib(zutil.obj)' in function 'zcfree'
LINK : warning LNK4217: symbol 'malloc' defined in 'libucrt.lib(malloc.obj)' is imported by 'zlibstatic.lib(zutil.obj)' in function 'zcalloc'
clang-repl.exp : error LNK2001: unresolved external symbol "public: class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(float)" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@M@Z)
clang-repl.exp : error LNK2001: unresolved external symbol "public: class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > & (__cdecl*)(class std::basic_ostream<char,struct std::char_traits<char> > &))" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z)
clang-repl.exp : error LNK2001: unresolved external symbol "public: class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(void const *)" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@PEBX@Z)
bin\clang-repl.exe : fatal error LNK1120: 3 unresolved externals

@dschuff
Copy link
Member

dschuff commented Apr 26, 2024

We are also seeing the Windows failure. Given that there appear to be 2 separate problems, this patch should probably be reverted rather than trying to fix-forward.

@vitalybuka
Copy link
Collaborator

Lets revert #90299 to recover bots before the weekend.

@wangpc-pp
Copy link
Contributor Author

Lets revert #90299 to recover bots before the weekend.

Many thanks for reverting it and fixing one of the failures!

@wangpc-pp
Copy link
Contributor Author

This change is also causing a failure on our internal Windows builder, and a public Windows bot:
https://lab.llvm.org/buildbot/#/builders/119/builds/17634

88.872 [191/66/4550] Linking CXX executable bin\clang-repl.exe
FAILED: bin/clang-repl.exe 
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=tools\clang\tools\clang-repl\CMakeFiles\clang-repl.dir --rc=C:\PROGRA~2\WINDOW~4\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WINDOW~4\10\bin\100226~1.0\x64\mt.exe --manifests  -- C:\PROGRA~1\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1439~1.335\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\clang-repl.rsp  /out:bin\clang-repl.exe /implib:lib\clang-repl.lib /pdb:bin\clang-repl.pdb /version:0.0 /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console  /EXPORT:??_7type_info@@6B@ /EXPORT:?__type_info_root_node@@3U__type_info_node@@A /EXPORT:?nothrow@std@@3Unothrow_t@1@B /EXPORT:_Init_thread_abort /EXPORT:_Init_thread_epoch /EXPORT:_Init_thread_footer /EXPORT:_Init_thread_header /EXPORT:_tls_index /EXPORT:??2@YAPEAX_K@Z /EXPORT:??3@YAXPEAX@Z /EXPORT:??_U@YAPEAX_K@Z /EXPORT:??_V@YAXPEAX@Z /EXPORT:??3@YAXPEAX_K@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@H@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@M@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@N@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@PEBX@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@D@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@PEBD@Z /EXPORT:?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z  -Wl,--long-plt  && cd ."
LINK: command "C:\PROGRA~1\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1439~1.335\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\clang-repl.rsp /out:bin\clang-repl.exe /implib:lib\clang-repl.lib /pdb:bin\clang-repl.pdb /version:0.0 /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console /EXPORT:??_7type_info@@6B@ /EXPORT:?__type_info_root_node@@3U__type_info_node@@A /EXPORT:?nothrow@std@@3Unothrow_t@1@B /EXPORT:_Init_thread_abort /EXPORT:_Init_thread_epoch /EXPORT:_Init_thread_footer /EXPORT:_Init_thread_header /EXPORT:_tls_index /EXPORT:??2@YAPEAX_K@Z /EXPORT:??3@YAXPEAX@Z /EXPORT:??_U@YAPEAX_K@Z /EXPORT:??_V@YAXPEAX@Z /EXPORT:??3@YAXPEAX_K@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@H@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@M@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@N@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@PEBX@Z /EXPORT:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@D@Z /EXPORT:??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@PEBD@Z /EXPORT:?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z -Wl,--long-plt /MANIFEST /MANIFESTFILE:bin\clang-repl.exe.manifest" failed (exit code 1120) with the following output:
LINK : warning LNK4044: unrecognized option '/Wl,--long-plt'; ignored
   Creating library lib\clang-repl.lib and object lib\clang-repl.exp
LIBCMT.lib(initializers.obj) : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4217: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'zlibstatic.lib(zutil.obj)' in function 'zcfree'
LINK : warning LNK4217: symbol 'malloc' defined in 'libucrt.lib(malloc.obj)' is imported by 'zlibstatic.lib(zutil.obj)' in function 'zcalloc'
clang-repl.exp : error LNK2001: unresolved external symbol "public: class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(float)" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@M@Z)
clang-repl.exp : error LNK2001: unresolved external symbol "public: class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > & (__cdecl*)(class std::basic_ostream<char,struct std::char_traits<char> > &))" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@P6AAEAV01@AEAV01@@Z@Z)
clang-repl.exp : error LNK2001: unresolved external symbol "public: class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(void const *)" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@PEBX@Z)
bin\clang-repl.exe : fatal error LNK1120: 3 unresolved externals

It seems that we need to remove these symbols from the CMakeLists.txt of clang-repl.

@wangpc-pp wangpc-pp deleted the main-sized-deallocation branch April 28, 2024 04:21
wangpc-pp added a commit to wangpc-pp/llvm-project that referenced this pull request Apr 28, 2024
Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

The original commit cf5a8b4 was reverted by 2e5035a due to some
failures (see llvm#83774).

Fixes llvm#60061
vitalybuka added a commit that referenced this pull request Apr 30, 2024
This is detected by asan after #83774

New assert already fails a lot of tests even without asan.
vitalybuka added a commit to vitalybuka/llvm-project that referenced this pull request May 2, 2024
This is detected by asan after llvm#83774

New assert already fails a lot of tests even without asan.
vitalybuka added a commit that referenced this pull request May 2, 2024
This is detected by asan after #83774

Allocation size will be divided by `__endian_factor` before storing. If
it's not aligned,
we will not be able to recover allocation size to pass into
`__alloc_traits::deallocate`.

we have code like this 
```
 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
    __p               = __allocation.ptr;
    __set_long_cap(__allocation.count);

void __set_long_cap(size_type __s) _NOEXCEPT {
    __r_.first().__l.__cap_     = __s / __endian_factor;
    __r_.first().__l.__is_long_ = true;
  }

size_type __get_long_cap() const _NOEXCEPT {
    return __r_.first().__l.__cap_ * __endian_factor;
  }

inline ~basic_string() {
    __annotate_delete();
    if (__is_long())
      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
  }
```
1. __recommend() -> even size
2. `std::__allocate_at_least(__alloc(), __recommend(__sz) + 1)` - > not
even size
3. ` __set_long_cap() `- > lose one bit of size for __endian_factor == 2
(see `/ __endian_factor`)
4. `__alloc_traits::deallocate(__alloc(), __get_long_pointer(),
__get_long_cap())` -> uses even size (see `__get_long_cap`)
wangpc-pp added a commit to wangpc-pp/llvm-project that referenced this pull request May 22, 2024
Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

The original commit cf5a8b4 was reverted by 2e5035a due to some
failures (see llvm#83774).

Fixes llvm#60061
wangpc-pp added a commit that referenced this pull request May 22, 2024
#90373)

Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

The original commit cf5a8b4 was reverted by 2e5035a due to some
failures (see #83774).

Fixes #60061
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Jun 12, 2024
This is detected by asan after llvm#83774

Allocation size will be divided by `__endian_factor` before storing. If
it's not aligned,
we will not be able to recover allocation size to pass into
`__alloc_traits::deallocate`.

we have code like this
```
 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
    __p               = __allocation.ptr;
    __set_long_cap(__allocation.count);

void __set_long_cap(size_type __s) _NOEXCEPT {
    __r_.first().__l.__cap_     = __s / __endian_factor;
    __r_.first().__l.__is_long_ = true;
  }

size_type __get_long_cap() const _NOEXCEPT {
    return __r_.first().__l.__cap_ * __endian_factor;
  }

inline ~basic_string() {
    __annotate_delete();
    if (__is_long())
      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
  }
```
1. __recommend() -> even size
2. `std::__allocate_at_least(__alloc(), __recommend(__sz) + 1)` - > not
even size
3. ` __set_long_cap() `- > lose one bit of size for __endian_factor == 2
(see `/ __endian_factor`)
4. `__alloc_traits::deallocate(__alloc(), __get_long_pointer(),
__get_long_cap())` -> uses even size (see `__get_long_cap`)

(cherry picked from commit d129ea8)
vitalybuka pushed a commit that referenced this pull request Jun 12, 2024
#90373)

Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

The original commit cf5a8b4 was reverted by 2e5035a due to some
failures (see #83774).

Fixes #60061
vitalybuka added a commit that referenced this pull request Jun 12, 2024
This is detected by asan after #83774

Allocation size will be divided by `__endian_factor` before storing. If
it's not aligned,
we will not be able to recover allocation size to pass into
`__alloc_traits::deallocate`.

we have code like this
```
 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
    __p               = __allocation.ptr;
    __set_long_cap(__allocation.count);

void __set_long_cap(size_type __s) _NOEXCEPT {
    __r_.first().__l.__cap_     = __s / __endian_factor;
    __r_.first().__l.__is_long_ = true;
  }

size_type __get_long_cap() const _NOEXCEPT {
    return __r_.first().__l.__cap_ * __endian_factor;
  }

inline ~basic_string() {
    __annotate_delete();
    if (__is_long())
      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
  }
```
1. __recommend() -> even size
2. `std::__allocate_at_least(__alloc(), __recommend(__sz) + 1)` - > not
even size
3. ` __set_long_cap() `- > lose one bit of size for __endian_factor == 2
(see `/ __endian_factor`)
4. `__alloc_traits::deallocate(__alloc(), __get_long_pointer(),
__get_long_cap())` -> uses even size (see `__get_long_cap`)

(cherry picked from commit d129ea8)
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Jun 15, 2024
This is detected by asan after llvm#83774

Allocation size will be divided by `__endian_factor` before storing. If
it's not aligned,
we will not be able to recover allocation size to pass into
`__alloc_traits::deallocate`.

we have code like this
```
 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
    __p               = __allocation.ptr;
    __set_long_cap(__allocation.count);

void __set_long_cap(size_type __s) _NOEXCEPT {
    __r_.first().__l.__cap_     = __s / __endian_factor;
    __r_.first().__l.__is_long_ = true;
  }

size_type __get_long_cap() const _NOEXCEPT {
    return __r_.first().__l.__cap_ * __endian_factor;
  }

inline ~basic_string() {
    __annotate_delete();
    if (__is_long())
      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
  }
```
1. __recommend() -> even size
2. `std::__allocate_at_least(__alloc(), __recommend(__sz) + 1)` - > not
even size
3. ` __set_long_cap() `- > lose one bit of size for __endian_factor == 2
(see `/ __endian_factor`)
4. `__alloc_traits::deallocate(__alloc(), __get_long_pointer(),
__get_long_cap())` -> uses even size (see `__get_long_cap`)

(cherry picked from commit d129ea8)
owenca pushed a commit to owenca/llvm-project that referenced this pull request Jun 22, 2024
This is detected by asan after llvm#83774

Allocation size will be divided by `__endian_factor` before storing. If
it's not aligned,
we will not be able to recover allocation size to pass into
`__alloc_traits::deallocate`.

we have code like this
```
 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
    __p               = __allocation.ptr;
    __set_long_cap(__allocation.count);

void __set_long_cap(size_type __s) _NOEXCEPT {
    __r_.first().__l.__cap_     = __s / __endian_factor;
    __r_.first().__l.__is_long_ = true;
  }

size_type __get_long_cap() const _NOEXCEPT {
    return __r_.first().__l.__cap_ * __endian_factor;
  }

inline ~basic_string() {
    __annotate_delete();
    if (__is_long())
      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
  }
```
1. __recommend() -> even size
2. `std::__allocate_at_least(__alloc(), __recommend(__sz) + 1)` - > not
even size
3. ` __set_long_cap() `- > lose one bit of size for __endian_factor == 2
(see `/ __endian_factor`)
4. `__alloc_traits::deallocate(__alloc(), __get_long_pointer(),
__get_long_cap())` -> uses even size (see `__get_long_cap`)

(cherry picked from commit d129ea8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:SystemZ clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category clang-tidy clang-tools-extra clangd coroutines C++20 coroutines libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[C++14] Enable sized deallocation by default