<div dir="ltr">Sorry, I didn't see the failure yesterday.<div><br></div><div>I'll get on it or revert it.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 22, 2018 at 11:51 AM, Galina Kistanova <span dir="ltr"><<a href="mailto:gkistanova@gmail.com" target="_blank">gkistanova@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello Eric,<br><br>One of added tests fails on the next builder:<br><a href="http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/8624" target="_blank">http://lab.llvm.org:8011/<wbr>builders/llvm-clang-x86_64-<wbr>expensive-checks-win/builds/<wbr>8624</a><br><br>. . . <br>Failing Tests:<br>   . . .<br>    Clang :: SemaCXX/builtin-operator-new-<wbr>delete.cpp<br><br>Please have a look?<br><br>It is not good idea to keep the bot red for too long. This hides new problem which later hard to track down.<br><br>Thanks<span class="HOEnZb"><font color="#888888"><br><br>Galina<br><br></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 21, 2018 at 12:19 PM, Eric Fiselier via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ericwf<br>
Date: Wed Mar 21 12:19:48 2018<br>
New Revision: 328134<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=328134&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=328134&view=rev</a><br>
Log:<br>
[Builtins] Overload __builtin_operator_new/delete to allow forwarding to usual allocation/deallocation functions.<br>
<br>
Summary:<br>
Libc++'s default allocator uses `__builtin_operator_new` and `__builtin_operator_delete` in order to allow the calls to new/delete to be ellided. However, libc++ now needs to support over-aligned types in the default allocator. In order to support this without disabling the existing optimization Clang needs to support calling the aligned new overloads from the builtins.<br>
<br>
See <a href="http://llvm.org/PR22634" rel="noreferrer" target="_blank">llvm.org/PR22634</a> for more information about the libc++ bug.<br>
<br>
This patch changes `__builtin_operator_new`/`__bu<wbr>iltin_operator_delete` to call any usual `operator new`/`operator delete` function. It does this by performing overload resolution with the arguments passed to the builtin to determine which allocation function to call. If the selected function is not a usual allocation function a diagnostic is issued.<br>
<br>
One open issue is if the `align_val_t` overloads should be considered "usual" when `LangOpts::AlignedAllocation` is disabled.<br>
<br>
<br>
In order to allow libc++ to detect this new behavior the value for `__has_builtin(__builtin_opera<wbr>tor_new)` has been updated to `201802`.<br>
<br>
Reviewers: rsmith, majnemer, aaron.ballman, erik.pilkington, bogner, ahatanak<br>
<br>
Reviewed By: rsmith<br>
<br>
Subscribers: cfe-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D43047" rel="noreferrer" target="_blank">https://reviews.llvm.org/D4304<wbr>7</a><br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/buil<wbr>tin-operator-new-delete.cpp<br>
    cfe/trunk/test/SemaCXX/builtin<wbr>-operator-new-delete.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>Builtins.def<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
    cfe/trunk/lib/CodeGen/CGBuilti<wbr>n.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprCX<wbr>X.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenF<wbr>unction.h<br>
    cfe/trunk/lib/Lex/PPMacroExpan<wbr>sion.cpp<br>
    cfe/trunk/lib/Sema/SemaCheckin<wbr>g.cpp<br>
    cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>Builtins.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/Builtins.def?rev=328134&<wbr>r1=328133&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>Builtins.def (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>Builtins.def Wed Mar 21 12:19:48 2018<br>
@@ -1371,8 +1371,8 @@ BUILTIN(__builtin_smulll_overf<wbr>low, "bSLL<br>
<br>
 // Clang builtins (not available in GCC).<br>
 BUILTIN(__builtin_addressof, "v*v&", "nct")<br>
-BUILTIN(__builtin_operator_ne<wbr>w, "v*z", "c")<br>
-BUILTIN(__builtin_operator_de<wbr>lete, "vv*", "n")<br>
+BUILTIN(__builtin_operator_ne<wbr>w, "v*z", "tc")<br>
+BUILTIN(__builtin_operator_de<wbr>lete, "vv*", "tn")<br>
 BUILTIN(__builtin_char_<wbr>memchr, "c*cC*iz", "n")<br>
<br>
 // Safestack builtins<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/DiagnosticSemaKinds.td?<wbr>rev=328134&r1=328133&r2=<wbr>328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Wed Mar 21 12:19:48 2018<br>
@@ -7627,6 +7627,11 @@ def err_destroying_operator_delete<wbr>_not_u<br>
   "alignment parameter">;<br>
 def note_implicit_delete_this_in_d<wbr>estructor_here : Note<<br>
   "while checking implicit 'delete this' for virtual destructor">;<br>
+def err_builtin_operator_new_delet<wbr>e_not_usual : Error<<br>
+  "call to '%select{__builtin_operator_ne<wbr>w|__builtin_operator_delete}0' "<br>
+  "selects non-usual %select{allocation|deallocatio<wbr>n}0 function">;<br>
+def note_non_usual_function_declar<wbr>ed_here : Note<<br>
+  "non-usual %0 declared here">;<br>
<br>
 // C++ literal operators<br>
 def err_literal_operator_outside_n<wbr>amespace : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/Sema.h?rev=328134&r1=<wbr>328133&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/S<wbr>ema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/S<wbr>ema.h Wed Mar 21 12:19:48 2018<br>
@@ -10376,6 +10376,8 @@ private:<br>
   ExprResult SemaBuiltinNontemporalOverload<wbr>ed(ExprResult TheCallResult);<br>
   ExprResult SemaAtomicOpsOverloaded(ExprRe<wbr>sult TheCallResult,<br>
                                      AtomicExpr::AtomicOp Op);<br>
+  ExprResult SemaBuiltinOperatorNewDeleteOv<wbr>erloaded(ExprResult TheCallResult,<br>
+                                                    bool IsDelete);<br>
   bool SemaBuiltinConstantArg(CallExp<wbr>r *TheCall, int ArgNum,<br>
                               llvm::APSInt &Result);<br>
   bool SemaBuiltinConstantArgRange(Ca<wbr>llExpr *TheCall, int ArgNum,<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGBuilti<wbr>n.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/CodeGen/CG<wbr>Builtin.cpp?rev=328134&r1=3281<wbr>33&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/CGBuilti<wbr>n.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGBuilti<wbr>n.cpp Wed Mar 21 12:19:48 2018<br>
@@ -2611,11 +2611,12 @@ RValue CodeGenFunction::EmitBuiltinEx<wbr>pr(<br>
   case Builtin::BI__builtin_addressof<wbr>:<br>
     return RValue::get(EmitLValue(E->getA<wbr>rg(0)).getPointer());<br>
   case Builtin::BI__builtin_operator_<wbr>new:<br>
-    return EmitBuiltinNewDeleteCall(FD->g<wbr>etType()->castAs<FunctionProto<wbr>Type>(),<br>
-                                    E->getArg(0), false);<br>
+    return EmitBuiltinNewDeleteCall(<br>
+        E->getCallee()->getType()->cas<wbr>tAs<FunctionProtoType>(), E, false);<br>
   case Builtin::BI__builtin_operator_<wbr>delete:<br>
-    return EmitBuiltinNewDeleteCall(FD->g<wbr>etType()->castAs<FunctionProto<wbr>Type>(),<br>
-                                    E->getArg(0), true);<br>
+    return EmitBuiltinNewDeleteCall(<br>
+        E->getCallee()->getType()->cas<wbr>tAs<FunctionProtoType>(), E, true);<br>
+<br>
   case Builtin::BI__noop:<br>
     // __noop always evaluates to an integer literal zero.<br>
     return RValue::get(ConstantInt::get(I<wbr>ntTy, 0));<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprCX<wbr>X.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/CodeGen/CG<wbr>ExprCXX.cpp?rev=328134&r1=3281<wbr>33&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/CGExprCX<wbr>X.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprCX<wbr>X.cpp Wed Mar 21 12:19:48 2018<br>
@@ -1307,19 +1307,19 @@ static RValue EmitNewDeleteCall(CodeGenF<br>
 }<br>
<br>
 RValue CodeGenFunction::EmitBuiltinNe<wbr>wDeleteCall(const FunctionProtoType *Type,<br>
-                                                 const Expr *Arg,<br>
+                                                 const CallExpr *TheCall,<br>
                                                  bool IsDelete) {<br>
   CallArgList Args;<br>
-  const Stmt *ArgS = Arg;<br>
-  EmitCallArgs(Args, *Type->param_type_begin(), llvm::makeArrayRef(ArgS));<br>
+  EmitCallArgs(Args, Type->getParamTypes(), TheCall->arguments());<br>
   // Find the allocation or deallocation function that we're calling.<br>
   ASTContext &Ctx = getContext();<br>
   DeclarationName Name = Ctx.DeclarationNames<br>
       .getCXXOperatorName(IsDelete ? OO_Delete : OO_New);<br>
+<br>
   for (auto *Decl : Ctx.getTranslationUnitDecl()-><wbr>lookup(Name))<br>
     if (auto *FD = dyn_cast<FunctionDecl>(Decl))<br>
       if (Ctx.hasSameType(FD->getType()<wbr>, QualType(Type, 0)))<br>
-        return EmitNewDeleteCall(*this, cast<FunctionDecl>(Decl), Type, Args);<br>
+        return EmitNewDeleteCall(*this, FD, Type, Args);<br>
   llvm_unreachable("predeclared global operator new/delete is missing");<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenF<wbr>unction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/CodeGen/Co<wbr>deGenFunction.h?rev=328134&r1=<wbr>328133&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/CodeGenF<wbr>unction.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenF<wbr>unction.h Wed Mar 21 12:19:48 2018<br>
@@ -2356,7 +2356,7 @@ public:<br>
                       CharUnits CookieSize = CharUnits());<br>
<br>
   RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,<br>
-                                  const Expr *Arg, bool IsDelete);<br>
+                                  const CallExpr *TheCallExpr, bool IsDelete);<br>
<br>
   llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E);<br>
   llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE);<br>
<br>
Modified: cfe/trunk/lib/Lex/PPMacroExpan<wbr>sion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Lex/PPMacr<wbr>oExpansion.cpp?rev=328134&r1=<wbr>328133&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Lex/PPMacroExpan<wbr>sion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPMacroExpan<wbr>sion.cpp Wed Mar 21 12:19:48 2018<br>
@@ -1801,12 +1801,21 @@ void Preprocessor::ExpandBuiltinMac<wbr>ro(To<br>
       [this](Token &Tok, bool &HasLexedNextToken) -> int {<br>
         IdentifierInfo *II = ExpectFeatureIdentifierInfo(To<wbr>k, *this,<br>
                                            diag::err_feature_check_malfor<wbr>med);<br>
+        const LangOptions &LangOpts = getLangOpts();<br>
         if (!II)<br>
           return false;<br>
-        else if (II->getBuiltinID() != 0)<br>
+        else if (II->getBuiltinID() != 0) {<br>
+          switch (II->getBuiltinID()) {<br>
+          case Builtin::BI__builtin_operator_<wbr>new:<br>
+          case Builtin::BI__builtin_operator_<wbr>delete:<br>
+            // denotes date of behavior change to support calling arbitrary<br>
+            // usual allocation and deallocation functions. Required by libc++<br>
+            return 201802;<br>
+          default:<br>
+            return true;<br>
+          }<br>
           return true;<br>
-        else {<br>
-          const LangOptions &LangOpts = getLangOpts();<br>
+        } else {<br>
           return llvm::StringSwitch<bool>(II->g<wbr>etName())<br>
                       .Case("__make_integer_seq", LangOpts.CPlusPlus)<br>
                       .Case("__type_pack_element", LangOpts.CPlusPlus)<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCheckin<wbr>g.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaC<wbr>hecking.cpp?rev=328134&r1=<wbr>328133&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaCheckin<wbr>g.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCheckin<wbr>g.cpp Wed Mar 21 12:19:48 2018<br>
@@ -1097,20 +1097,14 @@ Sema::CheckBuiltinFunctionCall<wbr>(FunctionD<br>
       return ExprError();<br>
     break;<br>
   case Builtin::BI__builtin_operator_<wbr>new:<br>
-  case Builtin::BI__builtin_operator_<wbr>delete:<br>
-    if (!getLangOpts().CPlusPlus) {<br>
-      Diag(TheCall->getExprLoc(), diag::err_builtin_requires_lan<wbr>guage)<br>
-        << (BuiltinID == Builtin::BI__builtin_operator_<wbr>new<br>
-                ? "__builtin_operator_new"<br>
-                : "__builtin_operator_delete")<br>
-        << "C++";<br>
-      return ExprError();<br>
-    }<br>
-    // CodeGen assumes it can find the global new and delete to call,<br>
-    // so ensure that they are declared.<br>
-    DeclareGlobalNewDelete();<br>
-    break;<br>
-<br>
+  case Builtin::BI__builtin_operator_<wbr>delete: {<br>
+    bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_<wbr>delete;<br>
+    ExprResult Res =<br>
+        SemaBuiltinOperatorNewDeleteOv<wbr>erloaded(TheCallResult, IsDelete);<br>
+    if (Res.isInvalid())<br>
+      CorrectDelayedTyposInExpr(TheC<wbr>allResult.get());<br>
+    return Res;<br>
+  }<br>
   // check secure string manipulation functions where overflows<br>
   // are detectable at compile time<br>
   case Builtin::BI__builtin___memcpy_<wbr>chk:<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=328134&r1=328133&r2=328134&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaE<wbr>xprCXX.cpp?rev=328134&r1=32813<wbr>3&r2=328134&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp Wed Mar 21 12:19:48 2018<br>
@@ -1443,7 +1443,7 @@ namespace {<br>
           CUDAPref = S.IdentifyCUDAPreference(Calle<wbr>r, FD);<br>
     }<br>
<br>
-    operator bool() const { return FD; }<br>
+    explicit operator bool() const { return FD; }<br>
<br>
     bool isBetterThan(const UsualDeallocFnInfo &Other, bool WantSize,<br>
                       bool WantAlign) const {<br>
@@ -2271,7 +2271,6 @@ static bool resolveAllocationOverload(<br>
   llvm_unreachable("<wbr>Unreachable, bad result from BestViableFunction");<br>
 }<br>
<br>
-<br>
 /// FindAllocationFunctions - Finds the overloads of operator new and delete<br>
 /// that are appropriate for the allocation.<br>
 bool Sema::FindAllocationFunctions(<wbr>SourceLocation StartLoc, SourceRange Range,<br>
@@ -3343,6 +3342,128 @@ Sema::ActOnCXXDelete(SourceLoc<wbr>ation Star<br>
   return Result;<br>
 }<br>
<br>
+static bool resolveBuiltinNewDeleteOverloa<wbr>d(Sema &S, CallExpr *TheCall,<br>
+                                            bool IsDelete,<br>
+                                            FunctionDecl *&Operator) {<br>
+<br>
+  DeclarationName NewName = S.Context.DeclarationNames.get<wbr>CXXOperatorName(<br>
+      IsDelete ? OO_Delete : OO_New);<br>
+<br>
+  LookupResult R(S, NewName, TheCall->getLocStart(), Sema::LookupOrdinaryName);<br>
+  S.LookupQualifiedName(R, S.Context.getTranslationUnitDe<wbr>cl());<br>
+  assert(!R.empty() && "implicitly declared allocation functions not found");<br>
+  assert(!R.isAmbiguous() && "global allocation functions are ambiguous");<br>
+<br>
+  // We do our own custom access checks below.<br>
+  R.suppressDiagnostics();<br>
+<br>
+  SmallVector<Expr *, 8> Args(TheCall->arg_begin(), TheCall->arg_end());<br>
+  OverloadCandidateSet Candidates(R.getNameLoc(),<br>
+                                  OverloadCandidateSet::CSK_Norm<wbr>al);<br>
+  for (LookupResult::iterator FnOvl = R.begin(), FnOvlEnd = R.end();<br>
+       FnOvl != FnOvlEnd; ++FnOvl) {<br>
+    // Even member operator new/delete are implicitly treated as<br>
+    // static, so don't use AddMemberCandidate.<br>
+    NamedDecl *D = (*FnOvl)->getUnderlyingDecl();<br>
+<br>
+    if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl><wbr>(D)) {<br>
+      S.AddTemplateOverloadCandidate<wbr>(FnTemplate, FnOvl.getPair(),<br>
+                                     /*ExplicitTemplateArgs=*/null<wbr>ptr, Args,<br>
+                                     Candidates,<br>
+                                     /*SuppressUserConversions=*/f<wbr>alse);<br>
+      continue;<br>
+    }<br>
+<br>
+    FunctionDecl *Fn = cast<FunctionDecl>(D);<br>
+    S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates,<br>
+                           /*SuppressUserConversions=*/f<wbr>alse);<br>
+  }<br>
+<br>
+  SourceRange Range = TheCall->getSourceRange();<br>
+<br>
+  // Do the resolution.<br>
+  OverloadCandidateSet::iterator Best;<br>
+  switch (Candidates.BestViableFunction<wbr>(S, R.getNameLoc(), Best)) {<br>
+  case OR_Success: {<br>
+    // Got one!<br>
+    FunctionDecl *FnDecl = Best->Function;<br>
+    assert(R.getNamingClass() == nullptr &&<br>
+           "class members should not be considered");<br>
+<br>
+    if (!FnDecl->isReplaceableGlobalA<wbr>llocationFunction()) {<br>
+      S.Diag(R.getNameLoc(), diag::err_builtin_operator_new<wbr>_delete_not_usual)<br>
+          << (IsDelete ? 1 : 0) << Range;<br>
+      S.Diag(FnDecl->getLocation(), diag::note_non_usual_function_<wbr>declared_here)<br>
+          << R.getLookupName() << FnDecl->getSourceRange();<br>
+      return true;<br>
+    }<br>
+<br>
+    Operator = FnDecl;<br>
+    return false;<br>
+  }<br>
+<br>
+  case OR_No_Viable_Function:<br>
+    S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_functi<wbr>on_in_call)<br>
+        << R.getLookupName() << Range;<br>
+    Candidates.NoteCandidates(S, OCD_AllCandidates, Args);<br>
+    return true;<br>
+<br>
+  case OR_Ambiguous:<br>
+    S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)<br>
+        << R.getLookupName() << Range;<br>
+    Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);<br>
+    return true;<br>
+<br>
+  case OR_Deleted: {<br>
+    S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)<br>
+        << Best->Function->isDeleted() << R.getLookupName()<br>
+        << S.getDeletedOrUnavailableSuffi<wbr>x(Best->Function) << Range;<br>
+    Candidates.NoteCandidates(S, OCD_AllCandidates, Args);<br>
+    return true;<br>
+  }<br>
+  }<br>
+  llvm_unreachable("Unreachable, bad result from BestViableFunction");<br>
+}<br>
+<br>
+ExprResult<br>
+Sema::SemaBuiltinOperatorNewD<wbr>eleteOverloaded(ExprResult TheCallResult,<br>
+                                             bool IsDelete) {<br>
+  CallExpr *TheCall = cast<CallExpr>(TheCallResult.g<wbr>et());<br>
+  if (!getLangOpts().CPlusPlus) {<br>
+    Diag(TheCall->getExprLoc(), diag::err_builtin_requires_lan<wbr>guage)<br>
+        << (IsDelete ? "__builtin_operator_delete" : "__builtin_operator_new")<br>
+        << "C++";<br>
+    return ExprError();<br>
+  }<br>
+  // CodeGen assumes it can find the global new and delete to call,<br>
+  // so ensure that they are declared.<br>
+  DeclareGlobalNewDelete();<br>
+<br>
+  FunctionDecl *OperatorNewOrDelete = nullptr;<br>
+  if (resolveBuiltinNewDeleteOverlo<wbr>ad(*this, TheCall, IsDelete,<br>
+                                      OperatorNewOrDelete))<br>
+    return ExprError();<br>
+  assert(OperatorNewOrDelete && "should be found");<br>
+<br>
+  TheCall->setType(OperatorNewOr<wbr>Delete->getReturnType());<br>
+  for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) {<br>
+    QualType ParamTy = OperatorNewOrDelete->getParamD<wbr>ecl(i)->getType();<br>
+    InitializedEntity Entity =<br>
+        InitializedEntity::InitializeP<wbr>arameter(Context, ParamTy, false);<br>
+    ExprResult Arg = PerformCopyInitialization(<br>
+        Entity, TheCall->getArg(i)->getLocStar<wbr>t(), TheCall->getArg(i));<br>
+    if (Arg.isInvalid())<br>
+      return ExprError();<br>
+    TheCall->setArg(i, Arg.get());<br>
+  }<br>
+  auto Callee = dyn_cast<ImplicitCastExpr>(The<wbr>Call->getCallee());<br>
+  assert(Callee && Callee->getCastKind() == CK_BuiltinFnToFnPtr &&<br>
+         "Callee expected to be implicit cast to a builtin function pointer");<br>
+  Callee->setType(OperatorNewOrD<wbr>elete->getType());<br>
+<br>
+  return TheCallResult;<br>
+}<br>
+<br>
 void Sema::CheckVirtualDtorCall(CXX<wbr>DestructorDecl *dtor, SourceLocation Loc,<br>
                                 bool IsDelete, bool CallCanBeVirtual,<br>
                                 bool WarnOnNonAbstractTypes,<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/buil<wbr>tin-operator-new-delete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/builtin-operator-new-delete.cpp?rev=328134&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CodeGenCX<wbr>X/builtin-operator-new-delete.<wbr>cpp?rev=328134&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/buil<wbr>tin-operator-new-delete.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/buil<wbr>tin-operator-new-delete.cpp Wed Mar 21 12:19:48 2018<br>
@@ -0,0 +1,71 @@<br>
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s  \<br>
+// RUN:     -faligned-allocation -fsized-deallocation -emit-llvm -o - \<br>
+// RUN:    | FileCheck %s<br>
+<br>
+typedef __SIZE_TYPE__ size_t;<br>
+<br>
+// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.<br>
+template<typename T> void *operator new(size_t, int (*)(T));<br>
+<br>
+// Ensure that this declaration doesn't cause operator new to lose its<br>
+// 'noalias' attribute.<br>
+void *operator new(size_t);<br>
+<br>
+namespace std {<br>
+  struct nothrow_t {};<br>
+  enum class align_val_t : size_t { __zero = 0,<br>
+                                  __max = (size_t)-1 };<br>
+}<br>
+std::nothrow_t nothrow;<br>
+<br>
+// Declare the reserved placement operators.<br>
+void *operator new(size_t, void*) throw();<br>
+void operator delete(void*, void*) throw();<br>
+void *operator new[](size_t, void*) throw();<br>
+void operator delete[](void*, void*) throw();<br>
+<br>
+// Declare the replaceable global allocation operators.<br>
+void *operator new(size_t, const std::nothrow_t &) throw();<br>
+void *operator new[](size_t, const std::nothrow_t &) throw();<br>
+void operator delete(void *, const std::nothrow_t &) throw();<br>
+void operator delete[](void *, const std::nothrow_t &) throw();<br>
+<br>
+// Declare some other placement operators.<br>
+void *operator new(size_t, void*, bool) throw();<br>
+void *operator new[](size_t, void*, bool) throw();<br>
+<br>
+<br>
+// CHECK-LABEL: define void @test_basic(<br>
+extern "C" void test_basic() {<br>
+  // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]<br>
+  // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]<br>
+  // CHECK: ret void<br>
+  __builtin_operator_delete(__bu<wbr>iltin_operator_new(4));<br>
+}<br>
+// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]]<br>
+// CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]<br>
+<br>
+// CHECK-LABEL: define void @test_aligned_alloc(<br>
+extern "C" void test_aligned_alloc() {<br>
+  // CHECK: call i8* @_ZnwmSt11align_val_t(i64 4, i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]<br>
+  // CHECK: call void @_ZdlPvSt11align_val_t({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]]<br>
+  __builtin_operator_delete(__bu<wbr>iltin_operator_new(4, std::align_val_t(4)), std::align_val_t(4));<br>
+}<br>
+// CHECK: declare noalias i8* @_ZnwmSt11align_val_t(i64, i64) [[ATTR_NOBUILTIN:#[^ ]*]]<br>
+// CHECK: declare void @_ZdlPvSt11align_val_t(i8*, i64) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]<br>
+<br>
+<br>
+// CHECK-LABEL: define void @test_sized_delete(<br>
+extern "C" void test_sized_delete() {<br>
+  // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]<br>
+  // CHECK: call void @_ZdlPvm({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]]<br>
+  __builtin_operator_delete(__bu<wbr>iltin_operator_new(4), 4);<br>
+}<br>
+// CHECK: declare void @_ZdlPvm(i8*, i64) [[ATTR_NOBUILTIN_UNWIND:#[^ ]*]]<br>
+<br>
+<br>
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}}<br>
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}<br>
+<br>
+// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}}<br>
+// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}}<br>
<br>
Added: cfe/trunk/test/SemaCXX/builtin<wbr>-operator-new-delete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-operator-new-delete.cpp?rev=328134&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaCXX/<wbr>builtin-operator-new-delete.<wbr>cpp?rev=328134&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/builtin<wbr>-operator-new-delete.cpp (added)<br>
+++ cfe/trunk/test/SemaCXX/builtin<wbr>-operator-new-delete.cpp Wed Mar 21 12:19:48 2018<br>
@@ -0,0 +1,153 @@<br>
+// RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -std=c++03 -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -std=c++03 -faligned-allocation -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fsized-deallocation %s<br>
+<br>
+#if !__has_builtin(__builtin_opera<wbr>tor_new) || !__has_builtin(__builtin_opera<wbr>tor_delete)<br>
+#error builtins should always be available<br>
+#endif<br>
+<br>
+#if __has_builtin(__builtin_operat<wbr>or_new) != 201802L || \<br>
+    __has_builtin(__builtin_operat<wbr>or_delete) != 201802L<br>
+#error builtin should report updated value<br>
+#endif<br>
+<br>
+typedef __SIZE_TYPE__ size_t;<br>
+namespace std {<br>
+  struct nothrow_t {};<br>
+#if __cplusplus >= 201103L<br>
+enum class align_val_t : size_t {};<br>
+#else<br>
+  enum align_val_t { __zero = 0,<br>
+                     __max = (size_t)-1 };<br>
+#endif<br>
+}<br>
+std::nothrow_t nothrow;<br>
+<br>
+void *operator new(size_t); // expected-note 1+ {{candidate function}}<br>
+void operator delete(void *); // expected-note 1+ {{candidate function}}<br>
+<br>
+// Declare the reserved placement operators.<br>
+void *operator new(size_t, void*) throw(); // expected-note 1+ {{candidate function}}<br>
+void operator delete(void *, void *)throw(); // expected-note 1+ {{candidate function}}<br>
+void *operator new[](size_t, void*) throw();<br>
+void operator delete[](void*, void*) throw();<br>
+<br>
+// Declare the replaceable global allocation operators.<br>
+void *operator new(size_t, const std::nothrow_t &) throw(); // expected-note 1+ {{candidate function}}<br>
+void *operator new[](size_t, const std::nothrow_t &) throw();<br>
+void operator delete(void *, const std::nothrow_t &)throw(); // expected-note 1+ {{candidate function}}<br>
+void operator delete[](void *, const std::nothrow_t &) throw();<br>
+<br>
+// aligned allocation and deallocation functions.<br>
+void* operator new  ( size_t count, std::align_val_t al); // expected-note 1+ {{candidate function}}<br>
+void operator delete(void *, std::align_val_t); // expected-note 1+ {{candidate}}<br>
+#ifndef __cpp_aligned_new<br>
+// expected-note@-3 1+ {{non-usual 'operator new' declared here}}<br>
+// expected-note@-3 1+ {{non-usual 'operator delete' declared here}}<br>
+#endif<br>
+void *operator new[](size_t count, std::align_val_t al);<br>
+void operator delete[](void*, std::align_val_t);<br>
+<br>
+void operator delete(void *, size_t); // expected-note 1+ {{candidate}}<br>
+#ifndef __cpp_sized_deallocation<br>
+// expected-note@-2 1+ {{non-usual 'operator delete' declared here}}<br>
+#endif<br>
+void operator delete[](void*, size_t);<br>
+<br>
+// Declare some other placemenet operators.<br>
+void *operator new(size_t, void*, bool) throw(); // expected-note 1+ {{candidate function}}<br>
+void *operator new[](size_t, void*, bool) throw();<br>
+<br>
+void *NP = 0;<br>
+<br>
+void test_typo_in_args() {<br>
+  __builtin_operator_new(DNE);          // expected-error {{undeclared identifier 'DNE'}}<br>
+  __builtin_operator_new(DNE, DNE2);    // expected-error {{undeclared identifier 'DNE'}} expected-error {{'DNE2'}}<br>
+  __builtin_operator_delete(DNE)<wbr>;       // expected-error {{'DNE'}}<br>
+  __builtin_operator_delete(DNE, DNE2); // expected-error {{'DNE'}} expected-error {{'DNE2'}}<br>
+}<br>
+<br>
+void test_arg_types() {<br>
+  __builtin_operator_new(NP);                      // expected-error {{no matching function for call to 'operator new'}}<br>
+  __builtin_operator_new(NP, std::align_val_t(0)); // expected-error {{no matching function for call to 'operator new'}}}<br>
+}<br>
+void test_return_type() {<br>
+  int w = __builtin_operator_new(42);        // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}}<br>
+  int y = __builtin_operator_delete(NP);<wbr>     // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void'}}<br>
+}<br>
+<br>
+void test_aligned_new() {<br>
+#ifdef __cpp_aligned_new<br>
+  void *p = __builtin_operator_new(42, std::align_val_t(2));<br>
+  __builtin_operator_delete(p, std::align_val_t(2));<br>
+#else<br>
+  // FIXME: We've manually declared the aligned new/delete overloads,<br>
+  // but LangOpts::AlignedAllocation is false. Should our overloads be considered<br>
+  // usual allocation/deallocation functions?<br>
+  void *p = __builtin_operator_new(42, std::align_val_t(2)); // expected-error {{call to '__builtin_operator_new' selects non-usual allocation function}}<br>
+  __builtin_operator_delete(p, std::align_val_t(2));         // expected-error {{call to '__builtin_operator_delete' selects non-usual deallocation function}}<br>
+#endif<br>
+}<br>
+<br>
+void test_sized_delete() {<br>
+#ifdef __cpp_sized_deallocation<br>
+  __builtin_operator_delete(NP, 4);<br>
+#else<br>
+  __builtin_operator_delete(NP, 4); // expected-error {{call to '__builtin_operator_delete' selects non-usual deallocation function}}<br>
+#endif<br>
+}<br>
+<br>
+void *operator new(size_t, bool);   // expected-note 1+ {{candidate}}<br>
+// expected-note@-1 {{non-usual 'operator new' declared here}}<br>
+void operator delete(void *, bool); // expected-note 1+ {{candidate}}<br>
+// expected-note@-1 {{non-usual 'operator delete' declared here}}<br>
+<br>
+void test_non_usual() {<br>
+  __builtin_operator_new(42, true);     // expected-error {{call to '__builtin_operator_new' selects non-usual allocation function}}<br>
+  __builtin_operator_delete(NP, false); // expected-error {{call to '__builtin_operator_delete' selects non-usual deallocation function}}<br>
+}<br>
+<br>
+template <int ID><br>
+struct Tag {};<br>
+struct ConvertsToTypes {<br>
+  operator std::align_val_t() const;<br>
+  operator Tag<0>() const;<br>
+};<br>
+<br>
+void *operator new(size_t, Tag<0>);   // expected-note 0+ {{candidate}}<br>
+void operator delete(void *, Tag<0>); // expected-note 0+ {{candidate}}<br>
+<br>
+void test_ambiguous() {<br>
+#ifdef __cpp_aligned_new<br>
+  ConvertsToTypes cvt;<br>
+  __builtin_operator_new(42, cvt);    // expected-error {{call to 'operator new' is ambiguous}}<br>
+  __builtin_operator_delete(NP, cvt); // expected-error {{call to 'operator delete' is ambiguous}}<br>
+#endif<br>
+}<br>
+<br>
+void test_no_args() {<br>
+  __builtin_operator_new();    // expected-error {{no matching function for call to 'operator new'}}<br>
+  __builtin_operator_delete(); // expected-error {{no matching function for call to 'operator delete'}}<br>
+}<br>
+<br>
+void test_no_matching_fn() {<br>
+  Tag<1> tag;<br>
+  __builtin_operator_new(42, tag);    // expected-error {{no matching function for call to 'operator new'}}<br>
+  __builtin_operator_delete(NP, tag); // expected-error {{no matching function for call to 'operator delete'}}<br>
+}<br>
+<br>
+template <class Tp, class Up, class RetT><br>
+void test_dependent_call(Tp new_arg, Up delete_arg, RetT) {<br>
+  RetT ret = __builtin_operator_new(new_arg<wbr>);<br>
+  __builtin_operator_delete(dele<wbr>te_arg);<br>
+}<br>
+template void test_dependent_call(int, int*, void*);<br>
+<br>
+void test_const_attribute() {<br>
+  __builtin_operator_new(42); // expected-warning {{ignoring return value of function declared with const attribute}}<br>
+#ifdef __cpp_aligned_new<br>
+  __builtin_operator_new(42, std::align_val_t(8)); // expected-warning {{ignoring return value of function declared with const attribute}}<br>
+#endif<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>