~ubuntu-branches/debian/sid/gcc-4.8/sid

« back to all changes in this revision

Viewing changes to .svn/pristine/ba/baf8b94d91249e033f573abda7428fca3bf142a2.svn-base

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-12-19 19:48:34 UTC
  • Revision ID: package-import@ubuntu.com-20141219194834-4dz1q7rrn5pad823
Tags: 4.8.4-1
* GCC 4.8.4 release.
  - Fix PR target/61407 (darwin), PR middle-end/58624 (ice),
    PR sanitizer/64265 (wrong code).
* Require recent binutils to pass go test failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# DP: Backport fix for the generated hash functions of types that are
 
2
# DP: aliases for structures containing unexported fields.
 
3
 
 
4
--- a/src/gcc/go/gofrontend/types.cc
 
5
+++ b/src/gcc/go/gofrontend/types.cc
 
6
@@ -1834,7 +1834,9 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name,
 
7
                                               bloc);
 
8
   gogo->start_block(bloc);
 
9
 
 
10
-  if (this->struct_type() != NULL)
 
11
+  if (name != NULL && name->real_type()->named_type() != NULL)
 
12
+    this->write_named_hash(gogo, name, hash_fntype, equal_fntype);
 
13
+  else if (this->struct_type() != NULL)
 
14
     this->struct_type()->write_hash_function(gogo, name, hash_fntype,
 
15
                                             equal_fntype);
 
16
   else if (this->array_type() != NULL)
 
17
@@ -1852,7 +1854,9 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name,
 
18
                                                false, bloc);
 
19
   gogo->start_block(bloc);
 
20
 
 
21
-  if (this->struct_type() != NULL)
 
22
+  if (name != NULL && name->real_type()->named_type() != NULL)
 
23
+    this->write_named_equal(gogo, name);
 
24
+  else if (this->struct_type() != NULL)
 
25
     this->struct_type()->write_equal_function(gogo, name);
 
26
   else if (this->array_type() != NULL)
 
27
     this->array_type()->write_equal_function(gogo, name);
 
28
@@ -1865,6 +1869,100 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name,
 
29
   gogo->finish_function(bloc);
 
30
 }
 
31
 
 
32
+// Write a hash function that simply calls the hash function for a
 
33
+// named type.  This is used when one named type is defined as
 
34
+// another.  This ensures that this case works when the other named
 
35
+// type is defined in another package and relies on calling hash
 
36
+// functions defined only in that package.
 
37
+
 
38
+void
 
39
+Type::write_named_hash(Gogo* gogo, Named_type* name,
 
40
+                      Function_type* hash_fntype, Function_type* equal_fntype)
 
41
+{
 
42
+  Location bloc = Linemap::predeclared_location();
 
43
+
 
44
+  Named_type* base_type = name->real_type()->named_type();
 
45
+  go_assert(base_type != NULL);
 
46
+
 
47
+  // The pointer to the type we are going to hash.  This is an
 
48
+  // unsafe.Pointer.
 
49
+  Named_object* key_arg = gogo->lookup("key", NULL);
 
50
+  go_assert(key_arg != NULL);
 
51
+
 
52
+  // The size of the type we are going to hash.
 
53
+  Named_object* keysz_arg = gogo->lookup("key_size", NULL);
 
54
+  go_assert(keysz_arg != NULL);
 
55
+
 
56
+  Named_object* hash_fn;
 
57
+  Named_object* equal_fn;
 
58
+  name->real_type()->type_functions(gogo, base_type, hash_fntype, equal_fntype,
 
59
+                                   &hash_fn, &equal_fn);
 
60
+
 
61
+  // Call the hash function for the base type.
 
62
+  Expression* key_ref = Expression::make_var_reference(key_arg, bloc);
 
63
+  Expression* keysz_ref = Expression::make_var_reference(keysz_arg, bloc);
 
64
+  Expression_list* args = new Expression_list();
 
65
+  args->push_back(key_ref);
 
66
+  args->push_back(keysz_ref);
 
67
+  Expression* func = Expression::make_func_reference(hash_fn, NULL, bloc);
 
68
+  Expression* call = Expression::make_call(func, args, false, bloc);
 
69
+
 
70
+  // Return the hash of the base type.
 
71
+  Expression_list* vals = new Expression_list();
 
72
+  vals->push_back(call);
 
73
+  Statement* s = Statement::make_return_statement(vals, bloc);
 
74
+  gogo->add_statement(s);
 
75
+}
 
76
+
 
77
+// Write an equality function that simply calls the equality function
 
78
+// for a named type.  This is used when one named type is defined as
 
79
+// another.  This ensures that this case works when the other named
 
80
+// type is defined in another package and relies on calling equality
 
81
+// functions defined only in that package.
 
82
+
 
83
+void
 
84
+Type::write_named_equal(Gogo* gogo, Named_type* name)
 
85
+{
 
86
+  Location bloc = Linemap::predeclared_location();
 
87
+
 
88
+  // The pointers to the types we are going to compare.  These have
 
89
+  // type unsafe.Pointer.
 
90
+  Named_object* key1_arg = gogo->lookup("key1", NULL);
 
91
+  Named_object* key2_arg = gogo->lookup("key2", NULL);
 
92
+  go_assert(key1_arg != NULL && key2_arg != NULL);
 
93
+
 
94
+  Named_type* base_type = name->real_type()->named_type();
 
95
+  go_assert(base_type != NULL);
 
96
+
 
97
+  // Build temporaries with the base type.
 
98
+  Type* pt = Type::make_pointer_type(base_type);
 
99
+
 
100
+  Expression* ref = Expression::make_var_reference(key1_arg, bloc);
 
101
+  ref = Expression::make_cast(pt, ref, bloc);
 
102
+  Temporary_statement* p1 = Statement::make_temporary(pt, ref, bloc);
 
103
+  gogo->add_statement(p1);
 
104
+
 
105
+  ref = Expression::make_var_reference(key2_arg, bloc);
 
106
+  ref = Expression::make_cast(pt, ref, bloc);
 
107
+  Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc);
 
108
+  gogo->add_statement(p2);
 
109
+
 
110
+  // Compare the values for equality.
 
111
+  Expression* t1 = Expression::make_temporary_reference(p1, bloc);
 
112
+  t1 = Expression::make_unary(OPERATOR_MULT, t1, bloc);
 
113
+
 
114
+  Expression* t2 = Expression::make_temporary_reference(p2, bloc);
 
115
+  t2 = Expression::make_unary(OPERATOR_MULT, t2, bloc);
 
116
+
 
117
+  Expression* cond = Expression::make_binary(OPERATOR_EQEQ, t1, t2, bloc);
 
118
+
 
119
+  // Return the equality comparison.
 
120
+  Expression_list* vals = new Expression_list();
 
121
+  vals->push_back(cond);
 
122
+  Statement* s = Statement::make_return_statement(vals, bloc);
 
123
+  gogo->add_statement(s);
 
124
+}
 
125
+
 
126
 // Return a composite literal for the type descriptor for a plain type
 
127
 // of kind RUNTIME_TYPE_KIND named NAME.
 
128
 
 
129
--- a/src/gcc/go/gofrontend/types.h
 
130
+++ b/src/gcc/go/gofrontend/types.h
 
131
@@ -1138,6 +1138,13 @@ class Type
 
132
                          Function_type* equal_fntype, Named_object** hash_fn,
 
133
                          Named_object** equal_fn);
 
134
 
 
135
+  void
 
136
+  write_named_hash(Gogo*, Named_type*, Function_type* hash_fntype,
 
137
+                  Function_type* equal_fntype);
 
138
+
 
139
+  void
 
140
+  write_named_equal(Gogo*, Named_type*);
 
141
+
 
142
   // Build a composite literal for the uncommon type information.
 
143
   Expression*
 
144
   uncommon_type_constructor(Gogo*, Type* uncommon_type,