[clang] [Clang] Drop `exclude_from_explicit_instantiation` on a non-template context (PR #183514)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 26 04:46:47 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Tomohiro Kashiwada (kikairoya)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/183514.diff
3 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6)
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+11)
- (added) clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.nontemplate.cpp (+68)
``````````diff
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 at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ EXCLUDE_ATTR static int var_excluded;
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ struct EXCLUDE_ATTR nested_excluded {
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ EXCLUDE_ATTR void fn_excluded();
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ EXCLUDE_ATTR static int var_excluded;
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ };
+ struct nested {
+ EXCLUDE_ATTR void fn_excluded();
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ EXCLUDE_ATTR static int var_excluded;
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ };
+ template <class T>
+ struct EXCLUDE_ATTR class_template_excluded {};
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ template <class T>
+ EXCLUDE_ATTR static T var_template_excluded;
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+ template <class T>
+ EXCLUDE_ATTR void fn_template_excluded();
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-template context}}
+};
+
+struct EXCLUDE_ATTR class_excluded {};
+// expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+EXCLUDE_ATTR int var_excluded;
+// expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+EXCLUDE_ATTR void fn_excluded();
+// expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+
+template <class T>
+struct EXCLUDE_ATTR class_template_excluded {};
+// expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+template <class T>
+EXCLUDE_ATTR T var_template_excluded;
+// expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+template <class T>
+EXCLUDE_ATTR void fn_template_excluded();
+// expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+
+void fn () {
+ EXCLUDE_ATTR static int var_excluded;
+ // expected-warning at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+}
+
+auto lambda = [](auto x) {
+ EXCLUDE_ATTR static int var_excluded;
+ // expected-warning at -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 at -1{{'exclude_from_explicit_instantiation' attribute ignored on a non-member declaration}}
+};
``````````
</details>
https://github.com/llvm/llvm-project/pull/183514
More information about the cfe-commits
mailing list