[clang] [Clang] Fix isWeakImported() to traverse redeclaration chain for avai… (PR #181482)

via cfe-commits cfe-commits at lists.llvm.org
Tue May 5 19:19:22 PDT 2026


https://github.com/kevinlzh1108 updated https://github.com/llvm/llvm-project/pull/181482

>From fd80ae5b1ebf58cabb537aef121f39adc070428d Mon Sep 17 00:00:00 2001
From: kevinlzh1108 <kevinlzh1108 at gmail.com>
Date: Mon, 20 Apr 2026 15:15:26 +0800
Subject: [PATCH] [Clang] Fix mergeInheritableAttributes() to propagate all
 AvailabilityAttrs

getAttr<AvailabilityAttr>() only returns the first matching attribute,
but a declaration can carry multiple AvailabilityAttrs (one per
platform, e.g. macOS + iOS).  Use specific_attrs<AvailabilityAttr>()
to iterate over all of them so every platform's availability is
propagated during cross-module redeclaration merging.

This aligns the PCM merge path with how mergeDeclAttributes already
iterates via specific_attrs<InheritableAttr>() on the Sema side.

Extend clang/test/Modules/decl-attr-merge.mm with a multi-platform
case and an iOS triple RUN line that triggers the bug without the fix.

Fixes #181298.
---
 clang/lib/Serialization/ASTReaderDecl.cpp | 11 +++++----
 clang/test/Modules/decl-attr-merge.mm     | 28 +++++++++++++++++++----
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 9033ea55bc5e2..7209fdcca3a4e 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3620,11 +3620,12 @@ void mergeInheritableAttributes(ASTReader &Reader, Decl *D, Decl *Previous) {
     D->addAttr(NewAttr);
   }
 
-  const auto *AA = Previous->getAttr<AvailabilityAttr>();
-  if (AA && !D->hasAttr<AvailabilityAttr>()) {
-    NewAttr = AA->clone(Context);
-    NewAttr->setInherited(true);
-    D->addAttr(NewAttr);
+  if (!D->hasAttr<AvailabilityAttr>()) {
+    for (const auto *AA : Previous->specific_attrs<AvailabilityAttr>()) {
+      NewAttr = AA->clone(Context);
+      NewAttr->setInherited(true);
+      D->addAttr(NewAttr);
+    }
   }
 }
 } // namespace
diff --git a/clang/test/Modules/decl-attr-merge.mm b/clang/test/Modules/decl-attr-merge.mm
index 57f3f93df480e..53abdea220052 100644
--- a/clang/test/Modules/decl-attr-merge.mm
+++ b/clang/test/Modules/decl-attr-merge.mm
@@ -1,13 +1,21 @@
 // RUN: rm -rf %t.dir
 // RUN: split-file %s %t.dir
+// macOS: single-platform availability worked even before the fix.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
-// RUN:   -fmodules-cache-path=%t.dir/cache -triple x86_64-apple-macosx10.11.0 \
-// RUN:   -I%t.dir/headers %t.dir/main.m -emit-llvm -o %t.dir/main.ll
-// RUN: cat %t.dir/main.ll | FileCheck %s
+// RUN:   -fmodules-cache-path=%t.dir/mcache -triple x86_64-apple-macosx10.11.0 \
+// RUN:   -I%t.dir/headers %t.dir/main-macos.m -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MACOS
+// iOS: the @interface carries two AvailabilityAttrs (macOS + iOS).
+// Without the fix, mergeInheritableAttributes used getAttr<AvailabilityAttr>()
+// which only copied the first (macOS); the iOS attr was lost on the @class
+// redeclaration, causing isWeakImported() to return false (strong linkage).
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
+// RUN:   -fmodules-cache-path=%t.dir/icache -triple arm64-apple-ios12.0 \
+// RUN:   -I%t.dir/headers %t.dir/main-ios.m -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-IOS
 
 //--- headers/a.h
 
 __attribute__((availability(macos,introduced=10.16)))
+__attribute__((availability(ios,introduced=14.0)))
 @interface INIntent
 - (instancetype)self;
 @end
@@ -26,7 +34,7 @@ - (instancetype)self;
   header "b.h"
 }
 
-//--- main.m
+//--- main-macos.m
 
 #import <a.h>
 #import <b.h> // NOTE: Non attributed decl imported after one with attrs.
@@ -38,4 +46,14 @@ int main() {
     F([INIntent self]);
 }
 
-// CHECK: @"OBJC_CLASS_$_INIntent" = extern_weak
+// CHECK-MACOS: @"OBJC_CLASS_$_INIntent" = extern_weak
+
+//--- main-ios.m
+
+#import <a.h>
+#import <b.h>
+
+ at implementation INIntent (Testing)
+ at end
+
+// CHECK-IOS: @"OBJC_CLASS_$_INIntent" = extern_weak



More information about the cfe-commits mailing list