I discovered pushdecl_top_level was not setting the decl's context,
and we ended up with namespace-scope decls with NULL context.  That
broke modules.  Then I discovered a couple of places where we set the
context to a FUNCTION_DECL, which is also wrong.  AFAICT the literals
in question belong in global scope, as they're comdatable entities.
But create_temporary would use current_scope for the context before we
pushed it into namespace scope.

This patch asserts the context is NULL and then sets it to the frobbed
global_namespace.

        gcc/cp/
        * name-lookup.c (pushdecl_top_level): Assert incoming context is
        null, add global_namespace context.
        (pushdecl_top_level_and_finish): Likewise.
        * pt.c (get_template_parm_object): Clear decl context before
        pushing.
        * semantics.c (finish_compound_literal): Likewise.

pushing to trunk

nathan

--
Nathan Sidwell
diff --git i/gcc/cp/name-lookup.c w/gcc/cp/name-lookup.c
index 8cd6fe38271..6204444f3a6 100644
--- i/gcc/cp/name-lookup.c
+++ w/gcc/cp/name-lookup.c
@@ -7404,6 +7404,8 @@ pushdecl_top_level (tree x)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   do_push_to_top_level ();
+  gcc_checking_assert (!DECL_CONTEXT (x));
+  DECL_CONTEXT (x) = FROB_CONTEXT (global_namespace);
   x = pushdecl_namespace_level (x);
   do_pop_from_top_level ();
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
@@ -7418,6 +7420,8 @@ pushdecl_top_level_and_finish (tree x, tree init)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   do_push_to_top_level ();
+  gcc_checking_assert (!DECL_CONTEXT (x));
+  DECL_CONTEXT (x) = FROB_CONTEXT (global_namespace);
   x = pushdecl_namespace_level (x);
   cp_finish_decl (x, init, false, NULL_TREE, 0);
   do_pop_from_top_level ();
diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
index 869477f2c2e..45b18f6a5ad 100644
--- i/gcc/cp/pt.c
+++ w/gcc/cp/pt.c
@@ -7094,12 +7094,12 @@ get_template_parm_object (tree expr, tsubst_flags_t complain)
 
   tree type = cp_build_qualified_type (TREE_TYPE (expr), TYPE_QUAL_CONST);
   decl = create_temporary_var (type);
+  DECL_CONTEXT (decl) = NULL_TREE;
   TREE_STATIC (decl) = true;
   DECL_DECLARED_CONSTEXPR_P (decl) = true;
   TREE_READONLY (decl) = true;
   DECL_NAME (decl) = name;
   SET_DECL_ASSEMBLER_NAME (decl, name);
-  DECL_CONTEXT (decl) = global_namespace;
   comdat_linkage (decl);
 
   if (!zero_init_p (type))
diff --git i/gcc/cp/semantics.c w/gcc/cp/semantics.c
index b0930442bda..1e42cd799c2 100644
--- i/gcc/cp/semantics.c
+++ w/gcc/cp/semantics.c
@@ -3030,6 +3030,7 @@ finish_compound_literal (tree type, tree compound_literal,
       && initializer_constant_valid_p (compound_literal, type))
     {
       tree decl = create_temporary_var (type);
+      DECL_CONTEXT (decl) = NULL_TREE;
       DECL_INITIAL (decl) = compound_literal;
       TREE_STATIC (decl) = 1;
       if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))

Reply via email to