https://github.com/kikairoya created 
https://github.com/llvm/llvm-project/pull/183514

None

>From c1125edd9c3222a7bbe58b815f57f4a664cc420d Mon Sep 17 00:00:00 2001
From: kikairoya <[email protected]>
Date: Thu, 26 Feb 2026 21:43:59 +0900
Subject: [PATCH] [Clang] Drop `exclude_from_explicit_instantiation` on a
 non-template context

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  6 ++
 clang/lib/Sema/SemaDeclAttr.cpp               | 11 +++
 ...rom_explicit_instantiation.nontemplate.cpp | 68 +++++++++++++++++++
 3 files changed, 85 insertions(+)
 create mode 100644 
clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.nontemplate.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8a3b9de19ad32..b35c0694cf518 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3796,6 +3796,12 @@ def warn_attribute_ignored_on_non_definition :
 def warn_attribute_ignored_on_inline :
   Warning<"%0 attribute ignored on inline function">,
   InGroup<IgnoredAttributes>;
+def warn_attribute_ignored_on_non_member :
+  Warning<"%0 attribute ignored on a non-member declaration">,
+  InGroup<IgnoredAttributes>;
+def warn_attribute_ignored_on_non_template :
+  Warning<"%0 attribute ignored on a non-template context">,
+  InGroup<IgnoredAttributes>;
 def warn_nocf_check_attribute_ignored :
   Warning<"'nocf_check' attribute ignored; use -fcf-protection to enable the 
attribute">,
   InGroup<IgnoredAttributes>;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 3abc69d0e4b96..4c288170a6ed2 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -705,6 +705,17 @@ static void 
handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
         << AL << /*IsMember=*/!isa<CXXRecordDecl>(D);
     return;
   }
+  if (const auto *RD = 
dyn_cast_if_present<CXXRecordDecl>(D->getDeclContext()->getRedeclContext())) {
+    if (!isa<TemplateDecl>(RD) && !RD->isDependentType() &&
+        !isTemplateInstantiation(RD->getTemplateSpecializationKind())) {
+      S.Diag(AL.getLoc(), diag::warn_attribute_ignored_on_non_template) << AL;
+      return;
+    }
+  } else {
+    S.Diag(AL.getLoc(), diag::warn_attribute_ignored_on_non_member) << AL;
+    return;
+  }
+
   D->addAttr(::new (S.Context)
                  ExcludeFromExplicitInstantiationAttr(S.Context, AL));
 }
diff --git 
a/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.nontemplate.cpp 
b/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.nontemplate.cpp
new file mode 100644
index 0000000000000..0196869117ed8
--- /dev/null
+++ 
b/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.nontemplate.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test that exclude_from_explicit_instantiation is warned if attached
+// on a non-template context or on a non-member entity.
+
+#define EXCLUDE_ATTR __attribute__((exclude_from_explicit_instantiation))
+
+struct C {
+  EXCLUDE_ATTR void fn_excluded();
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+  EXCLUDE_ATTR static int var_excluded;
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+  struct EXCLUDE_ATTR nested_excluded {
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+    EXCLUDE_ATTR void fn_excluded();
+    // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+    EXCLUDE_ATTR static int var_excluded;
+    // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+  };
+  struct nested {
+    EXCLUDE_ATTR void fn_excluded();
+    // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+    EXCLUDE_ATTR static int var_excluded;
+    // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+  };
+  template <class T>
+  struct EXCLUDE_ATTR class_template_excluded {};
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+  template <class T>
+  EXCLUDE_ATTR static T var_template_excluded;
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+  template <class T>
+  EXCLUDE_ATTR void fn_template_excluded();
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-template context}}
+};
+
+struct EXCLUDE_ATTR class_excluded {};
+// expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+EXCLUDE_ATTR int var_excluded;
+// expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+EXCLUDE_ATTR void fn_excluded();
+// expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+
+template <class T>
+struct EXCLUDE_ATTR class_template_excluded {};
+// expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+template <class T>
+EXCLUDE_ATTR T var_template_excluded;
+// expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+template <class T>
+EXCLUDE_ATTR void fn_template_excluded();
+// expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+
+void fn () {
+  EXCLUDE_ATTR static int var_excluded;
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+}
+
+auto lambda = [](auto x) {
+  EXCLUDE_ATTR static int var_excluded;
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+};
+
+template <class T>
+void fn_template() {
+  EXCLUDE_ATTR static T var_excluded;
+  // expected-warning@-1{{'exclude_from_explicit_instantiation' attribute 
ignored on a non-member declaration}}
+};

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

Reply via email to