ahatanak created this revision.
ahatanak added reviewers: rsmith, vsapsai, EricWF, erik.pilkington.

Deallocation functions are called from deleting destructors that are declared 
virtual. Issue an error if an aligned deallocation function is selected but is 
not available.


Repository:
  rC Clang

https://reviews.llvm.org/D47757

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExprCXX.cpp
  test/SemaCXX/unavailable_aligned_allocation.cpp

Index: test/SemaCXX/unavailable_aligned_allocation.cpp
===================================================================
--- test/SemaCXX/unavailable_aligned_allocation.cpp
+++ test/SemaCXX/unavailable_aligned_allocation.cpp
@@ -124,6 +124,33 @@
 // expected-note@-20 2 {{if you supply your own aligned allocation functions}}
 #endif
 
+// Test that diagnostics are produced when an unavailable aligned deallocation
+// function is called from a deleting destructor.
+struct alignas(256) OveralignedS2 {
+  int a[4];
+  virtual ~OveralignedS2();
+};
+
+OveralignedS2::~OveralignedS2() {}
+
+#ifdef NO_ERRORS
+// expected-no-diagnostics
+#else
+#if defined(IOS)
+// expected-error@-6 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on iOS 11 or newer}}}
+// expected-note@-7 {{if you supply your own aligned allocation functions}}
+#elif defined(TVOS)
+// expected-error@-9 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on tvOS 11 or newer}}}
+// expected-note@-10 {{if you supply your own aligned allocation functions}}
+#elif defined(WATCHOS)
+// expected-error@-12 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}}
+// expected-note@-13 {{if you supply your own aligned allocation functions}}
+#else
+// expected-error@-15 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}}
+// expected-note@-16 {{if you supply your own aligned allocation functions}}
+#endif
+#endif
+
 // No errors if user-defined aligned allocation functions are available.
 void *operator new(std::size_t __sz, std::align_val_t) {
   static char array[256];
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -1681,26 +1681,26 @@
 
 // Emit a diagnostic if an aligned allocation/deallocation function that is not
 // implemented in the standard library is selected.
-static void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
-                                                 SourceLocation Loc, bool IsDelete,
-                                                 Sema &S) {
-  if (!S.getLangOpts().AlignedAllocationUnavailable)
+void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
+                                                SourceLocation Loc,
+                                                bool IsDelete) {
+  if (!getLangOpts().AlignedAllocationUnavailable)
     return;
 
   // Return if there is a definition.
   if (FD.isDefined())
     return;
 
   bool IsAligned = false;
   if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) {
-    const llvm::Triple &T = S.getASTContext().getTargetInfo().getTriple();
+    const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
     StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
-        S.getASTContext().getTargetInfo().getPlatformName());
+        getASTContext().getTargetInfo().getPlatformName());
 
-    S.Diag(Loc, diag::warn_aligned_allocation_unavailable)
+    Diag(Loc, diag::warn_aligned_allocation_unavailable)
          << IsDelete << FD.getType().getAsString() << OSName
          << alignedAllocMinVersion(T.getOS()).getAsString();
-    S.Diag(Loc, diag::note_silence_unligned_allocation_unavailable);
+    Diag(Loc, diag::note_silence_unligned_allocation_unavailable);
   }
 }
 
@@ -2091,13 +2091,13 @@
     if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
       return ExprError();
     MarkFunctionReferenced(StartLoc, OperatorNew);
-    diagnoseUnavailableAlignedAllocation(*OperatorNew, StartLoc, false, *this);
+    diagnoseUnavailableAlignedAllocation(*OperatorNew, StartLoc, false);
   }
   if (OperatorDelete) {
     if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
       return ExprError();
     MarkFunctionReferenced(StartLoc, OperatorDelete);
-    diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true, *this);
+    diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true);
   }
 
   // C++0x [expr.new]p17:
@@ -3329,8 +3329,7 @@
       }
     }
 
-    diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true,
-                                         *this);
+    diagnoseUnavailableAlignedAllocation(*OperatorDelete, StartLoc, true);
 
     // Convert the operand to the type of the first parameter of operator
     // delete. This is only necessary if we selected a destroying operator
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -8160,6 +8160,7 @@
     // If we have a virtual destructor, look up the deallocation function
     if (FunctionDecl *OperatorDelete =
             FindDeallocationFunctionForDestructor(Loc, RD)) {
+      diagnoseUnavailableAlignedAllocation(*OperatorDelete, Loc, true);
       Expr *ThisArg = nullptr;
 
       // If the notional 'delete this' expression requires a non-trivial
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -5166,6 +5166,9 @@
                          SourceRange DirectInitRange,
                          Expr *Initializer);
 
+  void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
+                                            SourceLocation Loc, bool IsDelete);
+
   bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
                           SourceRange R);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to