]> granicus.if.org Git - clang/commitdiff
Complain about attempts to use 'protected' visibility on targets
authorJohn McCall <rjmccall@apple.com>
Sun, 29 Jan 2012 01:20:30 +0000 (01:20 +0000)
committerJohn McCall <rjmccall@apple.com>
Sun, 29 Jan 2012 01:20:30 +0000 (01:20 +0000)
like Darwin that don't support it.  We should also complain about
invalid -fvisibility=protected, but that information doesn't seem
to exist at the most appropriate time, so I've left a FIXME behind.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149186 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/TargetInfo.h
lib/Basic/Targets.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Sema/SemaDeclAttr.cpp
test/CodeGenCXX/thunks.cpp
test/Sema/attr-visibility.c [new file with mode: 0644]

index 948236edc6ac59b373b9f5e557ed65d0e71ff492..7888ce555cef48f675b0c8da894896afe545b0a1 100644 (file)
@@ -1740,6 +1740,9 @@ def warn_transparent_union_attribute_zero_fields : Warning<
 def warn_attribute_type_not_supported : Warning<
   "'%0' attribute argument not supported: %1">;
 def warn_attribute_unknown_visibility : Warning<"unknown visibility '%0'">;
+def warn_attribute_protected_visibility :
+  Warning<"target does not support 'protected' visibility; using 'default'">,
+  InGroup<DiagGroup<"unsupported-visibility">>;
 def err_unknown_machine_mode : Error<"unknown machine mode %0">;
 def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
 def err_mode_not_primitive : Error<
index b1e1cbdf66cf7b5682af85d0ba128c0e512a6a88..966797c4ff7382cf98d4174585bd1097bc5173dd 100644 (file)
@@ -479,6 +479,19 @@ public:
     const unsigned RegNum;
   };
 
+  /// hasProtectedVisibility - Does this target support "protected"
+  /// visibility?
+  ///
+  /// Any target which dynamic libraries will naturally support
+  /// something like "default" (meaning that the symbol is visible
+  /// outside this shared object) and "hidden" (meaning that it isn't)
+  /// visibilities, but "protected" is really an ELF-specific concept
+  /// with wierd semantics designed around the convenience of dynamic
+  /// linker implementations.  Which is not to suggest that there's
+  /// consistent target-independent semantics for "default" visibility
+  /// either; the entire thing is pretty badly mangled.
+  virtual bool hasProtectedVisibility() const { return true; }
+
   virtual bool useGlobalsForAutomaticVariables() const { return false; }
 
   /// getCFStringSection - Return the section to use for CFString
index 5cdb36f16b1f59d3635ec9d3b76023d61650350d..5dc63e79cf8e5013f51cdb66e979b703fc1142a8 100644 (file)
@@ -218,6 +218,12 @@ public:
     return "__TEXT,__StaticInit,regular,pure_instructions";
   }
 
+  /// Darwin does not support protected visibility.  Darwin's "default"
+  /// is very similar to ELF's "protected";  Darwin requires a "weak"
+  /// attribute on declarations that can be dynamically replaced.
+  virtual bool hasProtectedVisibility() const {
+    return false;
+  }
 };
 
 
index a189155e12dc3873b45c0f3fd85755fed53b7ee5..e9bb30325c5e8c236b64455675ab6c1f32cbb6dc 100644 (file)
@@ -1792,6 +1792,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   else if (Vis == "hidden")
     Opts.setVisibilityMode(HiddenVisibility);
   else if (Vis == "protected")
+    // FIXME: diagnose if target does not support protected visibility
     Opts.setVisibilityMode(ProtectedVisibility);
   else
     Diags.Report(diag::err_drv_invalid_value)
index aa827a40c62f0c4d2cd1fcae7f10554e30a6f818..d4b9988d88cdaa6ac03071abea5e2316afdd6226 100644 (file)
@@ -1694,9 +1694,16 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     type = VisibilityAttr::Hidden;
   else if (TypeStr == "internal")
     type = VisibilityAttr::Hidden; // FIXME
-  else if (TypeStr == "protected")
-    type = VisibilityAttr::Protected;
-  else {
+  else if (TypeStr == "protected") {
+    // Complain about attempts to use protected visibility on targets
+    // (like Darwin) that don't support it.
+    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
+      type = VisibilityAttr::Default;
+    } else {
+      type = VisibilityAttr::Protected;
+    }
+  } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
     return;
   }
index 7c80b96b794905f257567b6e480ed3de16619ced..04d0820da7a3100a75b5a8f7a4fb3b8e57a3dc0e 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=HIDDEN %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=HIDDEN %s
 
 namespace Test1 {
 
diff --git a/test/Sema/attr-visibility.c b/test/Sema/attr-visibility.c
new file mode 100644 (file)
index 0000000..5cf2695
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
+
+void test0() __attribute__((visibility("default")));
+void test1() __attribute__((visibility("hidden")));
+void test2() __attribute__((visibility("internal")));
+
+// rdar://problem/10753392
+void test3() __attribute__((visibility("protected"))); // expected-warning {{target does not support 'protected' visibility; using 'default'}}
+