llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Ayush Kumar Gaur (Ayush3941) <details> <summary>Changes</summary> ### Whats the error Clang could assert when diagnosing new or delete on types in language-specific address spaces (e.g. OpenCL __local), instead of emitting a normal error. ### Why it happened The diagnostics used getAddressSpaceAttributePrintValue(), which assumes target-specific address spaces and asserts for language-defined ones like OpenCL. ### Whats the Fix Use a safe address-space formatter helper in new/delete diagnostics so errors are emitted without crashing. Add a regression test. Fixes #<!-- -->178319 --- Full diff: https://github.com/llvm/llvm-project/pull/178424.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaExprCXX.cpp (+22-3) - (added) clang/test/SemaCXX/address-space-new-delete.cpp (+13) ``````````diff diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 91967a7a9ff97..9fd28ca43d8c5 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2653,6 +2653,22 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, ResultType, AllocTypeInfo, Range, DirectInitRange); } +// Format an address space for diagnostics without assuming it maps to a +// target-specific value. Language-specific spaces (e.g. OpenCL) are rendered +// using their spelled qualifiers, while target-specific ones are printed as the +// numeric attribute value for compatibility with existing messages. + +static std::string formatAddressSpaceForDiag(LangAS AS, + const LangOptions &LangOpts) { + PrintingPolicy PP(LangOpts); + Qualifiers Q; + Q.setAddressSpace(AS); + std::string S; + llvm::raw_string_ostream OS(S); + Q.print(OS, PP, false); + return OS.str(); +} + bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, SourceRange R) { // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an @@ -2676,8 +2692,10 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, else if (AllocType.getAddressSpace() != LangAS::Default && !getLangOpts().OpenCLCPlusPlus) return Diag(Loc, diag::err_address_space_qualified_new) - << AllocType.getUnqualifiedType() - << AllocType.getQualifiers().getAddressSpaceAttributePrintValue(); + << AllocType.getUnqualifiedType() + << formatAddressSpaceForDiag(AllocType.getAddressSpace(), + getLangOpts()); + else if (getLangOpts().ObjCAutoRefCount) { if (const ArrayType *AT = Context.getAsArrayType(AllocType)) { QualType BaseAllocType = Context.getBaseElementType(AT); @@ -4069,7 +4087,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, return Diag(Ex.get()->getBeginLoc(), diag::err_address_space_qualified_delete) << Pointee.getUnqualifiedType() - << Pointee.getQualifiers().getAddressSpaceAttributePrintValue(); + << formatAddressSpaceForDiag(Pointee.getAddressSpace(), + getLangOpts()); CXXRecordDecl *PointeeRD = nullptr; if (Pointee->isVoidType() && !isSFINAEContext()) { diff --git a/clang/test/SemaCXX/address-space-new-delete.cpp b/clang/test/SemaCXX/address-space-new-delete.cpp new file mode 100644 index 0000000000000..2d1d4352b8dd9 --- /dev/null +++ b/clang/test/SemaCXX/address-space-new-delete.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++17 %s -verify + +typedef int FOO __attribute__((opencl_local)); + +void test_new() { + int *p = new FOO[1]; + // expected-error@-1 {{'new' cannot allocate objects of type 'int' in address space '__local'}} +} + +void test_delete(FOO *p) { + delete p; + // expected-error@-1 {{cannot delete objects of type 'int' in address space '__local'}} +} `````````` </details> https://github.com/llvm/llvm-project/pull/178424 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
