@@ -6500,6 +6500,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
65006500 if (!New)
65016501 return nullptr;
65026502
6503+ warnOnCTypeHiddenInCPlusPlus(New);
6504+
65036505 // If this has an identifier and is not a function template specialization,
65046506 // add it to the scope stack.
65056507 if (New->getDeclName() && AddToScope)
@@ -15213,6 +15215,32 @@ void Sema::CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D) {
1521315215 }
1521415216}
1521515217
15218+ void Sema::warnOnCTypeHiddenInCPlusPlus(const NamedDecl *D) {
15219+ // This only matters in C.
15220+ if (getLangOpts().CPlusPlus)
15221+ return;
15222+
15223+ // This only matters if the declaration has a type.
15224+ const auto *VD = dyn_cast<ValueDecl>(D);
15225+ if (!VD)
15226+ return;
15227+
15228+ // Get the type, this only matters for tag types.
15229+ QualType QT = VD->getType();
15230+ const auto *TD = QT->getAsTagDecl();
15231+ if (!TD)
15232+ return;
15233+
15234+ // Check if the tag declaration is lexically declared somewhere different
15235+ // from the lexical declaration of the given object, then it will be hidden
15236+ // in C++ and we should warn on it.
15237+ if (!TD->getLexicalParent()->LexicallyEncloses(D->getLexicalDeclContext())) {
15238+ unsigned Kind = TD->isEnum() ? 2 : TD->isUnion() ? 1 : 0;
15239+ Diag(D->getLocation(), diag::warn_decl_hidden_in_cpp) << Kind;
15240+ Diag(TD->getLocation(), diag::note_declared_at);
15241+ }
15242+ }
15243+
1521615244static void CheckExplicitObjectParameter(Sema &S, ParmVarDecl *P,
1521715245 SourceLocation ExplicitThisLoc) {
1521815246 if (!ExplicitThisLoc.isValid())
@@ -15334,6 +15362,8 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D,
1533415362 New->setScopeInfo(S->getFunctionPrototypeDepth() - 1,
1533515363 S->getNextFunctionPrototypeIndex());
1533615364
15365+ warnOnCTypeHiddenInCPlusPlus(New);
15366+
1533715367 // Add the parameter declaration into this scope.
1533815368 S->AddDecl(New);
1533915369 if (II)
@@ -18864,6 +18894,9 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
1886418894 if (InvalidDecl)
1886518895 NewFD->setInvalidDecl();
1886618896
18897+ if (!InvalidDecl)
18898+ warnOnCTypeHiddenInCPlusPlus(NewFD);
18899+
1886718900 if (PrevDecl && !isa<TagDecl>(PrevDecl) &&
1886818901 !PrevDecl->isPlaceholderVar(getLangOpts())) {
1886918902 Diag(Loc, diag::err_duplicate_member) << II;
0 commit comments