Author: Susana Monteiro
Date: 2025-12-23T17:49:43Z
New Revision: 1ab98893f73f5389a9dae50e5634d1d4b6ea851a

URL: 
https://github.com/llvm/llvm-project/commit/1ab98893f73f5389a9dae50e5634d1d4b6ea851a
DIFF: 
https://github.com/llvm/llvm-project/commit/1ab98893f73f5389a9dae50e5634d1d4b6ea851a.diff

LOG: [APINotes] Avoid duplicate attributes when fields instantiate class 
templates (#173386)

If a C++ class template `A` is annotated via API Notes and another class
`B` has a field of type `A`, we would apply the attributes from the API
Notes twice. This happened during `ActOnFields`, so this change makes
sure we stop processing API Notes for class template instantiations in
this function.

rdar://166179307

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/APINotes/Inputs/Headers/Templates.apinotes
    clang/test/APINotes/Inputs/Headers/Templates.h
    clang/test/APINotes/templates.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5da665a5acad2..11323803e1910 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -20161,7 +20161,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, 
Decl *EnclosingDecl,
       CDecl->setIvarRBraceLoc(RBrac);
     }
   }
-  ProcessAPINotes(Record);
+  if (Record && !isa<ClassTemplateSpecializationDecl>(Record))
+    ProcessAPINotes(Record);
 }
 
 // Given an integral type, return the next larger integral type

diff  --git a/clang/test/APINotes/Inputs/Headers/Templates.apinotes 
b/clang/test/APINotes/Inputs/Headers/Templates.apinotes
index b7336484da0c7..ded688b5a9076 100644
--- a/clang/test/APINotes/Inputs/Headers/Templates.apinotes
+++ b/clang/test/APINotes/Inputs/Headers/Templates.apinotes
@@ -3,3 +3,5 @@ Name: Templates
 Tags:
 - Name: Box
   SwiftImportAs: owned
+- Name: MoveOnly
+  SwiftCopyable: false

diff  --git a/clang/test/APINotes/Inputs/Headers/Templates.h 
b/clang/test/APINotes/Inputs/Headers/Templates.h
index 2a86a46d4af27..836b6d69b1847 100644
--- a/clang/test/APINotes/Inputs/Headers/Templates.h
+++ b/clang/test/APINotes/Inputs/Headers/Templates.h
@@ -8,3 +8,18 @@ struct Box {
 
 using FloatBox = Box<float>;
 using IntBox = Box<int>;
+
+template <typename T>
+struct MoveOnly {
+  T value;
+};
+
+template <>
+struct MoveOnly<float> {
+  double value;
+};
+
+struct MoveOnlyBox {
+  MoveOnly<int> value1;
+  MoveOnly<float> value2;
+};

diff  --git a/clang/test/APINotes/templates.cpp 
b/clang/test/APINotes/templates.cpp
index 48109011e73a9..ef887196cabe7 100644
--- a/clang/test/APINotes/templates.cpp
+++ b/clang/test/APINotes/templates.cpp
@@ -1,6 +1,7 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/Tmpl -fdisable-module-hash 
-fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks 
%s -x c++
 // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/Tmpl -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter Box -x c++ | FileCheck -check-prefix=CHECK-BOX %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/Tmpl -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter MoveOnly -x c++ | FileCheck -check-prefix=CHECK-MOVEONLY %s
 
 #include "Templates.h"
 
@@ -10,3 +11,24 @@
 
 // Make sure the attributes aren't duplicated.
 // CHECK-BOX-NOT: SwiftAttrAttr {{.+}} <<invalid sloc>> "import_owned"
+
+// CHECK-MOVEONLY: Dumping MoveOnly:
+// CHECK-MOVEONLY-NEXT: ClassTemplateDecl {{.+}} imported in Templates MoveOnly
+// CHECK-MOVEONLY: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"
+
+// Make sure the attributes aren't duplicated.
+// CHECK-MOVEONLY-NOT: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"
+
+// CHECK-MOVEONLY: ClassTemplateSpecializationDecl {{.+}} imported in 
Templates {{.+}} MoveOnly
+// CHECK-MOVEONLY: TemplateArgument type 'int'
+// CHECK-MOVEONLY: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"
+
+// Make sure the attributes aren't duplicated.
+// CHECK-MOVEONLY-NOT: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"
+
+// CHECK-MOVEONLY: ClassTemplateSpecializationDecl {{.+}} imported in 
Templates {{.+}} MoveOnly
+// CHECK-MOVEONLY: TemplateArgument type 'float'
+// CHECK-MOVEONLY: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"
+
+// Make sure the attributes aren't duplicated.
+// CHECK-MOVEONLY-NOT: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to