[clang] [clang][Sema] Avoid assert when diagnosing address-space qualified new/delete (PR #178424)
Ayush Kumar Gaur via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 28 06:18:27 PST 2026
https://github.com/Ayush3941 updated https://github.com/llvm/llvm-project/pull/178424
>From 092d180df50f99e8bc81a0328e74dc249434614f Mon Sep 17 00:00:00 2001
From: Ayush3941 <ayushkgaur1 at gmail.com>
Date: Wed, 28 Jan 2026 08:46:08 -0500
Subject: [PATCH 1/3] [clang][Sema] Fix crash when diagnosing address-space
qualified new/delete
---
clang/lib/Sema/SemaExprCXX.cpp | 21 +++++++++++++++++--
.../test/SemaCXX/address-space-new-delete.cpp | 13 ++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 clang/test/SemaCXX/address-space-new-delete.cpp
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 91967a7a9ff97..b2a1a4dfa5e9c 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
@@ -2677,7 +2693,8 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
!getLangOpts().OpenCLCPlusPlus)
return Diag(Loc, diag::err_address_space_qualified_new)
<< AllocType.getUnqualifiedType()
- << AllocType.getQualifiers().getAddressSpaceAttributePrintValue();
+ << formatAddressSpaceForDiag(AllocType.getAddressSpace(), getLangOpts());
+
else if (getLangOpts().ObjCAutoRefCount) {
if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
QualType BaseAllocType = Context.getBaseElementType(AT);
@@ -4069,7 +4086,7 @@ 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 at -1 {{'new' cannot allocate objects of type 'int' in address space '__local'}}
+}
+
+void test_delete(FOO *p) {
+ delete p;
+ // expected-error at -1 {{cannot delete objects of type 'int' in address space '__local'}}
+}
>From 342773363ca684fefc55a4f9e168d167f1a0b70f Mon Sep 17 00:00:00 2001
From: Ayush3941 <ayushkgaur1 at gmail.com>
Date: Wed, 28 Jan 2026 08:49:12 -0500
Subject: [PATCH 2/3] [clang][Sema] Fix crash when diagnosing address-space
qualified new/delete with fixed format
---
clang/lib/Sema/SemaExprCXX.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index b2a1a4dfa5e9c..9fd28ca43d8c5 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -2692,8 +2692,9 @@ 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()
- << formatAddressSpaceForDiag(AllocType.getAddressSpace(), getLangOpts());
+ << AllocType.getUnqualifiedType()
+ << formatAddressSpaceForDiag(AllocType.getAddressSpace(),
+ getLangOpts());
else if (getLangOpts().ObjCAutoRefCount) {
if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
@@ -4086,7 +4087,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
return Diag(Ex.get()->getBeginLoc(),
diag::err_address_space_qualified_delete)
<< Pointee.getUnqualifiedType()
- << formatAddressSpaceForDiag(Pointee.getAddressSpace(), getLangOpts());
+ << formatAddressSpaceForDiag(Pointee.getAddressSpace(),
+ getLangOpts());
CXXRecordDecl *PointeeRD = nullptr;
if (Pointee->isVoidType() && !isSFINAEContext()) {
>From 12c7a0520311ceee0e9eca322ad4d8c8fcc1af87 Mon Sep 17 00:00:00 2001
From: Ayush3941 <ayushkgaur1 at gmail.com>
Date: Wed, 28 Jan 2026 09:17:32 -0500
Subject: [PATCH 3/3] [clang][Sema] Fix crash when diagnosing address-space
qualified new/delete with fixed format v2
---
clang/lib/Sema/SemaExprCXX.cpp | 1 +
clang/test/SemaCXX/address-space-new-delete.cpp | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 9fd28ca43d8c5..f8b1d11c7e9ac 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -50,6 +50,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/raw_ostream.h"
#include <optional>
using namespace clang;
using namespace sema;
diff --git a/clang/test/SemaCXX/address-space-new-delete.cpp b/clang/test/SemaCXX/address-space-new-delete.cpp
index 2d1d4352b8dd9..6cbadc4aa784a 100644
--- a/clang/test/SemaCXX/address-space-new-delete.cpp
+++ b/clang/test/SemaCXX/address-space-new-delete.cpp
@@ -4,10 +4,10 @@ typedef int FOO __attribute__((opencl_local));
void test_new() {
int *p = new FOO[1];
- // expected-error at -1 {{'new' cannot allocate objects of type 'int' in address space '__local'}}
+ // expected-error at -1 {{'new' cannot allocate objects of type 'int' in address space}}
}
void test_delete(FOO *p) {
delete p;
- // expected-error at -1 {{cannot delete objects of type 'int' in address space '__local'}}
+ // expected-error at -1 {{cannot delete objects of type 'int' in address space}}
}
More information about the cfe-commits
mailing list