PR c++/41774
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Nov 2009 13:39:46 +0000 (13:39 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Nov 2009 13:39:46 +0000 (13:39 +0000)
* c-pragma.c (visstack): Change into vector of ints rather than
enum symbol_visibility.
(push_visibility): Add kind argument, push default_visibility together
with kind.
(pop_visibility): Add kind argument, return true if successful, fail
if visibility stack is empty or if stack top is of different kind.
(handle_pragma_visibility): Don't check length of visstack, instead
call pop_visibility and issue diagnostics if it failed.  Pass 0
as last argument to push_visibility and pop_visibility.
* c-pragma.h (push_visibility): Add kind argument.
(pop_visibility): Likewise.  Return bool instead of void.

* name-lookup.c (handle_namespace_attrs): Pass 1 as last argument to
push_visibility.
* parser.c (cp_parser_namespace_definition): Pass 1 as argument to
pop_visibility.
* rtti.c (push_abi_namespace): Pass 2 as last argument to
push_visibility.
(pop_abi_namespace): Pass 2 as argument to pop_visibility.

* g++.dg/ext/visibility/namespace3.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153805 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-pragma.c
gcc/c-pragma.h
gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/rtti.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/visibility/namespace3.C [new file with mode: 0644]

index b4e1bff..721c69e 100644 (file)
@@ -1,3 +1,18 @@
+2009-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/41774
+       * c-pragma.c (visstack): Change into vector of ints rather than
+       enum symbol_visibility.
+       (push_visibility): Add kind argument, push default_visibility together
+       with kind.
+       (pop_visibility): Add kind argument, return true if successful, fail
+       if visibility stack is empty or if stack top is of different kind.
+       (handle_pragma_visibility): Don't check length of visstack, instead
+       call pop_visibility and issue diagnostics if it failed.  Pass 0
+       as last argument to push_visibility and pop_visibility.
+       * c-pragma.h (push_visibility): Add kind argument.
+       (pop_visibility): Likewise.  Return bool instead of void.
+
 2009-11-01  Eric Botcazou  <ebotcazou@adacore.com>
 
        * tree.def (TARGET_MEM_REF): Update comment.
index b707d16..f281644 100644 (file)
@@ -723,19 +723,20 @@ maybe_apply_renaming_pragma (tree decl, tree asmname)
 #ifdef HANDLE_PRAGMA_VISIBILITY
 static void handle_pragma_visibility (cpp_reader *);
 
-typedef enum symbol_visibility visibility;
-DEF_VEC_I (visibility);
-DEF_VEC_ALLOC_I (visibility, heap);
-static VEC (visibility, heap) *visstack;
+static VEC (int, heap) *visstack;
 
 /* Push the visibility indicated by STR onto the top of the #pragma
-   visibility stack.  */
+   visibility stack.  KIND is 0 for #pragma GCC visibility, 1 for
+   C++ namespace with visibility attribute and 2 for C++ builtin
+   ABI namespace.  push_visibility/pop_visibility calls must have
+   matching KIND, it is not allowed to push visibility using one
+   KIND and pop using a different one.  */
 
 void
-push_visibility (const char *str)
+push_visibility (const char *str, int kind)
 {
-  VEC_safe_push (visibility, heap, visstack,
-                default_visibility);
+  VEC_safe_push (int, heap, visstack,
+                ((int) default_visibility) | (kind << 8));
   if (!strcmp (str, "default"))
     default_visibility = VISIBILITY_DEFAULT;
   else if (!strcmp (str, "internal"))
@@ -749,14 +750,21 @@ push_visibility (const char *str)
   visibility_options.inpragma = 1;
 }
 
-/* Pop a level of the #pragma visibility stack.  */
+/* Pop a level of the #pragma visibility stack.  Return true if
+   successful.  */
 
-void
-pop_visibility (void)
+bool
+pop_visibility (int kind)
 {
-  default_visibility = VEC_pop (visibility, visstack);
+  if (!VEC_length (int, visstack))
+    return false;
+  if ((VEC_last (int, visstack) >> 8) != kind)
+    return false;
+  default_visibility
+    = (enum symbol_visibility) (VEC_pop (int, visstack) & 0xff);
   visibility_options.inpragma
-    = VEC_length (visibility, visstack) != 0;
+    = VEC_length (int, visstack) != 0;
+  return true;
 }
 
 /* Sets the default visibility for symbols to something other than that
@@ -785,10 +793,8 @@ handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
     {
       if (pop == action)
        {
-         if (!VEC_length (visibility, visstack))
+         if (! pop_visibility (0))
            GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
-         else
-           pop_visibility ();
        }
       else
        {
@@ -798,7 +804,7 @@ handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
          if (token != CPP_NAME)
            GCC_BAD ("malformed #pragma GCC visibility push");
          else
-           push_visibility (IDENTIFIER_POINTER (x));
+           push_visibility (IDENTIFIER_POINTER (x), 0);
          if (pragma_lex (&x) != CPP_CLOSE_PAREN)
            GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
        }
index be085ee..eab23db 100644 (file)
@@ -95,8 +95,8 @@ extern struct cpp_reader* parse_in;
    visibility is not supported on the host OS platform the
    statements are ignored.  */
 #define HANDLE_PRAGMA_VISIBILITY 1
-extern void push_visibility (const char *);
-extern void pop_visibility (void);
+extern void push_visibility (const char *, int);
+extern bool pop_visibility (int);
 
 extern void init_pragma (void);
 
index 2182bb1..044b568 100644 (file)
@@ -1,3 +1,14 @@
+2009-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/41774
+       * name-lookup.c (handle_namespace_attrs): Pass 1 as last argument to
+       push_visibility.
+       * parser.c (cp_parser_namespace_definition): Pass 1 as argument to
+       pop_visibility.
+       * rtti.c (push_abi_namespace): Pass 2 as last argument to
+       push_visibility.
+       (pop_abi_namespace): Pass 2 as argument to pop_visibility.
+
 2009-10-31  Jason Merrill  <jason@redhat.com>
 
        * tree.c (cv_unqualified): New fn.
index 8089427..25c8ac0 100644 (file)
@@ -3219,7 +3219,7 @@ handle_namespace_attrs (tree ns, tree attributes)
                     "%qD attribute is meaningless since members of the "
                     "anonymous namespace get local symbols", name);
 
-         push_visibility (TREE_STRING_POINTER (x));
+         push_visibility (TREE_STRING_POINTER (x), 1);
          saw_vis = true;
        }
       else
index 2a0cc37..b24d6b1 100644 (file)
@@ -12846,7 +12846,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
 #ifdef HANDLE_PRAGMA_VISIBILITY
   if (has_visibility)
-    pop_visibility ();
+    pop_visibility (1);
 #endif
 
   /* Finish the namespace.  */
index c7af74a..3fb6d11 100644 (file)
@@ -128,13 +128,13 @@ static void
 push_abi_namespace (void)
 {
   push_nested_namespace (abi_node);
-  push_visibility ("default");
+  push_visibility ("default", 2);
 }
 
 static void
 pop_abi_namespace (void)
 {
-  pop_visibility ();
+  pop_visibility (2);
   pop_nested_namespace (abi_node);
 }
 
index ec98de1..dd49956 100644 (file)
@@ -1,3 +1,8 @@
+2009-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/41774
+       * g++.dg/ext/visibility/namespace3.C: New test.
+
 2009-11-01  Jason Merrill  <jason@redhat.com>
 
        * gcc.dg/tree-ssa/restrict-1.c: Move to c-c++-common.
diff --git a/gcc/testsuite/g++.dg/ext/visibility/namespace3.C b/gcc/testsuite/g++.dg/ext/visibility/namespace3.C
new file mode 100644 (file)
index 0000000..a07abdc
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/41774
+// { dg-do compile }
+
+namespace std __attribute__ ((__visibility__ ("default"))) {
+#pragma GCC visibility pop     // { dg-warning "no matching push for" }
+}