diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-11-02 14:39:46 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-11-02 14:39:46 +0100 |
commit | 9789ba46f6c647ed2f893c8785585338b30c9847 (patch) | |
tree | f1e838ec9a46d86a7ba26afebc76472b3823676e /gcc/c-pragma.c | |
parent | 3f252b91b1e4fd540f0e9e40a4ead814a011ec6e (diff) | |
download | gcc-9789ba46f6c647ed2f893c8785585338b30c9847.zip gcc-9789ba46f6c647ed2f893c8785585338b30c9847.tar.gz gcc-9789ba46f6c647ed2f893c8785585338b30c9847.tar.bz2 |
re PR c++/41774 (ice: vector VEC(visibility,base) pop domain error, in pop_visibility at c-pragma.c:757)
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.
* 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.
From-SVN: r153805
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r-- | gcc/c-pragma.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index b707d16..f281644 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -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"); } |