Skip to content

Commit

Permalink
Revert "[clang] Fix missing diagnostic of declaration use when access…
Browse files Browse the repository at this point in the history
…ing TypeDecls through typename access"

This reverts commit dc17043.
Breaks building LLVM on mac when targeting macOS before 10.15, see
comments on https://reviews.llvm.org/D136533
  • Loading branch information
nico committed Oct 25, 2022
1 parent 9d5adc7 commit 60809cd
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 64 deletions.
3 changes: 0 additions & 3 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,6 @@ Bug Fixes
- Reject non-type template arguments formed by casting a non-zero integer
to a pointer in pre-C++17 modes, instead of treating them as null
pointers.
- Fix missing diagnostics for uses of declarations when performing typename access,
such as when performing member access on a '[[deprecated]]' type alias.
`Issue 58547 <https://github.com/llvm/llvm-project/issues/58547>`

Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 0 additions & 4 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2566,10 +2566,6 @@ class Sema final {

bool isSimpleTypeSpecifier(tok::TokenKind Kind) const;

enum class DiagCtorKind { None, Implicit, Typename };
QualType getTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
TypeDecl *TD, SourceLocation NameLoc);

ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec *SS = nullptr,
bool isClassName = false, bool HasTrailingDot = false,
Expand Down
47 changes: 18 additions & 29 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,26 +169,6 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
return false;
}

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,
Expand Down Expand Up @@ -352,11 +332,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;
Expand All @@ -380,9 +359,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);
Expand Down Expand Up @@ -556,10 +537,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)
Expand Down
18 changes: 12 additions & 6 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10963,14 +10963,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 == ETK_Typename ? DiagCtorKind::Typename : DiagCtorKind::None,
Type, IILoc);
auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(Ctx);
auto *FoundRD = dyn_cast<CXXRecordDecl>(Type);
if (Keyword == ETK_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:
Expand Down
14 changes: 0 additions & 14 deletions clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@

// Deprecated in C++17

// FIXME: Remove 'clang-16' from UNSUPPORTED by 2022-11-05 (bugfix D136533).
// UNSUPPORTED: c++03, c++11, c++14, clang-16
// UNSUPPORTED: c++03, c++11, c++14

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS

Expand All @@ -24,11 +23,7 @@
int main(int, char**)
{
std::allocator<int> a;
TEST_IGNORE_NODISCARD a.allocate(3, nullptr);
// expected-warning@-1 {{'allocate' is deprecated}}
#if defined(TEST_CLANG_VER) && TEST_CLANG_VER >= 1600
// expected-warning@*:* {{'pointer' is deprecated}}
// expected-warning@*:* {{'const_pointer' is deprecated}}
#endif
TEST_IGNORE_NODISCARD a.allocate(3, nullptr); // expected-warning {{'allocate' is deprecated}}

return 0;
}

0 comments on commit 60809cd

Please sign in to comment.