re PR c/13134 (Visibility attribute is ignored)
authorMatt Austern <austern@apple.com>
Wed, 10 Dec 2003 06:34:46 +0000 (06:34 +0000)
committerMatt Austern <austern@gcc.gnu.org>
Wed, 10 Dec 2003 06:34:46 +0000 (06:34 +0000)
PR c/13134
* c--decl.c (duplicate_decls): Copy visibility flag when appropriate.
* cp/decl.c (duplicate_decls): Copy visibility flag when appropriate.
* testsuite/lib/gcc-dg.exp (dg-require-visibility): Define.
* testsuite/lib/target-supports (check_visibility_available): Define.
* testsuite/gcc.dg/visibility-1.c: New test.
* testsuite/gcc.dg/visibility-2.c: Likewise.
* testsuite/gcc.dg/visibility-3.c: Likewise.
* testsuite/gcc.dg/visibility-4.c: Likewise.
* testsuite/gcc.dg/visibility-5.c: Likewise.
* testsuite/gcc.dg/visibility-6.c: Likewise.
* testsuite/g++.dg/ext/visibility-1.C: Likewise.
* testsuite/g++.dg/ext/visibility-2.C: Likewise.
* testsuite/g++.dg/ext/visibility-3.C: Likewise.
* testsuite/g++.dg/ext/visibility-4.C: Likewise.
* testsuite/g++.dg/ext/visibility-5.C: Likewise.
* testsuite/g++.dg/ext/visibility-6.C: Likewise.

From-SVN: r74487

21 files changed:
gcc/ChangeLog
gcc/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/visibility-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility-5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility-6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility-7.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/visibility-7.c [new file with mode: 0644]
gcc/testsuite/lib/gcc-dg.exp
gcc/testsuite/lib/target-supports.exp

index c54a4fe..f1b73f6 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-09  Matt Austern  <austern@apple.com>
+
+       PR c/13134
+       * c-decl.c (duplicate_decls): Copy visibility flag when appropriate.
+       
 2003-12-09  Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
 
        * config/m32r/m32r.h: Add support for m32r2 processor.  Including
index 16cf655..8fc1f19 100644 (file)
@@ -1335,6 +1335,19 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level,
         Currently, it can only be defined in the prototype.  */
       COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
 
+      /* If either declaration has a nondefault visibility, use it. */
+      if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT)
+       {
+         if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT
+             && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
+           {
+             warning ("%J'%D': visibility attribute ignored because it",
+                      newdecl, newdecl);
+             warning ("%Jconflicts with previous declaration here", olddecl);
+           }
+         DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+       }
+
       if (TREE_CODE (newdecl) == FUNCTION_DECL)
        {
          DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
index 7f23f0f..b9a0638 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-08  Matt Austern  <austern@apple.com>
+
+       PR c/13134
+       * decl.c (duplicate_decls): Copy visibility flag when appropriate.
+       
 2003-12-09  Giovanni Bajo  <giovannibajo@gcc.gnu.org>\r
 \r
        * init.c (build_new_1): Deal with an OVERLOAD set when\r
index 9c6379f..f205f74 100644 (file)
@@ -1854,9 +1854,21 @@ duplicate_decls (tree newdecl, tree olddecl)
   TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl);
   TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl);
   DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
-  DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
   COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
 
+  /* If either declaration has a nondefault visibility, use it. */
+  if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT)
+    {
+      if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT
+         && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
+       {
+         warning ("%J'%D': visibility attribute ignored because it",
+                  newdecl, newdecl);
+         warning ("%Jconflicts with previous declaration here", olddecl);
+       }
+      DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+    }
+
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       int function_size;
index 09784c0..78e4a7d 100644 (file)
@@ -1,3 +1,21 @@
+2003-12-08  Matt Austern  <austern@apple.com>
+
+       PR c/13134
+       * lib/gcc-dg.exp (dg-require-visibility): Define.
+       * lib/target-supports (check_visibility_available): Define.
+       * gcc.dg/visibility-1.c: New test.
+       * gcc.dg/visibility-2.c: Likewise.
+       * gcc.dg/visibility-3.c: Likewise.
+       * gcc.dg/visibility-4.c: Likewise.
+       * gcc.dg/visibility-5.c: Likewise.
+       * gcc.dg/visibility-6.c: Likewise.
+       * g++.dg/ext/visibility-1.C: Likewise.
+       * g++.dg/ext/visibility-2.C: Likewise.
+       * g++.dg/ext/visibility-3.C: Likewise.
+       * g++.dg/ext/visibility-4.C: Likewise.
+       * g++.dg/ext/visibility-5.C: Likewise.
+       * g++.dg/ext/visibility-6.C: Likewise.
+       
 2003-12-07  Giovanni Bajo  <giovannibajo@gcc.gnu.org>\r
 \r
        * g++.dg/lookup/java1.C: New test.\r
diff --git a/gcc/testsuite/g++.dg/ext/visibility-1.C b/gcc/testsuite/g++.dg/ext/visibility-1.C
new file mode 100644 (file)
index 0000000..d579eb2
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test visibility attribute on function definition. */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*_Z3foov" } } */
+
+void
+__attribute__((visibility ("hidden")))
+foo()
+{ }
diff --git a/gcc/testsuite/g++.dg/ext/visibility-2.C b/gcc/testsuite/g++.dg/ext/visibility-2.C
new file mode 100644 (file)
index 0000000..89e853c
--- /dev/null
@@ -0,0 +1,7 @@
+/* Test that visibility attribute on declaration extends to definition. */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*_Z3foov" } } */
+
+void __attribute__((visibility ("hidden"))) foo();
+
+void foo() { }
diff --git a/gcc/testsuite/g++.dg/ext/visibility-3.C b/gcc/testsuite/g++.dg/ext/visibility-3.C
new file mode 100644 (file)
index 0000000..d0cc891
--- /dev/null
@@ -0,0 +1,7 @@
+/* Test visibility attribute on forward declaration of global variable */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+int
+__attribute__((visibility ("hidden")))
+xyzzy = 5;
diff --git a/gcc/testsuite/g++.dg/ext/visibility-4.C b/gcc/testsuite/g++.dg/ext/visibility-4.C
new file mode 100644 (file)
index 0000000..d217bc9
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test visibility attribute on forward declaration of global variable */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+extern int __attribute__ ((visibility ("hidden")))
+xyzzy;
+
+int xyzzy = 5;
diff --git a/gcc/testsuite/g++.dg/ext/visibility-5.C b/gcc/testsuite/g++.dg/ext/visibility-5.C
new file mode 100644 (file)
index 0000000..9cdc802
--- /dev/null
@@ -0,0 +1,11 @@
+/* Test visibility attribute on definition of a function that has
+   already had a forward declaration. */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*_Z3foov" } } */
+
+void foo();
+
+void 
+ __attribute__((visibility ("hidden")))
+foo() 
+{ }
diff --git a/gcc/testsuite/g++.dg/ext/visibility-6.C b/gcc/testsuite/g++.dg/ext/visibility-6.C
new file mode 100644 (file)
index 0000000..6e8f0ce
--- /dev/null
@@ -0,0 +1,10 @@
+/* Test visibility attribute on definition of global variable that has
+   already had a forward declaration. */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+extern int xyzzy;
+
+int 
+__attribute__((visibility ("hidden")))
+xyzzy = 5;
diff --git a/gcc/testsuite/g++.dg/ext/visibility-7.C b/gcc/testsuite/g++.dg/ext/visibility-7.C
new file mode 100644 (file)
index 0000000..40acb72
--- /dev/null
@@ -0,0 +1,11 @@
+/* Test warning from conflicting visibility specifications. */
+/* { dg-do compile { target *86-*-linux* } } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+extern int 
+__attribute__((visibility ("hidden")))
+xyzzy; /* { dg-warning "previous declaration here" "" } */
+
+int 
+__attribute__((visibility ("protected")))
+xyzzy = 5; /* { dg-warning "visibility attribute ignored" "" } */
diff --git a/gcc/testsuite/gcc.dg/visibility-1.c b/gcc/testsuite/gcc.dg/visibility-1.c
new file mode 100644 (file)
index 0000000..f76c3ca
--- /dev/null
@@ -0,0 +1,9 @@
+/* Test visibility attribute on function definition. */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*foo" } } */
+
+void
+__attribute__((visibility ("hidden")))
+foo()
+{ }
diff --git a/gcc/testsuite/gcc.dg/visibility-2.c b/gcc/testsuite/gcc.dg/visibility-2.c
new file mode 100644 (file)
index 0000000..e62dbbb
--- /dev/null
@@ -0,0 +1,10 @@
+/* Test that visibility attribute on declaration extends to definition. */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*foo" } } */
+
+void 
+__attribute__((visibility ("hidden")))
+foo();
+
+void foo() { }
diff --git a/gcc/testsuite/gcc.dg/visibility-3.c b/gcc/testsuite/gcc.dg/visibility-3.c
new file mode 100644 (file)
index 0000000..e0bf01f
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test visibility attribute on forward declaration of global variable */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+int
+__attribute__((visibility ("hidden")))
+xyzzy = 5;
diff --git a/gcc/testsuite/gcc.dg/visibility-4.c b/gcc/testsuite/gcc.dg/visibility-4.c
new file mode 100644 (file)
index 0000000..1a0b3ca
--- /dev/null
@@ -0,0 +1,10 @@
+/* Test visibility attribute on forward declaration of global variable */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+extern int 
+__attribute__((visibility ("hidden")))
+xyzzy;
+
+int xyzzy = 5;
diff --git a/gcc/testsuite/gcc.dg/visibility-5.c b/gcc/testsuite/gcc.dg/visibility-5.c
new file mode 100644 (file)
index 0000000..b1f46d2
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test visibility attribute on definition of a function that has
+   already had a forward declaration. */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*foo" } } */
+
+void foo();
+
+void
+ __attribute__((visibility ("hidden")))
+foo()
+{ }
diff --git a/gcc/testsuite/gcc.dg/visibility-6.c b/gcc/testsuite/gcc.dg/visibility-6.c
new file mode 100644 (file)
index 0000000..632f2ac
--- /dev/null
@@ -0,0 +1,11 @@
+/* Test visibility attribute on definition of global variable that has
+   already had a forward declaration. */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+extern int xyzzy;
+
+int 
+__attribute__((visibility ("hidden"))) 
+xyzzy = 5;
diff --git a/gcc/testsuite/gcc.dg/visibility-7.c b/gcc/testsuite/gcc.dg/visibility-7.c
new file mode 100644 (file)
index 0000000..e98b432
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test warning from conflicting visibility specifications. */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+
+extern int 
+__attribute__((visibility ("hidden")))
+xyzzy; /* { dg-warning "previous declaration here" "" } */
+
+int 
+__attribute__((visibility ("protected")))
+xyzzy = 5; /* { dg-warning "visibility attribute ignored" "" } */
index ee1d4d8..7fd52a9 100644 (file)
@@ -267,6 +267,23 @@ proc dg-require-weak { args } {
     }
 }
 
+# If this target does not support the "visibility" attribute, skip this
+# test.
+
+proc dg-require-visibility { args } {
+    upvar dg-do-what dg-do-what
+    upvar name name
+
+    set visibility_available [ check_visibility_available ]
+    if { $visibility_available == -1 } {
+       unresolved "$name"
+    }
+    if { $visibility_available != 1 } {
+       set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+       return
+    }
+}
+
 # If this target does not support the "alias" attribute, skip this
 # test.
 
index 38d416c..e9a57a1 100644 (file)
@@ -63,6 +63,30 @@ proc check_weak_available { } {
 }
 
 ###############################
+# proc check_visibility_available { }
+###############################
+
+# The visibility attribute is only support in some object formats
+# This proc returns 1 if it is supported, 0 if not, -1 if unsure.
+
+proc check_visibility_available { } {
+    global target_triplet
+    global target_cpu
+
+    # ELF supports it if the system has recent GNU ld and gas.
+    # As a start we return 1 for all ELF systems; we'll let people
+    # add exceptions as necessary.
+
+    set objformat [gcc_target_object_format]
+
+    switch $objformat {
+        elf      { return 1 }
+        unknown  { return -1 }
+        default  { return 0 }
+    }
+}
+
+###############################
 # proc check_alias_available { }
 ###############################