diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaCoroutine.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 30 |
2 files changed, 38 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 139a21014d1..24b6bdbbdcb 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -1110,8 +1110,8 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { PlacementArgs.push_back(PDRefExpr.get()); } - S.FindAllocationFunctions(Loc, SourceRange(), - /*UseGlobal*/ false, PromiseType, + S.FindAllocationFunctions(Loc, SourceRange(), /*NewScope*/ Sema::AFS_Class, + /*DeleteScope*/ Sema::AFS_Both, PromiseType, /*isArray*/ false, PassAlignment, PlacementArgs, OperatorNew, UnusedResult, /*Diagnose*/ false); @@ -1121,10 +1121,21 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { // an argument of type std::size_t." if (!OperatorNew && !PlacementArgs.empty()) { PlacementArgs.clear(); - S.FindAllocationFunctions(Loc, SourceRange(), - /*UseGlobal*/ false, PromiseType, - /*isArray*/ false, PassAlignment, - PlacementArgs, OperatorNew, UnusedResult); + S.FindAllocationFunctions(Loc, SourceRange(), /*NewScope*/ Sema::AFS_Class, + /*DeleteScope*/ Sema::AFS_Both, PromiseType, + /*isArray*/ false, PassAlignment, PlacementArgs, + OperatorNew, UnusedResult, /*Diagnose*/ false); + } + + // [dcl.fct.def.coroutine]/7 + // "The allocation function’s name is looked up in the scope of P. If this + // lookup fails, the allocation function’s name is looked up in the global + // scope." + if (!OperatorNew) { + S.FindAllocationFunctions(Loc, SourceRange(), /*NewScope*/ Sema::AFS_Global, + /*DeleteScope*/ Sema::AFS_Both, PromiseType, + /*isArray*/ false, PassAlignment, PlacementArgs, + OperatorNew, UnusedResult); } bool IsGlobalOverload = @@ -1138,8 +1149,8 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { return false; PlacementArgs = {StdNoThrow}; OperatorNew = nullptr; - S.FindAllocationFunctions(Loc, SourceRange(), - /*UseGlobal*/ true, PromiseType, + S.FindAllocationFunctions(Loc, SourceRange(), /*NewScope*/ Sema::AFS_Both, + /*DeleteScope*/ Sema::AFS_Both, PromiseType, /*isArray*/ false, PassAlignment, PlacementArgs, OperatorNew, UnusedResult); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4ec76bde906..849fc3c3cf3 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1975,11 +1975,12 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, bool PassAlignment = getLangOpts().AlignedAllocation && Alignment > NewAlignment; + AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both; if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlacementArgs) && FindAllocationFunctions(StartLoc, SourceRange(PlacementLParen, PlacementRParen), - UseGlobal, AllocType, ArraySize, PassAlignment, + Scope, Scope, AllocType, ArraySize, PassAlignment, PlacementArgs, OperatorNew, OperatorDelete)) return ExprError(); @@ -2271,19 +2272,19 @@ static bool resolveAllocationOverload( llvm_unreachable("Unreachable, bad result from BestViableFunction"); } -/// FindAllocationFunctions - Finds the overloads of operator new and delete -/// that are appropriate for the allocation. bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, - bool UseGlobal, QualType AllocType, - bool IsArray, bool &PassAlignment, - MultiExprArg PlaceArgs, + AllocationFunctionScope NewScope, + AllocationFunctionScope DeleteScope, + QualType AllocType, bool IsArray, + bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose) { // --- Choosing an allocation function --- // C++ 5.3.4p8 - 14 & 18 - // 1) If UseGlobal is true, only look in the global scope. Else, also look - // in the scope of the allocated class. + // 1) If looking in AFS_Global scope for allocation functions, only look in + // the global scope. Else, if AFS_Class, only look in the scope of the + // allocated class. If AFS_Both, look in both. // 2) If an array size is given, look for operator new[], else look for // operator new. // 3) The first argument is always size_t. Append the arguments from the @@ -2333,7 +2334,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // function's name is looked up in the global scope. Otherwise, if the // allocated type is a class type T or array thereof, the allocation // function's name is looked up in the scope of T. - if (AllocElemType->isRecordType() && !UseGlobal) + if (AllocElemType->isRecordType() && NewScope != AFS_Global) LookupQualifiedName(R, AllocElemType->getAsCXXRecordDecl()); // We can see ambiguity here if the allocation function is found in @@ -2344,8 +2345,12 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // If this lookup fails to find the name, or if the allocated type is not // a class type, the allocation function's name is looked up in the // global scope. - if (R.empty()) + if (R.empty()) { + if (NewScope == AFS_Class) + return true; + LookupQualifiedName(R, Context.getTranslationUnitDecl()); + } assert(!R.empty() && "implicitly declared allocation functions not found"); assert(!R.isAmbiguous() && "global allocation functions are ambiguous"); @@ -2382,7 +2387,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // the allocated type is not a class type or array thereof, the // deallocation function's name is looked up in the global scope. LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName); - if (AllocElemType->isRecordType() && !UseGlobal) { + if (AllocElemType->isRecordType() && DeleteScope != AFS_Global) { CXXRecordDecl *RD = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl()); LookupQualifiedName(FoundDelete, RD); @@ -2392,6 +2397,9 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, bool FoundGlobalDelete = FoundDelete.empty(); if (FoundDelete.empty()) { + if (DeleteScope == AFS_Class) + return true; + DeclareGlobalNewDelete(); LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl()); } |