From 05f4e7181a1e8ed519b8dd580502f9e71ee9ea5a Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 15 Aug 2012 18:42:26 +0000 Subject: [PATCH] Patch to warn about __private_extern__ on tentative definitions as it does something unexpected (but gcc compatible). Suggest use of __attribute__((visibility("hidden"))) on declaration instead. // rdar://7703982 llvm-svn: 161972 --- clang/include/clang/Basic/DiagnosticGroups.td | 4 +++- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++ clang/lib/Sema/SemaDecl.cpp | 4 ++++ clang/test/Sema/tentative-decls.c | 5 +++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index b95a90bd21c3..ead596cc05fd 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -155,6 +155,7 @@ def MethodAccess : DiagGroup<"objc-method-access">; def ObjCReceiver : DiagGroup<"receiver-expr">; def OverlengthStrings : DiagGroup<"overlength-strings">; def OverloadedVirtual : DiagGroup<"overloaded-virtual">; +def PrivateExtern : DiagGroup<"private-extern">; def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">; def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; @@ -371,7 +372,8 @@ def Most : DiagGroup<"most", [ Unused, VolatileRegisterVar, ObjCMissingSuperCalls, - OverloadedVirtual + OverloadedVirtual, + PrivateExtern ]>; // Thread Safety warnings diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0fbe40f4f829..cd73dca05f8d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1489,6 +1489,11 @@ def note_non_literal_user_provided_dtor : Note< "%0 is not literal because it has a user-provided destructor">; def note_non_literal_nontrivial_dtor : Note< "%0 is not literal because it has a non-trivial destructor">; +def warn_private_extern : Warning< + "Use of __private_extern__ on tentative definition has unexpected" + " behaviour - use __attribute__((visibility(\"hidden\"))) on extern" + " declaration or definition instead">, + InGroup, DefaultIgnore; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6526d01e08b8..d37fbf537861 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6754,6 +6754,10 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, diag::err_abstract_type_in_decl, AbstractVariableType)) Var->setInvalidDecl(); + if (!Type->isDependentType() && !Var->isInvalidDecl() && + Var->getStorageClass() == SC_PrivateExtern) + Diag(Var->getLocation(), diag::warn_private_extern); + return; case VarDecl::TentativeDefinition: diff --git a/clang/test/Sema/tentative-decls.c b/clang/test/Sema/tentative-decls.c index b15537bfa0cd..e14540ba8417 100644 --- a/clang/test/Sema/tentative-decls.c +++ b/clang/test/Sema/tentative-decls.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify +// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -verify // PR3310 struct a x1; // expected-note 2{{forward declaration of 'struct a'}} @@ -32,7 +32,8 @@ int i2 = 3; // expected-error{{non-static declaration of 'i2' follows static dec static int i3 = 5; extern int i3; -__private_extern__ int pExtern; +// rdar://7703982 +__private_extern__ int pExtern; // expected-warning {{Use of __private_extern__ on tentative definition has unexpected behaviour}} int pExtern = 0; int i4;