[clang] 28fa1fc - Revert "[clang] Fix missing diagnostic of declaration use when accessing TypeDecls through typename access (#129681)"
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 10 06:02:49 PDT 2025
Author: Hans Wennborg
Date: 2025-03-10T14:02:04+01:00
New Revision: 28fa1fcf55b973e13018ac115fcbb357b4c0baad
URL: https://github.com/llvm/llvm-project/commit/28fa1fcf55b973e13018ac115fcbb357b4c0baad
DIFF: https://github.com/llvm/llvm-project/commit/28fa1fcf55b973e13018ac115fcbb357b4c0baad.diff
LOG: Revert "[clang] Fix missing diagnostic of declaration use when accessing TypeDecls through typename access (#129681)"
This caused incorrect -Wunguarded-availability warnings. See comment on
the pull request.
> We were missing a call to DiagnoseUseOfDecl when performing typename
> access.
>
> This refactors the code so that TypeDecl lookups funnel through a helper
> which performs all the necessary checks, removing some related
> duplication on the way.
>
> Fixes #58547
>
> Differential Revision: https://reviews.llvm.org/D136533
This reverts commit 4c4fd6b03149348cf11af245ad2603d24144a9d5.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f8cb7ed34f041..7b254b371e5fa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -35,9 +35,6 @@ Potentially Breaking Changes
============================
- The Objective-C ARC migrator (ARCMigrate) has been removed.
-- Fix missing diagnostics for uses of declarations when performing typename access,
- such as when performing member access on a '[[deprecated]]' type alias.
- (#GH58547)
C/C++ Language Potentially Breaking Changes
-------------------------------------------
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fecc870945ac5..159c908a1b26c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3168,13 +3168,6 @@ class Sema final : public SemaBase {
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
- enum class DiagCtorKind { None, Implicit, Typename };
- /// Returns the TypeDeclType for the given type declaration,
- /// as ASTContext::getTypeDeclType would, but
- /// performs the required semantic checks for name lookup of said entity.
- QualType getTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
- TypeDecl *TD, SourceLocation NameLoc);
-
/// If the identifier refers to a type name within this scope,
/// return the declaration of that type.
///
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5ae3e58e4088d..9d102abb17c19 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -139,26 +139,6 @@ class TypeNameValidatorCCC final : public CorrectionCandidateCallback {
} // end anonymous namespace
-QualType Sema::getTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
- TypeDecl *TD, SourceLocation NameLoc) {
- auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(LookupCtx);
- auto *FoundRD = dyn_cast<CXXRecordDecl>(TD);
- if (DCK != DiagCtorKind::None && LookupRD && FoundRD &&
- FoundRD->isInjectedClassName() &&
- declaresSameEntity(LookupRD, cast<Decl>(FoundRD->getParent()))) {
- Diag(NameLoc,
- DCK == DiagCtorKind::Typename
- ? diag::ext_out_of_line_qualified_id_type_names_constructor
- : diag::err_out_of_line_qualified_id_type_names_constructor)
- << TD->getIdentifier() << /*Type=*/1
- << 0 /*if any keyword was present, it was 'typename'*/;
- }
-
- DiagnoseUseOfDecl(TD, NameLoc);
- MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
- return Context.getTypeDeclType(TD);
-}
-
namespace {
enum class UnqualifiedTypeNameLookupResult {
NotFound,
@@ -315,11 +295,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
bool IsClassTemplateDeductionContext,
ImplicitTypenameContext AllowImplicitTypename,
IdentifierInfo **CorrectedII) {
- bool IsImplicitTypename = !isClassName && !IsCtorOrDtorName;
// FIXME: Consider allowing this outside C++1z mode as an extension.
bool AllowDeducedTemplate = IsClassTemplateDeductionContext &&
- getLangOpts().CPlusPlus17 && IsImplicitTypename &&
- !HasTrailingDot;
+ getLangOpts().CPlusPlus17 && !IsCtorOrDtorName &&
+ !isClassName && !HasTrailingDot;
// Determine where we will perform name lookup.
DeclContext *LookupCtx = nullptr;
@@ -343,9 +322,11 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
// refer to a member of an unknown specialization.
// In C++2a, in several contexts a 'typename' is not required. Also
// allow this as an extension.
+ if (AllowImplicitTypename == ImplicitTypenameContext::No &&
+ !isClassName && !IsCtorOrDtorName)
+ return nullptr;
+ bool IsImplicitTypename = !isClassName && !IsCtorOrDtorName;
if (IsImplicitTypename) {
- if (AllowImplicitTypename == ImplicitTypenameContext::No)
- return nullptr;
SourceLocation QualifiedLoc = SS->getRange().getBegin();
if (getLangOpts().CPlusPlus20)
Diag(QualifiedLoc, diag::warn_cxx17_compat_implicit_typename);
@@ -534,10 +515,18 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
// C++ [class.qual]p2: A lookup that would find the injected-class-name
// instead names the constructors of the class, except when naming a class.
// This is ill-formed when we're not actually forming a ctor or dtor name.
- T = getTypeDeclType(LookupCtx,
- IsImplicitTypename ? DiagCtorKind::Implicit
- : DiagCtorKind::None,
- TD, NameLoc);
+ auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(LookupCtx);
+ auto *FoundRD = dyn_cast<CXXRecordDecl>(TD);
+ if (!isClassName && !IsCtorOrDtorName && LookupRD && FoundRD &&
+ FoundRD->isInjectedClassName() &&
+ declaresSameEntity(LookupRD, cast<Decl>(FoundRD->getParent())))
+ Diag(NameLoc, diag::err_out_of_line_qualified_id_type_names_constructor)
+ << &II << /*Type*/1;
+
+ DiagnoseUseOfDecl(IIDecl, NameLoc);
+
+ T = Context.getTypeDeclType(TD);
+ MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
} else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
(void)DiagnoseUseOfDecl(IDecl, NameLoc);
if (!HasTrailingDot)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 96f3ceb9ef8f5..dfd7a55ce63be 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10918,15 +10918,20 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
//
// FIXME: That's not strictly true: mem-initializer-id lookup does not
// ignore functions, but that appears to be an oversight.
- QualType T = getTypeDeclType(Ctx,
- Keyword == ElaboratedTypeKeyword::Typename
- ? DiagCtorKind::Typename
- : DiagCtorKind::None,
- Type, IILoc);
+ auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(Ctx);
+ auto *FoundRD = dyn_cast<CXXRecordDecl>(Type);
+ if (Keyword == ElaboratedTypeKeyword::Typename && LookupRD && FoundRD &&
+ FoundRD->isInjectedClassName() &&
+ declaresSameEntity(LookupRD, cast<Decl>(FoundRD->getParent())))
+ Diag(IILoc, diag::ext_out_of_line_qualified_id_type_names_constructor)
+ << &II << 1 << 0 /*'typename' keyword used*/;
+
// We found a type. Build an ElaboratedType, since the
// typename-specifier was just sugar.
- return Context.getElaboratedType(
- Keyword, QualifierLoc.getNestedNameSpecifier(), T);
+ MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
+ return Context.getElaboratedType(Keyword,
+ QualifierLoc.getNestedNameSpecifier(),
+ Context.getTypeDeclType(Type));
}
// C++ [dcl.type.simple]p2:
diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
index 26738583da506..58c7c0cfac8bf 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -58,17 +58,3 @@ template <typename T>
FunS2 f;// No warning, entire function is deprecated, so usage here should be fine.
}
-
-namespace GH58547 {
-struct A {
- using ta [[deprecated]] = int; // expected-note 2{{marked deprecated here}}
-};
-
-using t1 = typename A::ta; // expected-warning {{'ta' is deprecated}}
-
-template <class B1> struct B {
- using tb = typename B1::ta; // expected-warning {{'ta' is deprecated}}
-};
-
-template struct B<A>; // expected-note {{requested here}}
-} // namespace GH58547
More information about the cfe-commits
mailing list