Don't crash if a map index is used outside of a function.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 24 Feb 2011 03:01:22 +0000 (03:01 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 24 Feb 2011 03:01:22 +0000 (03:01 +0000)
From-SVN: r170453

gcc/go/gofrontend/expressions.cc

index e9a26a0da0d832c9b2b8809ccdb6aa1f7fc3ddd2..2e31e8064785f30fd1e7605bf46a6c95ff55af78 100644 (file)
@@ -9888,12 +9888,39 @@ Map_index_expression::get_value_pointer(Translate_context* context,
 
   // We need to pass in a pointer to the key, so stuff it into a
   // variable.
-  tree tmp = create_tmp_var(TREE_TYPE(index_tree), get_name(index_tree));
-  DECL_IGNORED_P(tmp) = 0;
-  DECL_INITIAL(tmp) = index_tree;
-  tree make_tmp = build1(DECL_EXPR, void_type_node, tmp);
-  tree tmpref = fold_convert(const_ptr_type_node, build_fold_addr_expr(tmp));
-  TREE_ADDRESSABLE(tmp) = 1;
+  tree tmp;
+  tree make_tmp;
+  if (current_function_decl != NULL)
+    {
+      tmp = create_tmp_var(TREE_TYPE(index_tree), get_name(index_tree));
+      DECL_IGNORED_P(tmp) = 0;
+      DECL_INITIAL(tmp) = index_tree;
+      make_tmp = build1(DECL_EXPR, void_type_node, tmp);
+      TREE_ADDRESSABLE(tmp) = 1;
+    }
+  else
+    {
+      tmp = build_decl(this->location(), VAR_DECL, create_tmp_var_name("M"),
+                      TREE_TYPE(index_tree));
+      DECL_EXTERNAL(tmp) = 0;
+      TREE_PUBLIC(tmp) = 0;
+      TREE_STATIC(tmp) = 1;
+      DECL_ARTIFICIAL(tmp) = 1;
+      if (!TREE_CONSTANT(index_tree))
+       make_tmp = fold_build2_loc(this->location(), INIT_EXPR, void_type_node,
+                                  tmp, index_tree);
+      else
+       {
+         TREE_READONLY(tmp) = 1;
+         TREE_CONSTANT(tmp) = 1;
+         DECL_INITIAL(tmp) = index_tree;
+         make_tmp = NULL_TREE;
+       }
+      rest_of_decl_compilation(tmp, 1, 0);
+    }
+  tree tmpref = fold_convert_loc(this->location(), const_ptr_type_node,
+                                build_fold_addr_expr_loc(this->location(),
+                                                         tmp));
 
   static tree map_index_fndecl;
   tree call = Gogo::call_builtin(&map_index_fndecl,
@@ -9920,9 +9947,10 @@ Map_index_expression::get_value_pointer(Translate_context* context,
     return error_mark_node;
   tree ptr_val_type_tree = build_pointer_type(val_type_tree);
 
-  return build2(COMPOUND_EXPR, ptr_val_type_tree,
-               make_tmp,
-               fold_convert(ptr_val_type_tree, call));
+  tree ret = fold_convert_loc(this->location(), ptr_val_type_tree, call);
+  if (make_tmp != NULL_TREE)
+    ret = build2(COMPOUND_EXPR, ptr_val_type_tree, make_tmp, ret);
+  return ret;
 }
 
 // Make a map index expression.