[clang] [clang][sema]`no address_space attribute found at the expected location!` assertion fail (PR #216348)

Akash Manna via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 19 05:20:01 PDT 2026


https://github.com/akash-manna-sky updated https://github.com/llvm/llvm-project/pull/216348

>From 09077e2b96e01e7a0bc93318991b9c9557c1989e Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Fri, 14 Aug 2026 21:44:45 +0530
Subject: [PATCH 1/5] [clang][Sema] Fix crash on address_space attribute
 written after the declarator-id

---
 clang/docs/ReleaseNotes.md                    |  4 ++++
 clang/lib/Sema/SemaType.cpp                   | 24 ++++++++++++-------
 .../SemaTemplate/address_space-dependent.cpp  | 14 +++++++++++
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 16911cf384ea3..3647cfe20af91 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -441,6 +441,10 @@ features cannot lower the translation-unit ABI level;
   `sized_by_or_null` describe the size in bytes rather than a count of elements,
   they are now correctly accepted on such pointers.
 
+- Fixed a crash when an `address_space` attribute with a dependent argument was
+  written after the declarator-id, where it appertains to the declared entity
+  rather than to a declarator chunk. (#GH196982)
+
 #### Bug Fixes to C++ Support
 
 - Fixed an issue where `__typeof__` incorrectly rejected cv-qualified function types.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 42ef93b98aa0a..da848d6431004 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6343,11 +6343,20 @@ namespace {
   };
 } // end anonymous namespace
 
-static void
-fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
-                                 const ParsedAttributesView &Attrs) {
-  for (const ParsedAttr &AL : Attrs) {
-    if (AL.getKind() == ParsedAttr::AT_AddressSpace) {
+static void fillDependentAddressSpaceTypeLoc(ASTContext &Context,
+                                             DependentAddressSpaceTypeLoc DASTL,
+                                             const Declarator &D,
+                                             const DeclaratorChunk &Chunk) {
+  // An attribute written after the declarator-id appertains to the declared
+  // entity, so it is applied to the outermost type instead of to the chunk
+  // that is being visited.
+  const ParsedAttributesView *AttrLists[] = {&Chunk.getAttrs(),
+                                             &D.getAttributes()};
+  for (const ParsedAttributesView *Attrs : AttrLists) {
+    for (const ParsedAttr &AL : *Attrs) {
+      if (AL.getKind() != ParsedAttr::AT_AddressSpace || AL.getNumArgs() != 1 ||
+          !AL.isArgExpr(0))
+        continue;
       DASTL.setAttrNameLoc(AL.getLoc());
       DASTL.setAttrExprOperand(AL.getArgAsExpr(0));
       DASTL.setAttrOperandParensRange(SourceRange());
@@ -6355,8 +6364,7 @@ fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
     }
   }
 
-  llvm_unreachable(
-      "no address_space attribute found at the expected location!");
+  DASTL.initializeLocal(Context, DASTL.getTypePtr()->getAttributeLoc());
 }
 
 /// Create and instantiate a TypeSourceInfo with type source information.
@@ -6422,7 +6430,7 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
 
       case TypeLoc::DependentAddressSpace: {
         auto TL = CurrTL.castAs<DependentAddressSpaceTypeLoc>();
-        fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());
+        fillDependentAddressSpaceTypeLoc(S.Context, TL, D, D.getTypeObject(i));
         CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
         break;
       }
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index d6f25923b69b5..9c90c9831b7e3 100644
--- a/clang/test/SemaTemplate/address_space-dependent.cpp
+++ b/clang/test/SemaTemplate/address_space-dependent.cpp
@@ -130,3 +130,17 @@ struct EntryTy {
 ASPtrTy<1> x;
 EntryTy<2> y;
 }
+
+namespace gh196982 {
+template <int AS>
+void trailing() {
+  void *p [[clang::address_space(AS)]]; // expected-warning {{applying attribute 'clang::address_space' to a declaration is deprecated; apply it to the type instead}}
+  void *q __attribute__((address_space(AS)));
+  int r[2] __attribute__((address_space(AS)));
+}
+
+void invalidOperand() {
+  void *p [[clang::address_space(undeclared())]]; // expected-error {{use of undeclared identifier 'undeclared'}} \
+                                                 // expected-warning {{applying attribute 'clang::address_space' to a declaration is deprecated; apply it to the type instead}}
+}
+}

>From 9f4826a7f88d713435476757f78f4f7ff6a434b6 Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Tue, 18 Aug 2026 22:54:52 +0530
Subject: [PATCH 2/5] [Sema] Refactor fillDependentAddressSpaceTypeLoc to
 streamline attribute handling

---
 clang/lib/Sema/SemaType.cpp | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index da848d6431004..3613897a832ea 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6343,19 +6343,21 @@ namespace {
   };
 } // end anonymous namespace
 
-static void fillDependentAddressSpaceTypeLoc(ASTContext &Context,
-                                             DependentAddressSpaceTypeLoc DASTL,
-                                             const Declarator &D,
-                                             const DeclaratorChunk &Chunk) {
+static void
+fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
+                                 const Declarator &D,
+                                 const DeclaratorChunk &Chunk) {
   // An attribute written after the declarator-id appertains to the declared
-  // entity, so it is applied to the outermost type instead of to the chunk
-  // that is being visited.
-  const ParsedAttributesView *AttrLists[] = {&Chunk.getAttrs(),
-                                             &D.getAttributes()};
+  // entity and is applied to the outermost type rather than to a chunk, so
+  // every attribute list of the declarator has to be searched.
+  const ParsedAttributesView *AttrLists[] = {
+      &Chunk.getAttrs(), &D.getAttributes(), &D.getDeclSpec().getAttributes(),
+      &D.getDeclarationAttributes()};
   for (const ParsedAttributesView *Attrs : AttrLists) {
     for (const ParsedAttr &AL : *Attrs) {
-      if (AL.getKind() != ParsedAttr::AT_AddressSpace || AL.getNumArgs() != 1 ||
-          !AL.isArgExpr(0))
+      // Invalid or malformed attributes never produce a type.
+      if (AL.getKind() != ParsedAttr::AT_AddressSpace || AL.isInvalid() ||
+          AL.getNumArgs() != 1 || !AL.isArgExpr(0))
         continue;
       DASTL.setAttrNameLoc(AL.getLoc());
       DASTL.setAttrExprOperand(AL.getArgAsExpr(0));
@@ -6364,7 +6366,8 @@ static void fillDependentAddressSpaceTypeLoc(ASTContext &Context,
     }
   }
 
-  DASTL.initializeLocal(Context, DASTL.getTypePtr()->getAttributeLoc());
+  llvm_unreachable(
+      "no address_space attribute found at the expected location!");
 }
 
 /// Create and instantiate a TypeSourceInfo with type source information.
@@ -6430,7 +6433,7 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
 
       case TypeLoc::DependentAddressSpace: {
         auto TL = CurrTL.castAs<DependentAddressSpaceTypeLoc>();
-        fillDependentAddressSpaceTypeLoc(S.Context, TL, D, D.getTypeObject(i));
+        fillDependentAddressSpaceTypeLoc(TL, D, D.getTypeObject(i));
         CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
         break;
       }

>From 0e283748e0b6cf0886b7a925172013e605177159 Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Tue, 18 Aug 2026 23:56:35 +0530
Subject: [PATCH 3/5] [Sema] Refactor fillDependentAddressSpaceTypeLoc to
 accept attribute lists as an array reference

---
 clang/lib/Sema/SemaType.cpp | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3613897a832ea..368cb4b254290 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6343,21 +6343,16 @@ namespace {
   };
 } // end anonymous namespace
 
-static void
-fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
-                                 const Declarator &D,
-                                 const DeclaratorChunk &Chunk) {
-  // An attribute written after the declarator-id appertains to the declared
-  // entity and is applied to the outermost type rather than to a chunk, so
-  // every attribute list of the declarator has to be searched.
-  const ParsedAttributesView *AttrLists[] = {
-      &Chunk.getAttrs(), &D.getAttributes(), &D.getDeclSpec().getAttributes(),
-      &D.getDeclarationAttributes()};
+static void fillDependentAddressSpaceTypeLoc(
+    DependentAddressSpaceTypeLoc DASTL,
+    ArrayRef<const ParsedAttributesView *> AttrLists) {
   for (const ParsedAttributesView *Attrs : AttrLists) {
     for (const ParsedAttr &AL : *Attrs) {
-      // Invalid or malformed attributes never produce a type.
-      if (AL.getKind() != ParsedAttr::AT_AddressSpace || AL.isInvalid() ||
-          AL.getNumArgs() != 1 || !AL.isArgExpr(0))
+      if (AL.getKind() != ParsedAttr::AT_AddressSpace)
+        continue;
+      // Skip an attribute that did not produce a type: one diagnosed as
+      // invalid, or one whose argument is missing or is not an expression.
+      if (AL.isInvalid() || AL.getNumArgs() != 1 || !AL.isArgExpr(0))
         continue;
       DASTL.setAttrNameLoc(AL.getLoc());
       DASTL.setAttrExprOperand(AL.getArgAsExpr(0));
@@ -6433,7 +6428,14 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
 
       case TypeLoc::DependentAddressSpace: {
         auto TL = CurrTL.castAs<DependentAddressSpaceTypeLoc>();
-        fillDependentAddressSpaceTypeLoc(TL, D, D.getTypeObject(i));
+        // An attribute written after the declarator-id appertains to the
+        // declared entity and is applied to the outermost type rather than
+        // to a chunk, so every attribute list of the declarator has to be
+        // searched.
+        fillDependentAddressSpaceTypeLoc(TL, {&D.getTypeObject(i).getAttrs(),
+                                              &D.getAttributes(),
+                                              &D.getDeclSpec().getAttributes(),
+                                              &D.getDeclarationAttributes()});
         CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
         break;
       }

>From 2e89c1eced3cc84f61a9988eb8bc28751af91fae Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Wed, 19 Aug 2026 15:37:16 +0530
Subject: [PATCH 4/5] [Sema] Improve comments for address space attribute
 handling and add test for malformed attributes

---
 clang/lib/Sema/SemaType.cpp                         | 8 +++-----
 clang/test/SemaTemplate/address_space-dependent.cpp | 7 +++++++
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 368cb4b254290..65ce71bfdc67d 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6350,8 +6350,7 @@ static void fillDependentAddressSpaceTypeLoc(
     for (const ParsedAttr &AL : *Attrs) {
       if (AL.getKind() != ParsedAttr::AT_AddressSpace)
         continue;
-      // Skip an attribute that did not produce a type: one diagnosed as
-      // invalid, or one whose argument is missing or is not an expression.
+      // Skip invalid or malformed attributes; they did not produce a type.
       if (AL.isInvalid() || AL.getNumArgs() != 1 || !AL.isArgExpr(0))
         continue;
       DASTL.setAttrNameLoc(AL.getLoc());
@@ -6429,9 +6428,8 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
       case TypeLoc::DependentAddressSpace: {
         auto TL = CurrTL.castAs<DependentAddressSpaceTypeLoc>();
         // An attribute written after the declarator-id appertains to the
-        // declared entity and is applied to the outermost type rather than
-        // to a chunk, so every attribute list of the declarator has to be
-        // searched.
+        // declared entity, not to a chunk, so every attribute list of the
+        // declarator has to be searched.
         fillDependentAddressSpaceTypeLoc(TL, {&D.getTypeObject(i).getAttrs(),
                                               &D.getAttributes(),
                                               &D.getDeclSpec().getAttributes(),
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index 9c90c9831b7e3..f3f418cd16251 100644
--- a/clang/test/SemaTemplate/address_space-dependent.cpp
+++ b/clang/test/SemaTemplate/address_space-dependent.cpp
@@ -143,4 +143,11 @@ void invalidOperand() {
   void *p [[clang::address_space(undeclared())]]; // expected-error {{use of undeclared identifier 'undeclared'}} \
                                                  // expected-warning {{applying attribute 'clang::address_space' to a declaration is deprecated; apply it to the type instead}}
 }
+
+template <int AS>
+void invalidFirst() {
+  // The type location is filled from the second attribute; the first one is
+  // malformed and produced no type.
+  void *v __attribute__((address_space)) __attribute__((address_space(AS))); // expected-error {{'address_space' attribute takes one argument}}
+}
 }

>From 1a75159eeaaca5a0f9f9a5c7e8e61c2ed5e01ffd Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Wed, 19 Aug 2026 17:48:54 +0530
Subject: [PATCH 5/5] [clang][Sema] Update release notes for address_space
 attribute fixes and add test for dependent address space usage

---
 clang/docs/ReleaseNotes.md                          | 2 +-
 clang/test/SemaTemplate/address_space-dependent.cpp | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3647cfe20af91..d78f72cb2c0bf 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -443,7 +443,7 @@ features cannot lower the translation-unit ABI level;
 
 - Fixed a crash when an `address_space` attribute with a dependent argument was
   written after the declarator-id, where it appertains to the declared entity
-  rather than to a declarator chunk. (#GH196982)
+  rather than to a declarator chunk. (#GH196982, #GH111463)
 
 #### Bug Fixes to C++ Support
 
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index f3f418cd16251..f3655760be17d 100644
--- a/clang/test/SemaTemplate/address_space-dependent.cpp
+++ b/clang/test/SemaTemplate/address_space-dependent.cpp
@@ -151,3 +151,10 @@ void invalidFirst() {
   void *v __attribute__((address_space)) __attribute__((address_space(AS))); // expected-error {{'address_space' attribute takes one argument}}
 }
 }
+
+namespace gh111463 {
+template <int I>
+void func() {
+  int *y __attribute__((address_space(I)));
+}
+}



More information about the cfe-commits mailing list