|
@@ -1975,11 +1975,12 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|
bool PassAlignment = getLangOpts().AlignedAllocation &&
|
|
bool PassAlignment = getLangOpts().AlignedAllocation &&
|
|
Alignment > NewAlignment;
|
|
Alignment > NewAlignment;
|
|
|
|
|
|
|
|
+ AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both;
|
|
if (!AllocType->isDependentType() &&
|
|
if (!AllocType->isDependentType() &&
|
|
!Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
|
|
!Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
|
|
FindAllocationFunctions(StartLoc,
|
|
FindAllocationFunctions(StartLoc,
|
|
SourceRange(PlacementLParen, PlacementRParen),
|
|
SourceRange(PlacementLParen, PlacementRParen),
|
|
- UseGlobal, AllocType, ArraySize, PassAlignment,
|
|
|
|
|
|
+ Scope, Scope, AllocType, ArraySize, PassAlignment,
|
|
PlacementArgs, OperatorNew, OperatorDelete))
|
|
PlacementArgs, OperatorNew, OperatorDelete))
|
|
return ExprError();
|
|
return ExprError();
|
|
|
|
|
|
@@ -2271,19 +2272,19 @@ static bool resolveAllocationOverload(
|
|
llvm_unreachable("Unreachable, bad result from BestViableFunction");
|
|
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 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 *&OperatorNew,
|
|
FunctionDecl *&OperatorDelete,
|
|
FunctionDecl *&OperatorDelete,
|
|
bool Diagnose) {
|
|
bool Diagnose) {
|
|
// --- Choosing an allocation function ---
|
|
// --- Choosing an allocation function ---
|
|
// C++ 5.3.4p8 - 14 & 18
|
|
// 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
|
|
// 2) If an array size is given, look for operator new[], else look for
|
|
// operator new.
|
|
// operator new.
|
|
// 3) The first argument is always size_t. Append the arguments from the
|
|
// 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
|
|
// 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
|
|
// allocated type is a class type T or array thereof, the allocation
|
|
// function's name is looked up in the scope of T.
|
|
// 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());
|
|
LookupQualifiedName(R, AllocElemType->getAsCXXRecordDecl());
|
|
|
|
|
|
// We can see ambiguity here if the allocation function is found in
|
|
// 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
|
|
// 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
|
|
// a class type, the allocation function's name is looked up in the
|
|
// global scope.
|
|
// global scope.
|
|
- if (R.empty())
|
|
|
|
|
|
+ if (R.empty()) {
|
|
|
|
+ if (NewScope == AFS_Class)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
LookupQualifiedName(R, Context.getTranslationUnitDecl());
|
|
LookupQualifiedName(R, Context.getTranslationUnitDecl());
|
|
|
|
+ }
|
|
|
|
|
|
assert(!R.empty() && "implicitly declared allocation functions not found");
|
|
assert(!R.empty() && "implicitly declared allocation functions not found");
|
|
assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
|
|
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
|
|
// the allocated type is not a class type or array thereof, the
|
|
// deallocation function's name is looked up in the global scope.
|
|
// deallocation function's name is looked up in the global scope.
|
|
LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
|
|
LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
|
|
- if (AllocElemType->isRecordType() && !UseGlobal) {
|
|
|
|
|
|
+ if (AllocElemType->isRecordType() && DeleteScope != AFS_Global) {
|
|
CXXRecordDecl *RD
|
|
CXXRecordDecl *RD
|
|
= cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
|
|
= cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
|
|
LookupQualifiedName(FoundDelete, RD);
|
|
LookupQualifiedName(FoundDelete, RD);
|
|
@@ -2392,6 +2397,9 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
|
|
|
|
|
|
bool FoundGlobalDelete = FoundDelete.empty();
|
|
bool FoundGlobalDelete = FoundDelete.empty();
|
|
if (FoundDelete.empty()) {
|
|
if (FoundDelete.empty()) {
|
|
|
|
+ if (DeleteScope == AFS_Class)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
DeclareGlobalNewDelete();
|
|
DeclareGlobalNewDelete();
|
|
LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
|
|
LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
|
|
}
|
|
}
|