diff options
author | Marc Espie <espie@cvs.openbsd.org> | 1999-06-20 16:02:07 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 1999-06-20 16:02:07 +0000 |
commit | 4afe9ad9930b7ccaffe9016029cdc4a06c4cf09c (patch) | |
tree | 907832cf342b708bde5ee1dccdb6e96cf4d468d7 | |
parent | 98b4c1c3edb281110081f22d9fef01547a00f2d6 (diff) |
Fix for kdelibs ICE, to appear in the next egcs-snapshot
(by Mark Mitchell)
-rw-r--r-- | gnu/egcs/gcc/cp/decl.c | 68 |
1 files changed, 58 insertions, 10 deletions
diff --git a/gnu/egcs/gcc/cp/decl.c b/gnu/egcs/gcc/cp/decl.c index 9df5474c1e4..291c5df52b3 100644 --- a/gnu/egcs/gcc/cp/decl.c +++ b/gnu/egcs/gcc/cp/decl.c @@ -8504,6 +8504,8 @@ expand_static_init (decl, init) { tree cleanup, fcall; static tree Atexit = 0; + int saved_flag_access_control; + if (Atexit == 0) { tree atexit_fndecl, PFV, pfvlist; @@ -8530,13 +8532,31 @@ expand_static_init (decl, init) so that any access checks will be done relative to the current scope, rather than the scope of the anonymous function. */ - fcall = build_cleanup (decl); + build_cleanup (decl); + + /* Now start the function. */ cleanup = start_anon_func (); + + /* Now, recompute the cleanup. It may contain SAVE_EXPRs + that refer to the original function, rather than the + anonymous one. That will make the back-end think that + nested functions are in use, which causes confusion. */ + saved_flag_access_control = flag_access_control; + flag_access_control = 0; + fcall = build_cleanup (decl); + flag_access_control = saved_flag_access_control; + + /* Finish off the function. */ expand_expr_stmt (fcall); end_anon_func (); + + /* Call atexit with the cleanup function. */ mark_addressable (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); - fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE)); + fcall = build_function_call (Atexit, + expr_tree_cons (NULL_TREE, + cleanup, + NULL_TREE)); expand_expr_stmt (fcall); } @@ -8558,7 +8578,7 @@ expand_static_init (decl, init) /* Make TYPE a complete type based on INITIAL_VALUE. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ + 2 if there was no information (in which case assume 0 if DO_DEFAULT). */ int complete_array_type (type, initial_value, do_default) @@ -8567,7 +8587,10 @@ complete_array_type (type, initial_value, do_default) { register tree maxindex = NULL_TREE; int value = 0; - + + /* Allocate on the same obstack as TYPE. */ + push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); + if (initial_value) { /* Note MAXINDEX is really the maximum index, @@ -8615,23 +8638,28 @@ complete_array_type (type, initial_value, do_default) if (maxindex) { tree itype; + tree domain; + + domain = build_index_type (maxindex); + TYPE_DOMAIN (type) = domain; - TYPE_DOMAIN (type) = build_index_type (maxindex); if (! TREE_TYPE (maxindex)) - TREE_TYPE (maxindex) = TYPE_DOMAIN (type); + TREE_TYPE (maxindex) = domain; if (initial_value) itype = TREE_TYPE (initial_value); else itype = NULL; if (itype && !TYPE_DOMAIN (itype)) - TYPE_DOMAIN (itype) = TYPE_DOMAIN (type); + TYPE_DOMAIN (itype) = domain; /* The type of the main variant should never be used for arrays of different sizes. It should only ever be completed with the size of the array. */ if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type))) - TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = TYPE_DOMAIN (type); + TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain; } + pop_obstacks(); + /* Lay out the type now that we can get the real answer. */ layout_type (type); @@ -8710,6 +8738,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, { tree cname, decl; int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; + int has_default_arg = 0; tree t; if (ctype) @@ -8826,7 +8855,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { - add_defarg_fn (decl); + has_default_arg = 1; break; } @@ -8847,6 +8876,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, return NULL_TREE; } + /* A friend declaration of the form friend void f<>(). Record the information in the TEMPLATE_ID_EXPR. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); @@ -8854,9 +8884,26 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, = perm_tree_cons (TREE_OPERAND (orig_declarator, 0), TREE_OPERAND (orig_declarator, 1), NULL_TREE); + + if (has_default_arg) + { + cp_error ("default arguments are not allowed in declaration of friend template specialization `%D'", + decl); + return NULL_TREE; + } + + if (inlinep) + { + cp_error ("`inline' is not allowed in declaration of friend template specialization `%D'", + decl); + return NULL_TREE; + } } } + if (has_default_arg) + add_defarg_fn (decl); + /* Plain overloading: will not be grok'd by grokclassfn. */ if (! ctype && ! processing_template_decl && DECL_LANGUAGE (decl) != lang_c @@ -10300,7 +10347,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) continue; /* VC++ spells a zero-sized array with []. */ - if (size == NULL_TREE && decl_context == FIELD && ! staticp) + if (size == NULL_TREE && decl_context == FIELD && ! staticp + && ! RIDBIT_SETP (RID_TYPEDEF, specbits)) size = integer_zero_node; if (size) |