The current 4.5, 4.6 and 4.7 branches are now seriously broken for all PA target due to the fix applied for PR middle-end/52640, an optimization fix. This is because the PA backend defers output of function descriptors and externals (hpux) using TARGET_ASM_FILE_END. As a result, assemble_external can be called after after varasm.c processes it's list of pending externals and the vector used for this list deleted.
The attached change fixes this problem. The change has been tested on hppa-unknown-linux-gnu and hppa2.0w-hp-hpux11.11 with no observed regressions. I believe it to be the simplest way to fix these release branches although it may not be optimal (externals are doublely delayed on PA hpux). Ok for the 4.5, 4.6 and 4.7 branches? The fix for PR middle-end/52640 was not applied to the trunk. Dave -- J. David Anglin dave.ang...@nrc-cnrc.gc.ca National Research Council of Canada (613) 990-0752 (FAX: 952-6602) 2012-04-09 John David Anglin <dave.ang...@nrc-cnrc.gc.ca> PR middle-end/52894 * varasm.c (process_pending_assemble_externals): Set pending_assemble_externals_processed true. (assemble_external): Call assemble_external_real if the pending assemble externals have been processed. Index: varasm.c =================================================================== --- varasm.c (revision 186213) +++ varasm.c (working copy) @@ -2108,6 +2108,11 @@ the entire pending_assemble_externals list. See assemble_external(). */ static struct pointer_set_t *pending_assemble_externals_set; +/* Some targets delay some output to final using TARGET_ASM_FILE_END. + As a result, assemble_external can be called after the list of externals + is processed and the pointer set destroyed. */ +static bool pending_assemble_externals_processed; + #ifdef ASM_OUTPUT_EXTERNAL /* True if DECL is a function decl for which no out-of-line copy exists. It is assumed that DECL's assembler name has been set. */ @@ -2160,6 +2165,7 @@ assemble_external_real (TREE_VALUE (list)); pending_assemble_externals = 0; + pending_assemble_externals_processed = true; pointer_set_destroy (pending_assemble_externals_set); #endif } @@ -2201,6 +2207,12 @@ weak_decls = tree_cons (NULL, decl, weak_decls); #ifdef ASM_OUTPUT_EXTERNAL + if (pending_assemble_externals_processed) + { + assemble_external_real (decl); + return; + } + if (! pointer_set_insert (pending_assemble_externals_set, decl)) pending_assemble_externals = tree_cons (NULL, decl, pending_assemble_externals);