Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -5751,9 +5751,11 @@ if (!S.checkStringLiteralArgumentAttr(AL, 0, BT)) return; - // Don't duplicate annotations that are already set. - if (D->hasAttr()) { - S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL; + // Warn about duplicate attributes if they have different arguments, but drop + // any duplicate attributes regardless. + if (const auto *Other = D->getAttr()) { + if (Other->getSwiftType() != BT) + S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL; return; } Index: clang/test/SemaObjC/attr-swift_bridge.m =================================================================== --- clang/test/SemaObjC/attr-swift_bridge.m +++ clang/test/SemaObjC/attr-swift_bridge.m @@ -31,3 +31,8 @@ typedef NSArray *NSArrayAlias __attribute__((__swift_bridge__("ArrayAlias"))); struct __attribute__((__swift_bridge__("StructT"))) T {}; + +// Duplicate attributes with the same arguments are fine. +struct __attribute__((swift_bridge("foo"), swift_bridge("foo"))) S; +// Duplicate attributes with different arguments are not. +struct __attribute__((swift_bridge("foo"), swift_bridge("bar"))) S; // expected-warning {{attribute 'swift_bridge' is already applied with different arguments}}