https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/88777
>From 5f19ff4e34c3e3153157cfb06ba1022e982b4f2d Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Fri, 12 Apr 2024 14:33:30 -0400 Subject: [PATCH 1/3] [Clang][Sema] Ignore 'exclude_from_explicit_instantiation' attribute for members of local classes --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7cd428de0bb32d..bf6501bfeb3f0c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -4124,7 +4124,8 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } - if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>() && + !Instantiation->isLocalClass()) continue; MemberSpecializationInfo *MSInfo = @@ -4169,7 +4170,8 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Var->isStaticDataMember()) { - if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>() && + !Instantiation->isLocalClass()) continue; MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); @@ -4203,7 +4205,8 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) { - if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>() && + !Instantiation->isLocalClass()) continue; // Always skip the injected-class-name, along with any >From 695e618cb5fb20bee4d24a440fb4fe1a7d428e78 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Mon, 15 Apr 2024 14:15:28 -0400 Subject: [PATCH 2/3] [FOLD] add warning + tests --- .../clang/Basic/DiagnosticSemaKinds.td | 3 + clang/lib/Sema/SemaDeclAttr.cpp | 18 ++++++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 9 +-- ...rom_explicit_instantiation.local-class.cpp | 64 +++++++++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.local-class.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 44f802c0c28e84..604699231645c3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3669,6 +3669,9 @@ def warn_attribute_dllexport_explicit_instantiation_decl : Warning< def warn_attribute_dllexport_explicit_instantiation_def : Warning< "'dllexport' attribute ignored on explicit instantiation definition">, InGroup<IgnoredAttributes>; +def warn_attribute_exclude_from_explicit_instantiation_local_class : Warning< + "%0 attribute ignored on local class%select{| member}1">, + InGroup<IgnoredAttributes>; def warn_invalid_initializer_from_system_header : Warning< "invalid constructor from class in system header, should not be explicit">, InGroup<DiagGroup<"invalid-initializer-from-system-header">>; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c3bf18a3f79e23..363ae93cb62df1 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -984,6 +984,21 @@ static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(EA); } +static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D, + const ParsedAttr &AL) { + const auto *PD = isa<CXXRecordDecl>(D) + ? cast<DeclContext>(D) + : D->getDeclContext()->getRedeclContext(); + if (const auto *RD = dyn_cast<CXXRecordDecl>(PD); RD && RD->isLocalClass()) { + S.Diag(AL.getLoc(), + diag::warn_attribute_exclude_from_explicit_instantiation_local_class) + << AL << /*IsMember=*/!isa<CXXRecordDecl>(D); + return; + } + D->addAttr(::new (S.Context) + ExcludeFromExplicitInstantiationAttr(S.Context, AL)); +} + namespace { /// Determines if a given Expr references any of the given function's /// ParmVarDecls, or the function's implicit `this` parameter (if applicable). @@ -9339,6 +9354,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_Error: handleErrorAttr(S, D, AL); break; + case ParsedAttr::AT_ExcludeFromExplicitInstantiation: + handleExcludeFromExplicitInstantiationAttr(S, D, AL); + break; case ParsedAttr::AT_DiagnoseIf: handleDiagnoseIfAttr(S, D, AL); break; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index bf6501bfeb3f0c..7cd428de0bb32d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -4124,8 +4124,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } - if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>() && - !Instantiation->isLocalClass()) + if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; MemberSpecializationInfo *MSInfo = @@ -4170,8 +4169,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Var->isStaticDataMember()) { - if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>() && - !Instantiation->isLocalClass()) + if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); @@ -4205,8 +4203,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) { - if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>() && - !Instantiation->isLocalClass()) + if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; // Always skip the injected-class-name, along with any diff --git a/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.local-class.cpp b/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.local-class.cpp new file mode 100644 index 00000000000000..f0b2cec095c97f --- /dev/null +++ b/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.local-class.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +// Test that the exclude_from_explicit_instantiation attribute is ignored +// for local classes and members thereof. + +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) // expected-note 0+{{expanded from macro}} + +namespace N0 { + + template<typename T> + void f() { + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION A { // expected-warning {{attribute ignored on local class}} + // expected-note@-1 2{{in instantiation of}} + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void g(T t) { // expected-warning {{attribute ignored on local class member}} + *t; // expected-error {{indirection requires pointer operand ('int' invalid)}} + } + + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION B { // expected-warning {{attribute ignored on local class}} + void h(T t) { + *t; // expected-error {{indirection requires pointer operand ('int' invalid)}} + } + }; + }; + } + + template void f<int>(); // expected-note 2{{in instantiation of}} + +} + +// This is a reduced example from libc++ which required that 'value' +// be prefixed with 'this->' because the definition of 'Local::operator A' +// was not instantiated when the definition of 'g' was. +namespace N1 { + + struct A { }; + + struct B { + operator A() { + return A(); + } + }; + + template<typename T> + auto f(T t) { + return A(t); + } + + template<typename T> + auto g(T t) { + struct Local { + T value; + + EXCLUDE_FROM_EXPLICIT_INSTANTIATION // expected-warning {{attribute ignored on local class member}} + operator A() { + return A(value); + } + }; + + return f(Local(t)); + } + + auto x = g(B()); + +} >From 2cb78154b7bcde44ecfc08b56fdb95198ff55109 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Wed, 17 Apr 2024 09:27:19 -0400 Subject: [PATCH 3/3] [FOLD] add release note --- clang/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 96ad92b540b47f..d2af0254b08594 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -287,6 +287,9 @@ Attribute Changes in Clang This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to apply to this class. +- Clang now warns that the ``exclude_from_explicit_instantiation`` attribute + is ignored when applied to a local class or a member thereof. + Improvements to Clang's diagnostics ----------------------------------- - Clang now applies syntax highlighting to the code snippets it _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits