diff options
author | Sven van Haastregt <sven.vanhaastregt@arm.com> | 2018-06-14 09:51:54 +0000 |
---|---|---|
committer | Sven van Haastregt <sven.vanhaastregt@arm.com> | 2018-06-14 09:51:54 +0000 |
commit | af560779404671ccbbba0714fdff3f550ef6b49d (patch) | |
tree | b1942b4fe3c6387b22b2b1fbe2510572e63e3ff5 /lib/Sema | |
parent | 9c72f2596ef1e333adbb469ca2207b95b85158f6 (diff) | |
download | clang-af560779404671ccbbba0714fdff3f550ef6b49d.tar.gz |
[OpenCL] Support new/delete in Sema
Reject uses of the default new/delete operators with a diagnostic
instead of a crash in OpenCL C++ mode and accept user-defined forms.
Differential Revision: https://reviews.llvm.org/D46651
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334700 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 5 |
3 files changed, 43 insertions, 4 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f5e4821092..e21f380fb7 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -13007,6 +13007,13 @@ CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef, return false; } +static QualType +RemoveAddressSpaceFromPtr(Sema &SemaRef, const PointerType *PtrTy) { + QualType QTy = PtrTy->getPointeeType(); + QTy = SemaRef.Context.removeAddrSpaceQualType(QTy); + return SemaRef.Context.getPointerType(QTy); +} + static inline bool CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, CanQualType ExpectedResultType, @@ -13022,6 +13029,13 @@ CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, diag::err_operator_new_delete_dependent_result_type) << FnDecl->getDeclName() << ExpectedResultType; + // OpenCL C++: the operator is valid on any address space. + if (SemaRef.getLangOpts().OpenCLCPlusPlus) { + if (auto *PtrTy = ResultType->getAs<PointerType>()) { + ResultType = RemoveAddressSpaceFromPtr(SemaRef, PtrTy); + } + } + // Check that the result type is what we expect. if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType) return SemaRef.Diag(FnDecl->getLocation(), @@ -13047,6 +13061,13 @@ CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, << FnDecl->getDeclName() << ExpectedFirstParamType; // Check that the first parameter type is what we expect. + if (SemaRef.getLangOpts().OpenCLCPlusPlus) { + // OpenCL C++: the operator is valid on any address space. + if (auto *PtrTy = + FnDecl->getParamDecl(0)->getType()->getAs<PointerType>()) { + FirstParamType = RemoveAddressSpaceFromPtr(SemaRef, PtrTy); + } + } if (SemaRef.Context.getCanonicalType(FirstParamType).getUnqualifiedType() != ExpectedFirstParamType) return SemaRef.Diag(FnDecl->getLocation(), InvalidParamTypeDiag) diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2847069ce5..5d1001dc84 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2146,7 +2146,8 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, else if (AllocType->isVariablyModifiedType()) return Diag(Loc, diag::err_variably_modified_new_type) << AllocType; - else if (AllocType.getAddressSpace() != LangAS::Default) + else if (AllocType.getAddressSpace() != LangAS::Default && + !getLangOpts().OpenCLCPlusPlus) return Diag(Loc, diag::err_address_space_qualified_new) << AllocType.getUnqualifiedType() << AllocType.getQualifiers().getAddressSpaceAttributePrintValue(); @@ -2362,6 +2363,11 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, LookupQualifiedName(R, Context.getTranslationUnitDecl()); } + if (getLangOpts().OpenCLCPlusPlus && R.empty()) { + Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new"; + return true; + } + assert(!R.empty() && "implicitly declared allocation functions not found"); assert(!R.isAmbiguous() && "global allocation functions are ambiguous"); @@ -2597,6 +2603,11 @@ void Sema::DeclareGlobalNewDelete() { if (GlobalNewDeleteDeclared) return; + // OpenCL C++ 1.0 s2.9: the implicitly declared new and delete operators + // are not supported. + if (getLangOpts().OpenCLCPlusPlus) + return; + // C++ [basic.std.dynamic]p2: // [...] The following allocation and deallocation functions (18.4) are // implicitly declared in global scope in each translation unit of a @@ -3230,7 +3241,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, QualType Pointee = Type->getAs<PointerType>()->getPointeeType(); QualType PointeeElem = Context.getBaseElementType(Pointee); - if (Pointee.getAddressSpace() != LangAS::Default) + if (Pointee.getAddressSpace() != LangAS::Default && + !getLangOpts().OpenCLCPlusPlus) return Diag(Ex.get()->getLocStart(), diag::err_address_space_qualified_delete) << Pointee.getUnqualifiedType() @@ -3305,6 +3317,11 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, } if (!OperatorDelete) { + if (getLangOpts().OpenCLCPlusPlus) { + Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete"; + return ExprError(); + } + bool IsComplete = isCompleteType(StartLoc, Pointee); bool CanProvideSize = IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize || diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index ac85e016ba..1f6034a07d 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -7173,8 +7173,9 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State, // The default address space name for arguments to a function in a // program, or local variables of a function is __private. All function // arguments shall be in the __private address space. - if (State.getSema().getLangOpts().OpenCLVersion <= 120) { - ImpAddr = LangAS::opencl_private; + if (State.getSema().getLangOpts().OpenCLVersion <= 120 && + !State.getSema().getLangOpts().OpenCLCPlusPlus) { + ImpAddr = LangAS::opencl_private; } else { // If address space is not set, OpenCL 2.0 defines non private default // address spaces for some cases: |