aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.dg
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-06-15 19:44:36 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-06-15 20:11:04 +0200
commit636b01ab4910da0b96d844301fea1a2b56c5344d (patch)
tree480d97c9a670995fe519be3a7f8b86c5e97e50cb /gcc/testsuite/gdc.dg
parent49d14a841fd9a798fe6d68ae49c6fbb753d21032 (diff)
downloadgcc-636b01ab4910da0b96d844301fea1a2b56c5344d.zip
gcc-636b01ab4910da0b96d844301fea1a2b56c5344d.tar.gz
gcc-636b01ab4910da0b96d844301fea1a2b56c5344d.tar.bz2
d: Add `@visibility' and `@hidden' attributes.
The `@visibility' attribute is functionality the same as `__attribute__((visibility))', and `@hidden' is a convenience alias to `@visibility("hidden")' defined in the `gcc.attributes' module. As the visibility of a symbol is also indirectly controlled by the `export' keyword, the handling of this in the code generation pass has been improved so that conflicts will be appropriately diagnosed. gcc/d/ChangeLog: * d-attribs.cc (d_langhook_attribute_table): Add visibility. (insert_type_attribute): Use decl_attributes instead of merge_attributes. (insert_decl_attribute): Likewise. (apply_user_attributes): Do nothing when no UDAs applied. (d_handle_visibility_attribute): New function. * d-gimplify.cc (d_gimplify_binary_expr): Adjust. * d-tree.h (set_visibility_for_decl): Declare. * decl.cc (get_symbol_decl): Move setting of visibility flags to... (set_visibility_for_decl): ... here. New function. * types.cc (TypeVisitor::visit (TypeStruct *)): Call set_visibility_for_decl(). (TypeVisitor::visit (TypeClass *)): Likewise. gcc/testsuite/ChangeLog: * gdc.dg/attr_visibility1.d: New test. * gdc.dg/attr_visibility2.d: New test. * gdc.dg/attr_visibility3.d: New test. libphobos/ChangeLog: * libdruntime/gcc/attributes.d (visibility): Define. (hidden): Define.
Diffstat (limited to 'gcc/testsuite/gdc.dg')
-rw-r--r--gcc/testsuite/gdc.dg/attr_visibility1.d25
-rw-r--r--gcc/testsuite/gdc.dg/attr_visibility2.d26
-rw-r--r--gcc/testsuite/gdc.dg/attr_visibility3.d29
3 files changed, 80 insertions, 0 deletions
diff --git a/gcc/testsuite/gdc.dg/attr_visibility1.d b/gcc/testsuite/gdc.dg/attr_visibility1.d
new file mode 100644
index 0000000..a7ed406
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/attr_visibility1.d
@@ -0,0 +1,25 @@
+// { dg-do compile }
+// { dg-require-visibility "" }
+
+import gcc.attributes;
+
+void nested()
+{
+ @attribute("visibility", "default")
+ struct nested_struct { } // { dg-warning ".visibility. attribute ignored" }
+
+ @attribute("visibility", "default")
+ void nested_func() { } // { dg-warning ".visibility. attribute ignored" }
+}
+
+@attribute("visibility", 123)
+int not_a_string(); // { dg-error "visibility argument not a string" }
+
+@attribute("visibility", "invalid argument")
+int invalid_argument(); // { dg-error ".visibility. argument must be one of" }
+
+@attribute("visibility", "default")
+int redeclared_visibility();
+
+@attribute("visibility", "internal")
+int redeclared_visibility(); // { dg-error "redeclared with different visibility" }
diff --git a/gcc/testsuite/gdc.dg/attr_visibility2.d b/gcc/testsuite/gdc.dg/attr_visibility2.d
new file mode 100644
index 0000000..a339882
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/attr_visibility2.d
@@ -0,0 +1,26 @@
+// { dg-do compile }
+// { dg-require-visibility "" }
+
+module attr_visibility2;
+
+import gcc.attributes;
+
+// { dg-final { scan-hidden "_D16attr_visibility25func1FZv" } }
+
+@hidden void func1() { }
+
+// { dg-final { scan-hidden "_D16attr_visibility25func2FZv" } }
+
+@hidden void func2();
+
+void func2() { }
+
+// { dg-final { scan-hidden "_D16attr_visibility25func3FZv" } }
+
+void func3();
+
+@hidden void func3() { }
+
+// { dg-final { scan-hidden "_D16attr_visibility210globalvar1i" } }
+
+@hidden __gshared int globalvar1 = 5;
diff --git a/gcc/testsuite/gdc.dg/attr_visibility3.d b/gcc/testsuite/gdc.dg/attr_visibility3.d
new file mode 100644
index 0000000..3298428
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/attr_visibility3.d
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-require-visibility "" }
+// { dg-require-dll "" }
+
+import gcc.attributes;
+
+@visibility("hidden")
+export void func1(); // { dg-error ".func1. was declared .export." }
+
+@visibility("hidden")
+export void func2() { } // { dg-error ".func2. was declared .export." }
+
+@visibility("default")
+export void func3();
+
+@visibility("default")
+export void func4() { };
+
+@visibility("hidden")
+export struct type1 { } // { dg-error ".type1. was declared .export." }
+
+@visibility("default")
+export struct type2 { }
+
+@visibility("hidden")
+export class type3 { } // { dg-error ".type3. was declared .export." }
+
+@visibility("default")
+export class type4 { }