Branch data Line data Source code
1 : : // expressions.cc -- Go frontend expression handling.
2 : :
3 : : // Copyright 2009 The Go Authors. All rights reserved.
4 : : // Use of this source code is governed by a BSD-style
5 : : // license that can be found in the LICENSE file.
6 : :
7 : : #include "go-system.h"
8 : :
9 : : #include <algorithm>
10 : :
11 : : #include "go-c.h"
12 : : #include "gogo.h"
13 : : #include "go-diagnostics.h"
14 : : #include "go-encode-id.h"
15 : : #include "types.h"
16 : : #include "export.h"
17 : : #include "import.h"
18 : : #include "statements.h"
19 : : #include "lex.h"
20 : : #include "runtime.h"
21 : : #include "backend.h"
22 : : #include "expressions.h"
23 : : #include "ast-dump.h"
24 : :
25 : : // Class Expression.
26 : :
27 : 51519945 : Expression::Expression(Expression_classification classification,
28 : 51519945 : Location location)
29 : 51519945 : : classification_(classification), location_(location)
30 : : {
31 : 51519945 : }
32 : :
33 : 200645 : Expression::~Expression()
34 : : {
35 : 200645 : }
36 : :
37 : : // Traverse the expressions.
38 : :
39 : : int
40 : 236805199 : Expression::traverse(Expression** pexpr, Traverse* traverse)
41 : : {
42 : 236805199 : Expression* expr = *pexpr;
43 : 236805199 : if ((traverse->traverse_mask() & Traverse::traverse_expressions) != 0)
44 : : {
45 : 178199332 : int t = traverse->expression(pexpr);
46 : 178199332 : if (t == TRAVERSE_EXIT)
47 : : return TRAVERSE_EXIT;
48 : 176467021 : else if (t == TRAVERSE_SKIP_COMPONENTS)
49 : : return TRAVERSE_CONTINUE;
50 : : }
51 : 165483700 : return expr->do_traverse(traverse);
52 : : }
53 : :
54 : : // Traverse subexpressions of this expression.
55 : :
56 : : int
57 : 71887706 : Expression::traverse_subexpressions(Traverse* traverse)
58 : : {
59 : 71887706 : return this->do_traverse(traverse);
60 : : }
61 : :
62 : : // A traversal used to set the location of subexpressions.
63 : :
64 : 18170 : class Set_location : public Traverse
65 : : {
66 : : public:
67 : 9085 : Set_location(Location loc)
68 : 9085 : : Traverse(traverse_expressions),
69 : 9085 : loc_(loc)
70 : : { }
71 : :
72 : : int
73 : : expression(Expression** pexpr);
74 : :
75 : : private:
76 : : Location loc_;
77 : : };
78 : :
79 : : // Set the location of an expression.
80 : :
81 : : int
82 : 5614 : Set_location::expression(Expression** pexpr)
83 : : {
84 : : // Some expressions are shared or don't have an independent
85 : : // location, so we shouldn't change their location. This is the set
86 : : // of expressions for which do_copy is just "return this" or
87 : : // otherwise does not pass down the location.
88 : 5614 : switch ((*pexpr)->classification())
89 : : {
90 : : case Expression::EXPRESSION_ERROR:
91 : : case Expression::EXPRESSION_VAR_REFERENCE:
92 : : case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
93 : : case Expression::EXPRESSION_STRING:
94 : : case Expression::EXPRESSION_FUNC_DESCRIPTOR:
95 : : case Expression::EXPRESSION_TYPE:
96 : : case Expression::EXPRESSION_BOOLEAN:
97 : : case Expression::EXPRESSION_CONST_REFERENCE:
98 : : case Expression::EXPRESSION_NIL:
99 : : case Expression::EXPRESSION_TYPE_DESCRIPTOR:
100 : : case Expression::EXPRESSION_GC_SYMBOL:
101 : : case Expression::EXPRESSION_PTRMASK_SYMBOL:
102 : : case Expression::EXPRESSION_TYPE_INFO:
103 : : case Expression::EXPRESSION_STRUCT_FIELD_OFFSET:
104 : : return TRAVERSE_CONTINUE;
105 : 5607 : default:
106 : 5607 : break;
107 : : }
108 : :
109 : 5607 : (*pexpr)->location_ = this->loc_;
110 : 5607 : return TRAVERSE_CONTINUE;
111 : : }
112 : :
113 : : // Set the location of an expression and its subexpressions.
114 : :
115 : : void
116 : 9085 : Expression::set_location(Location loc)
117 : : {
118 : 9085 : this->location_ = loc;
119 : 9085 : Set_location sl(loc);
120 : 9085 : this->traverse_subexpressions(&sl);
121 : 9085 : }
122 : :
123 : : // Default implementation for do_traverse for child classes.
124 : :
125 : : int
126 : 69447905 : Expression::do_traverse(Traverse*)
127 : : {
128 : 69447905 : return TRAVERSE_CONTINUE;
129 : : }
130 : :
131 : : // This virtual function is called by the parser if the value of this
132 : : // expression is being discarded. By default, we give an error.
133 : : // Expressions with side effects override.
134 : :
135 : : bool
136 : 18 : Expression::do_discarding_value()
137 : : {
138 : 18 : this->unused_value_error();
139 : 18 : return false;
140 : : }
141 : :
142 : : // This virtual function is called to export expressions. This will
143 : : // only be used by expressions which may be constant.
144 : :
145 : : void
146 : 0 : Expression::do_export(Export_function_body*) const
147 : : {
148 : 0 : go_unreachable();
149 : : }
150 : :
151 : : // Write a name to the export data.
152 : :
153 : : void
154 : 13427 : Expression::export_name(Export_function_body* efb, const Named_object* no)
155 : : {
156 : 13427 : if (no->package() != NULL)
157 : : {
158 : 4700 : char buf[50];
159 : 4700 : snprintf(buf, sizeof buf, "<p%d>", efb->package_index(no->package()));
160 : 4700 : efb->write_c_string(buf);
161 : : }
162 : :
163 : 13427 : if (!Gogo::is_hidden_name(no->name()))
164 : 5679 : efb->write_string(no->name());
165 : : else
166 : : {
167 : 7748 : efb->write_c_string(".");
168 : 7748 : efb->write_string(Gogo::unpack_hidden_name(no->name()));
169 : : }
170 : 13427 : }
171 : :
172 : : // Give an error saying that the value of the expression is not used.
173 : :
174 : : void
175 : 95 : Expression::unused_value_error()
176 : : {
177 : 95 : if (this->type()->is_error())
178 : : {
179 : 13 : go_assert(saw_errors());
180 : 13 : this->set_is_error();
181 : : }
182 : : else
183 : 82 : this->report_error(_("value computed is not used"));
184 : 95 : }
185 : :
186 : : // Note that this expression is an error. This is called by children
187 : : // when they discover an error.
188 : :
189 : : void
190 : 5305 : Expression::set_is_error()
191 : : {
192 : 5305 : this->classification_ = EXPRESSION_ERROR;
193 : 5305 : }
194 : :
195 : : // For children to call to report an error conveniently.
196 : :
197 : : void
198 : 1291 : Expression::report_error(const char* msg)
199 : : {
200 : 1291 : go_error_at(this->location_, "%s", msg);
201 : 1291 : this->set_is_error();
202 : 1291 : }
203 : :
204 : : // A convenience function for handling a type in do_is_untyped. If
205 : : // TYPE is not abstract, return false. Otherwise set *PTYPE to TYPE
206 : : // and return true.
207 : :
208 : : bool
209 : 1389332 : Expression::is_untyped_type(Type* type, Type** ptype)
210 : : {
211 : 1389332 : if (!type->is_abstract())
212 : : return false;
213 : 53363 : *ptype = type;
214 : 53363 : return true;
215 : : }
216 : :
217 : : // Report whether this is a type expression.
218 : :
219 : : bool
220 : 26634365 : Expression::is_type_expression() const
221 : : {
222 : 26634365 : if (this->classification_ == EXPRESSION_TYPE)
223 : : return true;
224 : 26444713 : if (this->unknown_expression() != NULL)
225 : : {
226 : 833530 : Named_object* no = this->unknown_expression()->named_object();
227 : 833530 : if (no->is_unknown())
228 : : {
229 : 634205 : no = no->unknown_value()->real_named_object();
230 : 634205 : if (no == NULL)
231 : : return false;
232 : : }
233 : 250021 : return no->is_type();
234 : : }
235 : 25611183 : if (this->unary_expression() != NULL
236 : 149942 : && this->unary_expression()->op() == OPERATOR_MULT
237 : 35160 : && this->unary_expression()->operand()->is_type_expression())
238 : : return true;
239 : : return false;
240 : : }
241 : :
242 : : // Set types of variables and constants. This is implemented by the
243 : : // child class.
244 : :
245 : : void
246 : 38410878 : Expression::determine_type(Gogo* gogo, const Type_context* context)
247 : : {
248 : 38410878 : this->do_determine_type(gogo, context);
249 : 38410878 : }
250 : :
251 : : // Set types when there is no context.
252 : :
253 : : void
254 : 14366435 : Expression::determine_type_no_context(Gogo* gogo)
255 : : {
256 : 14366435 : Type_context context;
257 : 14366435 : this->do_determine_type(gogo, &context);
258 : 14366435 : }
259 : :
260 : : // Return true if two expressions refer to the same variable or struct
261 : : // field. This can only be true when there are no side effects.
262 : :
263 : : bool
264 : 47768 : Expression::is_same_variable(Expression* a, Expression* b)
265 : : {
266 : 47768 : if (a->classification() != b->classification())
267 : : return false;
268 : :
269 : 43769 : Var_expression* av = a->var_expression();
270 : 43769 : if (av != NULL)
271 : 30528 : return av->named_object() == b->var_expression()->named_object();
272 : :
273 : 13241 : Field_reference_expression* af = a->field_reference_expression();
274 : 13241 : if (af != NULL)
275 : : {
276 : 6441 : Field_reference_expression* bf = b->field_reference_expression();
277 : 6441 : return (af->field_index() == bf->field_index()
278 : 6441 : && Expression::is_same_variable(af->expr(), bf->expr()));
279 : : }
280 : :
281 : 6800 : Unary_expression* au = a->unary_expression();
282 : 6800 : if (au != NULL)
283 : : {
284 : 6083 : Unary_expression* bu = b->unary_expression();
285 : 6083 : return (au->op() == OPERATOR_MULT
286 : 6083 : && bu->op() == OPERATOR_MULT
287 : 12166 : && Expression::is_same_variable(au->operand(),
288 : : bu->operand()));
289 : : }
290 : :
291 : 717 : Array_index_expression* aie = a->array_index_expression();
292 : 717 : if (aie != NULL)
293 : : {
294 : 86 : Array_index_expression* bie = b->array_index_expression();
295 : 86 : return (aie->end() == NULL
296 : 86 : && bie->end() == NULL
297 : 86 : && Expression::is_same_variable(aie->array(), bie->array())
298 : 172 : && Expression::is_same_variable(aie->start(), bie->start()));
299 : : }
300 : :
301 : 631 : Numeric_constant aval;
302 : 631 : if (a->numeric_constant_value(&aval))
303 : : {
304 : 28 : Numeric_constant bval;
305 : 28 : if (b->numeric_constant_value(&bval))
306 : 28 : return aval.equals(bval);
307 : 28 : }
308 : :
309 : : return false;
310 : 631 : }
311 : :
312 : : // Return an expression handling any conversions which must be done during
313 : : // assignment.
314 : :
315 : : Expression*
316 : 12776439 : Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type,
317 : : Expression* rhs, Location location)
318 : : {
319 : 12776439 : Type* rhs_type = rhs->type();
320 : 12776439 : if (lhs_type->is_error()
321 : 12776434 : || rhs_type->is_error()
322 : 25552866 : || rhs->is_error_expression())
323 : 13 : return Expression::make_error(location);
324 : :
325 : 12776426 : bool are_identical = Type::are_identical(lhs_type, rhs_type,
326 : : (Type::COMPARE_ERRORS
327 : : | Type::COMPARE_TAGS),
328 : : NULL);
329 : 12776426 : Expression* ret;
330 : 12776426 : if (!are_identical && lhs_type->interface_type() != NULL)
331 : : {
332 : : // Type to interface conversions have been made explicit early.
333 : 26024 : go_assert(rhs_type->interface_type() != NULL);
334 : 26024 : ret = Expression::convert_interface_to_interface(gogo, lhs_type, rhs,
335 : : false, location);
336 : : }
337 : 12750402 : else if (!are_identical && rhs_type->interface_type() != NULL)
338 : 12525 : ret = Expression::convert_interface_to_type(gogo, lhs_type, rhs, location);
339 : 12737877 : else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
340 : : {
341 : : // Assigning nil to a slice.
342 : 19166 : Expression* nil = Expression::make_nil(location);
343 : 19166 : Expression* zero = Expression::make_integer_ul(0, NULL, location);
344 : 19166 : ret = Expression::make_slice_value(lhs_type, nil, zero, zero, location);
345 : : }
346 : 12718711 : else if (rhs_type->is_nil_type())
347 : 851738 : ret = Expression::make_nil(location);
348 : 11866973 : else if (are_identical)
349 : : {
350 : 11664570 : if (lhs_type->forwarded() != rhs_type->forwarded())
351 : : {
352 : : // Different but identical types require an explicit
353 : : // conversion. This happens with type aliases.
354 : 473959 : return Expression::make_cast(lhs_type, rhs, location);
355 : : }
356 : :
357 : : // No conversion is needed.
358 : : return rhs;
359 : : }
360 : 202403 : else if (lhs_type->points_to() != NULL)
361 : 13359 : ret = Expression::make_unsafe_cast(lhs_type, rhs, location);
362 : 189044 : else if (lhs_type->is_numeric_type())
363 : 143884 : ret = Expression::make_cast(lhs_type, rhs, location);
364 : 45196 : else if ((lhs_type->struct_type() != NULL
365 : 45124 : && rhs_type->struct_type() != NULL)
366 : 3434 : || (lhs_type->array_type() != NULL
367 : 3470 : && rhs_type->array_type() != NULL))
368 : : {
369 : : // This conversion must be permitted by Go, or we wouldn't have
370 : : // gotten here.
371 : 3470 : ret = Expression::make_unsafe_cast(lhs_type, rhs, location);
372 : : }
373 : : else
374 : 41690 : return rhs;
375 : :
376 : 1070166 : Type_context context(lhs_type, false);
377 : 1070166 : ret->determine_type(gogo, &context);
378 : 1070166 : return ret;
379 : : }
380 : :
381 : : // Return an expression for a conversion from a non-interface type to an
382 : : // interface type. If ON_STACK is true, it can allocate the storage on
383 : : // stack.
384 : :
385 : : Expression*
386 : 201200 : Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
387 : : bool on_stack, Location location)
388 : : {
389 : 201200 : Interface_type* lhs_interface_type = lhs_type->interface_type();
390 : 201200 : bool lhs_is_empty = lhs_interface_type->is_empty();
391 : :
392 : : // Since RHS_TYPE is a static type, we can create the interface
393 : : // method table at compile time.
394 : :
395 : : // When setting an interface to nil, we just set both fields to
396 : : // NULL.
397 : 201200 : Type* rhs_type = rhs->type();
398 : 201200 : if (rhs_type->is_nil_type())
399 : : {
400 : 28459 : Expression* nil = Expression::make_nil(location);
401 : 28459 : return Expression::make_interface_value(lhs_type, nil, nil, location);
402 : : }
403 : :
404 : : // This should have been checked already.
405 : 172741 : if (!lhs_interface_type->implements_interface(rhs_type, NULL))
406 : : {
407 : 0 : go_assert(saw_errors());
408 : 0 : return Expression::make_error(location);
409 : : }
410 : :
411 : : // An interface is a tuple. If LHS_TYPE is an empty interface type,
412 : : // then the first field is the type descriptor for RHS_TYPE.
413 : : // Otherwise it is the interface method table for RHS_TYPE.
414 : 172741 : Expression* first_field;
415 : 172741 : if (lhs_is_empty)
416 : 129332 : first_field = Expression::make_type_descriptor(rhs_type, location);
417 : : else
418 : : {
419 : : // Build the interface method table for this interface and this
420 : : // object type: a list of function pointers for each interface
421 : : // method.
422 : 43409 : Named_type* rhs_named_type = rhs_type->named_type();
423 : 43409 : Struct_type* rhs_struct_type = rhs_type->struct_type();
424 : 43409 : bool is_pointer = false;
425 : 43409 : if (rhs_named_type == NULL && rhs_struct_type == NULL)
426 : : {
427 : 59638 : rhs_named_type = rhs_type->deref()->named_type();
428 : 59638 : rhs_struct_type = rhs_type->deref()->struct_type();
429 : : is_pointer = true;
430 : : }
431 : 43409 : if (rhs_named_type != NULL)
432 : 43285 : first_field =
433 : 43285 : rhs_named_type->interface_method_table(lhs_interface_type,
434 : : is_pointer);
435 : 124 : else if (rhs_struct_type != NULL)
436 : 124 : first_field =
437 : 124 : rhs_struct_type->interface_method_table(lhs_interface_type,
438 : : is_pointer);
439 : : else
440 : 0 : first_field = Expression::make_nil(location);
441 : : }
442 : :
443 : 172741 : Expression* obj;
444 : 172741 : if (rhs_type->is_direct_iface_type())
445 : : {
446 : : // We are assigning a pointer to the interface; the interface
447 : : // holds the pointer itself.
448 : 47262 : obj = unpack_direct_iface(rhs, location);
449 : : }
450 : : else
451 : : {
452 : : // We are assigning a non-pointer value to the interface; the
453 : : // interface gets a copy of the value in the heap if it escapes.
454 : :
455 : : // An exception is &global if global is notinheap, which is a
456 : : // pointer value but not a direct-iface type and we can't simply
457 : : // take its address.
458 : 125479 : bool is_address = (rhs->unary_expression() != NULL
459 : 735 : && rhs->unary_expression()->op() == OPERATOR_AND);
460 : :
461 : 125479 : if (rhs->is_constant() && !is_address)
462 : 31942 : obj = Expression::make_unary(OPERATOR_AND, rhs, location);
463 : : else
464 : : {
465 : 93537 : obj = Expression::make_heap_expression(rhs, location);
466 : 93537 : if (on_stack)
467 : 597 : obj->heap_expression()->set_allocate_on_stack();
468 : : }
469 : : }
470 : :
471 : 172741 : return Expression::make_interface_value(lhs_type, first_field, obj, location);
472 : : }
473 : :
474 : : // Return an expression for the pointer-typed value of a direct interface
475 : : // type. Specifically, for single field struct or array, get the single
476 : : // field, and do this recursively. The reason for this is that we don't
477 : : // want to assign a struct or an array to a pointer-typed field. The
478 : : // backend may not like that.
479 : :
480 : : Expression*
481 : 57906 : Expression::unpack_direct_iface(Expression* rhs, Location loc)
482 : : {
483 : 62190 : Struct_type* st = rhs->type()->struct_type();
484 : 62190 : if (st != NULL)
485 : : {
486 : 4284 : go_assert(st->field_count() == 1);
487 : 4284 : Expression* field = Expression::make_field_reference(rhs, 0, loc);
488 : 4284 : return unpack_direct_iface(field, loc);
489 : : }
490 : 57906 : Array_type* at = rhs->type()->array_type();
491 : 814 : if (at != NULL)
492 : : {
493 : 814 : int64_t len;
494 : 814 : bool ok = at->int_length(&len);
495 : 814 : go_assert(ok && len == 1);
496 : 814 : Type* int_type = Type::lookup_integer_type("int");
497 : 814 : Expression* index = Expression::make_integer_ul(0, int_type, loc);
498 : 814 : Expression* elem = Expression::make_array_index(rhs, index, NULL, NULL, loc);
499 : 814 : return unpack_direct_iface(elem, loc);
500 : : }
501 : : return rhs;
502 : : }
503 : :
504 : : // The opposite of unpack_direct_iface.
505 : :
506 : : Expression*
507 : 13513 : Expression::pack_direct_iface(Type* t, Expression* rhs, Location loc)
508 : : {
509 : 13513 : if (rhs->type() == t)
510 : : return rhs;
511 : 13513 : Struct_type* st = t->struct_type();
512 : 13513 : if (st != NULL)
513 : : {
514 : 1665 : Expression_list* vals = new Expression_list();
515 : 1665 : vals->push_back(pack_direct_iface(st->field(0)->type(), rhs, loc));
516 : 1665 : return Expression::make_struct_composite_literal(t, vals, loc);
517 : : }
518 : 11848 : Array_type* at = t->array_type();
519 : 11848 : if (at != NULL)
520 : : {
521 : 4 : Expression_list* vals = new Expression_list();
522 : 4 : vals->push_back(pack_direct_iface(at->element_type(), rhs, loc));
523 : 4 : return Expression::make_array_composite_literal(t, vals, loc);
524 : : }
525 : 11844 : return Expression::make_unsafe_cast(t, rhs, loc);
526 : : }
527 : :
528 : : // Return an expression for the type descriptor of RHS.
529 : :
530 : : Expression*
531 : 54471 : Expression::get_interface_type_descriptor(Expression* rhs)
532 : : {
533 : 54471 : go_assert(rhs->type()->interface_type() != NULL);
534 : 54471 : Location location = rhs->location();
535 : :
536 : : // The type descriptor is the first field of an empty interface.
537 : 108942 : if (rhs->type()->interface_type()->is_empty())
538 : 8989 : return Expression::make_interface_info(rhs, INTERFACE_INFO_TYPE_DESCRIPTOR,
539 : 8989 : location);
540 : :
541 : 45482 : Expression* mtable =
542 : 45482 : Expression::make_interface_info(rhs, INTERFACE_INFO_METHODS, location);
543 : :
544 : 45482 : Expression* descriptor =
545 : 45482 : Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, location);
546 : 45482 : descriptor = Expression::make_field_reference(descriptor, 0, location);
547 : 45482 : Expression* nil = Expression::make_nil(location);
548 : :
549 : 45482 : Expression* eq =
550 : 45482 : Expression::make_binary(OPERATOR_EQEQ, mtable, nil, location);
551 : 45482 : return Expression::make_conditional(eq, nil, descriptor, location);
552 : : }
553 : :
554 : : // Return an expression for the conversion of an interface type to an
555 : : // interface type.
556 : :
557 : : Expression*
558 : 27040 : Expression::convert_interface_to_interface(Gogo* gogo, Type *lhs_type,
559 : : Expression* rhs,
560 : : bool for_type_guard,
561 : : Location location)
562 : : {
563 : 27040 : if (Type::are_identical(lhs_type, rhs->type(),
564 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
565 : : NULL))
566 : : return rhs;
567 : :
568 : 27035 : Interface_type* lhs_interface_type = lhs_type->interface_type();
569 : 27035 : bool lhs_is_empty = lhs_interface_type->is_empty();
570 : :
571 : : // In the general case this requires runtime examination of the type
572 : : // method table to match it up with the interface methods.
573 : :
574 : : // FIXME: If all of the methods in the right hand side interface
575 : : // also appear in the left hand side interface, then we don't need
576 : : // to do a runtime check, although we still need to build a new
577 : : // method table.
578 : :
579 : : // We are going to evaluate RHS multiple times.
580 : 27035 : go_assert(rhs->is_multi_eval_safe());
581 : :
582 : : // Get the type descriptor for the right hand side. This will be
583 : : // NULL for a nil interface.
584 : 27035 : Expression* rhs_type_expr = Expression::get_interface_type_descriptor(rhs);
585 : 27035 : Expression* lhs_type_expr =
586 : 27035 : Expression::make_type_descriptor(lhs_type, location);
587 : :
588 : 27035 : Expression* first_field;
589 : 27035 : if (for_type_guard)
590 : : {
591 : : // A type assertion fails when converting a nil interface.
592 : 1011 : first_field = Runtime::make_call(gogo, Runtime::ASSERTITAB, location, 2,
593 : : lhs_type_expr, rhs_type_expr);
594 : : }
595 : 26024 : else if (lhs_is_empty)
596 : : {
597 : : // A conversion to an empty interface always succeeds, and the
598 : : // first field is just the type descriptor of the object.
599 : : first_field = rhs_type_expr;
600 : : }
601 : : else
602 : : {
603 : : // A conversion to a non-empty interface may fail, but unlike a
604 : : // type assertion converting nil will always succeed.
605 : 4304 : first_field = Runtime::make_call(gogo, Runtime::REQUIREITAB, location, 2,
606 : : lhs_type_expr, rhs_type_expr);
607 : : }
608 : :
609 : : // The second field is simply the object pointer.
610 : 27035 : Expression* obj =
611 : 27035 : Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, location);
612 : 27035 : Expression* ret = Expression::make_interface_value(lhs_type, first_field,
613 : : obj, location);
614 : 27035 : Type_context context(lhs_type, false);
615 : 27035 : ret->determine_type(gogo, &context);
616 : 27035 : return ret;
617 : : }
618 : :
619 : : // Return an expression for the conversion of an interface type to a
620 : : // non-interface type.
621 : :
622 : : Expression*
623 : 12525 : Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rhs,
624 : : Location location)
625 : : {
626 : : // We are going to evaluate RHS multiple times.
627 : 12525 : go_assert(rhs->is_multi_eval_safe());
628 : :
629 : : // Build an expression to check that the type is valid. It will
630 : : // panic with an appropriate runtime type error if the type is not
631 : : // valid.
632 : : // (lhs_type == rhs_type ? nil /*dummy*/ :
633 : : // panicdottype(lhs_type, rhs_type, inter_type))
634 : : // For some Oses, we need to call runtime.eqtype instead of
635 : : // lhs_type == rhs_type, as we may have unmerged type descriptors
636 : : // from shared libraries.
637 : 12525 : Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
638 : : location);
639 : 12525 : Expression* rhs_descriptor =
640 : 12525 : Expression::get_interface_type_descriptor(rhs);
641 : :
642 : 12525 : Type* rhs_type = rhs->type();
643 : 12525 : Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
644 : : location);
645 : :
646 : 12525 : Expression* cond;
647 : 12525 : if (gogo->need_eqtype()) {
648 : 0 : cond = Runtime::make_call(gogo, Runtime::EQTYPE, location,
649 : : 2, lhs_type_expr,
650 : : rhs_descriptor);
651 : : } else {
652 : 12525 : cond = Expression::make_binary(OPERATOR_EQEQ, lhs_type_expr,
653 : : rhs_descriptor, location);
654 : : }
655 : :
656 : 12525 : rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
657 : 12525 : Expression* panic = Runtime::make_call(gogo, Runtime::PANICDOTTYPE, location,
658 : : 3, lhs_type_expr->copy(),
659 : : rhs_descriptor,
660 : : rhs_inter_expr);
661 : 12525 : Expression* nil = Expression::make_nil(location);
662 : 12525 : Expression* check = Expression::make_conditional(cond, nil, panic,
663 : : location);
664 : :
665 : : // If the conversion succeeds, pull out the value.
666 : 12525 : Expression* obj = Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT,
667 : : location);
668 : :
669 : : // If the value is a direct interface, then it is the value we want.
670 : : // Otherwise it points to the value.
671 : 12525 : if (lhs_type->is_direct_iface_type())
672 : 9828 : obj = Expression::pack_direct_iface(lhs_type, obj, location);
673 : : else
674 : : {
675 : 2697 : obj = Expression::make_unsafe_cast(Type::make_pointer_type(lhs_type), obj,
676 : : location);
677 : 2697 : obj = Expression::make_dereference(obj, NIL_CHECK_NOT_NEEDED,
678 : : location);
679 : : }
680 : 12525 : return Expression::make_compound(check, obj, location);
681 : : }
682 : :
683 : : // Convert an expression to its backend representation. This is implemented by
684 : : // the child class. Not that it is not in general safe to call this multiple
685 : : // times for a single expression, but that we don't catch such errors.
686 : :
687 : : Bexpression*
688 : 40327264 : Expression::get_backend(Translate_context* context)
689 : : {
690 : : // The child may have marked this expression as having an error.
691 : 40327264 : if (this->classification_ == EXPRESSION_ERROR)
692 : : {
693 : 3629 : go_assert(saw_errors());
694 : 3629 : return context->backend()->error_expression();
695 : : }
696 : :
697 : 40323635 : return this->do_get_backend(context);
698 : : }
699 : :
700 : : // Return a backend expression for VAL.
701 : : Bexpression*
702 : 6048762 : Expression::backend_numeric_constant_expression(Translate_context* context,
703 : : Numeric_constant* val)
704 : : {
705 : 6048762 : Gogo* gogo = context->gogo();
706 : 6048762 : Type* type = val->type();
707 : 6048762 : if (type == NULL)
708 : 0 : return gogo->backend()->error_expression();
709 : :
710 : 6048762 : Btype* btype = type->get_backend(gogo);
711 : 6048762 : Bexpression* ret;
712 : 6048762 : if (type->integer_type() != NULL)
713 : : {
714 : 6012394 : mpz_t ival;
715 : 6012394 : if (!val->to_int(&ival))
716 : : {
717 : 0 : go_assert(saw_errors());
718 : 0 : return gogo->backend()->error_expression();
719 : : }
720 : 6012394 : ret = gogo->backend()->integer_constant_expression(btype, ival);
721 : 6012394 : mpz_clear(ival);
722 : : }
723 : 36368 : else if (type->float_type() != NULL)
724 : : {
725 : 33424 : mpfr_t fval;
726 : 33424 : if (!val->to_float(&fval))
727 : : {
728 : 0 : go_assert(saw_errors());
729 : 0 : return gogo->backend()->error_expression();
730 : : }
731 : 33424 : ret = gogo->backend()->float_constant_expression(btype, fval);
732 : 33424 : mpfr_clear(fval);
733 : : }
734 : 2944 : else if (type->complex_type() != NULL)
735 : : {
736 : 2944 : mpc_t cval;
737 : 2944 : if (!val->to_complex(&cval))
738 : : {
739 : 0 : go_assert(saw_errors());
740 : 0 : return gogo->backend()->error_expression();
741 : : }
742 : 2944 : ret = gogo->backend()->complex_constant_expression(btype, cval);
743 : 2944 : mpc_clear(cval);
744 : : }
745 : : else
746 : 0 : go_unreachable();
747 : :
748 : : return ret;
749 : : }
750 : :
751 : : // Insert bounds checks for an index expression. Check that that VAL
752 : : // >= 0 and that it fits in an int. Then check that VAL OP BOUND is
753 : : // true. If any condition is false, call one of the CODE runtime
754 : : // functions, which will panic.
755 : :
756 : : void
757 : 224475 : Expression::check_bounds(Gogo* gogo, Expression* val, Operator op,
758 : : Expression* bound,
759 : : Runtime::Function code,
760 : : Runtime::Function code_u,
761 : : Runtime::Function code_extend,
762 : : Runtime::Function code_extend_u,
763 : : Statement_inserter* inserter,
764 : : Location loc)
765 : : {
766 : 224475 : go_assert(val->is_multi_eval_safe());
767 : 224475 : go_assert(bound->is_multi_eval_safe());
768 : :
769 : 224475 : Type* int_type = Type::lookup_integer_type("int");
770 : 448950 : int int_type_size = int_type->integer_type()->bits();
771 : :
772 : 224475 : Type* val_type = val->type();
773 : 224475 : if (val_type->integer_type() == NULL)
774 : : {
775 : 0 : go_assert(saw_errors());
776 : : return;
777 : : }
778 : 448950 : int val_type_size = val_type->integer_type()->bits();
779 : 448950 : bool val_is_unsigned = val_type->integer_type()->is_unsigned();
780 : :
781 : : // Check that VAL >= 0.
782 : 224475 : Expression* check = NULL;
783 : 224475 : if (!val_is_unsigned)
784 : : {
785 : 213394 : Expression* zero = Expression::make_integer_ul(0, val_type, loc);
786 : 213394 : check = Expression::make_binary(OPERATOR_GE, val->copy(), zero, loc);
787 : : }
788 : :
789 : : // If VAL's type is larger than int, check that VAL fits in an int.
790 : 224475 : if (val_type_size > int_type_size
791 : 223780 : || (val_type_size == int_type_size
792 : 223780 : && val_is_unsigned))
793 : : {
794 : 5511 : mpz_t one;
795 : 5511 : mpz_init_set_ui(one, 1UL);
796 : :
797 : : // maxval = 2^(int_type_size - 1) - 1
798 : 5511 : mpz_t maxval;
799 : 5511 : mpz_init(maxval);
800 : 5511 : mpz_mul_2exp(maxval, one, int_type_size - 1);
801 : 5511 : mpz_sub_ui(maxval, maxval, 1);
802 : 5511 : Expression* max = Expression::make_integer_z(&maxval, val_type, loc);
803 : 5511 : mpz_clear(one);
804 : 5511 : mpz_clear(maxval);
805 : :
806 : 5511 : Expression* cmp = Expression::make_binary(OPERATOR_LE, val->copy(),
807 : : max, loc);
808 : 5511 : if (check == NULL)
809 : : check = cmp;
810 : : else
811 : 311 : check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc);
812 : : }
813 : :
814 : : // For the final check we can assume that VAL fits in an int.
815 : 224475 : Expression* ival;
816 : 224475 : if (val_type == int_type)
817 : 188567 : ival = val->copy();
818 : : else
819 : 35908 : ival = Expression::make_cast(int_type, val->copy(), loc);
820 : :
821 : : // BOUND is assumed to fit in an int. Either it comes from len or
822 : : // cap, or it was checked by an earlier call.
823 : 224475 : Expression* ibound;
824 : 224475 : if (bound->type() == int_type)
825 : 205360 : ibound = bound->copy();
826 : : else
827 : 19115 : ibound = Expression::make_cast(int_type, bound->copy(), loc);
828 : :
829 : 224475 : Expression* cmp = Expression::make_binary(op, ival, ibound, loc);
830 : 224475 : if (check == NULL)
831 : : check = cmp;
832 : : else
833 : 218594 : check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc);
834 : :
835 : 224475 : Runtime::Function c;
836 : 224475 : if (val_type_size > int_type_size)
837 : : {
838 : 695 : if (val_is_unsigned)
839 : : c = code_extend_u;
840 : : else
841 : 311 : c = code_extend;
842 : : }
843 : : else
844 : : {
845 : 223780 : if (val_is_unsigned)
846 : : c = code_u;
847 : : else
848 : 213083 : c = code;
849 : : }
850 : :
851 : 224475 : Expression* ignore = Expression::make_boolean(true, loc);
852 : 224475 : Expression* crash = Runtime::make_call(gogo, c, loc, 2,
853 : : val->copy(), bound->copy());
854 : 224475 : Expression* cond = Expression::make_conditional(check, ignore, crash, loc);
855 : 224475 : Statement* s = Statement::make_statement(cond, true);
856 : 224475 : s->determine_types(gogo);
857 : 224475 : inserter->insert(s);
858 : : }
859 : :
860 : : void
861 : 0 : Expression::dump_expression(Ast_dump_context* ast_dump_context) const
862 : : {
863 : 0 : this->do_dump_expression(ast_dump_context);
864 : 0 : }
865 : :
866 : : // Error expressions. This are used to avoid cascading errors.
867 : :
868 : : class Error_expression : public Expression
869 : : {
870 : : public:
871 : 9856 : Error_expression(Location location)
872 : 19712 : : Expression(EXPRESSION_ERROR, location)
873 : : { }
874 : :
875 : : protected:
876 : : bool
877 : 62 : do_is_constant() const
878 : 62 : { return true; }
879 : :
880 : : bool
881 : 25 : do_is_untyped(Type**) const
882 : 25 : { return false; }
883 : :
884 : : bool
885 : 30 : do_numeric_constant_value(Numeric_constant*)
886 : 30 : { return false; }
887 : :
888 : : bool
889 : 6 : do_discarding_value()
890 : 6 : { return true; }
891 : :
892 : : Type*
893 : 12537 : do_type()
894 : 12537 : { return Type::make_error_type(); }
895 : :
896 : : void
897 : 160 : do_determine_type(Gogo*, const Type_context*)
898 : 160 : { }
899 : :
900 : : Expression*
901 : 0 : do_copy()
902 : 0 : { return this; }
903 : :
904 : : bool
905 : 9 : do_is_addressable() const
906 : 9 : { return true; }
907 : :
908 : : Bexpression*
909 : 0 : do_get_backend(Translate_context* context)
910 : 0 : { return context->backend()->error_expression(); }
911 : :
912 : : void
913 : : do_dump_expression(Ast_dump_context*) const;
914 : : };
915 : :
916 : : // Dump the ast representation for an error expression to a dump context.
917 : :
918 : : void
919 : 0 : Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
920 : : {
921 : 0 : ast_dump_context->ostream() << "_Error_" ;
922 : 0 : }
923 : :
924 : : Expression*
925 : 9856 : Expression::make_error(Location location)
926 : : {
927 : 9856 : return new Error_expression(location);
928 : : }
929 : :
930 : : // An expression which is really a type. This is used during parsing.
931 : : // It is an error if these survive after lowering.
932 : :
933 : : class Type_expression : public Expression
934 : : {
935 : : public:
936 : 254309 : Type_expression(Type* type, Location location)
937 : 254309 : : Expression(EXPRESSION_TYPE, location),
938 : 508618 : type_(type)
939 : : { }
940 : :
941 : : protected:
942 : : int
943 : 143439 : do_traverse(Traverse* traverse)
944 : 143439 : { return Type::traverse(this->type_, traverse); }
945 : :
946 : : Type*
947 : 476280 : do_type()
948 : 476280 : { return this->type_; }
949 : :
950 : : void
951 : 21109 : do_determine_type(Gogo*, const Type_context*)
952 : 21109 : { }
953 : :
954 : : void
955 : : do_check_types(Gogo*);
956 : :
957 : : Expression*
958 : 0 : do_copy()
959 : 0 : { return this; }
960 : :
961 : : Bexpression*
962 : : do_get_backend(Translate_context*);
963 : :
964 : : void do_dump_expression(Ast_dump_context*) const;
965 : :
966 : : private:
967 : : // The type which we are representing as an expression.
968 : : Type* type_;
969 : : };
970 : :
971 : : void
972 : 23066 : Type_expression::do_check_types(Gogo*)
973 : : {
974 : 23066 : if (this->type_->is_error())
975 : : {
976 : 2 : go_assert(saw_errors());
977 : 2 : this->set_is_error();
978 : : }
979 : 23066 : }
980 : :
981 : : Bexpression*
982 : 2 : Type_expression::do_get_backend(Translate_context* context)
983 : : {
984 : 2 : if (!this->is_error_expression())
985 : 2 : this->report_error("invalid use of type");
986 : 2 : return context->backend()->error_expression();
987 : : }
988 : :
989 : : void
990 : 0 : Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
991 : : {
992 : 0 : ast_dump_context->dump_type(this->type_);
993 : 0 : }
994 : :
995 : : Expression*
996 : 254309 : Expression::make_type(Type* type, Location location)
997 : : {
998 : 254309 : return new Type_expression(type, location);
999 : : }
1000 : :
1001 : : // Class Var_expression.
1002 : :
1003 : : // Lower a variable expression. Here we just make sure that the
1004 : : // initialization expression of the variable has been lowered. This
1005 : : // ensures that we will be able to determine the type of the variable
1006 : : // if necessary.
1007 : :
1008 : : Expression*
1009 : 6401598 : Var_expression::do_lower(Gogo* gogo, Named_object* function,
1010 : : Statement_inserter* inserter)
1011 : : {
1012 : 6401598 : if (this->variable_->is_variable())
1013 : : {
1014 : 5667305 : Variable* var = this->variable_->var_value();
1015 : : // This is either a local variable or a global variable. A
1016 : : // reference to a variable which is local to an enclosing
1017 : : // function will be a reference to a field in a closure.
1018 : 5667305 : if (var->is_global())
1019 : : {
1020 : 446198 : function = NULL;
1021 : 446198 : inserter = NULL;
1022 : : }
1023 : 5667305 : var->lower_init_expression(gogo, function, inserter);
1024 : : }
1025 : 6401598 : return this;
1026 : : }
1027 : :
1028 : : // Return the type of a reference to a variable.
1029 : :
1030 : : Type*
1031 : 51508694 : Var_expression::do_type()
1032 : : {
1033 : 51508694 : if (this->variable_->is_variable())
1034 : 45970954 : return this->variable_->var_value()->type();
1035 : 5537740 : else if (this->variable_->is_result_variable())
1036 : 5537740 : return this->variable_->result_var_value()->type();
1037 : : else
1038 : 0 : go_unreachable();
1039 : : }
1040 : :
1041 : : // Determine the type of a reference to a variable.
1042 : :
1043 : : void
1044 : 6260682 : Var_expression::do_determine_type(Gogo* gogo, const Type_context*)
1045 : : {
1046 : 6260682 : if (this->variable_->is_variable())
1047 : 5608969 : this->variable_->var_value()->determine_type(gogo);
1048 : 6260682 : }
1049 : :
1050 : : // Something takes the address of this variable. This means that we
1051 : : // may want to move the variable onto the heap.
1052 : :
1053 : : void
1054 : 1429477 : Var_expression::do_address_taken(bool escapes)
1055 : : {
1056 : 1429477 : if (!escapes)
1057 : : {
1058 : 1080327 : if (this->variable_->is_variable())
1059 : 1077310 : this->variable_->var_value()->set_non_escaping_address_taken();
1060 : 3017 : else if (this->variable_->is_result_variable())
1061 : 3017 : this->variable_->result_var_value()->set_non_escaping_address_taken();
1062 : : else
1063 : 0 : go_unreachable();
1064 : : }
1065 : : else
1066 : : {
1067 : 349150 : if (this->variable_->is_variable())
1068 : 348813 : this->variable_->var_value()->set_address_taken();
1069 : 337 : else if (this->variable_->is_result_variable())
1070 : 337 : this->variable_->result_var_value()->set_address_taken();
1071 : : else
1072 : 0 : go_unreachable();
1073 : : }
1074 : :
1075 : 1429477 : if (this->variable_->is_variable()
1076 : 1429477 : && this->variable_->var_value()->is_in_heap())
1077 : : {
1078 : 1176897 : Node::make_node(this)->set_encoding(Node::ESCAPE_HEAP);
1079 : 1176897 : Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
1080 : : }
1081 : 1429477 : }
1082 : :
1083 : : // Export a reference to a variable.
1084 : :
1085 : : void
1086 : 54719 : Var_expression::do_export(Export_function_body* efb) const
1087 : : {
1088 : 54719 : Named_object* no = this->variable_;
1089 : 54719 : if (no->is_result_variable() || !no->var_value()->is_global())
1090 : 52210 : efb->write_string(Gogo::unpack_hidden_name(no->name()));
1091 : : else
1092 : 2509 : Expression::export_name(efb, no);
1093 : 54719 : }
1094 : :
1095 : : // Get the backend representation for a reference to a variable.
1096 : :
1097 : : Bexpression*
1098 : 4053613 : Var_expression::do_get_backend(Translate_context* context)
1099 : : {
1100 : 4053613 : Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
1101 : : context->function());
1102 : 4053613 : bool is_in_heap;
1103 : 4053613 : Location loc = this->location();
1104 : 4053613 : Btype* btype;
1105 : 4053613 : Gogo* gogo = context->gogo();
1106 : 4053613 : if (this->variable_->is_variable())
1107 : : {
1108 : 3143729 : is_in_heap = this->variable_->var_value()->is_in_heap();
1109 : 3143729 : btype = this->variable_->var_value()->type()->get_backend(gogo);
1110 : : }
1111 : 909884 : else if (this->variable_->is_result_variable())
1112 : : {
1113 : 909884 : is_in_heap = this->variable_->result_var_value()->is_in_heap();
1114 : 909884 : btype = this->variable_->result_var_value()->type()->get_backend(gogo);
1115 : : }
1116 : : else
1117 : 0 : go_unreachable();
1118 : :
1119 : 4053613 : Bexpression* ret =
1120 : 4053613 : context->backend()->var_expression(bvar, loc);
1121 : 4053613 : if (is_in_heap)
1122 : 66935 : ret = context->backend()->indirect_expression(btype, ret, true, loc);
1123 : 4053613 : return ret;
1124 : : }
1125 : :
1126 : : // Ast dump for variable expression.
1127 : :
1128 : : void
1129 : 0 : Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1130 : : {
1131 : 0 : ast_dump_context->ostream() << this->variable_->message_name() ;
1132 : 0 : }
1133 : :
1134 : : // Make a reference to a variable in an expression.
1135 : :
1136 : : Expression*
1137 : 3520517 : Expression::make_var_reference(Named_object* var, Location location)
1138 : : {
1139 : 3520517 : if (var->is_sink())
1140 : 19221 : return Expression::make_sink(location);
1141 : 3501296 : if (var->is_redefinition())
1142 : 0 : return Expression::make_error(location);
1143 : :
1144 : : // FIXME: Creating a new object for each reference to a variable is
1145 : : // wasteful.
1146 : 3501296 : return new Var_expression(var, location);
1147 : : }
1148 : :
1149 : : // Class Enclosed_var_expression.
1150 : :
1151 : : int
1152 : 822743 : Enclosed_var_expression::do_traverse(Traverse*)
1153 : : {
1154 : 822743 : return TRAVERSE_CONTINUE;
1155 : : }
1156 : :
1157 : : // Lower the reference to the enclosed variable.
1158 : :
1159 : : Expression*
1160 : 92072 : Enclosed_var_expression::do_lower(Gogo* gogo, Named_object* function,
1161 : : Statement_inserter* inserter)
1162 : : {
1163 : 92072 : gogo->lower_expression(function, inserter, &this->reference_);
1164 : 92072 : return this;
1165 : : }
1166 : :
1167 : : // Flatten the reference to the enclosed variable.
1168 : :
1169 : : Expression*
1170 : 46839 : Enclosed_var_expression::do_flatten(Gogo* gogo, Named_object* function,
1171 : : Statement_inserter* inserter)
1172 : : {
1173 : 46839 : gogo->flatten_expression(function, inserter, &this->reference_);
1174 : 46839 : return this;
1175 : : }
1176 : :
1177 : : void
1178 : 28424 : Enclosed_var_expression::do_address_taken(bool escapes)
1179 : : {
1180 : 28424 : if (!escapes)
1181 : : {
1182 : 23149 : if (this->variable_->is_variable())
1183 : 23080 : this->variable_->var_value()->set_non_escaping_address_taken();
1184 : 69 : else if (this->variable_->is_result_variable())
1185 : 69 : this->variable_->result_var_value()->set_non_escaping_address_taken();
1186 : : else
1187 : 0 : go_unreachable();
1188 : : }
1189 : : else
1190 : : {
1191 : 5275 : if (this->variable_->is_variable())
1192 : 5266 : this->variable_->var_value()->set_address_taken();
1193 : 9 : else if (this->variable_->is_result_variable())
1194 : 9 : this->variable_->result_var_value()->set_address_taken();
1195 : : else
1196 : 0 : go_unreachable();
1197 : : }
1198 : :
1199 : 28424 : if (this->variable_->is_variable()
1200 : 28424 : && this->variable_->var_value()->is_in_heap())
1201 : 22145 : Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
1202 : 28424 : }
1203 : :
1204 : : // Ast dump for enclosed variable expression.
1205 : :
1206 : : void
1207 : 0 : Enclosed_var_expression::do_dump_expression(Ast_dump_context* adc) const
1208 : : {
1209 : 0 : adc->ostream() << this->variable_->message_name();
1210 : 0 : }
1211 : :
1212 : : // Make a reference to a variable within an enclosing function.
1213 : :
1214 : : Expression*
1215 : 43136 : Expression::make_enclosing_var_reference(Expression* reference,
1216 : : Named_object* var, Location location)
1217 : : {
1218 : 43136 : return new Enclosed_var_expression(reference, var, location);
1219 : : }
1220 : :
1221 : : // Class Temporary_reference_expression.
1222 : :
1223 : : // The type.
1224 : :
1225 : : Type*
1226 : 18807369 : Temporary_reference_expression::do_type()
1227 : : {
1228 : 18807369 : return this->statement_->type();
1229 : : }
1230 : :
1231 : : // Called if something takes the address of this temporary variable.
1232 : : // We never have to move temporary variables to the heap, but we do
1233 : : // need to know that they must live in the stack rather than in a
1234 : : // register.
1235 : :
1236 : : void
1237 : 33858 : Temporary_reference_expression::do_address_taken(bool)
1238 : : {
1239 : 33858 : this->statement_->set_is_address_taken();
1240 : 33858 : }
1241 : :
1242 : : // Export a reference to a temporary.
1243 : :
1244 : : void
1245 : 6731 : Temporary_reference_expression::do_export(Export_function_body* efb) const
1246 : : {
1247 : 6731 : unsigned int idx = efb->temporary_index(this->statement_);
1248 : 6731 : char buf[50];
1249 : 6731 : snprintf(buf, sizeof buf, "$t%u", idx);
1250 : 6731 : efb->write_c_string(buf);
1251 : 6731 : }
1252 : :
1253 : : // Import a reference to a temporary.
1254 : :
1255 : : Expression*
1256 : 3923 : Temporary_reference_expression::do_import(Import_function_body* ifb,
1257 : : Location loc)
1258 : : {
1259 : 3923 : std::string id = ifb->read_identifier();
1260 : 3923 : go_assert(id[0] == '$' && id[1] == 't');
1261 : 3923 : const char *p = id.c_str();
1262 : 3923 : char *end;
1263 : 3923 : long idx = strtol(p + 2, &end, 10);
1264 : 3923 : if (*end != '\0' || idx > 0x7fffffff)
1265 : : {
1266 : 0 : if (!ifb->saw_error())
1267 : 0 : go_error_at(loc,
1268 : : ("invalid export data for %qs: "
1269 : : "invalid temporary reference index at %lu"),
1270 : 0 : ifb->name().c_str(),
1271 : 0 : static_cast<unsigned long>(ifb->off()));
1272 : 0 : ifb->set_saw_error();
1273 : 0 : return Expression::make_error(loc);
1274 : : }
1275 : :
1276 : 3923 : Temporary_statement* temp =
1277 : 3923 : ifb->temporary_statement(static_cast<unsigned int>(idx));
1278 : 3923 : if (temp == NULL)
1279 : : {
1280 : 0 : if (!ifb->saw_error())
1281 : 0 : go_error_at(loc,
1282 : : ("invalid export data for %qs: "
1283 : : "undefined temporary reference index at %lu"),
1284 : 0 : ifb->name().c_str(),
1285 : 0 : static_cast<unsigned long>(ifb->off()));
1286 : 0 : ifb->set_saw_error();
1287 : 0 : return Expression::make_error(loc);
1288 : : }
1289 : :
1290 : 3923 : return Expression::make_temporary_reference(temp, loc);
1291 : 3923 : }
1292 : :
1293 : : // Get a backend expression referring to the variable.
1294 : :
1295 : : Bexpression*
1296 : 3793092 : Temporary_reference_expression::do_get_backend(Translate_context* context)
1297 : : {
1298 : 3793092 : Gogo* gogo = context->gogo();
1299 : 3793092 : Bvariable* bvar = this->statement_->get_backend_variable(context);
1300 : 3793092 : Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
1301 : :
1302 : : // The backend can't always represent the same set of recursive types
1303 : : // that the Go frontend can. In some cases this means that a
1304 : : // temporary variable won't have the right backend type. Correct
1305 : : // that here by adding a type cast. We need to use base() to push
1306 : : // the circularity down one level.
1307 : 3793092 : Type* stype = this->statement_->type();
1308 : 3793092 : if (!this->is_lvalue_
1309 : 3698718 : && stype->points_to() != NULL
1310 : 4263658 : && stype->points_to()->is_void_type())
1311 : : {
1312 : 18132 : Btype* btype = this->type()->base()->get_backend(gogo);
1313 : 18132 : ret = gogo->backend()->convert_expression(btype, ret, this->location());
1314 : : }
1315 : 3793092 : return ret;
1316 : : }
1317 : :
1318 : : // Ast dump for temporary reference.
1319 : :
1320 : : void
1321 : 0 : Temporary_reference_expression::do_dump_expression(
1322 : : Ast_dump_context* ast_dump_context) const
1323 : : {
1324 : 0 : ast_dump_context->dump_temp_variable_name(this->statement_);
1325 : 0 : }
1326 : :
1327 : : // Make a reference to a temporary variable.
1328 : :
1329 : : Temporary_reference_expression*
1330 : 3859417 : Expression::make_temporary_reference(Temporary_statement* statement,
1331 : : Location location)
1332 : : {
1333 : 3859417 : statement->add_use();
1334 : 3859417 : return new Temporary_reference_expression(statement, location);
1335 : : }
1336 : :
1337 : : // Class Set_and_use_temporary_expression.
1338 : :
1339 : : // Return the type.
1340 : :
1341 : : Type*
1342 : 326051 : Set_and_use_temporary_expression::do_type()
1343 : : {
1344 : 326051 : return this->statement_->type();
1345 : : }
1346 : :
1347 : : // Determine the type of the expression.
1348 : :
1349 : : void
1350 : 20883 : Set_and_use_temporary_expression::do_determine_type(
1351 : : Gogo* gogo,
1352 : : const Type_context* context)
1353 : : {
1354 : 20883 : this->expr_->determine_type(gogo, context);
1355 : 20883 : }
1356 : :
1357 : : // Take the address.
1358 : :
1359 : : void
1360 : 0 : Set_and_use_temporary_expression::do_address_taken(bool)
1361 : : {
1362 : 0 : this->statement_->set_is_address_taken();
1363 : 0 : }
1364 : :
1365 : : // Return the backend representation.
1366 : :
1367 : : Bexpression*
1368 : 16126 : Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
1369 : : {
1370 : 16126 : Location loc = this->location();
1371 : 16126 : Gogo* gogo = context->gogo();
1372 : 16126 : Bvariable* bvar = this->statement_->get_backend_variable(context);
1373 : 16126 : Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc);
1374 : :
1375 : 16126 : Named_object* fn = context->function();
1376 : 16126 : go_assert(fn != NULL);
1377 : 16126 : Bfunction* bfn = fn->func_value()->get_or_make_decl(gogo, fn);
1378 : 16126 : Bexpression* bexpr = this->expr_->get_backend(context);
1379 : 16126 : Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
1380 : : bexpr, loc);
1381 : 16126 : Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
1382 : 16126 : Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
1383 : 16126 : return ret;
1384 : : }
1385 : :
1386 : : // Dump.
1387 : :
1388 : : void
1389 : 0 : Set_and_use_temporary_expression::do_dump_expression(
1390 : : Ast_dump_context* ast_dump_context) const
1391 : : {
1392 : 0 : ast_dump_context->ostream() << '(';
1393 : 0 : ast_dump_context->dump_temp_variable_name(this->statement_);
1394 : 0 : ast_dump_context->ostream() << " = ";
1395 : 0 : this->expr_->dump_expression(ast_dump_context);
1396 : 0 : ast_dump_context->ostream() << ')';
1397 : 0 : }
1398 : :
1399 : : // Make a set-and-use temporary.
1400 : :
1401 : : Set_and_use_temporary_expression*
1402 : 19060 : Expression::make_set_and_use_temporary(Temporary_statement* statement,
1403 : : Expression* expr, Location location)
1404 : : {
1405 : 19060 : return new Set_and_use_temporary_expression(statement, expr, location);
1406 : : }
1407 : :
1408 : : // A sink expression--a use of the blank identifier _.
1409 : :
1410 : : class Sink_expression : public Expression
1411 : : {
1412 : : public:
1413 : 27627 : Sink_expression(Location location)
1414 : 27627 : : Expression(EXPRESSION_SINK, location),
1415 : 0 : type_(NULL), bvar_(NULL)
1416 : : { }
1417 : :
1418 : : protected:
1419 : : bool
1420 : 0 : do_discarding_value()
1421 : 0 : { return true; }
1422 : :
1423 : : Type*
1424 : : do_type();
1425 : :
1426 : : void
1427 : : do_determine_type(Gogo*, const Type_context*);
1428 : :
1429 : : Expression*
1430 : 0 : do_copy()
1431 : 0 : { return new Sink_expression(this->location()); }
1432 : :
1433 : : Bexpression*
1434 : : do_get_backend(Translate_context*);
1435 : :
1436 : : void
1437 : : do_dump_expression(Ast_dump_context*) const;
1438 : :
1439 : : private:
1440 : : // The type of this sink variable.
1441 : : Type* type_;
1442 : : // The temporary variable we generate.
1443 : : Bvariable* bvar_;
1444 : : };
1445 : :
1446 : : // Return the type of a sink expression.
1447 : :
1448 : : Type*
1449 : 189204 : Sink_expression::do_type()
1450 : : {
1451 : 189204 : if (this->type_ == NULL)
1452 : 189204 : return Type::make_sink_type();
1453 : : return this->type_;
1454 : : }
1455 : :
1456 : : // Determine the type of a sink expression.
1457 : :
1458 : : void
1459 : 63873 : Sink_expression::do_determine_type(Gogo*, const Type_context* context)
1460 : : {
1461 : 63873 : if (context->type != NULL)
1462 : 0 : this->type_ = context->type;
1463 : 63873 : }
1464 : :
1465 : : // Return a temporary variable for a sink expression. This will
1466 : : // presumably be a write-only variable which the middle-end will drop.
1467 : :
1468 : : Bexpression*
1469 : 0 : Sink_expression::do_get_backend(Translate_context* context)
1470 : : {
1471 : 0 : Location loc = this->location();
1472 : 0 : Gogo* gogo = context->gogo();
1473 : 0 : if (this->bvar_ == NULL)
1474 : : {
1475 : 0 : if (this->type_ == NULL || this->type_->is_sink_type())
1476 : : {
1477 : 0 : go_assert(saw_errors());
1478 : 0 : return gogo->backend()->error_expression();
1479 : : }
1480 : :
1481 : 0 : Named_object* fn = context->function();
1482 : 0 : go_assert(fn != NULL);
1483 : 0 : Bfunction* fn_ctx = fn->func_value()->get_or_make_decl(gogo, fn);
1484 : 0 : Btype* bt = this->type_->get_backend(context->gogo());
1485 : 0 : Bstatement* decl;
1486 : 0 : this->bvar_ =
1487 : 0 : gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
1488 : : 0, loc, &decl);
1489 : 0 : Bexpression* var_ref =
1490 : 0 : gogo->backend()->var_expression(this->bvar_, loc);
1491 : 0 : var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
1492 : 0 : return var_ref;
1493 : : }
1494 : 0 : return gogo->backend()->var_expression(this->bvar_, loc);
1495 : : }
1496 : :
1497 : : // Ast dump for sink expression.
1498 : :
1499 : : void
1500 : 0 : Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1501 : : {
1502 : 0 : ast_dump_context->ostream() << "_" ;
1503 : 0 : }
1504 : :
1505 : : // Make a sink expression.
1506 : :
1507 : : Expression*
1508 : 27627 : Expression::make_sink(Location location)
1509 : : {
1510 : 27627 : return new Sink_expression(location);
1511 : : }
1512 : :
1513 : : // Class Func_expression.
1514 : :
1515 : : // FIXME: Can a function expression appear in a constant expression?
1516 : : // The value is unchanging. Initializing a constant to the address of
1517 : : // a function seems like it could work, though there might be little
1518 : : // point to it.
1519 : :
1520 : : // Traversal.
1521 : :
1522 : : int
1523 : 14462201 : Func_expression::do_traverse(Traverse* traverse)
1524 : : {
1525 : 14462201 : return (this->closure_ == NULL
1526 : 14462201 : ? TRAVERSE_CONTINUE
1527 : 232320 : : Expression::traverse(&this->closure_, traverse));
1528 : : }
1529 : :
1530 : : // Return the type of a function expression.
1531 : :
1532 : : Type*
1533 : 24385573 : Func_expression::do_type()
1534 : : {
1535 : 24385573 : if (this->function_->is_function())
1536 : 11179678 : return this->function_->func_value()->type();
1537 : 13205895 : else if (this->function_->is_function_declaration())
1538 : 13205895 : return this->function_->func_declaration_value()->type();
1539 : : else
1540 : 0 : go_unreachable();
1541 : : }
1542 : :
1543 : : // Get the backend representation for the code of a function expression.
1544 : :
1545 : : Bexpression*
1546 : 2137453 : Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
1547 : : {
1548 : 2137453 : Function_type* fntype;
1549 : 2137453 : if (no->is_function())
1550 : 612584 : fntype = no->func_value()->type();
1551 : 1524869 : else if (no->is_function_declaration())
1552 : 1524869 : fntype = no->func_declaration_value()->type();
1553 : : else
1554 : 0 : go_unreachable();
1555 : :
1556 : : // Builtin functions are handled specially by Call_expression. We
1557 : : // can't take their address.
1558 : 2137453 : if (fntype->is_builtin())
1559 : : {
1560 : 0 : go_error_at(loc,
1561 : : ("invalid use of special built-in function %qs; "
1562 : : "must be called"),
1563 : 0 : no->message_name().c_str());
1564 : 0 : return gogo->backend()->error_expression();
1565 : : }
1566 : :
1567 : 2137453 : Bfunction* fndecl;
1568 : 2137453 : if (no->is_function())
1569 : 612584 : fndecl = no->func_value()->get_or_make_decl(gogo, no);
1570 : 1524869 : else if (no->is_function_declaration())
1571 : 1524869 : fndecl = no->func_declaration_value()->get_or_make_decl(gogo, no);
1572 : : else
1573 : : go_unreachable();
1574 : :
1575 : 2137453 : return gogo->backend()->function_code_expression(fndecl, loc);
1576 : : }
1577 : :
1578 : : // Get the backend representation for a function expression. This is used when
1579 : : // we take the address of a function rather than simply calling it. A func
1580 : : // value is represented as a pointer to a block of memory. The first
1581 : : // word of that memory is a pointer to the function code. The
1582 : : // remaining parts of that memory are the addresses of variables that
1583 : : // the function closes over.
1584 : :
1585 : : Bexpression*
1586 : 155429 : Func_expression::do_get_backend(Translate_context* context)
1587 : : {
1588 : : // If there is no closure, just use the function descriptor.
1589 : 155429 : if (this->closure_ == NULL)
1590 : : {
1591 : 142627 : Gogo* gogo = context->gogo();
1592 : 142627 : Named_object* no = this->function_;
1593 : 142627 : Expression* descriptor;
1594 : 142627 : if (no->is_function())
1595 : 37921 : descriptor = no->func_value()->descriptor(gogo, no);
1596 : 104706 : else if (no->is_function_declaration())
1597 : : {
1598 : 104706 : if (no->func_declaration_value()->type()->is_builtin())
1599 : : {
1600 : 1 : go_error_at(this->location(),
1601 : : ("invalid use of special built-in function %qs; "
1602 : : "must be called"),
1603 : 1 : no->message_name().c_str());
1604 : 1 : return gogo->backend()->error_expression();
1605 : : }
1606 : 104705 : descriptor = no->func_declaration_value()->descriptor(gogo, no);
1607 : : }
1608 : : else
1609 : 0 : go_unreachable();
1610 : :
1611 : 142626 : Bexpression* bdesc = descriptor->get_backend(context);
1612 : 142626 : return gogo->backend()->address_expression(bdesc, this->location());
1613 : : }
1614 : :
1615 : 12802 : go_assert(this->function_->func_value()->enclosing() != NULL);
1616 : :
1617 : : // If there is a closure, then the closure is itself the function
1618 : : // expression. It is a pointer to a struct whose first field points
1619 : : // to the function code and whose remaining fields are the addresses
1620 : : // of the closed-over variables.
1621 : 12802 : Bexpression *bexpr = this->closure_->get_backend(context);
1622 : :
1623 : : // Introduce a backend type conversion, to account for any differences
1624 : : // between the argument type (function descriptor, struct with a
1625 : : // single field) and the closure (struct with multiple fields).
1626 : 12802 : Gogo* gogo = context->gogo();
1627 : 12802 : Btype *btype = this->type()->get_backend(gogo);
1628 : 12802 : return gogo->backend()->convert_expression(btype, bexpr, this->location());
1629 : : }
1630 : :
1631 : : // The cost of inlining a function reference.
1632 : :
1633 : : int
1634 : 570562 : Func_expression::do_inlining_cost() const
1635 : : {
1636 : : // FIXME: We don't inline references to nested functions.
1637 : 570562 : if (this->closure_ != NULL)
1638 : : return 0x100000;
1639 : 560418 : if (this->function_->is_function()
1640 : 560418 : && this->function_->func_value()->enclosing() != NULL)
1641 : 2780 : return 0x100000;
1642 : :
1643 : : return 1;
1644 : : }
1645 : :
1646 : : // Export a reference to a function.
1647 : :
1648 : : void
1649 : 10918 : Func_expression::do_export(Export_function_body* efb) const
1650 : : {
1651 : 10918 : Expression::export_name(efb, this->function_);
1652 : 10918 : }
1653 : :
1654 : : // Ast dump for function.
1655 : :
1656 : : void
1657 : 0 : Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1658 : : {
1659 : 0 : ast_dump_context->ostream() << this->function_->name();
1660 : 0 : if (this->closure_ != NULL)
1661 : : {
1662 : 0 : ast_dump_context->ostream() << " {closure = ";
1663 : 0 : this->closure_->dump_expression(ast_dump_context);
1664 : 0 : ast_dump_context->ostream() << "}";
1665 : : }
1666 : 0 : }
1667 : :
1668 : : // Make a reference to a function in an expression.
1669 : :
1670 : : Expression*
1671 : 2155756 : Expression::make_func_reference(Named_object* function, Expression* closure,
1672 : : Location location)
1673 : : {
1674 : 2155756 : Func_expression* fe = new Func_expression(function, closure, location);
1675 : :
1676 : : // Detect references to builtin functions and set the runtime code if
1677 : : // appropriate.
1678 : 2155756 : if (function->is_function_declaration())
1679 : 1798461 : fe->set_runtime_code(Runtime::name_to_code(function->name()));
1680 : 2155756 : return fe;
1681 : : }
1682 : :
1683 : : // Class Func_descriptor_expression.
1684 : :
1685 : : // Constructor.
1686 : :
1687 : 259521 : Func_descriptor_expression::Func_descriptor_expression(Named_object* fn)
1688 : : : Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()),
1689 : 259521 : fn_(fn), dvar_(NULL)
1690 : : {
1691 : 259521 : go_assert(!fn->is_function() || !fn->func_value()->needs_closure());
1692 : 259521 : }
1693 : :
1694 : : // Traversal.
1695 : :
1696 : : int
1697 : 0 : Func_descriptor_expression::do_traverse(Traverse*)
1698 : : {
1699 : 0 : return TRAVERSE_CONTINUE;
1700 : : }
1701 : :
1702 : : // All function descriptors have the same type.
1703 : :
1704 : : Type* Func_descriptor_expression::descriptor_type;
1705 : :
1706 : : void
1707 : 407989 : Func_descriptor_expression::make_func_descriptor_type()
1708 : : {
1709 : 407989 : if (Func_descriptor_expression::descriptor_type != NULL)
1710 : : return;
1711 : 4646 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
1712 : 4646 : Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type);
1713 : 4646 : Func_descriptor_expression::descriptor_type =
1714 : 4646 : Type::make_builtin_named_type("functionDescriptor", struct_type);
1715 : : }
1716 : :
1717 : : Type*
1718 : 403343 : Func_descriptor_expression::do_type()
1719 : : {
1720 : 403343 : Func_descriptor_expression::make_func_descriptor_type();
1721 : 403343 : return Func_descriptor_expression::descriptor_type;
1722 : : }
1723 : :
1724 : : // The backend representation for a function descriptor.
1725 : :
1726 : : Bexpression*
1727 : 297738 : Func_descriptor_expression::do_get_backend(Translate_context* context)
1728 : : {
1729 : 297738 : Named_object* no = this->fn_;
1730 : 297738 : Location loc = no->location();
1731 : 297738 : if (this->dvar_ != NULL)
1732 : 38226 : return context->backend()->var_expression(this->dvar_, loc);
1733 : :
1734 : 259512 : Gogo* gogo = context->gogo();
1735 : 259512 : Backend_name bname;
1736 : 259512 : gogo->function_descriptor_backend_name(no, &bname);
1737 : 259512 : bool is_descriptor = false;
1738 : 259512 : if (no->is_function_declaration()
1739 : 105050 : && !no->func_declaration_value()->asm_name().empty()
1740 : 349534 : && Linemap::is_predeclared_location(no->location()))
1741 : : is_descriptor = true;
1742 : :
1743 : : // The runtime package implements some functions defined in the
1744 : : // syscall package. Let the syscall package define the descriptor
1745 : : // in this case.
1746 : 259512 : if (gogo->compiling_runtime()
1747 : 21436 : && gogo->package_name() == "runtime"
1748 : 14738 : && no->is_function()
1749 : 5497 : && !no->func_value()->asm_name().empty()
1750 : 263358 : && no->func_value()->asm_name().compare(0, 8, "syscall.") == 0)
1751 : : is_descriptor = true;
1752 : :
1753 : 259512 : Btype* btype = this->type()->get_backend(gogo);
1754 : :
1755 : 259512 : Bvariable* bvar;
1756 : 259512 : if (no->package() != NULL || is_descriptor)
1757 : 115681 : bvar =
1758 : 115681 : context->backend()->immutable_struct_reference(bname.name(),
1759 : 231362 : bname.optional_asm_name(),
1760 : : btype, loc);
1761 : : else
1762 : : {
1763 : 143831 : Location bloc = Linemap::predeclared_location();
1764 : :
1765 : : // The runtime package has hash/equality functions that are
1766 : : // referenced by type descriptors outside of the runtime, so the
1767 : : // function descriptors must be visible even though they are not
1768 : : // exported.
1769 : 143831 : bool is_exported_runtime = false;
1770 : 143831 : if (gogo->compiling_runtime()
1771 : 8867 : && gogo->package_name() == "runtime"
1772 : 149292 : && (no->name().find("hash") != std::string::npos
1773 : 5356 : || no->name().find("equal") != std::string::npos))
1774 : : is_exported_runtime = true;
1775 : :
1776 : 143831 : bool is_hidden = ((no->is_function()
1777 : 143181 : && no->func_value()->enclosing() != NULL)
1778 : 133060 : || (Gogo::is_hidden_name(no->name())
1779 : 7955 : && !is_exported_runtime)
1780 : 269139 : || Gogo::is_thunk(no));
1781 : :
1782 : 143831 : if (no->is_function() && no->func_value()->is_referenced_by_inline())
1783 : : is_hidden = false;
1784 : :
1785 : 142235 : unsigned int flags = 0;
1786 : 142235 : if (is_hidden)
1787 : 143831 : flags |= Backend::variable_is_hidden;
1788 : 143831 : bvar = context->backend()->immutable_struct(bname.name(),
1789 : 143831 : bname.optional_asm_name(),
1790 : : flags, btype, bloc);
1791 : 143831 : Expression_list* vals = new Expression_list();
1792 : 143831 : vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
1793 : 143831 : Expression* init =
1794 : 143831 : Expression::make_struct_composite_literal(this->type(), vals, bloc);
1795 : 143831 : Translate_context bcontext(gogo, NULL, NULL, NULL);
1796 : 143831 : bcontext.set_is_const();
1797 : 143831 : Bexpression* binit = init->get_backend(&bcontext);
1798 : 143831 : context->backend()->immutable_struct_set_init(bvar, bname.name(),
1799 : : flags, btype, bloc, binit);
1800 : : }
1801 : :
1802 : 259512 : this->dvar_ = bvar;
1803 : 259512 : return gogo->backend()->var_expression(bvar, loc);
1804 : 259512 : }
1805 : :
1806 : : // Print a function descriptor expression.
1807 : :
1808 : : void
1809 : 0 : Func_descriptor_expression::do_dump_expression(Ast_dump_context* context) const
1810 : : {
1811 : 0 : context->ostream() << "[descriptor " << this->fn_->name() << "]";
1812 : 0 : }
1813 : :
1814 : : // Make a function descriptor expression.
1815 : :
1816 : : Func_descriptor_expression*
1817 : 259521 : Expression::make_func_descriptor(Named_object* fn)
1818 : : {
1819 : 259521 : return new Func_descriptor_expression(fn);
1820 : : }
1821 : :
1822 : : // Make the function descriptor type, so that it can be converted.
1823 : :
1824 : : void
1825 : 4646 : Expression::make_func_descriptor_type()
1826 : : {
1827 : 4646 : Func_descriptor_expression::make_func_descriptor_type();
1828 : 4646 : }
1829 : :
1830 : : // A reference to just the code of a function.
1831 : :
1832 : : class Func_code_reference_expression : public Expression
1833 : : {
1834 : : public:
1835 : 2357423 : Func_code_reference_expression(Named_object* function, Location location)
1836 : 2357423 : : Expression(EXPRESSION_FUNC_CODE_REFERENCE, location),
1837 : 4714846 : function_(function)
1838 : : { }
1839 : :
1840 : : protected:
1841 : : int
1842 : 221665 : do_traverse(Traverse*)
1843 : 221665 : { return TRAVERSE_CONTINUE; }
1844 : :
1845 : : bool
1846 : 318868 : do_is_static_initializer() const
1847 : 318868 : { return true; }
1848 : :
1849 : : Type*
1850 : 456927 : do_type()
1851 : 456927 : { return Type::make_pointer_type(Type::make_void_type()); }
1852 : :
1853 : : void
1854 : 548828 : do_determine_type(Gogo*, const Type_context*)
1855 : 548828 : { }
1856 : :
1857 : : Expression*
1858 : 0 : do_copy()
1859 : : {
1860 : 0 : return Expression::make_func_code_reference(this->function_,
1861 : 0 : this->location());
1862 : : }
1863 : :
1864 : : Bexpression*
1865 : : do_get_backend(Translate_context*);
1866 : :
1867 : : void
1868 : 0 : do_dump_expression(Ast_dump_context* context) const
1869 : 0 : { context->ostream() << "[raw " << this->function_->name() << "]" ; }
1870 : :
1871 : : private:
1872 : : // The function.
1873 : : Named_object* function_;
1874 : : };
1875 : :
1876 : : // Get the backend representation for a reference to function code.
1877 : :
1878 : : Bexpression*
1879 : 2137453 : Func_code_reference_expression::do_get_backend(Translate_context* context)
1880 : : {
1881 : 2137453 : return Func_expression::get_code_pointer(context->gogo(), this->function_,
1882 : 2137453 : this->location());
1883 : : }
1884 : :
1885 : : // Make a reference to the code of a function.
1886 : :
1887 : : Expression*
1888 : 2357423 : Expression::make_func_code_reference(Named_object* function, Location location)
1889 : : {
1890 : 2357423 : return new Func_code_reference_expression(function, location);
1891 : : }
1892 : :
1893 : : // Class Unknown_expression.
1894 : :
1895 : : // Return the name of an unknown expression.
1896 : :
1897 : : const std::string&
1898 : 5232 : Unknown_expression::name() const
1899 : : {
1900 : 5232 : return this->named_object_->name();
1901 : : }
1902 : :
1903 : : // Set the iota value if this could be a reference to iota.
1904 : :
1905 : : void
1906 : 17166 : Unknown_expression::set_iota_value(int iota_value)
1907 : : {
1908 : 17166 : this->iota_value_ = iota_value;
1909 : 17166 : this->is_iota_ = true;
1910 : 17166 : }
1911 : :
1912 : : // Traversal.
1913 : :
1914 : : int
1915 : 2178652 : Unknown_expression::do_traverse(Traverse* traverse)
1916 : : {
1917 : 2178652 : if (this->lowered_ != NULL)
1918 : : {
1919 : 1130841 : if (Expression::traverse(&this->lowered_, traverse) == TRAVERSE_EXIT)
1920 : : return TRAVERSE_EXIT;
1921 : : }
1922 : : return TRAVERSE_CONTINUE;
1923 : : }
1924 : :
1925 : : // Determine the type of a reference to an unknown name. At this
1926 : : // point we have to figure out what the name refers to.
1927 : :
1928 : : void
1929 : 451021 : Unknown_expression::do_determine_type(Gogo* gogo, const Type_context* context)
1930 : : {
1931 : 451021 : if (this->is_error_expression())
1932 : 11143 : return;
1933 : :
1934 : 451021 : if (this->lowered_ != NULL)
1935 : : {
1936 : 11097 : this->lowered_->determine_type(gogo, context);
1937 : 11097 : return;
1938 : : }
1939 : :
1940 : 439924 : Location loc = this->location();
1941 : :
1942 : 439924 : Named_object* no = this->named_object_;
1943 : 439924 : if (no->is_unknown())
1944 : : {
1945 : 439396 : Named_object* real = no->unknown_value()->real_named_object();
1946 : 439396 : if (real == NULL)
1947 : : {
1948 : 46 : if (!this->no_error_message_)
1949 : 45 : go_error_at(loc, "reference to undefined name %qs",
1950 : 90 : no->message_name().c_str());
1951 : 46 : this->set_is_error();
1952 : 46 : return;
1953 : : }
1954 : 439350 : no = real;
1955 : 439350 : this->named_object_ = real;
1956 : : }
1957 : :
1958 : 439878 : switch (no->classification())
1959 : : {
1960 : 91849 : case Named_object::NAMED_OBJECT_TYPE:
1961 : 91849 : this->lowered_ = Expression::make_type(no->type_value(), loc);
1962 : 91849 : break;
1963 : 70720 : case Named_object::NAMED_OBJECT_FUNC:
1964 : 70720 : case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
1965 : 70720 : this->lowered_ = Expression::make_func_reference(no, NULL, loc);
1966 : 70720 : break;
1967 : 256222 : case Named_object::NAMED_OBJECT_CONST:
1968 : 256222 : this->lowered_ = Expression::make_const_reference(no, loc);
1969 : 256222 : this->lowered_->determine_type(gogo, context);
1970 : 256222 : if (this->is_iota_)
1971 : 11 : this->lowered_->const_expression()->set_iota_value(this->iota_value_);
1972 : : break;
1973 : 21087 : case Named_object::NAMED_OBJECT_VAR:
1974 : 21087 : this->lowered_ = Expression::make_var_reference(no, loc);
1975 : 21087 : no->var_value()->set_is_used();
1976 : 21087 : this->lowered_->determine_type(gogo, context);
1977 : 21087 : break;
1978 : 0 : case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
1979 : 0 : if (!this->no_error_message_)
1980 : 0 : go_error_at(this->location(), "reference to undefined type %qs",
1981 : 0 : no->message_name().c_str());
1982 : 0 : this->set_is_error();
1983 : 0 : break;
1984 : 0 : case Named_object::NAMED_OBJECT_PACKAGE:
1985 : 0 : if (!this->no_error_message_)
1986 : 0 : this->report_error(_("unexpected reference to package"));
1987 : 0 : this->set_is_error();
1988 : 0 : break;
1989 : 0 : default:
1990 : 0 : go_unreachable();
1991 : : }
1992 : : }
1993 : :
1994 : : Type*
1995 : 1083592 : Unknown_expression::do_type()
1996 : : {
1997 : 1083592 : if (this->is_error_expression())
1998 : 55 : return Type::make_error_type();
1999 : 1083537 : go_assert(this->lowered_ != NULL);
2000 : 1083537 : return this->lowered_->type();
2001 : : }
2002 : :
2003 : : bool
2004 : 111523 : Unknown_expression::do_is_constant() const
2005 : : {
2006 : 111523 : if (this->is_error_expression())
2007 : : return true;
2008 : 111517 : if (this->lowered_ != NULL)
2009 : 17855 : return this->lowered_->is_constant();
2010 : :
2011 : : // This can be called before do_determine_types by
2012 : : // Binary_expression::do_determine_type, which needs to know which
2013 : : // values are constant before it works out the appropriate
2014 : : // Type_context to pass down.
2015 : 93662 : Named_object* no = this->named_object_;
2016 : 93662 : if (no->is_unknown())
2017 : : {
2018 : 93662 : no = no->unknown_value()->real_named_object();
2019 : 93662 : if (no == NULL)
2020 : : return true;
2021 : : }
2022 : 93657 : return no->is_const();
2023 : : }
2024 : :
2025 : : bool
2026 : 94109 : Unknown_expression::do_is_untyped(Type** ptype) const
2027 : : {
2028 : 94109 : if (this->is_error_expression())
2029 : : return false;
2030 : 94109 : if (this->lowered_ != NULL)
2031 : 0 : return this->lowered_->is_untyped(ptype);
2032 : :
2033 : 94109 : Named_object* no = this->named_object_;
2034 : 94109 : if (no->is_unknown())
2035 : : {
2036 : 94109 : no = no->unknown_value()->real_named_object();
2037 : 94109 : if (no == NULL)
2038 : : return false;
2039 : : }
2040 : :
2041 : 94104 : if (!no->is_const())
2042 : : return false;
2043 : 92809 : Type* t = no->const_value()->type();
2044 : 92809 : if (t != NULL)
2045 : 87680 : return Expression::is_untyped_type(t, ptype);
2046 : 5129 : return no->const_value()->expr()->is_untyped(ptype);
2047 : : }
2048 : :
2049 : : bool
2050 : 69189 : Unknown_expression::do_numeric_constant_value(Numeric_constant* nc)
2051 : : {
2052 : 69189 : if (this->is_error_expression())
2053 : : return false;
2054 : 69189 : if (this->lowered_ != NULL)
2055 : 69117 : return this->lowered_->numeric_constant_value(nc);
2056 : :
2057 : : // This can be called before the determine_types pass.
2058 : 72 : Named_object* no = this->named_object_;
2059 : 72 : if (no->is_unknown())
2060 : : {
2061 : 72 : no = no->unknown_value()->real_named_object();
2062 : 72 : if (no == NULL)
2063 : : return false;
2064 : : }
2065 : 72 : if (!no->is_const())
2066 : : return false;
2067 : 72 : return no->const_value()->expr()->numeric_constant_value(nc);
2068 : : }
2069 : :
2070 : : bool
2071 : 259 : Unknown_expression::do_string_constant_value(std::string* val)
2072 : : {
2073 : 259 : if (this->is_error_expression())
2074 : : return false;
2075 : 259 : go_assert(this->lowered_ != NULL);
2076 : 259 : return this->lowered_->string_constant_value(val);
2077 : : }
2078 : :
2079 : : bool
2080 : 0 : Unknown_expression::do_boolean_constant_value(bool* val)
2081 : : {
2082 : 0 : if (this->is_error_expression())
2083 : : return false;
2084 : 0 : go_assert(this->lowered_ != NULL);
2085 : 0 : return this->lowered_->boolean_constant_value(val);
2086 : : }
2087 : :
2088 : : bool
2089 : 12895 : Unknown_expression::do_is_addressable() const
2090 : : {
2091 : 12895 : if (this->is_error_expression())
2092 : : return true;
2093 : 12893 : go_assert(this->lowered_ != NULL);
2094 : 12893 : return this->lowered_->is_addressable();
2095 : : }
2096 : :
2097 : : // Lower a reference to an unknown name.
2098 : :
2099 : : Expression*
2100 : 358020 : Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
2101 : : {
2102 : 358020 : if (this->is_error_expression())
2103 : 29 : return Expression::make_error(this->location());
2104 : 357991 : go_assert(this->lowered_ != NULL);
2105 : : return this->lowered_;
2106 : : }
2107 : :
2108 : : // Dump the ast representation for an unknown expression to a dump context.
2109 : :
2110 : : void
2111 : 0 : Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2112 : : {
2113 : 0 : if (this->lowered_ != NULL)
2114 : 0 : this->lowered_->dump_expression(ast_dump_context);
2115 : : else
2116 : 0 : ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
2117 : 0 : << ")";
2118 : 0 : }
2119 : :
2120 : : // Make a reference to an unknown name.
2121 : :
2122 : : Unknown_expression*
2123 : 592163 : Expression::make_unknown_reference(Named_object* no, Location location)
2124 : : {
2125 : 592163 : return new Unknown_expression(no, location);
2126 : : }
2127 : :
2128 : : // Start exporting a type conversion for a constant, if needed. This
2129 : : // returns whether we need to export a closing parenthesis.
2130 : :
2131 : : bool
2132 : 65333 : Expression::export_constant_type(Export_function_body* efb, Type* type)
2133 : : {
2134 : 65333 : if (type == NULL
2135 : 61926 : || type->is_abstract()
2136 : 95661 : || type == efb->type_context())
2137 : 51827 : return false;
2138 : 13506 : efb->write_c_string("$convert(");
2139 : 13506 : efb->write_type(type);
2140 : 13506 : efb->write_c_string(", ");
2141 : 13506 : return true;
2142 : : }
2143 : :
2144 : : // Finish a type conversion for a constant.
2145 : :
2146 : : void
2147 : 65333 : Expression::finish_export_constant_type(Export_function_body* efb, bool needed)
2148 : : {
2149 : 65333 : if (needed)
2150 : 13506 : efb->write_c_string(")");
2151 : 65333 : }
2152 : :
2153 : : // A boolean expression.
2154 : :
2155 : : class Boolean_expression : public Expression
2156 : : {
2157 : : public:
2158 : 594722 : Boolean_expression(bool val, Location location)
2159 : 594722 : : Expression(EXPRESSION_BOOLEAN, location),
2160 : 1189444 : val_(val), type_(NULL)
2161 : : { }
2162 : :
2163 : : static Expression*
2164 : : do_import(Import_expression*, Location);
2165 : :
2166 : : protected:
2167 : : int
2168 : : do_traverse(Traverse*);
2169 : :
2170 : : bool
2171 : 24838 : do_is_constant() const
2172 : 24838 : { return true; }
2173 : :
2174 : : bool
2175 : : do_is_untyped(Type**) const;
2176 : :
2177 : : bool
2178 : 0 : do_is_zero_value() const
2179 : 0 : { return this->val_ == false; }
2180 : :
2181 : : bool
2182 : 9479 : do_boolean_constant_value(bool* val)
2183 : : {
2184 : 9479 : *val = this->val_;
2185 : 9479 : return true;
2186 : : }
2187 : :
2188 : : bool
2189 : 11 : do_is_static_initializer() const
2190 : 11 : { return true; }
2191 : :
2192 : : Type*
2193 : : do_type();
2194 : :
2195 : : void
2196 : : do_determine_type(Gogo*, const Type_context*);
2197 : :
2198 : : Expression*
2199 : 0 : do_copy()
2200 : 0 : { return this; }
2201 : :
2202 : : Bexpression*
2203 : 652818 : do_get_backend(Translate_context* context)
2204 : 652818 : { return context->backend()->boolean_constant_expression(this->val_); }
2205 : :
2206 : : int
2207 : 47347 : do_inlining_cost() const
2208 : 47347 : { return 1; }
2209 : :
2210 : : void
2211 : : do_export(Export_function_body* efb) const;
2212 : :
2213 : : void
2214 : 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
2215 : 0 : { ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
2216 : :
2217 : : private:
2218 : : // The constant.
2219 : : bool val_;
2220 : : // The type as determined by context.
2221 : : Type* type_;
2222 : : };
2223 : :
2224 : : // Traverse a boolean expression. We just need to traverse the type
2225 : : // if there is one.
2226 : :
2227 : : int
2228 : 1399297 : Boolean_expression::do_traverse(Traverse* traverse)
2229 : : {
2230 : 1399297 : if (this->type_ != NULL)
2231 : 1364335 : return Type::traverse(this->type_, traverse);
2232 : : return TRAVERSE_CONTINUE;
2233 : : }
2234 : :
2235 : : bool
2236 : 24053 : Boolean_expression::do_is_untyped(Type** ptype) const
2237 : : {
2238 : 24053 : if (this->type_ != NULL)
2239 : 44 : return Expression::is_untyped_type(this->type_, ptype);
2240 : 24009 : *ptype = Type::make_boolean_type();
2241 : 24009 : return true;
2242 : : }
2243 : :
2244 : : // Get the type.
2245 : :
2246 : : Type*
2247 : 1545700 : Boolean_expression::do_type()
2248 : : {
2249 : 1545700 : if (this->type_ == NULL)
2250 : 15257 : this->type_ = Type::make_boolean_type();
2251 : 1545700 : return this->type_;
2252 : : }
2253 : :
2254 : : // Set the type from the context.
2255 : :
2256 : : void
2257 : 656165 : Boolean_expression::do_determine_type(Gogo*, const Type_context* context)
2258 : : {
2259 : 656165 : if (this->type_ != NULL && !this->type_->is_abstract())
2260 : : ;
2261 : 566849 : else if (context->type != NULL && context->type->is_boolean_type())
2262 : 189021 : this->type_ = context->type;
2263 : 377828 : else if (!context->may_be_abstract)
2264 : 377185 : this->type_ = Type::lookup_bool_type();
2265 : 656165 : }
2266 : :
2267 : : // Export a boolean constant.
2268 : :
2269 : : void
2270 : 3836 : Boolean_expression::do_export(Export_function_body* efb) const
2271 : : {
2272 : 3836 : bool exported_type = Expression::export_constant_type(efb, this->type_);
2273 : 5839 : efb->write_c_string(this->val_ ? "$true" : "$false");
2274 : 3836 : Expression::finish_export_constant_type(efb, exported_type);
2275 : 3836 : }
2276 : :
2277 : : // Import a boolean constant.
2278 : :
2279 : : Expression*
2280 : 2859 : Boolean_expression::do_import(Import_expression* imp, Location loc)
2281 : : {
2282 : 2859 : if (imp->version() >= EXPORT_FORMAT_V3)
2283 : 2859 : imp->require_c_string("$");
2284 : 2859 : if (imp->peek_char() == 't')
2285 : : {
2286 : 1370 : imp->require_c_string("true");
2287 : 1370 : return Expression::make_boolean(true, loc);
2288 : : }
2289 : : else
2290 : : {
2291 : 1489 : imp->require_c_string("false");
2292 : 1489 : return Expression::make_boolean(false, loc);
2293 : : }
2294 : : }
2295 : :
2296 : : // Make a boolean expression.
2297 : :
2298 : : Expression*
2299 : 594722 : Expression::make_boolean(bool val, Location location)
2300 : : {
2301 : 594722 : return new Boolean_expression(val, location);
2302 : : }
2303 : :
2304 : : // Class String_expression.
2305 : :
2306 : : // Traverse a string expression. We just need to traverse the type
2307 : : // if there is one.
2308 : :
2309 : : int
2310 : 7998434 : String_expression::do_traverse(Traverse* traverse)
2311 : : {
2312 : 7998434 : if (this->type_ != NULL)
2313 : 7103489 : return Type::traverse(this->type_, traverse);
2314 : : return TRAVERSE_CONTINUE;
2315 : : }
2316 : :
2317 : : bool
2318 : 102798683 : String_expression::do_is_untyped(Type** ptype) const
2319 : : {
2320 : 102798683 : if (this->type_ != NULL)
2321 : 8255 : return Expression::is_untyped_type(this->type_, ptype);
2322 : 102790428 : *ptype = Type::make_string_type();
2323 : 102790428 : return true;
2324 : : }
2325 : :
2326 : : // Get the type.
2327 : :
2328 : : Type*
2329 : 5382376 : String_expression::do_type()
2330 : : {
2331 : 5382376 : if (this->type_ == NULL)
2332 : 17815 : this->type_ = Type::make_string_type();
2333 : 5382376 : return this->type_;
2334 : : }
2335 : :
2336 : : // Set the type from the context.
2337 : :
2338 : : void
2339 : 2323249 : String_expression::do_determine_type(Gogo*, const Type_context* context)
2340 : : {
2341 : 2323249 : if (this->type_ != NULL && !this->type_->is_abstract())
2342 : : ;
2343 : 1586350 : else if (context->type != NULL && context->type->is_string_type())
2344 : 1539768 : this->type_ = context->type;
2345 : 46582 : else if (!context->may_be_abstract)
2346 : 28914 : this->type_ = Type::lookup_string_type();
2347 : 2323249 : }
2348 : :
2349 : : // Build a string constant.
2350 : :
2351 : : Bexpression*
2352 : 1011165 : String_expression::do_get_backend(Translate_context* context)
2353 : : {
2354 : 1011165 : Gogo* gogo = context->gogo();
2355 : 1011165 : Btype* btype = Type::make_string_type()->get_backend(gogo);
2356 : :
2357 : 1011165 : Location loc = this->location();
2358 : 1011165 : std::vector<Bexpression*> init(2);
2359 : :
2360 : 1011165 : if (this->val_.size() == 0)
2361 : 25731 : init[0] = gogo->backend()->nil_pointer_expression();
2362 : : else
2363 : : {
2364 : 985434 : Bexpression* str_cst =
2365 : 985434 : gogo->backend()->string_constant_expression(this->val_);
2366 : 985434 : init[0] = gogo->backend()->address_expression(str_cst, loc);
2367 : : }
2368 : :
2369 : 1011165 : Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo);
2370 : 1011165 : mpz_t lenval;
2371 : 1011165 : mpz_init_set_ui(lenval, this->val_.length());
2372 : 1011165 : init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval);
2373 : 1011165 : mpz_clear(lenval);
2374 : :
2375 : 1011165 : return gogo->backend()->constructor_expression(btype, init, loc);
2376 : 1011165 : }
2377 : :
2378 : : // Write string literal to string dump.
2379 : :
2380 : : void
2381 : 6474 : String_expression::export_string(String_dump* exp,
2382 : : const String_expression* str)
2383 : : {
2384 : 6474 : std::string s;
2385 : 6474 : s.reserve(str->val_.length() * 4 + 2);
2386 : 6474 : s += '"';
2387 : 175078 : for (std::string::const_iterator p = str->val_.begin();
2388 : 175078 : p != str->val_.end();
2389 : 168604 : ++p)
2390 : : {
2391 : 168604 : if (*p == '\\' || *p == '"')
2392 : : {
2393 : 6998 : s += '\\';
2394 : 6998 : s += *p;
2395 : : }
2396 : 161606 : else if (*p >= 0x20 && *p < 0x7f)
2397 : 120717 : s += *p;
2398 : 40889 : else if (*p == '\n')
2399 : 1036 : s += "\\n";
2400 : 39853 : else if (*p == '\t')
2401 : 360 : s += "\\t";
2402 : : else
2403 : : {
2404 : 39493 : s += "\\x";
2405 : 39493 : unsigned char c = *p;
2406 : 39493 : unsigned int dig = c >> 4;
2407 : 39493 : s += dig < 10 ? '0' + dig : 'A' + dig - 10;
2408 : 39493 : dig = c & 0xf;
2409 : 39493 : s += dig < 10 ? '0' + dig : 'A' + dig - 10;
2410 : : }
2411 : : }
2412 : 6474 : s += '"';
2413 : 6474 : exp->write_string(s);
2414 : 6474 : }
2415 : :
2416 : : // Export a string expression.
2417 : :
2418 : : void
2419 : 6474 : String_expression::do_export(Export_function_body* efb) const
2420 : : {
2421 : 6474 : bool exported_type = Expression::export_constant_type(efb, this->type_);
2422 : 6474 : String_expression::export_string(efb, this);
2423 : 6474 : Expression::finish_export_constant_type(efb, exported_type);
2424 : 6474 : }
2425 : :
2426 : : // Import a string expression.
2427 : :
2428 : : Expression*
2429 : 31862 : String_expression::do_import(Import_expression* imp, Location loc)
2430 : : {
2431 : 31862 : imp->require_c_string("\"");
2432 : 31862 : std::string val;
2433 : 633891 : while (true)
2434 : : {
2435 : 633891 : int c = imp->get_char();
2436 : 633891 : if (c == '"' || c == -1)
2437 : : break;
2438 : 602029 : if (c != '\\')
2439 : 555673 : val += static_cast<char>(c);
2440 : : else
2441 : : {
2442 : 46356 : c = imp->get_char();
2443 : 46356 : if (c == '\\' || c == '"')
2444 : 19650 : val += static_cast<char>(c);
2445 : 26706 : else if (c == 'n')
2446 : 1074 : val += '\n';
2447 : 25632 : else if (c == 't')
2448 : 517 : val += '\t';
2449 : 25115 : else if (c == 'x')
2450 : : {
2451 : 25115 : c = imp->get_char();
2452 : 25115 : unsigned int vh = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
2453 : 25115 : c = imp->get_char();
2454 : 25115 : unsigned int vl = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
2455 : 25115 : char v = (vh << 4) | vl;
2456 : 25115 : val += v;
2457 : : }
2458 : : else
2459 : : {
2460 : 0 : go_error_at(imp->location(), "bad string constant");
2461 : 0 : return Expression::make_error(loc);
2462 : : }
2463 : : }
2464 : : }
2465 : 31862 : return Expression::make_string(val, loc);
2466 : 31862 : }
2467 : :
2468 : : // Ast dump for string expression.
2469 : :
2470 : : void
2471 : 0 : String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2472 : : {
2473 : 0 : String_expression::export_string(ast_dump_context, this);
2474 : 0 : }
2475 : :
2476 : : // Make a string expression with abstract string type (common case).
2477 : :
2478 : : Expression*
2479 : 1559244 : Expression::make_string(const std::string& val, Location location)
2480 : : {
2481 : 1559244 : return new String_expression(val, NULL, location);
2482 : : }
2483 : :
2484 : : // Make a string expression with a specific string type.
2485 : :
2486 : : Expression*
2487 : 38286 : Expression::make_string_typed(const std::string& val, Type* type, Location location)
2488 : : {
2489 : 38286 : return new String_expression(val, type, location);
2490 : : }
2491 : :
2492 : : // An expression that evaluates to some characteristic of a string.
2493 : : // This is used when indexing, bound-checking, or nil checking a string.
2494 : :
2495 : : class String_info_expression : public Expression
2496 : : {
2497 : : public:
2498 : 441698 : String_info_expression(Expression* string, String_info string_info,
2499 : : Location location)
2500 : 441698 : : Expression(EXPRESSION_STRING_INFO, location),
2501 : 883396 : string_(string), string_info_(string_info)
2502 : : { }
2503 : :
2504 : : protected:
2505 : : Type*
2506 : : do_type();
2507 : :
2508 : : void
2509 : 755952 : do_determine_type(Gogo*, const Type_context*)
2510 : 755952 : { }
2511 : :
2512 : : Expression*
2513 : 140063 : do_copy()
2514 : : {
2515 : 140063 : return new String_info_expression(this->string_->copy(), this->string_info_,
2516 : 140063 : this->location());
2517 : : }
2518 : :
2519 : : Bexpression*
2520 : : do_get_backend(Translate_context* context);
2521 : :
2522 : : void
2523 : : do_dump_expression(Ast_dump_context*) const;
2524 : :
2525 : : void
2526 : 0 : do_issue_nil_check()
2527 : 0 : { this->string_->issue_nil_check(); }
2528 : :
2529 : : private:
2530 : : // The string for which we are getting information.
2531 : : Expression* string_;
2532 : : // What information we want.
2533 : : String_info string_info_;
2534 : : };
2535 : :
2536 : : // Return the type of the string info.
2537 : :
2538 : : Type*
2539 : 1103159 : String_info_expression::do_type()
2540 : : {
2541 : 1103159 : switch (this->string_info_)
2542 : : {
2543 : 610412 : case STRING_INFO_DATA:
2544 : 610412 : {
2545 : 610412 : Type* byte_type = Type::lookup_integer_type("uint8");
2546 : 610412 : return Type::make_pointer_type(byte_type);
2547 : : }
2548 : 492747 : case STRING_INFO_LENGTH:
2549 : 492747 : return Type::lookup_integer_type("int");
2550 : 0 : default:
2551 : 0 : go_unreachable();
2552 : : }
2553 : : }
2554 : :
2555 : : // Return string information in GENERIC.
2556 : :
2557 : : Bexpression*
2558 : 443347 : String_info_expression::do_get_backend(Translate_context* context)
2559 : : {
2560 : 443347 : Gogo* gogo = context->gogo();
2561 : :
2562 : 443347 : Bexpression* bstring = this->string_->get_backend(context);
2563 : 443347 : switch (this->string_info_)
2564 : : {
2565 : 443347 : case STRING_INFO_DATA:
2566 : 443347 : case STRING_INFO_LENGTH:
2567 : 443347 : return gogo->backend()->struct_field_expression(bstring,
2568 : : this->string_info_,
2569 : 443347 : this->location());
2570 : 0 : break;
2571 : 0 : default:
2572 : 0 : go_unreachable();
2573 : : }
2574 : : }
2575 : :
2576 : : // Dump ast representation for a type info expression.
2577 : :
2578 : : void
2579 : 0 : String_info_expression::do_dump_expression(
2580 : : Ast_dump_context* ast_dump_context) const
2581 : : {
2582 : 0 : ast_dump_context->ostream() << "stringinfo(";
2583 : 0 : this->string_->dump_expression(ast_dump_context);
2584 : 0 : ast_dump_context->ostream() << ",";
2585 : 0 : ast_dump_context->ostream() <<
2586 : 0 : (this->string_info_ == STRING_INFO_DATA ? "data"
2587 : 0 : : this->string_info_ == STRING_INFO_LENGTH ? "length"
2588 : 0 : : "unknown");
2589 : 0 : ast_dump_context->ostream() << ")";
2590 : 0 : }
2591 : :
2592 : : // Make a string info expression.
2593 : :
2594 : : Expression*
2595 : 301635 : Expression::make_string_info(Expression* string, String_info string_info,
2596 : : Location location)
2597 : : {
2598 : 301635 : return new String_info_expression(string, string_info, location);
2599 : : }
2600 : :
2601 : : // An expression that represents an string value: a struct with value pointer
2602 : : // and length fields.
2603 : :
2604 : : class String_value_expression : public Expression
2605 : : {
2606 : : public:
2607 : 1689 : String_value_expression(Expression* valptr, Expression* len, Location location)
2608 : 1689 : : Expression(EXPRESSION_STRING_VALUE, location),
2609 : 3378 : valptr_(valptr), len_(len)
2610 : : { }
2611 : :
2612 : : protected:
2613 : : int
2614 : : do_traverse(Traverse*);
2615 : :
2616 : : Type*
2617 : 0 : do_type()
2618 : 0 : { return Type::make_string_type(); }
2619 : :
2620 : : void
2621 : 0 : do_determine_type(Gogo*, const Type_context*)
2622 : 0 : { go_unreachable(); }
2623 : :
2624 : : Expression*
2625 : 0 : do_copy()
2626 : : {
2627 : 0 : return new String_value_expression(this->valptr_->copy(),
2628 : 0 : this->len_->copy(),
2629 : 0 : this->location());
2630 : : }
2631 : :
2632 : : Bexpression*
2633 : : do_get_backend(Translate_context* context);
2634 : :
2635 : : void
2636 : : do_dump_expression(Ast_dump_context*) const;
2637 : :
2638 : : private:
2639 : : // The value pointer.
2640 : : Expression* valptr_;
2641 : : // The length.
2642 : : Expression* len_;
2643 : : };
2644 : :
2645 : : int
2646 : 0 : String_value_expression::do_traverse(Traverse* traverse)
2647 : : {
2648 : 0 : if (Expression::traverse(&this->valptr_, traverse) == TRAVERSE_EXIT
2649 : 0 : || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT)
2650 : 0 : return TRAVERSE_EXIT;
2651 : : return TRAVERSE_CONTINUE;
2652 : : }
2653 : :
2654 : : Bexpression*
2655 : 1689 : String_value_expression::do_get_backend(Translate_context* context)
2656 : : {
2657 : 1689 : std::vector<Bexpression*> vals(2);
2658 : 1689 : vals[0] = this->valptr_->get_backend(context);
2659 : 1689 : vals[1] = this->len_->get_backend(context);
2660 : :
2661 : 1689 : Gogo* gogo = context->gogo();
2662 : 1689 : Btype* btype = Type::make_string_type()->get_backend(gogo);
2663 : 1689 : return gogo->backend()->constructor_expression(btype, vals, this->location());
2664 : 1689 : }
2665 : :
2666 : : void
2667 : 0 : String_value_expression::do_dump_expression(
2668 : : Ast_dump_context* ast_dump_context) const
2669 : : {
2670 : 0 : ast_dump_context->ostream() << "stringvalue(";
2671 : 0 : ast_dump_context->ostream() << "value: ";
2672 : 0 : this->valptr_->dump_expression(ast_dump_context);
2673 : 0 : ast_dump_context->ostream() << ", length: ";
2674 : 0 : this->len_->dump_expression(ast_dump_context);
2675 : 0 : ast_dump_context->ostream() << ")";
2676 : 0 : }
2677 : :
2678 : : Expression*
2679 : 1689 : Expression::make_string_value(Expression* valptr, Expression* len,
2680 : : Location location)
2681 : : {
2682 : 1689 : return new String_value_expression(valptr, len, location);
2683 : : }
2684 : :
2685 : : // Make an integer expression.
2686 : :
2687 : : class Integer_expression : public Expression
2688 : : {
2689 : : public:
2690 : 8444532 : Integer_expression(const mpz_t* val, Type* type, bool is_character_constant,
2691 : : Location location)
2692 : 8444532 : : Expression(EXPRESSION_INTEGER, location),
2693 : 8444532 : type_(type), is_character_constant_(is_character_constant)
2694 : 8444532 : { mpz_init_set(this->val_, *val); }
2695 : :
2696 : : static Expression*
2697 : : do_import(Import_expression*, Location);
2698 : :
2699 : : // Write VAL to string dump.
2700 : : static void
2701 : : export_integer(String_dump* exp, const mpz_t val);
2702 : :
2703 : : // Write VAL to dump context.
2704 : : static void
2705 : : dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
2706 : :
2707 : : protected:
2708 : : int
2709 : : do_traverse(Traverse*);
2710 : :
2711 : : bool
2712 : 3463170 : do_is_constant() const
2713 : 3463170 : { return true; }
2714 : :
2715 : : bool
2716 : : do_is_untyped(Type**) const;
2717 : :
2718 : : bool
2719 : 448 : do_is_zero_value() const
2720 : 448 : { return mpz_sgn(this->val_) == 0; }
2721 : :
2722 : : bool
2723 : 1537573 : do_is_static_initializer() const
2724 : 1537573 : { return true; }
2725 : :
2726 : : bool
2727 : : do_numeric_constant_value(Numeric_constant* nc);
2728 : :
2729 : : Type*
2730 : : do_type();
2731 : :
2732 : : void
2733 : : do_determine_type(Gogo*, const Type_context* context);
2734 : :
2735 : : void
2736 : : do_check_types(Gogo*);
2737 : :
2738 : : Bexpression*
2739 : : do_get_backend(Translate_context*);
2740 : :
2741 : : Expression*
2742 : 478159 : do_copy()
2743 : : {
2744 : 478159 : if (this->is_character_constant_)
2745 : 241 : return Expression::make_character(&this->val_,
2746 : 121 : (this->type_ == NULL
2747 : : ? NULL
2748 : 120 : : this->type_->copy_expressions()),
2749 : 121 : this->location());
2750 : : else
2751 : 941087 : return Expression::make_integer_z(&this->val_,
2752 : 478038 : (this->type_ == NULL
2753 : : ? NULL
2754 : 463049 : : this->type_->copy_expressions()),
2755 : 478038 : this->location());
2756 : : }
2757 : :
2758 : : int
2759 : 1685992 : do_inlining_cost() const
2760 : 1685992 : { return 1; }
2761 : :
2762 : : void
2763 : : do_export(Export_function_body*) const;
2764 : :
2765 : : void
2766 : : do_dump_expression(Ast_dump_context*) const;
2767 : :
2768 : : private:
2769 : : // The integer value.
2770 : : mpz_t val_;
2771 : : // The type so far.
2772 : : Type* type_;
2773 : : // Whether this is a character constant.
2774 : : bool is_character_constant_;
2775 : : };
2776 : :
2777 : : // Traverse an integer expression. We just need to traverse the type
2778 : : // if there is one.
2779 : :
2780 : : int
2781 : 50625701 : Integer_expression::do_traverse(Traverse* traverse)
2782 : : {
2783 : 50625701 : if (this->type_ != NULL)
2784 : 45821082 : return Type::traverse(this->type_, traverse);
2785 : : return TRAVERSE_CONTINUE;
2786 : : }
2787 : :
2788 : : // Return a numeric constant for this expression. We have to mark
2789 : : // this as a character when appropriate.
2790 : :
2791 : : bool
2792 : 26518185 : Integer_expression::do_numeric_constant_value(Numeric_constant* nc)
2793 : : {
2794 : 26518185 : if (this->is_character_constant_)
2795 : 37209 : nc->set_rune(this->type_, this->val_);
2796 : : else
2797 : 26480976 : nc->set_int(this->type_, this->val_);
2798 : 26518185 : return true;
2799 : : }
2800 : :
2801 : : bool
2802 : 1505004 : Integer_expression::do_is_untyped(Type** ptype) const
2803 : : {
2804 : 1505004 : if (this->type_ != NULL)
2805 : 1195040 : return Expression::is_untyped_type(this->type_, ptype);
2806 : 309964 : if (this->is_character_constant_)
2807 : 16451 : *ptype = Type::make_abstract_character_type();
2808 : : else
2809 : 293513 : *ptype = Type::make_abstract_integer_type();
2810 : : return true;
2811 : : }
2812 : :
2813 : : // Return the current type. If we haven't set the type yet, we return
2814 : : // an abstract integer type.
2815 : :
2816 : : Type*
2817 : 20239908 : Integer_expression::do_type()
2818 : : {
2819 : 20239908 : if (this->type_ == NULL)
2820 : : {
2821 : 796958 : if (this->is_character_constant_)
2822 : 5997 : this->type_ = Type::make_abstract_character_type();
2823 : : else
2824 : 790961 : this->type_ = Type::make_abstract_integer_type();
2825 : : }
2826 : 20239908 : return this->type_;
2827 : : }
2828 : :
2829 : : // Set the type of the integer value. Here we may switch from an
2830 : : // abstract type to a real type.
2831 : :
2832 : : void
2833 : 6692060 : Integer_expression::do_determine_type(Gogo*, const Type_context* context)
2834 : : {
2835 : 6692060 : if (this->type_ != NULL && !this->type_->is_abstract())
2836 : : ;
2837 : 2470616 : else if (context->type != NULL && context->type->is_numeric_type())
2838 : 1647335 : this->type_ = context->type;
2839 : 823281 : else if (!context->may_be_abstract)
2840 : : {
2841 : 41910 : if (this->is_character_constant_)
2842 : 361 : this->type_ = Type::lookup_integer_type("int32");
2843 : : else
2844 : 41549 : this->type_ = Type::lookup_integer_type("int");
2845 : : }
2846 : 6692060 : }
2847 : :
2848 : : // Check the type of an integer constant.
2849 : :
2850 : : void
2851 : 2448539 : Integer_expression::do_check_types(Gogo*)
2852 : : {
2853 : 2448539 : Type* type = this->type_;
2854 : 2448539 : if (type == NULL)
2855 : 1 : return;
2856 : 2448538 : Numeric_constant nc;
2857 : 2448538 : if (this->is_character_constant_)
2858 : 54823 : nc.set_rune(NULL, this->val_);
2859 : : else
2860 : 2393715 : nc.set_int(NULL, this->val_);
2861 : 2448538 : if (!nc.set_type(type, true, this->location()))
2862 : 28 : this->set_is_error();
2863 : 2448538 : }
2864 : :
2865 : : // Get the backend representation for an integer constant.
2866 : :
2867 : : Bexpression*
2868 : 6025703 : Integer_expression::do_get_backend(Translate_context* context)
2869 : : {
2870 : 6025703 : if (this->is_error_expression()
2871 : 6025703 : || (this->type_ != NULL && this->type_->is_error_type()))
2872 : : {
2873 : 0 : go_assert(saw_errors());
2874 : 0 : return context->gogo()->backend()->error_expression();
2875 : : }
2876 : :
2877 : 6025703 : Type* resolved_type = NULL;
2878 : 6025703 : if (this->type_ != NULL && !this->type_->is_abstract())
2879 : 5980191 : resolved_type = this->type_;
2880 : 45512 : else if (this->type_ != NULL && this->type_->float_type() != NULL)
2881 : : {
2882 : : // We are converting to an abstract floating point type.
2883 : 0 : resolved_type = Type::lookup_float_type("float64");
2884 : : }
2885 : 45512 : else if (this->type_ != NULL && this->type_->complex_type() != NULL)
2886 : : {
2887 : : // We are converting to an abstract complex type.
2888 : 0 : resolved_type = Type::lookup_complex_type("complex128");
2889 : : }
2890 : : else
2891 : : {
2892 : : // If we still have an abstract type here, then this is being
2893 : : // used in a constant expression which didn't get reduced for
2894 : : // some reason. Use a type which will fit the value. We use <,
2895 : : // not <=, because we need an extra bit for the sign bit.
2896 : 45512 : int bits = mpz_sizeinbase(this->val_, 2);
2897 : 45512 : Type* int_type = Type::lookup_integer_type("int");
2898 : 91024 : if (bits < int_type->integer_type()->bits())
2899 : : resolved_type = int_type;
2900 : 1 : else if (bits < 64)
2901 : 0 : resolved_type = Type::lookup_integer_type("int64");
2902 : : else
2903 : : {
2904 : 1 : if (!saw_errors())
2905 : 1 : go_error_at(this->location(), "integer constant overflow");
2906 : 1 : return context->gogo()->backend()->error_expression();
2907 : : }
2908 : : }
2909 : 6025702 : Numeric_constant nc;
2910 : 6025702 : nc.set_int(resolved_type, this->val_);
2911 : 6025702 : return Expression::backend_numeric_constant_expression(context, &nc);
2912 : 6025702 : }
2913 : :
2914 : : // Write VAL to export data.
2915 : :
2916 : : void
2917 : 54449 : Integer_expression::export_integer(String_dump* exp, const mpz_t val)
2918 : : {
2919 : 54449 : char* s = mpz_get_str(NULL, 10, val);
2920 : 54449 : exp->write_c_string(s);
2921 : 54449 : free(s);
2922 : 54449 : }
2923 : :
2924 : : // Export an integer in a constant expression.
2925 : :
2926 : : void
2927 : 54449 : Integer_expression::do_export(Export_function_body* efb) const
2928 : : {
2929 : 54449 : bool exported_type = Expression::export_constant_type(efb, this->type_);
2930 : :
2931 : 54449 : Integer_expression::export_integer(efb, this->val_);
2932 : 54449 : if (this->is_character_constant_)
2933 : 1421 : efb->write_c_string("'");
2934 : : // A trailing space lets us reliably identify the end of the number.
2935 : 54449 : efb->write_c_string(" ");
2936 : :
2937 : 54449 : Expression::finish_export_constant_type(efb, exported_type);
2938 : 54449 : }
2939 : :
2940 : : // Import an integer, floating point, or complex value. This handles
2941 : : // all these types because they all start with digits.
2942 : :
2943 : : Expression*
2944 : 962656 : Integer_expression::do_import(Import_expression* imp, Location loc)
2945 : : {
2946 : 962656 : std::string num = imp->read_identifier();
2947 : 962656 : imp->require_c_string(" ");
2948 : 962656 : if (!num.empty() && num[num.length() - 1] == 'i')
2949 : : {
2950 : 3 : mpfr_t real;
2951 : 3 : size_t plus_pos = num.find('+', 1);
2952 : 3 : size_t minus_pos = num.find('-', 1);
2953 : 3 : size_t pos;
2954 : 3 : if (plus_pos == std::string::npos)
2955 : : pos = minus_pos;
2956 : 2 : else if (minus_pos == std::string::npos)
2957 : : pos = plus_pos;
2958 : : else
2959 : : {
2960 : 0 : go_error_at(imp->location(), "bad number in import data: %qs",
2961 : : num.c_str());
2962 : 0 : return Expression::make_error(loc);
2963 : : }
2964 : 3 : if (pos == std::string::npos)
2965 : 0 : mpfr_init_set_ui(real, 0, MPFR_RNDN);
2966 : : else
2967 : : {
2968 : 3 : std::string real_str = num.substr(0, pos);
2969 : 3 : if (mpfr_init_set_str(real, real_str.c_str(), 10, MPFR_RNDN) != 0)
2970 : : {
2971 : 0 : go_error_at(imp->location(), "bad number in import data: %qs",
2972 : : real_str.c_str());
2973 : 0 : return Expression::make_error(loc);
2974 : : }
2975 : 3 : }
2976 : :
2977 : 3 : std::string imag_str;
2978 : 3 : if (pos == std::string::npos)
2979 : 0 : imag_str = num;
2980 : : else
2981 : 3 : imag_str = num.substr(pos);
2982 : 3 : imag_str = imag_str.substr(0, imag_str.size() - 1);
2983 : 3 : mpfr_t imag;
2984 : 3 : if (mpfr_init_set_str(imag, imag_str.c_str(), 10, MPFR_RNDN) != 0)
2985 : : {
2986 : 0 : go_error_at(imp->location(), "bad number in import data: %qs",
2987 : : imag_str.c_str());
2988 : 0 : return Expression::make_error(loc);
2989 : : }
2990 : 3 : mpc_t cval;
2991 : 3 : mpc_init2(cval, mpc_precision);
2992 : 3 : mpc_set_fr_fr(cval, real, imag, MPC_RNDNN);
2993 : 3 : mpfr_clear(real);
2994 : 3 : mpfr_clear(imag);
2995 : 3 : Expression* ret = Expression::make_complex(&cval, NULL, loc);
2996 : 3 : mpc_clear(cval);
2997 : 3 : return ret;
2998 : 3 : }
2999 : 962653 : else if (num.find('.') == std::string::npos
3000 : 962653 : && num.find('E') == std::string::npos)
3001 : : {
3002 : 958400 : bool is_character_constant = (!num.empty()
3003 : 958400 : && num[num.length() - 1] == '\'');
3004 : 6646 : if (is_character_constant)
3005 : 6646 : num = num.substr(0, num.length() - 1);
3006 : 958400 : mpz_t val;
3007 : 958400 : if (mpz_init_set_str(val, num.c_str(), 10) != 0)
3008 : : {
3009 : 0 : go_error_at(imp->location(), "bad number in import data: %qs",
3010 : : num.c_str());
3011 : 0 : return Expression::make_error(loc);
3012 : : }
3013 : 958400 : Expression* ret;
3014 : 958400 : if (is_character_constant)
3015 : 6646 : ret = Expression::make_character(&val, NULL, loc);
3016 : : else
3017 : 951754 : ret = Expression::make_integer_z(&val, NULL, loc);
3018 : 958400 : mpz_clear(val);
3019 : 958400 : return ret;
3020 : : }
3021 : : else
3022 : : {
3023 : 4253 : mpfr_t val;
3024 : 4253 : if (mpfr_init_set_str(val, num.c_str(), 10, MPFR_RNDN) != 0)
3025 : : {
3026 : 0 : go_error_at(imp->location(), "bad number in import data: %qs",
3027 : : num.c_str());
3028 : 0 : return Expression::make_error(loc);
3029 : : }
3030 : 4253 : Expression* ret = Expression::make_float(&val, NULL, loc);
3031 : 4253 : mpfr_clear(val);
3032 : 4253 : return ret;
3033 : : }
3034 : 962656 : }
3035 : : // Ast dump for integer expression.
3036 : :
3037 : : void
3038 : 0 : Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3039 : : {
3040 : 0 : if (this->is_character_constant_)
3041 : 0 : ast_dump_context->ostream() << '\'';
3042 : 0 : Integer_expression::export_integer(ast_dump_context, this->val_);
3043 : 0 : if (this->is_character_constant_)
3044 : 0 : ast_dump_context->ostream() << '\'';
3045 : 0 : }
3046 : :
3047 : : // Build a new integer value from a multi-precision integer.
3048 : :
3049 : : Expression*
3050 : 8384348 : Expression::make_integer_z(const mpz_t* val, Type* type, Location location)
3051 : : {
3052 : 8384348 : return new Integer_expression(val, type, false, location);
3053 : : }
3054 : :
3055 : : // Build a new integer value from an unsigned long.
3056 : :
3057 : : Expression*
3058 : 4213265 : Expression::make_integer_ul(unsigned long val, Type *type, Location location)
3059 : : {
3060 : 4213265 : mpz_t zval;
3061 : 4213265 : mpz_init_set_ui(zval, val);
3062 : 4213265 : Expression* ret = Expression::make_integer_z(&zval, type, location);
3063 : 4213265 : mpz_clear(zval);
3064 : 4213265 : return ret;
3065 : : }
3066 : :
3067 : : // Build a new integer value from a signed long.
3068 : :
3069 : : Expression*
3070 : 16515 : Expression::make_integer_sl(long val, Type *type, Location location)
3071 : : {
3072 : 16515 : mpz_t zval;
3073 : 16515 : mpz_init_set_si(zval, val);
3074 : 16515 : Expression* ret = Expression::make_integer_z(&zval, type, location);
3075 : 16515 : mpz_clear(zval);
3076 : 16515 : return ret;
3077 : : }
3078 : :
3079 : : // Store an int64_t in an uninitialized mpz_t.
3080 : :
3081 : : static void
3082 : 1219058 : set_mpz_from_int64(mpz_t* zval, int64_t val)
3083 : : {
3084 : 1219058 : if (val >= 0)
3085 : : {
3086 : 1219058 : unsigned long ul = static_cast<unsigned long>(val);
3087 : 1219058 : if (static_cast<int64_t>(ul) == val)
3088 : : {
3089 : 1219058 : mpz_init_set_ui(*zval, ul);
3090 : 1219058 : return;
3091 : : }
3092 : : }
3093 : 0 : uint64_t uv;
3094 : 0 : if (val >= 0)
3095 : : uv = static_cast<uint64_t>(val);
3096 : : else
3097 : 0 : uv = static_cast<uint64_t>(- val);
3098 : 0 : unsigned long ul = uv & 0xffffffffUL;
3099 : 0 : mpz_init_set_ui(*zval, ul);
3100 : 0 : mpz_t hval;
3101 : 0 : mpz_init_set_ui(hval, static_cast<unsigned long>(uv >> 32));
3102 : 0 : mpz_mul_2exp(hval, hval, 32);
3103 : 0 : mpz_add(*zval, *zval, hval);
3104 : 0 : mpz_clear(hval);
3105 : 0 : if (val < 0)
3106 : 0 : mpz_neg(*zval, *zval);
3107 : : }
3108 : :
3109 : : // Build a new integer value from an int64_t.
3110 : :
3111 : : Expression*
3112 : 1216932 : Expression::make_integer_int64(int64_t val, Type* type, Location location)
3113 : : {
3114 : 1216932 : mpz_t zval;
3115 : 1216932 : set_mpz_from_int64(&zval, val);
3116 : 1216932 : Expression* ret = Expression::make_integer_z(&zval, type, location);
3117 : 1216932 : mpz_clear(zval);
3118 : 1216932 : return ret;
3119 : : }
3120 : :
3121 : : // Build a new character constant value.
3122 : :
3123 : : Expression*
3124 : 60184 : Expression::make_character(const mpz_t* val, Type* type, Location location)
3125 : : {
3126 : 60184 : return new Integer_expression(val, type, true, location);
3127 : : }
3128 : :
3129 : : // Floats.
3130 : :
3131 : : class Float_expression : public Expression
3132 : : {
3133 : : public:
3134 : 32243 : Float_expression(const mpfr_t* val, Type* type, Location location)
3135 : 32243 : : Expression(EXPRESSION_FLOAT, location),
3136 : 32243 : type_(type)
3137 : : {
3138 : 32243 : mpfr_init_set(this->val_, *val, MPFR_RNDN);
3139 : 32243 : }
3140 : :
3141 : : // Write VAL to export data.
3142 : : static void
3143 : : export_float(String_dump* exp, const mpfr_t val);
3144 : :
3145 : : // Write VAL to dump file.
3146 : : static void
3147 : : dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
3148 : :
3149 : : protected:
3150 : : int
3151 : : do_traverse(Traverse*);
3152 : :
3153 : : bool
3154 : 17418 : do_is_constant() const
3155 : 17418 : { return true; }
3156 : :
3157 : : bool
3158 : : do_is_untyped(Type**) const;
3159 : :
3160 : : bool
3161 : 4 : do_is_zero_value() const
3162 : : {
3163 : 4 : return mpfr_zero_p(this->val_) != 0
3164 : 4 : && mpfr_signbit(this->val_) == 0;
3165 : : }
3166 : :
3167 : : bool
3168 : 13963 : do_is_static_initializer() const
3169 : 13963 : { return true; }
3170 : :
3171 : : bool
3172 : 20066 : do_numeric_constant_value(Numeric_constant* nc)
3173 : : {
3174 : 20066 : nc->set_float(this->type_, this->val_);
3175 : 20066 : return true;
3176 : : }
3177 : :
3178 : : Type*
3179 : : do_type();
3180 : :
3181 : : void
3182 : : do_determine_type(Gogo*, const Type_context*);
3183 : :
3184 : : void
3185 : : do_check_types(Gogo*);
3186 : :
3187 : : Expression*
3188 : 73 : do_copy()
3189 : 144 : { return Expression::make_float(&this->val_,
3190 : 73 : (this->type_ == NULL
3191 : : ? NULL
3192 : 71 : : this->type_->copy_expressions()),
3193 : 73 : this->location()); }
3194 : :
3195 : : Bexpression*
3196 : : do_get_backend(Translate_context*);
3197 : :
3198 : : int
3199 : 4765 : do_inlining_cost() const
3200 : 4765 : { return 1; }
3201 : :
3202 : : void
3203 : : do_export(Export_function_body*) const;
3204 : :
3205 : : void
3206 : : do_dump_expression(Ast_dump_context*) const;
3207 : :
3208 : : private:
3209 : : // The floating point value.
3210 : : mpfr_t val_;
3211 : : // The type so far.
3212 : : Type* type_;
3213 : : };
3214 : :
3215 : : // Traverse a float expression. We just need to traverse the type if
3216 : : // there is one.
3217 : :
3218 : : int
3219 : 431792 : Float_expression::do_traverse(Traverse* traverse)
3220 : : {
3221 : 431792 : if (this->type_ != NULL)
3222 : 385194 : return Type::traverse(this->type_, traverse);
3223 : : return TRAVERSE_CONTINUE;
3224 : : }
3225 : :
3226 : : bool
3227 : 7828 : Float_expression::do_is_untyped(Type** ptype) const
3228 : : {
3229 : 7828 : if (this->type_ != NULL)
3230 : 130 : return Expression::is_untyped_type(this->type_, ptype);
3231 : 7698 : *ptype = Type::make_abstract_float_type();
3232 : 7698 : return true;
3233 : : }
3234 : :
3235 : : // Return the current type. If we haven't set the type yet, we return
3236 : : // an abstract float type.
3237 : :
3238 : : Type*
3239 : 149905 : Float_expression::do_type()
3240 : : {
3241 : 149905 : if (this->type_ == NULL)
3242 : 8272 : this->type_ = Type::make_abstract_float_type();
3243 : 149905 : return this->type_;
3244 : : }
3245 : :
3246 : : // Set the type of the float value. Here we may switch from an
3247 : : // abstract type to a real type.
3248 : :
3249 : : void
3250 : 31815 : Float_expression::do_determine_type(Gogo*, const Type_context* context)
3251 : : {
3252 : 31815 : if (this->type_ != NULL && !this->type_->is_abstract())
3253 : : ;
3254 : 26734 : else if (context->type != NULL
3255 : 26734 : && (context->type->integer_type() != NULL
3256 : 33750 : || context->type->float_type() != NULL
3257 : 18531 : || context->type->complex_type() != NULL))
3258 : 17567 : this->type_ = context->type;
3259 : 9167 : else if (!context->may_be_abstract)
3260 : 895 : this->type_ = Type::lookup_float_type("float64");
3261 : 31815 : }
3262 : :
3263 : : // Check the type of a float value.
3264 : :
3265 : : void
3266 : 26516 : Float_expression::do_check_types(Gogo*)
3267 : : {
3268 : 26516 : Type* type = this->type_;
3269 : 26516 : if (type == NULL)
3270 : 1 : return;
3271 : 26515 : Numeric_constant nc;
3272 : 26515 : nc.set_float(NULL, this->val_);
3273 : 26515 : if (!nc.set_type(this->type_, true, this->location()))
3274 : 55 : this->set_is_error();
3275 : 26515 : }
3276 : :
3277 : : // Get the backend representation for a float constant.
3278 : :
3279 : : Bexpression*
3280 : 20531 : Float_expression::do_get_backend(Translate_context* context)
3281 : : {
3282 : 20531 : if (this->is_error_expression()
3283 : 20531 : || (this->type_ != NULL && this->type_->is_error_type()))
3284 : : {
3285 : 0 : go_assert(saw_errors());
3286 : 0 : return context->gogo()->backend()->error_expression();
3287 : : }
3288 : :
3289 : 20531 : Type* resolved_type;
3290 : 20531 : if (this->type_ != NULL && !this->type_->is_abstract())
3291 : 20512 : resolved_type = this->type_;
3292 : 19 : else if (this->type_ != NULL && this->type_->integer_type() != NULL)
3293 : : {
3294 : : // We have an abstract integer type. We just hope for the best.
3295 : 0 : resolved_type = Type::lookup_integer_type("int");
3296 : : }
3297 : 19 : else if (this->type_ != NULL && this->type_->complex_type() != NULL)
3298 : : {
3299 : : // We are converting to an abstract complex type.
3300 : 0 : resolved_type = Type::lookup_complex_type("complex128");
3301 : : }
3302 : : else
3303 : : {
3304 : : // If we still have an abstract type here, then this is being
3305 : : // used in a constant expression which didn't get reduced. We
3306 : : // just use float64 and hope for the best.
3307 : 19 : resolved_type = Type::lookup_float_type("float64");
3308 : : }
3309 : :
3310 : 20531 : Numeric_constant nc;
3311 : 20531 : nc.set_float(resolved_type, this->val_);
3312 : 20531 : return Expression::backend_numeric_constant_expression(context, &nc);
3313 : 20531 : }
3314 : :
3315 : : // Write a floating point number to a string dump.
3316 : :
3317 : : void
3318 : 593 : Float_expression::export_float(String_dump *exp, const mpfr_t val)
3319 : : {
3320 : 593 : mpfr_exp_t exponent;
3321 : 593 : char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, MPFR_RNDN);
3322 : 593 : if (*s == '-')
3323 : 53 : exp->write_c_string("-");
3324 : 593 : exp->write_c_string("0.");
3325 : 593 : exp->write_c_string(*s == '-' ? s + 1 : s);
3326 : 593 : mpfr_free_str(s);
3327 : 593 : char buf[30];
3328 : 593 : snprintf(buf, sizeof buf, "E%ld", exponent);
3329 : 593 : exp->write_c_string(buf);
3330 : 593 : }
3331 : :
3332 : : // Export a floating point number in a constant expression.
3333 : :
3334 : : void
3335 : 549 : Float_expression::do_export(Export_function_body* efb) const
3336 : : {
3337 : 549 : bool exported_type = Expression::export_constant_type(efb, this->type_);
3338 : :
3339 : 549 : Float_expression::export_float(efb, this->val_);
3340 : : // A trailing space lets us reliably identify the end of the number.
3341 : 549 : efb->write_c_string(" ");
3342 : :
3343 : 549 : Expression::finish_export_constant_type(efb, exported_type);
3344 : 549 : }
3345 : :
3346 : : // Dump a floating point number to the dump file.
3347 : :
3348 : : void
3349 : 0 : Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3350 : : {
3351 : 0 : Float_expression::export_float(ast_dump_context, this->val_);
3352 : 0 : }
3353 : :
3354 : : // Make a float expression.
3355 : :
3356 : : Expression*
3357 : 32243 : Expression::make_float(const mpfr_t* val, Type* type, Location location)
3358 : : {
3359 : 32243 : return new Float_expression(val, type, location);
3360 : : }
3361 : :
3362 : : // Complex numbers.
3363 : :
3364 : : class Complex_expression : public Expression
3365 : : {
3366 : : public:
3367 : 3600 : Complex_expression(const mpc_t* val, Type* type, Location location)
3368 : 3600 : : Expression(EXPRESSION_COMPLEX, location),
3369 : 3600 : type_(type)
3370 : : {
3371 : 3600 : mpc_init2(this->val_, mpc_precision);
3372 : 3600 : mpc_set(this->val_, *val, MPC_RNDNN);
3373 : 3600 : }
3374 : :
3375 : : // Write VAL to string dump.
3376 : : static void
3377 : : export_complex(String_dump* exp, const mpc_t val);
3378 : :
3379 : : // Write REAL/IMAG to dump context.
3380 : : static void
3381 : : dump_complex(Ast_dump_context* ast_dump_context, const mpc_t val);
3382 : :
3383 : : protected:
3384 : : int
3385 : : do_traverse(Traverse*);
3386 : :
3387 : : bool
3388 : 1594 : do_is_constant() const
3389 : 1594 : { return true; }
3390 : :
3391 : : bool
3392 : : do_is_untyped(Type**) const;
3393 : :
3394 : : bool
3395 : 4 : do_is_zero_value() const
3396 : : {
3397 : 4 : return mpfr_zero_p(mpc_realref(this->val_)) != 0
3398 : 0 : && mpfr_signbit(mpc_realref(this->val_)) == 0
3399 : 0 : && mpfr_zero_p(mpc_imagref(this->val_)) != 0
3400 : 4 : && mpfr_signbit(mpc_imagref(this->val_)) == 0;
3401 : : }
3402 : :
3403 : : bool
3404 : 1688 : do_is_static_initializer() const
3405 : 1688 : { return true; }
3406 : :
3407 : : bool
3408 : 1251 : do_numeric_constant_value(Numeric_constant* nc)
3409 : : {
3410 : 1251 : nc->set_complex(this->type_, this->val_);
3411 : 1251 : return true;
3412 : : }
3413 : :
3414 : : Type*
3415 : : do_type();
3416 : :
3417 : : void
3418 : : do_determine_type(Gogo*, const Type_context*);
3419 : :
3420 : : void
3421 : : do_check_types(Gogo*);
3422 : :
3423 : : Expression*
3424 : 12 : do_copy()
3425 : : {
3426 : 24 : return Expression::make_complex(&this->val_,
3427 : 12 : (this->type_ == NULL
3428 : : ? NULL
3429 : 12 : : this->type_->copy_expressions()),
3430 : 12 : this->location());
3431 : : }
3432 : :
3433 : : Bexpression*
3434 : : do_get_backend(Translate_context*);
3435 : :
3436 : : int
3437 : 125 : do_inlining_cost() const
3438 : 125 : { return 2; }
3439 : :
3440 : : void
3441 : : do_export(Export_function_body*) const;
3442 : :
3443 : : void
3444 : : do_dump_expression(Ast_dump_context*) const;
3445 : :
3446 : : private:
3447 : : // The complex value.
3448 : : mpc_t val_;
3449 : : // The type if known.
3450 : : Type* type_;
3451 : : };
3452 : :
3453 : : // Traverse a complex expression. We just need to traverse the type
3454 : : // if there is one.
3455 : :
3456 : : int
3457 : 43990 : Complex_expression::do_traverse(Traverse* traverse)
3458 : : {
3459 : 43990 : if (this->type_ != NULL)
3460 : 42004 : return Type::traverse(this->type_, traverse);
3461 : : return TRAVERSE_CONTINUE;
3462 : : }
3463 : :
3464 : : bool
3465 : 945 : Complex_expression::do_is_untyped(Type** ptype) const
3466 : : {
3467 : 945 : if (this->type_ != NULL)
3468 : 25 : return Expression::is_untyped_type(this->type_, ptype);
3469 : 920 : *ptype = Type::make_abstract_complex_type();
3470 : 920 : return true;
3471 : : }
3472 : :
3473 : : // Return the current type. If we haven't set the type yet, we return
3474 : : // an abstract complex type.
3475 : :
3476 : : Type*
3477 : 18583 : Complex_expression::do_type()
3478 : : {
3479 : 18583 : if (this->type_ == NULL)
3480 : 21 : this->type_ = Type::make_abstract_complex_type();
3481 : 18583 : return this->type_;
3482 : : }
3483 : :
3484 : : // Set the type of the complex value. Here we may switch from an
3485 : : // abstract type to a real type.
3486 : :
3487 : : void
3488 : 5406 : Complex_expression::do_determine_type(Gogo*, const Type_context* context)
3489 : : {
3490 : 5406 : if (this->type_ != NULL && !this->type_->is_abstract())
3491 : : ;
3492 : 1837 : else if (context->type != NULL && context->type->is_numeric_type())
3493 : 1768 : this->type_ = context->type;
3494 : 69 : else if (!context->may_be_abstract)
3495 : 48 : this->type_ = Type::lookup_complex_type("complex128");
3496 : 5406 : }
3497 : :
3498 : : // Check the type of a complex value.
3499 : :
3500 : : void
3501 : 1854 : Complex_expression::do_check_types(Gogo*)
3502 : : {
3503 : 1854 : Type* type = this->type_;
3504 : 1854 : if (type == NULL)
3505 : 0 : return;
3506 : 1854 : Numeric_constant nc;
3507 : 1854 : nc.set_complex(NULL, this->val_);
3508 : 1854 : if (!nc.set_type(this->type_, true, this->location()))
3509 : 4 : this->set_is_error();
3510 : 1854 : }
3511 : :
3512 : : // Get the backend representation for a complex constant.
3513 : :
3514 : : Bexpression*
3515 : 2529 : Complex_expression::do_get_backend(Translate_context* context)
3516 : : {
3517 : 2529 : if (this->is_error_expression()
3518 : 2529 : || (this->type_ != NULL && this->type_->is_error_type()))
3519 : : {
3520 : 0 : go_assert(saw_errors());
3521 : 0 : return context->gogo()->backend()->error_expression();
3522 : : }
3523 : :
3524 : 2529 : Type* resolved_type;
3525 : 2529 : if (this->type_ != NULL && !this->type_->is_abstract())
3526 : 2507 : resolved_type = this->type_;
3527 : 22 : else if (this->type_ != NULL && this->type_->integer_type() != NULL)
3528 : : {
3529 : : // We are converting to an abstract integer type.
3530 : 0 : resolved_type = Type::lookup_integer_type("int");
3531 : : }
3532 : 22 : else if (this->type_ != NULL && this->type_->float_type() != NULL)
3533 : : {
3534 : : // We are converting to an abstract float type.
3535 : 0 : resolved_type = Type::lookup_float_type("float64");
3536 : : }
3537 : : else
3538 : : {
3539 : : // If we still have an abstract type here, this is being
3540 : : // used in a constant expression which didn't get reduced. We
3541 : : // just use complex128 and hope for the best.
3542 : 22 : resolved_type = Type::lookup_complex_type("complex128");
3543 : : }
3544 : :
3545 : 2529 : Numeric_constant nc;
3546 : 2529 : nc.set_complex(resolved_type, this->val_);
3547 : 2529 : return Expression::backend_numeric_constant_expression(context, &nc);
3548 : 2529 : }
3549 : :
3550 : : // Write REAL/IMAG to export data.
3551 : :
3552 : : void
3553 : 25 : Complex_expression::export_complex(String_dump* exp, const mpc_t val)
3554 : : {
3555 : 25 : if (!mpfr_zero_p(mpc_realref(val)))
3556 : : {
3557 : 19 : Float_expression::export_float(exp, mpc_realref(val));
3558 : 19 : if (mpfr_sgn(mpc_imagref(val)) >= 0)
3559 : 14 : exp->write_c_string("+");
3560 : : }
3561 : 25 : Float_expression::export_float(exp, mpc_imagref(val));
3562 : 25 : exp->write_c_string("i");
3563 : 25 : }
3564 : :
3565 : : // Export a complex number in a constant expression.
3566 : :
3567 : : void
3568 : 25 : Complex_expression::do_export(Export_function_body* efb) const
3569 : : {
3570 : 25 : bool exported_type = Expression::export_constant_type(efb, this->type_);
3571 : :
3572 : 25 : Complex_expression::export_complex(efb, this->val_);
3573 : : // A trailing space lets us reliably identify the end of the number.
3574 : 25 : efb->write_c_string(" ");
3575 : :
3576 : 25 : Expression::finish_export_constant_type(efb, exported_type);
3577 : 25 : }
3578 : :
3579 : : // Dump a complex expression to the dump file.
3580 : :
3581 : : void
3582 : 0 : Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3583 : : {
3584 : 0 : Complex_expression::export_complex(ast_dump_context, this->val_);
3585 : 0 : }
3586 : :
3587 : : // Make a complex expression.
3588 : :
3589 : : Expression*
3590 : 3600 : Expression::make_complex(const mpc_t* val, Type* type, Location location)
3591 : : {
3592 : 3600 : return new Complex_expression(val, type, location);
3593 : : }
3594 : :
3595 : : // Find a named object in an expression.
3596 : :
3597 : 416020 : class Find_named_object : public Traverse
3598 : : {
3599 : : public:
3600 : 416020 : Find_named_object(Named_object* no)
3601 : 416020 : : Traverse(traverse_expressions),
3602 : 416020 : no_(no), found_(false)
3603 : : { }
3604 : :
3605 : : // Whether we found the object.
3606 : : bool
3607 : 416020 : found() const
3608 : 416020 : { return this->found_; }
3609 : :
3610 : : protected:
3611 : : int
3612 : : expression(Expression**);
3613 : :
3614 : : private:
3615 : : // The object we are looking for.
3616 : : Named_object* no_;
3617 : : // Whether we found it.
3618 : : bool found_;
3619 : : };
3620 : :
3621 : : // Class Const_expression.
3622 : :
3623 : : // Traversal.
3624 : :
3625 : : int
3626 : 7785763 : Const_expression::do_traverse(Traverse* traverse)
3627 : : {
3628 : 7785763 : if (this->type_ != NULL)
3629 : 7442238 : return Type::traverse(this->type_, traverse);
3630 : : return TRAVERSE_CONTINUE;
3631 : : }
3632 : :
3633 : : // Whether this is the zero value.
3634 : :
3635 : : bool
3636 : 32 : Const_expression::do_is_zero_value() const
3637 : : {
3638 : 32 : return this->constant_->const_value()->expr()->is_zero_value();
3639 : : }
3640 : :
3641 : : // Lower a constant expression. This is where we convert the
3642 : : // predeclared constant iota into an integer value.
3643 : :
3644 : : Expression*
3645 : 1202891 : Const_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*)
3646 : : {
3647 : 1202891 : Location loc = this->location();
3648 : :
3649 : 1202891 : if (this->is_error_expression())
3650 : 874 : return Expression::make_error(loc);
3651 : 1202017 : if (this->constant_->const_value()->expr()->is_error_expression())
3652 : 191 : return Expression::make_error(loc);
3653 : :
3654 : 1201826 : if (this->is_iota_)
3655 : 10365 : return Expression::make_integer_ul(this->iota_value_, NULL, loc);
3656 : :
3657 : : // Make sure that the constant itself has been lowered.
3658 : 1191461 : gogo->lower_constant(this->constant_);
3659 : :
3660 : 1191461 : return this;
3661 : : }
3662 : :
3663 : : // Return a numeric constant value.
3664 : :
3665 : : bool
3666 : 548843 : Const_expression::do_numeric_constant_value(Numeric_constant* nc)
3667 : : {
3668 : 548843 : if (this->seen_)
3669 : : return false;
3670 : :
3671 : 548843 : Type* ctype;
3672 : 548843 : if (this->type_ != NULL)
3673 : : ctype = this->type_;
3674 : : else
3675 : 234 : ctype = this->constant_->const_value()->type();
3676 : :
3677 : 548843 : if (this->is_iota_)
3678 : : {
3679 : 54473 : nc->set_unsigned_long(ctype,
3680 : 54473 : static_cast<unsigned long>(this->iota_value_));
3681 : 54473 : return true;
3682 : : }
3683 : :
3684 : 494370 : Expression* e = this->constant_->const_value()->expr();
3685 : :
3686 : 494370 : this->seen_ = true;
3687 : :
3688 : 494370 : bool r = e->numeric_constant_value(nc);
3689 : :
3690 : 494370 : this->seen_ = false;
3691 : :
3692 : 494370 : if (r && ctype != NULL)
3693 : : {
3694 : 481091 : if (!nc->set_type(ctype, false, this->location()))
3695 : : return false;
3696 : : }
3697 : :
3698 : : return r;
3699 : : }
3700 : :
3701 : : bool
3702 : 10533 : Const_expression::do_string_constant_value(std::string* val)
3703 : : {
3704 : 10533 : if (this->seen_)
3705 : : return false;
3706 : 10533 : if (this->is_iota_)
3707 : : return false;
3708 : :
3709 : 10533 : Expression* e = this->constant_->const_value()->expr();
3710 : :
3711 : 10533 : this->seen_ = true;
3712 : 10533 : bool ok = e->string_constant_value(val);
3713 : 10533 : this->seen_ = false;
3714 : :
3715 : 10533 : return ok;
3716 : : }
3717 : :
3718 : : bool
3719 : 6822 : Const_expression::do_boolean_constant_value(bool* val)
3720 : : {
3721 : 6822 : if (this->seen_)
3722 : : return false;
3723 : 6822 : if (this->is_iota_)
3724 : : return false;
3725 : :
3726 : 6822 : Expression* e = this->constant_->const_value()->expr();
3727 : :
3728 : 6822 : this->seen_ = true;
3729 : 6822 : bool ok = e->boolean_constant_value(val);
3730 : 6822 : this->seen_ = false;
3731 : :
3732 : 6822 : return ok;
3733 : : }
3734 : :
3735 : : // Whether this is untyped.
3736 : :
3737 : : bool
3738 : 87808 : Const_expression::do_is_untyped(Type** ptype) const
3739 : : {
3740 : 87808 : if (this->type_ != NULL)
3741 : 16888 : return Expression::is_untyped_type(this->type_, ptype);
3742 : :
3743 : 70920 : Named_constant* nc = this->constant_->const_value();
3744 : 70920 : if (nc->type() != NULL)
3745 : 67856 : return Expression::is_untyped_type(nc->type(), ptype);
3746 : :
3747 : 3064 : return nc->expr()->is_untyped(ptype);
3748 : : }
3749 : :
3750 : : // Return the type of the const reference.
3751 : :
3752 : : Type*
3753 : 3898483 : Const_expression::do_type()
3754 : : {
3755 : 3898483 : if (this->type_ == NULL)
3756 : : {
3757 : 0 : go_assert(saw_errors());
3758 : 0 : return Type::make_error_type();
3759 : : }
3760 : :
3761 : : return this->type_;
3762 : : }
3763 : :
3764 : : // Set the type of the const reference.
3765 : :
3766 : : void
3767 : 645006 : Const_expression::do_determine_type(Gogo* gogo, const Type_context* context)
3768 : : {
3769 : 645006 : if (this->type_ != NULL)
3770 : : return;
3771 : :
3772 : : // The type may depend on the type of other constants. Avoid an
3773 : : // endless loop.
3774 : 426643 : if (this->seen_)
3775 : : {
3776 : 0 : if (!saw_errors())
3777 : 0 : go_error_at(this->location(), "constant refers to itself");
3778 : 0 : this->set_is_error();
3779 : 0 : this->type_ = Type::make_error_type();
3780 : 0 : return;
3781 : : }
3782 : :
3783 : 426643 : this->seen_ = true;
3784 : :
3785 : 426643 : Named_constant* nc = this->constant_->const_value();
3786 : 426643 : nc->determine_type(gogo);
3787 : :
3788 : 426643 : Type* ctype = nc->type();
3789 : :
3790 : 426643 : this->seen_ = false;
3791 : :
3792 : 426643 : if (ctype == NULL)
3793 : : {
3794 : 2 : go_error_at(nc->expr()->location(), "constant refers to itself");
3795 : 2 : this->set_is_error();
3796 : 2 : this->type_ = Type::make_error_type();
3797 : : }
3798 : 426641 : else if (!ctype->is_abstract())
3799 : 224088 : this->type_ = ctype;
3800 : 202553 : else if (context->type != NULL
3801 : 149182 : && context->type->is_numeric_type()
3802 : 270720 : && ctype->is_numeric_type())
3803 : 68152 : this->type_ = context->type;
3804 : 134401 : else if (context->type != NULL
3805 : 81030 : && context->type->is_string_type()
3806 : 141939 : && ctype->is_string_type())
3807 : 7283 : this->type_ = context->type;
3808 : 127118 : else if (context->type != NULL
3809 : 73747 : && context->type->is_boolean_type()
3810 : 198764 : && ctype->is_boolean_type())
3811 : 71646 : this->type_ = context->type;
3812 : 55472 : else if (!context->may_be_abstract)
3813 : : {
3814 : 9022 : if (ctype->is_abstract())
3815 : 9022 : ctype = ctype->make_non_abstract_type();
3816 : 9022 : this->type_ = ctype;
3817 : : }
3818 : : else
3819 : 46450 : this->type_ = ctype;
3820 : : }
3821 : :
3822 : : // Check for a loop in which the initializer of a constant refers to
3823 : : // the constant itself.
3824 : :
3825 : : void
3826 : 416020 : Const_expression::check_for_init_loop()
3827 : : {
3828 : 416020 : if (this->is_error_expression())
3829 : 0 : return;
3830 : 416020 : if (this->type_ != NULL && this->type_->is_error())
3831 : : return;
3832 : 416020 : if (this->constant_->const_value()->expr()->is_error_expression())
3833 : : {
3834 : 0 : this->set_is_error();
3835 : 0 : return;
3836 : : }
3837 : :
3838 : 416020 : if (this->seen_)
3839 : : {
3840 : 0 : this->report_error(_("constant refers to itself"));
3841 : 0 : this->type_ = Type::make_error_type();
3842 : 0 : return;
3843 : : }
3844 : :
3845 : 416020 : Expression* init = this->constant_->const_value()->expr();
3846 : 416020 : Find_named_object find_named_object(this->constant_);
3847 : :
3848 : 416020 : this->seen_ = true;
3849 : 416020 : Expression::traverse(&init, &find_named_object);
3850 : 416020 : this->seen_ = false;
3851 : :
3852 : 416020 : if (find_named_object.found())
3853 : : {
3854 : 0 : if (this->type_ == NULL || !this->type_->is_error())
3855 : : {
3856 : 0 : this->report_error(_("constant refers to itself"));
3857 : 0 : this->type_ = Type::make_error_type();
3858 : : }
3859 : 0 : return;
3860 : : }
3861 : 416020 : }
3862 : :
3863 : : // Set the iota value if this is a reference to iota.
3864 : :
3865 : : void
3866 : 46011 : Const_expression::set_iota_value(int iota_value)
3867 : : {
3868 : 46011 : Named_constant* nc = this->constant_->const_value();
3869 : 46011 : if (nc->expr()->classification() == EXPRESSION_IOTA)
3870 : : {
3871 : 10363 : this->is_iota_ = true;
3872 : 10363 : this->iota_value_ = iota_value;
3873 : : }
3874 : 46011 : }
3875 : :
3876 : : // Check types of a const reference.
3877 : :
3878 : : void
3879 : 426388 : Const_expression::do_check_types(Gogo*)
3880 : : {
3881 : 426388 : if (this->is_error_expression())
3882 : : return;
3883 : 426388 : if (this->type_ != NULL && this->type_->is_error())
3884 : : return;
3885 : 426386 : if (this->constant_->const_value()->expr()->is_error_expression())
3886 : : {
3887 : 1 : this->set_is_error();
3888 : 1 : return;
3889 : : }
3890 : :
3891 : 426385 : Expression* expr = this->constant_->const_value()->expr();
3892 : 426385 : if (expr->classification() == EXPRESSION_IOTA && !this->is_iota_)
3893 : : {
3894 : 4 : go_error_at(this->location(),
3895 : : "iota is only defined in const declarations");
3896 : : // Avoid knock-on errors.
3897 : 4 : this->is_iota_ = true;
3898 : 4 : this->iota_value_ = 0;
3899 : : }
3900 : :
3901 : 426385 : if (this->is_iota_ && this->type_->is_numeric_type())
3902 : : {
3903 : 10365 : Numeric_constant nc;
3904 : 10365 : nc.set_unsigned_long(Type::make_abstract_integer_type(),
3905 : 10365 : static_cast<unsigned long>(this->iota_value_));
3906 : 10365 : if (!nc.set_type(this->type_, true, this->location()))
3907 : 0 : this->set_is_error();
3908 : 10365 : return;
3909 : 10365 : }
3910 : :
3911 : 416020 : this->check_for_init_loop();
3912 : :
3913 : : // Check that numeric constant fits in type.
3914 : 416020 : if (this->type_->is_numeric_type())
3915 : : {
3916 : 189793 : Numeric_constant nc;
3917 : 189793 : if (expr->numeric_constant_value(&nc))
3918 : : {
3919 : 189067 : if (!nc.set_type(this->type_, true, this->location()))
3920 : 873 : this->set_is_error();
3921 : : }
3922 : 189793 : }
3923 : : }
3924 : :
3925 : : // Return the backend representation for a const reference.
3926 : :
3927 : : Bexpression*
3928 : 259212 : Const_expression::do_get_backend(Translate_context* context)
3929 : : {
3930 : 259212 : if (this->is_error_expression()
3931 : 259212 : || (this->type_ != NULL && this->type_->is_error()))
3932 : : {
3933 : 0 : go_assert(saw_errors());
3934 : 0 : return context->backend()->error_expression();
3935 : : }
3936 : :
3937 : 259212 : go_assert(!this->is_iota_);
3938 : :
3939 : : // If the type has been set for this expression, but the underlying
3940 : : // object is an abstract int or float, we try to get the abstract
3941 : : // value. Otherwise we may lose something in the conversion.
3942 : 259212 : Expression* expr = this->constant_->const_value()->expr();
3943 : 259212 : if (this->type_ != NULL
3944 : 235813 : && this->type_->is_numeric_type()
3945 : 403440 : && (this->constant_->const_value()->type() == NULL
3946 : 144228 : || this->constant_->const_value()->type()->is_abstract()))
3947 : : {
3948 : 82314 : Numeric_constant nc;
3949 : 82314 : if (expr->numeric_constant_value(&nc)
3950 : 82314 : && nc.set_type(this->type_, false, this->location()))
3951 : : {
3952 : 82314 : Expression* e = nc.expression(this->location());
3953 : 82314 : return e->get_backend(context);
3954 : : }
3955 : 82314 : }
3956 : :
3957 : 176898 : if (this->type_ != NULL)
3958 : 153499 : expr = Expression::make_cast(this->type_, expr, this->location());
3959 : 176898 : return expr->get_backend(context);
3960 : : }
3961 : :
3962 : : // When exporting a reference to a const as part of a const
3963 : : // expression, we export the value. We ignore the fact that it has
3964 : : // a name.
3965 : :
3966 : : void
3967 : 29740 : Const_expression::do_export(Export_function_body* efb) const
3968 : : {
3969 : 29740 : this->constant_->const_value()->expr()->export_expression(efb);
3970 : 29740 : }
3971 : :
3972 : : // Dump ast representation for constant expression.
3973 : :
3974 : : void
3975 : 0 : Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3976 : : {
3977 : 0 : ast_dump_context->ostream() << this->constant_->name();
3978 : 0 : }
3979 : :
3980 : : // Make a reference to a constant in an expression.
3981 : :
3982 : : Expression*
3983 : 450153 : Expression::make_const_reference(Named_object* constant,
3984 : : Location location)
3985 : : {
3986 : 450153 : return new Const_expression(constant, location);
3987 : : }
3988 : :
3989 : : // Find a named object in an expression.
3990 : :
3991 : : int
3992 : 662125 : Find_named_object::expression(Expression** pexpr)
3993 : : {
3994 : 662125 : switch ((*pexpr)->classification())
3995 : : {
3996 : 74962 : case Expression::EXPRESSION_CONST_REFERENCE:
3997 : 74962 : {
3998 : 74962 : Const_expression* ce = static_cast<Const_expression*>(*pexpr);
3999 : 74962 : if (ce->named_object() == this->no_)
4000 : : break;
4001 : : return TRAVERSE_CONTINUE;
4002 : : }
4003 : :
4004 : 173 : case Expression::EXPRESSION_VAR_REFERENCE:
4005 : 173 : if ((*pexpr)->var_expression()->named_object() == this->no_)
4006 : : break;
4007 : : return TRAVERSE_CONTINUE;
4008 : 1414 : case Expression::EXPRESSION_FUNC_REFERENCE:
4009 : 1414 : if ((*pexpr)->func_expression()->named_object() == this->no_)
4010 : : break;
4011 : : return TRAVERSE_CONTINUE;
4012 : : case Expression::EXPRESSION_ERROR:
4013 : : return TRAVERSE_EXIT;
4014 : : default:
4015 : : return TRAVERSE_CONTINUE;
4016 : : }
4017 : 0 : this->found_ = true;
4018 : 0 : return TRAVERSE_EXIT;
4019 : : }
4020 : :
4021 : : // The nil value.
4022 : :
4023 : : class Nil_expression : public Expression
4024 : : {
4025 : : public:
4026 : 2348065 : Nil_expression(Location location)
4027 : 4696130 : : Expression(EXPRESSION_NIL, location)
4028 : : { }
4029 : :
4030 : : static Expression*
4031 : : do_import(Import_expression*, Location);
4032 : :
4033 : : protected:
4034 : : bool
4035 : 59824 : do_is_constant() const
4036 : 59824 : { return true; }
4037 : :
4038 : : bool
4039 : : do_untyped_type(Type** ptype) const
4040 : : {
4041 : : *ptype = Type::make_nil_type();
4042 : : return true;
4043 : : }
4044 : :
4045 : : bool
4046 : 18 : do_is_zero_value() const
4047 : 18 : { return true; }
4048 : :
4049 : : bool
4050 : 592499 : do_is_static_initializer() const
4051 : 592499 : { return true; }
4052 : :
4053 : : Type*
4054 : 2018525 : do_type()
4055 : 2018525 : { return Type::make_nil_type(); }
4056 : :
4057 : : void
4058 : 2946209 : do_determine_type(Gogo*, const Type_context*)
4059 : 2946209 : { }
4060 : :
4061 : : Expression*
4062 : 0 : do_copy()
4063 : 0 : { return this; }
4064 : :
4065 : : Bexpression*
4066 : 1202320 : do_get_backend(Translate_context* context)
4067 : 1202320 : { return context->backend()->nil_pointer_expression(); }
4068 : :
4069 : : int
4070 : 17529 : do_inlining_cost() const
4071 : 17529 : { return 1; }
4072 : :
4073 : : void
4074 : 1456 : do_export(Export_function_body* efb) const
4075 : 1456 : { efb->write_c_string("$nil"); }
4076 : :
4077 : : void
4078 : 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
4079 : 0 : { ast_dump_context->ostream() << "nil"; }
4080 : : };
4081 : :
4082 : : // Import a nil expression.
4083 : :
4084 : : Expression*
4085 : 621 : Nil_expression::do_import(Import_expression* imp, Location loc)
4086 : : {
4087 : 621 : if (imp->version() >= EXPORT_FORMAT_V3)
4088 : 621 : imp->require_c_string("$");
4089 : 621 : imp->require_c_string("nil");
4090 : 621 : return Expression::make_nil(loc);
4091 : : }
4092 : :
4093 : : // Make a nil expression.
4094 : :
4095 : : Expression*
4096 : 2348065 : Expression::make_nil(Location location)
4097 : : {
4098 : 2348065 : return new Nil_expression(location);
4099 : : }
4100 : :
4101 : : // The value of the predeclared constant iota. This is little more
4102 : : // than a marker. This will be lowered to an integer in
4103 : : // Const_expression::do_lower, which is where we know the value that
4104 : : // it should have.
4105 : :
4106 : : class Iota_expression : public Parser_expression
4107 : : {
4108 : : public:
4109 : 4646 : Iota_expression(Location location)
4110 : 4646 : : Parser_expression(EXPRESSION_IOTA, location)
4111 : 4646 : { }
4112 : :
4113 : : protected:
4114 : : Type*
4115 : 0 : do_type()
4116 : 0 : { return Type::make_abstract_integer_type(); }
4117 : :
4118 : : void
4119 : 471 : do_determine_type(Gogo*, const Type_context*)
4120 : 471 : { }
4121 : :
4122 : : Expression*
4123 : 0 : do_lower(Gogo*, Named_object*, Statement_inserter*)
4124 : 0 : { go_unreachable(); }
4125 : :
4126 : : // There should only ever be one of these.
4127 : : Expression*
4128 : 0 : do_copy()
4129 : 0 : { go_unreachable(); }
4130 : :
4131 : : void
4132 : 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
4133 : 0 : { ast_dump_context->ostream() << "iota"; }
4134 : : };
4135 : :
4136 : : // Make an iota expression. This is only called for one case: the
4137 : : // value of the predeclared constant iota.
4138 : :
4139 : : Expression*
4140 : 4646 : Expression::make_iota()
4141 : : {
4142 : 6351 : static Iota_expression iota_expression(Linemap::unknown_location());
4143 : 4646 : return &iota_expression;
4144 : : }
4145 : :
4146 : : // Class Type_conversion_expression.
4147 : :
4148 : : // Traversal.
4149 : :
4150 : : int
4151 : 6426934 : Type_conversion_expression::do_traverse(Traverse* traverse)
4152 : : {
4153 : 6426934 : if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
4154 : 6426934 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
4155 : 75690 : return TRAVERSE_EXIT;
4156 : : return TRAVERSE_CONTINUE;
4157 : : }
4158 : :
4159 : : // Return the type of the expression.
4160 : :
4161 : : Type*
4162 : 6938760 : Type_conversion_expression::do_type()
4163 : : {
4164 : 6938760 : if (this->is_error_expression() || this->expr_->is_error_expression())
4165 : 259 : return Type::make_error_type();
4166 : 6938501 : return this->type_;
4167 : : }
4168 : :
4169 : : // Convert to a constant at lowering time. Also lower conversions
4170 : : // from slice to pointer-to-array, as they can panic.
4171 : :
4172 : : Expression*
4173 : 463859 : Type_conversion_expression::do_lower(Gogo* gogo, Named_object*,
4174 : : Statement_inserter* inserter)
4175 : : {
4176 : 463859 : Type* type = this->type_;
4177 : 463859 : Expression* val = this->expr_;
4178 : 463859 : Location location = this->location();
4179 : :
4180 : 463859 : if (type->is_numeric_type())
4181 : : {
4182 : 293860 : Numeric_constant nc;
4183 : 293860 : if (val->numeric_constant_value(&nc))
4184 : : {
4185 : 31348 : if (!nc.set_type(type, true, location))
4186 : 19 : return Expression::make_error(location);
4187 : 31329 : return nc.expression(location);
4188 : : }
4189 : 293860 : }
4190 : :
4191 : : // According to the language specification on string conversions
4192 : : // (http://golang.org/ref/spec#Conversions_to_and_from_a_string_type):
4193 : : // When converting an integer into a string, the string will be a UTF-8
4194 : : // representation of the integer and integers "outside the range of valid
4195 : : // Unicode code points are converted to '\uFFFD'."
4196 : 432511 : if (type->is_string_type())
4197 : : {
4198 : 27230 : Numeric_constant nc;
4199 : 27230 : if (val->numeric_constant_value(&nc) && nc.is_int())
4200 : : {
4201 : : // An integer value doesn't fit in the Unicode code point range if it
4202 : : // overflows the Go "int" type or is negative.
4203 : 418 : unsigned long ul;
4204 : 418 : if (!nc.set_type(Type::lookup_integer_type("int"), false, location)
4205 : 418 : || nc.to_unsigned_long(&ul) == Numeric_constant::NC_UL_NEGATIVE)
4206 : 6 : return Expression::make_string("\ufffd", location);
4207 : : }
4208 : 27230 : }
4209 : :
4210 : 432505 : if (type->is_slice_type())
4211 : : {
4212 : 25664 : Type* element_type = type->array_type()->element_type()->forwarded();
4213 : 24656 : bool is_byte = (element_type->integer_type() != NULL
4214 : 11824 : && element_type->integer_type()->is_byte());
4215 : 24656 : bool is_rune = (element_type->integer_type() != NULL
4216 : 11824 : && element_type->integer_type()->is_rune());
4217 : 12628 : if (is_byte || is_rune)
4218 : : {
4219 : 9918 : std::string s;
4220 : 9918 : if (val->string_constant_value(&s))
4221 : : {
4222 : 4887 : Expression_list* vals = new Expression_list();
4223 : 4887 : if (is_byte)
4224 : : {
4225 : 4831 : for (std::string::const_iterator p = s.begin();
4226 : 164092 : p != s.end();
4227 : 159261 : p++)
4228 : : {
4229 : 159261 : unsigned char c = static_cast<unsigned char>(*p);
4230 : 159261 : vals->push_back(Expression::make_integer_ul(c,
4231 : : element_type,
4232 : : location));
4233 : : }
4234 : : }
4235 : : else
4236 : : {
4237 : 56 : const char *p = s.data();
4238 : 56 : const char *pend = s.data() + s.length();
4239 : 609 : while (p < pend)
4240 : : {
4241 : 553 : unsigned int c;
4242 : 553 : int adv = Lex::fetch_char(p, &c);
4243 : 553 : if (adv == 0)
4244 : : {
4245 : 4 : go_warning_at(this->location(), 0,
4246 : : "invalid UTF-8 encoding");
4247 : 4 : adv = 1;
4248 : : }
4249 : 553 : p += adv;
4250 : 553 : vals->push_back(Expression::make_integer_ul(c,
4251 : : element_type,
4252 : : location));
4253 : : }
4254 : : }
4255 : :
4256 : 4887 : return Expression::make_slice_composite_literal(type, vals,
4257 : : location);
4258 : : }
4259 : 9918 : }
4260 : : }
4261 : :
4262 : 427618 : if (type->points_to() != NULL
4263 : 120945 : && type->points_to()->array_type() != NULL
4264 : 3503 : && !type->points_to()->is_slice_type()
4265 : 1545 : && val->type()->is_slice_type()
4266 : 427710 : && Type::are_identical(type->points_to()->array_type()->element_type(),
4267 : 92 : val->type()->array_type()->element_type(),
4268 : : 0, NULL))
4269 : : {
4270 : 46 : Temporary_statement* val_temp = NULL;
4271 : 46 : if (!val->is_multi_eval_safe())
4272 : : {
4273 : 25 : val_temp = Statement::make_temporary(val->type(), NULL, location);
4274 : 25 : inserter->insert(val_temp);
4275 : 25 : val = Expression::make_set_and_use_temporary(val_temp, val,
4276 : : location);
4277 : : }
4278 : :
4279 : 46 : Type* int_type = Type::lookup_integer_type("int");
4280 : 46 : Temporary_statement* vallen_temp =
4281 : 46 : Statement::make_temporary(int_type, NULL, location);
4282 : 46 : inserter->insert(vallen_temp);
4283 : :
4284 : 92 : Expression* arrlen = type->points_to()->array_type()->length();
4285 : 46 : Expression* vallen =
4286 : 46 : Expression::make_slice_info(val, Expression::SLICE_INFO_LENGTH,
4287 : : location);
4288 : 46 : vallen = Expression::make_set_and_use_temporary(vallen_temp, vallen,
4289 : : location);
4290 : 46 : Expression* cond = Expression::make_binary(OPERATOR_GT, arrlen, vallen,
4291 : : location);
4292 : :
4293 : 46 : vallen = Expression::make_temporary_reference(vallen_temp, location);
4294 : 46 : Expression* panic = Runtime::make_call(gogo,
4295 : : Runtime::PANIC_SLICE_CONVERT,
4296 : : location, 2, arrlen, vallen);
4297 : :
4298 : 46 : Expression* nil = Expression::make_nil(location);
4299 : 46 : Expression* check = Expression::make_conditional(cond, panic, nil,
4300 : : location);
4301 : :
4302 : 46 : if (val_temp == NULL)
4303 : 21 : val = val->copy();
4304 : : else
4305 : 25 : val = Expression::make_temporary_reference(val_temp, location);
4306 : 46 : Expression* ptr =
4307 : 46 : Expression::make_slice_info(val, Expression::SLICE_INFO_VALUE_POINTER,
4308 : : location);
4309 : 46 : ptr = Expression::make_unsafe_cast(type, ptr, location);
4310 : :
4311 : 46 : Expression* ret = Expression::make_compound(check, ptr, location);
4312 : 46 : ret->determine_type_no_context(gogo);
4313 : 46 : return ret;
4314 : : }
4315 : :
4316 : 427572 : return this;
4317 : : }
4318 : :
4319 : : // Flatten a type conversion by using a temporary variable for the slice
4320 : : // in slice to string conversions.
4321 : :
4322 : : Expression*
4323 : 846696 : Type_conversion_expression::do_flatten(Gogo*, Named_object*,
4324 : : Statement_inserter* inserter)
4325 : : {
4326 : 846696 : if (this->type()->is_error_type() || this->expr_->is_error_expression())
4327 : : {
4328 : 723 : go_assert(saw_errors());
4329 : 723 : return Expression::make_error(this->location());
4330 : : }
4331 : :
4332 : 845973 : if (((this->type()->is_string_type()
4333 : 22867 : && this->expr_->type()->is_slice_type())
4334 : 840222 : || this->expr_->type()->interface_type() != NULL)
4335 : 882966 : && !this->expr_->is_multi_eval_safe())
4336 : : {
4337 : 7268 : Temporary_statement* temp =
4338 : 7268 : Statement::make_temporary(NULL, this->expr_, this->location());
4339 : 7268 : inserter->insert(temp);
4340 : 7268 : this->expr_ = Expression::make_temporary_reference(temp, this->location());
4341 : : }
4342 : :
4343 : : // For interface conversion and string to/from slice conversions,
4344 : : // decide if we can allocate on stack.
4345 : 1438158 : if (this->type()->interface_type() != NULL
4346 : 592185 : || this->type()->is_string_type()
4347 : 569318 : || this->expr_->type()->is_string_type())
4348 : : {
4349 : 278526 : Node* n = Node::make_node(this);
4350 : 278526 : if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
4351 : 10302 : this->no_escape_ = true;
4352 : : }
4353 : 845973 : return this;
4354 : : }
4355 : :
4356 : : // Return whether a type conversion is a constant.
4357 : :
4358 : : bool
4359 : 380574 : Type_conversion_expression::do_is_constant() const
4360 : : {
4361 : 380574 : if (!this->expr_->is_constant())
4362 : : return false;
4363 : :
4364 : : // A conversion to a type that may not be used as a constant is not
4365 : : // a constant. For example, []byte(nil).
4366 : 63191 : Type* type = this->type_;
4367 : 85345 : if (type->integer_type() == NULL
4368 : 21995 : && type->float_type() == NULL
4369 : 21982 : && type->complex_type() == NULL
4370 : 21982 : && !type->is_boolean_type()
4371 : 21885 : && !type->is_string_type())
4372 : : return false;
4373 : :
4374 : : return true;
4375 : : }
4376 : :
4377 : : // Return whether a type conversion is a zero value.
4378 : :
4379 : : bool
4380 : 183 : Type_conversion_expression::do_is_zero_value() const
4381 : : {
4382 : 183 : if (!this->expr_->is_zero_value())
4383 : : return false;
4384 : :
4385 : : // Some type conversion from zero value is still not zero value.
4386 : : // For example, []byte("") or interface{}(0).
4387 : : // Conservatively, only report true if the RHS is nil.
4388 : 0 : Type* type = this->type_;
4389 : 0 : if (type->integer_type() == NULL
4390 : 0 : && type->float_type() == NULL
4391 : 0 : && type->complex_type() == NULL
4392 : 0 : && !type->is_boolean_type()
4393 : 0 : && !type->is_string_type())
4394 : 0 : return this->expr_->is_nil_expression();
4395 : :
4396 : : return true;
4397 : : }
4398 : :
4399 : : // Return whether a type conversion can be used in a constant
4400 : : // initializer.
4401 : :
4402 : : bool
4403 : 47532 : Type_conversion_expression::do_is_static_initializer() const
4404 : : {
4405 : 47532 : Type* type = this->type_;
4406 : 47532 : Type* expr_type = this->expr_->type();
4407 : :
4408 : 91776 : if (type->interface_type() != NULL
4409 : 47532 : || expr_type->interface_type() != NULL)
4410 : 3288 : return false;
4411 : :
4412 : 44244 : if (!this->expr_->is_static_initializer())
4413 : : return false;
4414 : :
4415 : 34845 : if (Type::are_identical(type, expr_type,
4416 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
4417 : : NULL))
4418 : : return true;
4419 : :
4420 : 22310 : if (type->is_string_type() && expr_type->is_string_type())
4421 : : return true;
4422 : :
4423 : 22239 : if ((type->is_numeric_type()
4424 : 22210 : || type->is_boolean_type()
4425 : 22210 : || type->points_to() != NULL)
4426 : 44367 : && (expr_type->is_numeric_type()
4427 : 22092 : || expr_type->is_boolean_type()
4428 : 22092 : || expr_type->points_to() != NULL))
4429 : 22115 : return true;
4430 : :
4431 : : return false;
4432 : : }
4433 : :
4434 : : // Return the constant numeric value if there is one.
4435 : :
4436 : : bool
4437 : 105449 : Type_conversion_expression::do_numeric_constant_value(
4438 : : Numeric_constant* nc)
4439 : : {
4440 : 105449 : if (!this->type_->is_numeric_type())
4441 : : return false;
4442 : 96627 : if (!this->expr_->numeric_constant_value(nc))
4443 : : return false;
4444 : 10669 : return nc->set_type(this->type_, false, this->location());
4445 : : }
4446 : :
4447 : : // Return the constant string value if there is one.
4448 : :
4449 : : bool
4450 : 7974 : Type_conversion_expression::do_string_constant_value(std::string* val)
4451 : : {
4452 : 7974 : if (this->type_->is_string_type() && this->expr_->type()->is_string_type())
4453 : 126 : return this->expr_->string_constant_value(val);
4454 : :
4455 : 7848 : if (this->type_->is_string_type()
4456 : 7848 : && this->expr_->type()->integer_type() != NULL)
4457 : : {
4458 : 207 : Numeric_constant nc;
4459 : 207 : if (this->expr_->numeric_constant_value(&nc))
4460 : : {
4461 : 122 : unsigned long ival;
4462 : 122 : if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
4463 : : {
4464 : 122 : unsigned int cval = static_cast<unsigned int>(ival);
4465 : 122 : if (static_cast<unsigned long>(cval) != ival)
4466 : : {
4467 : 1 : go_warning_at(this->location(), 0,
4468 : : "unicode code point 0x%lx out of range",
4469 : : ival);
4470 : 1 : cval = 0xfffd; // Unicode "replacement character."
4471 : : }
4472 : 122 : val->clear();
4473 : 122 : Lex::append_char(cval, true, val, this->location());
4474 : 122 : return true;
4475 : : }
4476 : : }
4477 : 207 : }
4478 : :
4479 : : // FIXME: Could handle conversion from const []int here.
4480 : :
4481 : : return false;
4482 : : }
4483 : :
4484 : : // Return the constant boolean value if there is one.
4485 : :
4486 : : bool
4487 : 6048 : Type_conversion_expression::do_boolean_constant_value(bool* val)
4488 : : {
4489 : 6048 : if (!this->type_->is_boolean_type())
4490 : : return false;
4491 : 12 : return this->expr_->boolean_constant_value(val);
4492 : : }
4493 : :
4494 : : // Determine the resulting type of the conversion.
4495 : :
4496 : : void
4497 : 2505134 : Type_conversion_expression::do_determine_type(Gogo* gogo, const Type_context*)
4498 : : {
4499 : 2505134 : Type_context subcontext(this->type_, false);
4500 : 2505134 : this->expr_->determine_type(gogo, &subcontext);
4501 : 2505134 : }
4502 : :
4503 : : // Check that types are convertible.
4504 : :
4505 : : void
4506 : 126355 : Type_conversion_expression::do_check_types(Gogo*)
4507 : : {
4508 : 126355 : Type* type = this->type_;
4509 : 126355 : Type* expr_type = this->expr_->type();
4510 : 126355 : std::string reason;
4511 : :
4512 : 126355 : if (type->is_error() || expr_type->is_error())
4513 : : {
4514 : 2 : this->set_is_error();
4515 : 2 : return;
4516 : : }
4517 : :
4518 : 126353 : if (this->may_convert_function_types_
4519 : 0 : && type->function_type() != NULL
4520 : 252611 : && expr_type->function_type() != NULL)
4521 : : return;
4522 : :
4523 : 126353 : if (Type::are_convertible(type, expr_type, &reason))
4524 : : return;
4525 : :
4526 : : // We can convert all numeric types if the value is a constant.
4527 : 102 : if (type->is_numeric_type()
4528 : 17 : && expr_type->is_numeric_type()
4529 : 107 : && this->expr_->is_constant())
4530 : : return;
4531 : :
4532 : 97 : go_error_at(this->location(), "%s", reason.c_str());
4533 : 97 : this->set_is_error();
4534 : 126355 : }
4535 : :
4536 : : // Copy.
4537 : :
4538 : : Expression*
4539 : 5949 : Type_conversion_expression::do_copy()
4540 : : {
4541 : 11898 : Expression* ret = new Type_conversion_expression(this->type_->copy_expressions(),
4542 : 5949 : this->expr_->copy(),
4543 : 5949 : this->location());
4544 : 5949 : ret->conversion_expression()->set_no_copy(this->no_copy_);
4545 : 5949 : return ret;
4546 : : }
4547 : :
4548 : : // Get the backend representation for a type conversion.
4549 : :
4550 : : Bexpression*
4551 : 2943261 : Type_conversion_expression::do_get_backend(Translate_context* context)
4552 : : {
4553 : 2943261 : Type* type = this->type_;
4554 : 2943261 : Type* expr_type = this->expr_->type();
4555 : 2943261 : Type_context tcontext(type, false);
4556 : :
4557 : 2943261 : Gogo* gogo = context->gogo();
4558 : 2943261 : Btype* btype = type->get_backend(gogo);
4559 : 2943261 : Location loc = this->location();
4560 : :
4561 : 2943261 : if (Type::are_identical(type, expr_type,
4562 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
4563 : : NULL))
4564 : : {
4565 : 1104769 : Bexpression* bexpr = this->expr_->get_backend(context);
4566 : 1104769 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4567 : : }
4568 : 2065716 : else if (type->interface_type() != NULL
4569 : 1838492 : && expr_type->interface_type() == NULL)
4570 : : {
4571 : 201200 : Expression* conversion =
4572 : 402400 : Expression::convert_type_to_interface(type, this->expr_,
4573 : 201200 : this->no_escape_, loc);
4574 : 201200 : conversion->determine_type(gogo, &tcontext);
4575 : 201200 : return conversion->get_backend(context);
4576 : : }
4577 : 3248560 : else if (type->interface_type() != NULL
4578 : 1637292 : || expr_type->interface_type() != NULL)
4579 : : {
4580 : 26024 : Expression* conversion =
4581 : 26024 : Expression::convert_for_assignment(gogo, type, this->expr_,
4582 : : loc);
4583 : 26024 : conversion->determine_type(gogo, &tcontext);
4584 : 26024 : return conversion->get_backend(context);
4585 : : }
4586 : 1611268 : else if (type->is_string_type()
4587 : 1611268 : && expr_type->integer_type() != NULL)
4588 : : {
4589 : 648 : mpz_t intval;
4590 : 648 : Numeric_constant nc;
4591 : 648 : if (this->expr_->numeric_constant_value(&nc)
4592 : 648 : && nc.to_int(&intval))
4593 : : {
4594 : 380 : std::string s;
4595 : 380 : unsigned int x;
4596 : 380 : if (mpz_fits_uint_p(intval))
4597 : 381 : x = mpz_get_ui(intval);
4598 : : else
4599 : : {
4600 : 1 : char* ms = mpz_get_str(NULL, 16, intval);
4601 : 1 : go_warning_at(loc, 0,
4602 : : "unicode code point 0x%s out of range in string",
4603 : : ms);
4604 : 1 : free(ms);
4605 : 1 : x = 0xfffd;
4606 : : }
4607 : 380 : Lex::append_char(x, true, &s, loc);
4608 : 380 : mpz_clear(intval);
4609 : 380 : Expression* se = Expression::make_string(s, loc);
4610 : 380 : se->determine_type(gogo, &tcontext);
4611 : 380 : return se->get_backend(context);
4612 : 380 : }
4613 : :
4614 : 268 : Expression* buf;
4615 : 268 : if (this->no_escape_)
4616 : : {
4617 : 200 : Type* byte_type = Type::lookup_integer_type("uint8");
4618 : 200 : Expression* buflen =
4619 : 200 : Expression::make_integer_ul(4, NULL, loc);
4620 : 200 : Type* array_type = Type::make_array_type(byte_type, buflen);
4621 : 200 : buf = Expression::make_allocation(array_type, loc);
4622 : 200 : buf->allocation_expression()->set_allocate_on_stack();
4623 : 200 : buf->allocation_expression()->set_no_zero();
4624 : : }
4625 : : else
4626 : 68 : buf = Expression::make_nil(loc);
4627 : 268 : Expression* i2s_expr =
4628 : 268 : Runtime::make_call(gogo, Runtime::INTSTRING, loc, 2, buf, this->expr_);
4629 : 268 : Expression* ret = Expression::make_cast(type, i2s_expr, loc);
4630 : 268 : Type_context tcontext(type, false);
4631 : 268 : ret->determine_type(gogo, &tcontext);
4632 : 268 : return ret->get_backend(context);
4633 : 648 : }
4634 : 1610620 : else if (type->is_string_type() && expr_type->is_slice_type())
4635 : : {
4636 : 5289 : Array_type* a = expr_type->array_type();
4637 : 5289 : Type* e = a->element_type()->forwarded();
4638 : 5289 : go_assert(e->integer_type() != NULL);
4639 : 5289 : go_assert(this->expr_->is_multi_eval_safe());
4640 : :
4641 : 5289 : Expression* buf;
4642 : 5289 : if (this->no_escape_ && !this->no_copy_)
4643 : : {
4644 : 408 : Type* byte_type = Type::lookup_integer_type("uint8");
4645 : 408 : Expression* buflen =
4646 : 408 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
4647 : 408 : Type* array_type = Type::make_array_type(byte_type, buflen);
4648 : 408 : buf = Expression::make_allocation(array_type, loc);
4649 : 408 : buf->allocation_expression()->set_allocate_on_stack();
4650 : 408 : buf->allocation_expression()->set_no_zero();
4651 : : }
4652 : : else
4653 : 4881 : buf = Expression::make_nil(loc);
4654 : :
4655 : 10578 : if (e->integer_type()->is_byte())
4656 : : {
4657 : 5155 : Expression* ptr =
4658 : 5155 : Expression::make_slice_info(this->expr_, SLICE_INFO_VALUE_POINTER,
4659 : : loc);
4660 : 5155 : Expression* len =
4661 : 5155 : Expression::make_slice_info(this->expr_, SLICE_INFO_LENGTH, loc);
4662 : 5155 : if (this->no_copy_)
4663 : : {
4664 : 1689 : if (gogo->debug_optimization())
4665 : 6 : go_debug(loc, "no copy string([]byte)");
4666 : 1689 : Expression* str = Expression::make_string_value(ptr, len, loc);
4667 : 1689 : return str->get_backend(context);
4668 : : }
4669 : 3466 : Expression* ret = Runtime::make_call(gogo, Runtime::SLICEBYTETOSTRING,
4670 : : loc, 3, buf, ptr, len);
4671 : 3466 : Type_context tcontext(type, false);
4672 : 3466 : ret->determine_type(gogo, &tcontext);
4673 : 3466 : return ret->get_backend(context);
4674 : : }
4675 : : else
4676 : : {
4677 : 268 : go_assert(e->integer_type()->is_rune());
4678 : 134 : Expression* ret = Runtime::make_call(gogo, Runtime::SLICERUNETOSTRING,
4679 : : loc, 2, buf, this->expr_);
4680 : 134 : Type_context tcontext(type, false);
4681 : 134 : ret->determine_type(gogo, &tcontext);
4682 : 134 : return ret->get_backend(context);
4683 : : }
4684 : : }
4685 : 1608964 : else if (type->is_slice_type() && expr_type->is_string_type())
4686 : : {
4687 : 3128 : Type* e = type->array_type()->element_type()->forwarded();
4688 : 1564 : go_assert(e->integer_type() != NULL);
4689 : :
4690 : 1564 : Runtime::Function code;
4691 : 3128 : if (e->integer_type()->is_byte())
4692 : : code = Runtime::STRINGTOSLICEBYTE;
4693 : : else
4694 : : {
4695 : 90 : go_assert(e->integer_type()->is_rune());
4696 : : code = Runtime::STRINGTOSLICERUNE;
4697 : : }
4698 : :
4699 : 1564 : Expression* buf;
4700 : 1564 : if (this->no_escape_)
4701 : : {
4702 : 524 : Expression* buflen =
4703 : 524 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
4704 : 524 : Type* array_type = Type::make_array_type(e, buflen);
4705 : 524 : buf = Expression::make_allocation(array_type, loc);
4706 : 524 : buf->allocation_expression()->set_allocate_on_stack();
4707 : 524 : buf->allocation_expression()->set_no_zero();
4708 : : }
4709 : : else
4710 : 1040 : buf = Expression::make_nil(loc);
4711 : 1564 : Expression* s2a = Runtime::make_call(gogo, code, loc, 2, buf,
4712 : : this->expr_);
4713 : 1564 : Expression* ret = Expression::make_unsafe_cast(type, s2a, loc);
4714 : 1564 : Type_context tcontext(type, false);
4715 : 1564 : ret->determine_type(gogo, &tcontext);
4716 : 1564 : return ret->get_backend(context);
4717 : : }
4718 : 1603767 : else if (type->is_numeric_type())
4719 : : {
4720 : 412058 : go_assert(Type::are_convertible(type, expr_type, NULL));
4721 : 412058 : Bexpression* bexpr = this->expr_->get_backend(context);
4722 : 412058 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4723 : : }
4724 : 1191709 : else if ((type->is_unsafe_pointer_type()
4725 : 769910 : && (expr_type->points_to() != NULL
4726 : 1406143 : || expr_type->integer_type()))
4727 : 436852 : || (expr_type->is_unsafe_pointer_type()
4728 : 214434 : && type->points_to() != NULL)
4729 : 1414127 : || (this->may_convert_function_types_
4730 : 0 : && type->function_type() != NULL
4731 : 969291 : && expr_type->function_type() != NULL))
4732 : : {
4733 : 969291 : Bexpression* bexpr = this->expr_->get_backend(context);
4734 : 969291 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4735 : : }
4736 : : else
4737 : : {
4738 : 222418 : Expression* conversion =
4739 : 222418 : Expression::convert_for_assignment(gogo, type, this->expr_, loc);
4740 : 222418 : conversion->determine_type(gogo, &tcontext);
4741 : 222418 : return conversion->get_backend(context);
4742 : : }
4743 : : }
4744 : :
4745 : : // Cost of inlining a type conversion.
4746 : :
4747 : : int
4748 : 289413 : Type_conversion_expression::do_inlining_cost() const
4749 : : {
4750 : 289413 : Type* type = this->type_;
4751 : 289413 : Type* expr_type = this->expr_->type();
4752 : 491515 : if (type->interface_type() != NULL || expr_type->interface_type() != NULL)
4753 : 87311 : return 10;
4754 : 298377 : else if (type->is_string_type() && expr_type->integer_type() != NULL)
4755 : : return 10;
4756 : 201934 : else if (type->is_string_type() && expr_type->is_slice_type())
4757 : : return 10;
4758 : 199427 : else if (type->is_slice_type() && expr_type->is_string_type())
4759 : : return 10;
4760 : : else
4761 : 193138 : return 1;
4762 : : }
4763 : :
4764 : : // Output a type conversion in a constant expression.
4765 : :
4766 : : void
4767 : 10254 : Type_conversion_expression::do_export(Export_function_body* efb) const
4768 : : {
4769 : 10254 : efb->write_c_string("$convert(");
4770 : 10254 : efb->write_type(this->type_);
4771 : 10254 : efb->write_c_string(", ");
4772 : :
4773 : 10254 : Type* old_context = efb->type_context();
4774 : 10254 : efb->set_type_context(this->type_);
4775 : :
4776 : 10254 : this->expr_->export_expression(efb);
4777 : :
4778 : 10254 : efb->set_type_context(old_context);
4779 : :
4780 : 10254 : efb->write_c_string(")");
4781 : 10254 : }
4782 : :
4783 : : // Import a type conversion or a struct construction.
4784 : :
4785 : : Expression*
4786 : 18058 : Type_conversion_expression::do_import(Import_expression* imp, Location loc)
4787 : : {
4788 : 18058 : imp->require_c_string("$convert(");
4789 : 18058 : Type* type = imp->read_type();
4790 : 18058 : imp->require_c_string(", ");
4791 : 18058 : Expression* val = Expression::import_expression(imp, loc);
4792 : 18058 : imp->require_c_string(")");
4793 : 18058 : return Expression::make_cast(type, val, loc);
4794 : : }
4795 : :
4796 : : // Dump ast representation for a type conversion expression.
4797 : :
4798 : : void
4799 : 0 : Type_conversion_expression::do_dump_expression(
4800 : : Ast_dump_context* ast_dump_context) const
4801 : : {
4802 : 0 : ast_dump_context->dump_type(this->type_);
4803 : 0 : ast_dump_context->ostream() << "(";
4804 : 0 : ast_dump_context->dump_expression(this->expr_);
4805 : 0 : ast_dump_context->ostream() << ") ";
4806 : 0 : }
4807 : :
4808 : : // Make a type cast expression.
4809 : :
4810 : : Expression*
4811 : 3012220 : Expression::make_cast(Type* type, Expression* val, Location location)
4812 : : {
4813 : 3012220 : if (type->is_error_type() || val->is_error_expression())
4814 : 512 : return Expression::make_error(location);
4815 : 3011708 : return new Type_conversion_expression(type, val, location);
4816 : : }
4817 : :
4818 : : // Class Unsafe_type_conversion_expression.
4819 : :
4820 : : // Traversal.
4821 : :
4822 : : int
4823 : 1436028 : Unsafe_type_conversion_expression::do_traverse(Traverse* traverse)
4824 : : {
4825 : 1436028 : if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
4826 : 1436028 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
4827 : 70884 : return TRAVERSE_EXIT;
4828 : : return TRAVERSE_CONTINUE;
4829 : : }
4830 : :
4831 : : // Return whether an unsafe type conversion can be used as a constant
4832 : : // initializer.
4833 : :
4834 : : bool
4835 : 184 : Unsafe_type_conversion_expression::do_is_static_initializer() const
4836 : : {
4837 : 184 : Type* type = this->type_;
4838 : 184 : Type* expr_type = this->expr_->type();
4839 : :
4840 : 368 : if (type->interface_type() != NULL
4841 : 184 : || expr_type->interface_type() != NULL)
4842 : 0 : return false;
4843 : :
4844 : 184 : if (!this->expr_->is_static_initializer())
4845 : : return false;
4846 : :
4847 : 0 : if (Type::are_convertible(type, expr_type, NULL))
4848 : : return true;
4849 : :
4850 : 0 : if (type->is_string_type() && expr_type->is_string_type())
4851 : : return true;
4852 : :
4853 : 0 : if ((type->is_numeric_type()
4854 : 0 : || type->is_boolean_type()
4855 : 0 : || type->points_to() != NULL)
4856 : 0 : && (expr_type->is_numeric_type()
4857 : 0 : || expr_type->is_boolean_type()
4858 : 0 : || expr_type->points_to() != NULL))
4859 : 0 : return true;
4860 : :
4861 : : return false;
4862 : : }
4863 : :
4864 : : // Copy.
4865 : :
4866 : : Expression*
4867 : 0 : Unsafe_type_conversion_expression::do_copy()
4868 : : {
4869 : 0 : return new Unsafe_type_conversion_expression(this->type_->copy_expressions(),
4870 : 0 : this->expr_->copy(),
4871 : 0 : this->location());
4872 : : }
4873 : :
4874 : : // Convert to backend representation.
4875 : :
4876 : : Bexpression*
4877 : 741064 : Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
4878 : : {
4879 : : // We are only called for a limited number of cases.
4880 : :
4881 : 741064 : Type* t = this->type_;
4882 : 741064 : Type* et = this->expr_->type();
4883 : :
4884 : 741064 : if (t->is_error_type()
4885 : 741064 : || this->expr_->is_error_expression()
4886 : 1482128 : || et->is_error_type())
4887 : : {
4888 : 0 : go_assert(saw_errors());
4889 : 0 : return context->backend()->error_expression();
4890 : : }
4891 : :
4892 : 741064 : if (t->array_type() != NULL)
4893 : 58490 : go_assert(et->array_type() != NULL
4894 : : && t->is_slice_type() == et->is_slice_type());
4895 : 711819 : else if (t->struct_type() != NULL)
4896 : : {
4897 : 36 : if (t->named_type() != NULL
4898 : 30 : && et->named_type() != NULL
4899 : 58 : && !Type::are_convertible(t, et, NULL))
4900 : : {
4901 : 0 : go_assert(saw_errors());
4902 : 0 : return context->backend()->error_expression();
4903 : : }
4904 : :
4905 : 72 : go_assert(et->struct_type() != NULL
4906 : : && Type::are_convertible(t, et, NULL));
4907 : : }
4908 : 711783 : else if (t->map_type() != NULL)
4909 : 21419 : go_assert(et->map_type() != NULL || et->points_to() != NULL);
4910 : 690762 : else if (t->channel_type() != NULL)
4911 : 9220 : go_assert(et->channel_type() != NULL || et->points_to() != NULL);
4912 : 681655 : else if (t->points_to() != NULL)
4913 : 615205 : go_assert(et->points_to() != NULL
4914 : : || et->channel_type() != NULL
4915 : : || et->map_type() != NULL
4916 : : || et->function_type() != NULL
4917 : : || et->integer_type() != NULL
4918 : : || et->is_nil_type());
4919 : 114546 : else if (t->function_type() != NULL)
4920 : 1343 : go_assert(et->points_to() != NULL);
4921 : 113203 : else if (et->is_unsafe_pointer_type())
4922 : 44766 : go_assert(t->points_to() != NULL
4923 : : || (t->integer_type() != NULL
4924 : : && t->integer_type() == Type::lookup_integer_type("uintptr")->real_type()));
4925 : 98281 : else if (t->interface_type() != NULL)
4926 : : {
4927 : 79976 : bool empty_iface = t->interface_type()->is_empty();
4928 : 119964 : go_assert(et->interface_type() != NULL
4929 : : && et->interface_type()->is_empty() == empty_iface);
4930 : : }
4931 : 58293 : else if (t->integer_type() != NULL)
4932 : 866476 : go_assert(et->is_boolean_type()
4933 : : || et->integer_type() != NULL
4934 : : || et->function_type() != NULL
4935 : : || et->points_to() != NULL
4936 : : || et->map_type() != NULL
4937 : : || et->channel_type() != NULL
4938 : : || et->is_nil_type());
4939 : : else
4940 : 0 : go_unreachable();
4941 : :
4942 : 741064 : Gogo* gogo = context->gogo();
4943 : 741064 : Btype* btype = t->get_backend(gogo);
4944 : 741064 : Bexpression* bexpr = this->expr_->get_backend(context);
4945 : 741064 : Location loc = this->location();
4946 : 741064 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4947 : : }
4948 : :
4949 : : // Dump ast representation for an unsafe type conversion expression.
4950 : :
4951 : : void
4952 : 0 : Unsafe_type_conversion_expression::do_dump_expression(
4953 : : Ast_dump_context* ast_dump_context) const
4954 : : {
4955 : 0 : ast_dump_context->dump_type(this->type_);
4956 : 0 : ast_dump_context->ostream() << "(";
4957 : 0 : ast_dump_context->dump_expression(this->expr_);
4958 : 0 : ast_dump_context->ostream() << ") ";
4959 : 0 : }
4960 : :
4961 : : // Make an unsafe type conversion expression.
4962 : :
4963 : : Expression*
4964 : 780267 : Expression::make_unsafe_cast(Type* type, Expression* expr,
4965 : : Location location)
4966 : : {
4967 : 780267 : return new Unsafe_type_conversion_expression(type, expr, location);
4968 : : }
4969 : :
4970 : : // Class Unary_expression.
4971 : :
4972 : : // Call the address_taken method of the operand if needed. This is
4973 : : // called after escape analysis but before inserting write barriers.
4974 : :
4975 : : void
4976 : 826472 : Unary_expression::check_operand_address_taken(Gogo*)
4977 : : {
4978 : 826472 : if (this->op_ != OPERATOR_AND)
4979 : : return;
4980 : :
4981 : : // If this->escapes_ is false at this point, then it was set to
4982 : : // false by an explicit call to set_does_not_escape, and the value
4983 : : // does not escape. If this->escapes_ is true, we may be able to
4984 : : // set it to false based on the escape analysis pass.
4985 : 205232 : if (this->escapes_)
4986 : : {
4987 : 176941 : Node* n = Node::make_node(this);
4988 : 176941 : if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
4989 : 129249 : this->escapes_ = false;
4990 : : }
4991 : :
4992 : 205232 : this->expr_->address_taken(this->escapes_);
4993 : : }
4994 : :
4995 : : // If we are taking the address of a composite literal, and the
4996 : : // contents are not constant, then we want to make a heap expression
4997 : : // instead.
4998 : :
4999 : : Expression*
5000 : 1636944 : Unary_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*)
5001 : : {
5002 : 1636944 : Location loc = this->location();
5003 : :
5004 : 1636944 : if (this->is_error_expression())
5005 : 7 : return Expression::make_error(loc);
5006 : :
5007 : 1636937 : Operator op = this->op_;
5008 : 1636937 : Expression* expr = this->expr_;
5009 : :
5010 : 1636937 : if (expr->is_error_expression())
5011 : 2 : return Expression::make_error(loc);
5012 : :
5013 : 1636935 : if (op == OPERATOR_MULT && expr->is_type_expression())
5014 : : {
5015 : 163 : Expression* ret =
5016 : 163 : Expression::make_type(Type::make_pointer_type(expr->type()), loc);
5017 : 163 : ret->determine_type_no_context(gogo);
5018 : 163 : return ret;
5019 : : }
5020 : :
5021 : : // *&x simplifies to x. *(*T)(unsafe.Pointer)(&x) does not require
5022 : : // moving x to the heap. FIXME: Is it worth doing a real escape
5023 : : // analysis here? This case is found in math/unsafe.go and is
5024 : : // therefore worth special casing.
5025 : 1636772 : if (op == OPERATOR_MULT)
5026 : : {
5027 : : Expression* e = expr;
5028 : 1187203 : while (e->classification() == EXPRESSION_CONVERSION)
5029 : : {
5030 : 20844 : Type_conversion_expression* te
5031 : : = static_cast<Type_conversion_expression*>(e);
5032 : 20844 : e = te->expr();
5033 : : }
5034 : :
5035 : 1166359 : if (e->classification() == EXPRESSION_UNARY)
5036 : : {
5037 : 2957 : Unary_expression* ue = static_cast<Unary_expression*>(e);
5038 : 2957 : if (ue->op_ == OPERATOR_AND)
5039 : : {
5040 : 1069 : if (e == expr)
5041 : : {
5042 : : // *&x == x.
5043 : 24 : if (!ue->expr_->is_addressable() && !ue->create_temp_)
5044 : : {
5045 : 0 : go_error_at(ue->location(),
5046 : : "invalid operand for unary %<&%>");
5047 : 0 : this->set_is_error();
5048 : : }
5049 : 24 : return ue->expr_;
5050 : : }
5051 : 1045 : ue->set_does_not_escape();
5052 : : }
5053 : : }
5054 : : }
5055 : :
5056 : : // Check for an invalid pointer dereference. We need to do this
5057 : : // here because Unary_expression::do_type will return an error type
5058 : : // in this case. That can cause code to appear erroneous, and
5059 : : // therefore disappear at lowering time, without any error message.
5060 : 1166335 : if (op == OPERATOR_MULT && expr->type()->points_to() == NULL)
5061 : : {
5062 : 0 : this->report_error(_("expected pointer"));
5063 : 0 : return Expression::make_error(this->location());
5064 : : }
5065 : :
5066 : 1636748 : if (op == OPERATOR_PLUS || op == OPERATOR_MINUS || op == OPERATOR_XOR)
5067 : : {
5068 : 88063 : Numeric_constant nc;
5069 : 88063 : if (expr->numeric_constant_value(&nc))
5070 : : {
5071 : 64337 : Numeric_constant result;
5072 : 64337 : bool issued_error;
5073 : 64337 : if (Unary_expression::eval_constant(this->type_, op, &nc, loc,
5074 : : &result, &issued_error))
5075 : : {
5076 : 64337 : Expression* ret = result.expression(loc);
5077 : 64337 : Type_context subcontext(this->type_, this->type_->is_abstract());
5078 : 64337 : ret->determine_type(gogo, &subcontext);
5079 : 64337 : ret->check_types(gogo);
5080 : 64337 : return ret;
5081 : : }
5082 : 0 : else if (issued_error)
5083 : 0 : return Expression::make_error(this->location());
5084 : 64337 : }
5085 : 88063 : }
5086 : :
5087 : 1572411 : return this;
5088 : : }
5089 : :
5090 : : // Flatten expression if a nil check must be performed and create temporary
5091 : : // variables if necessary.
5092 : :
5093 : : Expression*
5094 : 1372633 : Unary_expression::do_flatten(Gogo* gogo, Named_object*,
5095 : : Statement_inserter* inserter)
5096 : : {
5097 : 1372633 : if (this->is_error_expression()
5098 : 1372633 : || this->expr_->is_error_expression()
5099 : 2745266 : || this->expr_->type()->is_error_type())
5100 : : {
5101 : 0 : go_assert(saw_errors());
5102 : 0 : return Expression::make_error(this->location());
5103 : : }
5104 : :
5105 : 1372633 : Location location = this->location();
5106 : 1372633 : if (this->op_ == OPERATOR_MULT
5107 : 1372633 : && !this->expr_->is_multi_eval_safe())
5108 : : {
5109 : 176468 : go_assert(this->expr_->type()->points_to() != NULL);
5110 : 176468 : switch (this->requires_nil_check(gogo))
5111 : : {
5112 : 0 : case NIL_CHECK_ERROR_ENCOUNTERED:
5113 : 0 : {
5114 : 0 : go_assert(saw_errors());
5115 : 0 : return Expression::make_error(this->location());
5116 : : }
5117 : : case NIL_CHECK_NOT_NEEDED:
5118 : : break;
5119 : 4142 : case NIL_CHECK_NEEDED:
5120 : 4142 : this->create_temp_ = true;
5121 : 4142 : break;
5122 : 0 : case NIL_CHECK_DEFAULT:
5123 : 0 : go_unreachable();
5124 : : }
5125 : : }
5126 : :
5127 : 1372633 : if (this->create_temp_ && !this->expr_->is_multi_eval_safe())
5128 : : {
5129 : 12729 : Temporary_statement* temp =
5130 : 12729 : Statement::make_temporary(NULL, this->expr_, location);
5131 : 12729 : inserter->insert(temp);
5132 : 12729 : this->expr_ = Expression::make_temporary_reference(temp, location);
5133 : : }
5134 : :
5135 : 1372633 : return this;
5136 : : }
5137 : :
5138 : : // Return whether a unary expression is a constant.
5139 : :
5140 : : bool
5141 : 334212 : Unary_expression::do_is_constant() const
5142 : : {
5143 : 334212 : if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
5144 : : {
5145 : : // These are not constant by Go language rules.
5146 : : return false;
5147 : : }
5148 : : else
5149 : 39473 : return this->expr_->is_constant();
5150 : : }
5151 : :
5152 : : bool
5153 : 234006 : Unary_expression::do_is_untyped(Type** ptype) const
5154 : : {
5155 : 234006 : if (this->type_ != NULL)
5156 : 144 : return Expression::is_untyped_type(this->type_, ptype);
5157 : :
5158 : 233862 : if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
5159 : : return false;
5160 : 28276 : return this->expr_->is_untyped(ptype);
5161 : : }
5162 : :
5163 : : // Return whether a unary expression can be used as a constant
5164 : : // initializer.
5165 : :
5166 : : bool
5167 : 1021262 : Unary_expression::do_is_static_initializer() const
5168 : : {
5169 : 1021262 : if (this->op_ == OPERATOR_MULT)
5170 : : return false;
5171 : 1021247 : else if (this->op_ == OPERATOR_AND)
5172 : 1021241 : return Unary_expression::base_is_static_initializer(this->expr_);
5173 : : else
5174 : 6 : return this->expr_->is_static_initializer();
5175 : : }
5176 : :
5177 : : // Return whether the address of EXPR can be used as a static
5178 : : // initializer.
5179 : :
5180 : : bool
5181 : 1021293 : Unary_expression::base_is_static_initializer(Expression* expr)
5182 : : {
5183 : : // The address of a field reference can be a static initializer if
5184 : : // the base can be a static initializer.
5185 : 1022113 : Field_reference_expression* fre = expr->field_reference_expression();
5186 : 1022113 : if (fre != NULL)
5187 : 820 : return Unary_expression::base_is_static_initializer(fre->expr());
5188 : :
5189 : : // The address of an index expression can be a static initializer if
5190 : : // the base can be a static initializer and the index is constant.
5191 : 1021293 : Array_index_expression* aind = expr->array_index_expression();
5192 : 1021293 : if (aind != NULL)
5193 : 52 : return (aind->end() == NULL
5194 : 52 : && aind->start()->is_constant()
5195 : 104 : && Unary_expression::base_is_static_initializer(aind->array()));
5196 : :
5197 : : // The address of a global variable can be a static initializer.
5198 : 1021241 : Var_expression* ve = expr->var_expression();
5199 : 1021241 : if (ve != NULL)
5200 : : {
5201 : 20904 : Named_object* no = ve->named_object();
5202 : 20904 : return no->is_variable() && no->var_value()->is_global();
5203 : : }
5204 : :
5205 : : // The address of a composite literal can be used as a static
5206 : : // initializer if the composite literal is itself usable as a
5207 : : // static initializer.
5208 : 1000337 : if (expr->is_composite_literal() && expr->is_static_initializer())
5209 : : return true;
5210 : :
5211 : : // The address of a string constant can be used as a static
5212 : : // initializer. This can not be written in Go itself but this is
5213 : : // used when building a type descriptor.
5214 : 1020916 : if (expr->string_expression() != NULL)
5215 : : return true;
5216 : :
5217 : : return false;
5218 : : }
5219 : :
5220 : : // Return whether this dereference expression requires an explicit nil
5221 : : // check. If we are dereferencing the pointer to a large struct
5222 : : // (greater than the specified size threshold), we need to check for
5223 : : // nil. We don't bother to check for small structs because we expect
5224 : : // the system to crash on a nil pointer dereference. However, if we
5225 : : // know the address of this expression is being taken, we must always
5226 : : // check for nil.
5227 : : Unary_expression::Nil_check_classification
5228 : 1277279 : Unary_expression::requires_nil_check(Gogo* gogo)
5229 : : {
5230 : 1277279 : go_assert(this->op_ == OPERATOR_MULT);
5231 : 1277279 : go_assert(this->expr_->type()->points_to() != NULL);
5232 : :
5233 : 1277279 : if (this->issue_nil_check_ == NIL_CHECK_NEEDED)
5234 : : return NIL_CHECK_NEEDED;
5235 : 1208649 : else if (this->issue_nil_check_ == NIL_CHECK_NOT_NEEDED)
5236 : : return NIL_CHECK_NOT_NEEDED;
5237 : :
5238 : 560866 : Type* ptype = this->expr_->type()->points_to();
5239 : 560866 : int64_t type_size = -1;
5240 : 560866 : if (!ptype->is_void_type())
5241 : : {
5242 : 560866 : bool ok = ptype->backend_type_size(gogo, &type_size);
5243 : 560866 : if (!ok)
5244 : : return NIL_CHECK_ERROR_ENCOUNTERED;
5245 : : }
5246 : :
5247 : 560866 : int64_t size_cutoff = gogo->nil_check_size_threshold();
5248 : 560866 : if (size_cutoff == -1 || (type_size != -1 && type_size >= size_cutoff))
5249 : 15662 : this->issue_nil_check_ = NIL_CHECK_NEEDED;
5250 : : else
5251 : 545204 : this->issue_nil_check_ = NIL_CHECK_NOT_NEEDED;
5252 : 560866 : return this->issue_nil_check_;
5253 : : }
5254 : :
5255 : : // Apply unary opcode OP to UNC, setting NC. Return true if this
5256 : : // could be done, false if not. On overflow, issues an error and sets
5257 : : // *ISSUED_ERROR.
5258 : :
5259 : : bool
5260 : 81790 : Unary_expression::eval_constant(Type* type, Operator op,
5261 : : const Numeric_constant* unc,
5262 : : Location location, Numeric_constant* nc,
5263 : : bool* issued_error)
5264 : : {
5265 : 81790 : *issued_error = false;
5266 : 81790 : switch (op)
5267 : : {
5268 : 1029 : case OPERATOR_PLUS:
5269 : 1029 : *nc = *unc;
5270 : 1029 : return true;
5271 : :
5272 : 71699 : case OPERATOR_MINUS:
5273 : 71699 : if (unc->is_int() || unc->is_rune())
5274 : : break;
5275 : 4061 : else if (unc->is_float())
5276 : : {
5277 : 4051 : mpfr_t uval;
5278 : 4051 : unc->get_float(&uval);
5279 : 4051 : mpfr_t val;
5280 : 4051 : mpfr_init(val);
5281 : 4051 : mpfr_neg(val, uval, MPFR_RNDN);
5282 : 4051 : Type* utype = unc->type();
5283 : 4051 : if (type != NULL
5284 : 4051 : && type->is_abstract()
5285 : 6024 : && type->is_numeric_type())
5286 : : utype = type;
5287 : 4051 : nc->set_float(utype, val);
5288 : 4051 : mpfr_clear(uval);
5289 : 4051 : mpfr_clear(val);
5290 : 4051 : return true;
5291 : : }
5292 : 10 : else if (unc->is_complex())
5293 : : {
5294 : 10 : mpc_t uval;
5295 : 10 : unc->get_complex(&uval);
5296 : 10 : mpc_t val;
5297 : 10 : mpc_init2(val, mpc_precision);
5298 : 10 : mpc_neg(val, uval, MPC_RNDNN);
5299 : 10 : Type* utype = unc->type();
5300 : 10 : if (type != NULL
5301 : 10 : && type->is_abstract()
5302 : 16 : && type->is_numeric_type())
5303 : : utype = type;
5304 : 10 : nc->set_complex(utype, val);
5305 : 10 : mpc_clear(uval);
5306 : 10 : mpc_clear(val);
5307 : 10 : return true;
5308 : : }
5309 : : else
5310 : 0 : go_unreachable();
5311 : :
5312 : : case OPERATOR_XOR:
5313 : : break;
5314 : :
5315 : : case OPERATOR_NOT:
5316 : : case OPERATOR_AND:
5317 : : case OPERATOR_MULT:
5318 : : return false;
5319 : :
5320 : 0 : default:
5321 : 0 : go_unreachable();
5322 : : }
5323 : :
5324 : 76700 : if (!unc->is_int() && !unc->is_rune())
5325 : : return false;
5326 : :
5327 : 76700 : mpz_t uval;
5328 : 76700 : if (unc->is_rune())
5329 : 0 : unc->get_rune(&uval);
5330 : : else
5331 : 76700 : unc->get_int(&uval);
5332 : 76700 : mpz_t val;
5333 : 76700 : mpz_init(val);
5334 : :
5335 : 76700 : switch (op)
5336 : : {
5337 : 67638 : case OPERATOR_MINUS:
5338 : 67638 : mpz_neg(val, uval);
5339 : 67638 : break;
5340 : :
5341 : : case OPERATOR_NOT:
5342 : : mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
5343 : : break;
5344 : :
5345 : 9062 : case OPERATOR_XOR:
5346 : 9062 : {
5347 : 9062 : Type* utype = unc->type();
5348 : 18124 : if (utype->integer_type() == NULL
5349 : 9062 : || utype->integer_type()->is_abstract())
5350 : 124 : mpz_com(val, uval);
5351 : : else
5352 : : {
5353 : : // The number of HOST_WIDE_INTs that it takes to represent
5354 : : // UVAL.
5355 : 8938 : size_t count = ((mpz_sizeinbase(uval, 2)
5356 : : + HOST_BITS_PER_WIDE_INT
5357 : 8938 : - 1)
5358 : : / HOST_BITS_PER_WIDE_INT);
5359 : :
5360 : 8938 : unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
5361 : 8938 : memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
5362 : :
5363 : 17876 : size_t obits = utype->integer_type()->bits();
5364 : :
5365 : 17876 : if (!utype->integer_type()->is_unsigned() && mpz_sgn(uval) < 0)
5366 : : {
5367 : 0 : mpz_t adj;
5368 : 0 : mpz_init_set_ui(adj, 1);
5369 : 0 : mpz_mul_2exp(adj, adj, obits);
5370 : 0 : mpz_add(uval, uval, adj);
5371 : 0 : mpz_clear(adj);
5372 : : }
5373 : :
5374 : 8938 : size_t ecount;
5375 : 8938 : mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
5376 : 8938 : go_assert(ecount <= count);
5377 : :
5378 : : // Trim down to the number of words required by the type.
5379 : 8938 : size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
5380 : : / HOST_BITS_PER_WIDE_INT);
5381 : 8938 : go_assert(ocount <= count);
5382 : :
5383 : 17876 : for (size_t i = 0; i < ocount; ++i)
5384 : 8938 : phwi[i] = ~phwi[i];
5385 : :
5386 : 8938 : size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
5387 : 8938 : if (clearbits != 0)
5388 : 4176 : phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
5389 : 4176 : >> clearbits);
5390 : :
5391 : 8938 : mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
5392 : :
5393 : 17876 : if (!utype->integer_type()->is_unsigned()
5394 : 8938 : && mpz_tstbit(val, obits - 1))
5395 : : {
5396 : 7 : mpz_t adj;
5397 : 7 : mpz_init_set_ui(adj, 1);
5398 : 7 : mpz_mul_2exp(adj, adj, obits);
5399 : 7 : mpz_sub(val, val, adj);
5400 : 7 : mpz_clear(adj);
5401 : : }
5402 : :
5403 : 8938 : delete[] phwi;
5404 : : }
5405 : : }
5406 : : break;
5407 : :
5408 : 0 : default:
5409 : 0 : go_unreachable();
5410 : : }
5411 : :
5412 : 76700 : if (unc->is_rune())
5413 : 0 : nc->set_rune(NULL, val);
5414 : : else
5415 : 76700 : nc->set_int(NULL, val);
5416 : :
5417 : 76700 : mpz_clear(uval);
5418 : 76700 : mpz_clear(val);
5419 : :
5420 : 76700 : if (!nc->set_type(unc->type(), true, location))
5421 : : {
5422 : 0 : *issued_error = true;
5423 : 0 : return false;
5424 : : }
5425 : : return true;
5426 : : }
5427 : :
5428 : : // Return the integral constant value of a unary expression, if it has one.
5429 : :
5430 : : bool
5431 : 38883 : Unary_expression::do_numeric_constant_value(Numeric_constant* nc)
5432 : : {
5433 : 38883 : if (this->is_error_expression())
5434 : : return false;
5435 : :
5436 : 38883 : Numeric_constant unc;
5437 : 38883 : if (!this->expr_->numeric_constant_value(&unc))
5438 : : return false;
5439 : 17453 : bool issued_error;
5440 : 17453 : bool r = Unary_expression::eval_constant(this->type_, this->op_, &unc,
5441 : : this->location(), nc,
5442 : : &issued_error);
5443 : 17453 : if (issued_error)
5444 : 0 : this->set_is_error();
5445 : : return r;
5446 : 38883 : }
5447 : :
5448 : : // Return the boolean constant value of a unary expression, if it has one.
5449 : :
5450 : : bool
5451 : 57888 : Unary_expression::do_boolean_constant_value(bool* val)
5452 : : {
5453 : 57888 : if (this->op_ == OPERATOR_NOT
5454 : 57888 : && this->expr_->boolean_constant_value(val))
5455 : : {
5456 : 295 : *val = !*val;
5457 : 295 : return true;
5458 : : }
5459 : : return false;
5460 : : }
5461 : :
5462 : : // Return the type of a unary expression.
5463 : :
5464 : : Type*
5465 : 20085074 : Unary_expression::do_type()
5466 : : {
5467 : 20085074 : if (this->type_ == NULL)
5468 : : {
5469 : 19586379 : switch (this->op_)
5470 : : {
5471 : 3928484 : case OPERATOR_AND:
5472 : 3928484 : return Type::make_pointer_type(this->expr_->type());
5473 : :
5474 : 15657895 : case OPERATOR_MULT:
5475 : 15657895 : {
5476 : 15657895 : if (this->expr_->is_type_expression())
5477 : 10468 : return Type::make_pointer_type(this->expr_->type());
5478 : :
5479 : 15647427 : Type* subtype = this->expr_->type();
5480 : 15647427 : Type* points_to = subtype->points_to();
5481 : 15647427 : if (points_to == NULL)
5482 : : {
5483 : 1 : this->report_error(_("expected pointer"));
5484 : 1 : this->type_ = Type::make_error_type();
5485 : 1 : return this->type_;
5486 : : }
5487 : : return points_to;
5488 : : }
5489 : :
5490 : 0 : default:
5491 : 0 : go_assert(saw_errors());
5492 : 0 : return Type::make_error_type();
5493 : : }
5494 : : }
5495 : :
5496 : : return this->type_;
5497 : : }
5498 : :
5499 : : // Determine abstract types for a unary expression.
5500 : :
5501 : : void
5502 : 4813043 : Unary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
5503 : : {
5504 : 4813043 : switch (this->op_)
5505 : : {
5506 : 187865 : case OPERATOR_PLUS:
5507 : 187865 : case OPERATOR_MINUS:
5508 : 187865 : case OPERATOR_NOT:
5509 : 187865 : case OPERATOR_XOR:
5510 : 187865 : {
5511 : 187865 : if (this->type_ != NULL)
5512 : 20904 : return;
5513 : :
5514 : 166961 : Type* dummy;
5515 : 166961 : Type_context subcontext(*context);
5516 : 166961 : if (this->expr_->is_untyped(&dummy) && this->expr_->is_constant())
5517 : : {
5518 : : // We evaluate an untyped operator as untyped. Then we
5519 : : // convert it to the desired type. Otherwise we may, for
5520 : : // example, give a useless error for one more than the
5521 : : // most positive integer when it is the operand of a unary
5522 : : // minus.
5523 : 63116 : subcontext.type = NULL;
5524 : 63116 : subcontext.may_be_abstract = true;
5525 : : }
5526 : 166961 : this->expr_->determine_type(gogo, &subcontext);
5527 : :
5528 : 166961 : this->type_ = this->expr_->type();
5529 : :
5530 : : // If this is an untyped expression in a typed context, use
5531 : : // the context type. If this doesn't work we'll report an
5532 : : // error later.
5533 : 166961 : if (this->type_->is_abstract()
5534 : 63381 : && !context->may_be_abstract
5535 : 220962 : && context->type != NULL)
5536 : : {
5537 : 53524 : if (context->type->interface_type() == NULL)
5538 : 53296 : this->type_ = context->type;
5539 : : else
5540 : 228 : this->type_ = this->type_->make_non_abstract_type();
5541 : : }
5542 : : }
5543 : 166961 : break;
5544 : :
5545 : 2926298 : case OPERATOR_AND:
5546 : : // Taking the address of something.
5547 : 2926298 : {
5548 : 2926298 : Type* subtype = (context->type == NULL
5549 : 2926298 : ? NULL
5550 : 2626788 : : context->type->points_to());
5551 : 2926298 : Type_context subcontext(subtype, false);
5552 : 2926298 : this->expr_->determine_type(gogo, &subcontext);
5553 : : }
5554 : 2926298 : break;
5555 : :
5556 : 1698880 : case OPERATOR_MULT:
5557 : 1698880 : {
5558 : 1698880 : if (this->expr_->is_type_expression())
5559 : : {
5560 : 4891 : this->expr_->determine_type_no_context(gogo);
5561 : 4891 : return;
5562 : : }
5563 : :
5564 : : // Indirecting through a pointer.
5565 : 1693989 : Type* subtype = (context->type == NULL
5566 : 1693989 : ? NULL
5567 : 53166 : : Type::make_pointer_type(context->type));
5568 : 1693989 : Type_context subcontext(subtype, false);
5569 : 1693989 : this->expr_->determine_type(gogo, &subcontext);
5570 : : }
5571 : 1693989 : break;
5572 : :
5573 : 0 : default:
5574 : 0 : go_unreachable();
5575 : : }
5576 : : }
5577 : :
5578 : : // Check types for a unary expression.
5579 : :
5580 : : void
5581 : 323039 : Unary_expression::do_check_types(Gogo*)
5582 : : {
5583 : 323039 : if (this->is_error_expression())
5584 : : return;
5585 : :
5586 : 323037 : Type* type = this->expr_->type();
5587 : 323037 : if (type->is_error())
5588 : : {
5589 : 0 : this->set_is_error();
5590 : 0 : return;
5591 : : }
5592 : :
5593 : 323037 : switch (this->op_)
5594 : : {
5595 : 68832 : case OPERATOR_PLUS:
5596 : 68832 : case OPERATOR_MINUS:
5597 : 76687 : if (type->integer_type() == NULL
5598 : 103 : && type->float_type() == NULL
5599 : 323041 : && type->complex_type() == NULL)
5600 : 2 : this->report_error(_("expected numeric type"));
5601 : : break;
5602 : :
5603 : 32185 : case OPERATOR_NOT:
5604 : 32185 : if (!type->is_boolean_type())
5605 : 0 : this->report_error(_("expected boolean type"));
5606 : : break;
5607 : :
5608 : 2582 : case OPERATOR_XOR:
5609 : 2582 : if (type->integer_type() == NULL)
5610 : 2 : this->report_error(_("expected integer"));
5611 : : break;
5612 : :
5613 : 181066 : case OPERATOR_AND:
5614 : 181066 : if (!this->expr_->is_addressable())
5615 : : {
5616 : 4826 : if (!this->create_temp_)
5617 : : {
5618 : 1 : go_error_at(this->location(), "invalid operand for unary %<&%>");
5619 : 1 : this->set_is_error();
5620 : : }
5621 : : }
5622 : : else
5623 : 176240 : this->expr_->issue_nil_check();
5624 : : break;
5625 : :
5626 : 38372 : case OPERATOR_MULT:
5627 : 38372 : if (this->expr_->is_type_expression())
5628 : : break;
5629 : :
5630 : : // Catching an invalid indirection of unsafe.Pointer here avoid
5631 : : // having to deal with TYPE_VOID in other places.
5632 : 38209 : if (this->expr_->type()->is_unsafe_pointer_type())
5633 : : {
5634 : 1 : go_error_at(this->location(),
5635 : : "invalid indirect of %<unsafe.Pointer%>");
5636 : 1 : this->set_is_error();
5637 : 1 : return;
5638 : : }
5639 : :
5640 : : // Indirecting through a pointer.
5641 : 38208 : if (type->points_to() == NULL)
5642 : 0 : this->report_error(_("expected pointer"));
5643 : 38208 : if (type->points_to()->is_error())
5644 : 1 : this->set_is_error();
5645 : : break;
5646 : :
5647 : 0 : default:
5648 : 0 : go_unreachable();
5649 : : }
5650 : : }
5651 : :
5652 : : // Get the backend representation for a unary expression.
5653 : :
5654 : : Bexpression*
5655 : 3039129 : Unary_expression::do_get_backend(Translate_context* context)
5656 : : {
5657 : 3039129 : Gogo* gogo = context->gogo();
5658 : 3039129 : Location loc = this->location();
5659 : :
5660 : : // Taking the address of a set-and-use-temporary expression requires
5661 : : // setting the temporary and then taking the address.
5662 : 3039129 : if (this->op_ == OPERATOR_AND)
5663 : : {
5664 : 1829916 : Set_and_use_temporary_expression* sut =
5665 : 1829916 : this->expr_->set_and_use_temporary_expression();
5666 : 619 : if (sut != NULL)
5667 : : {
5668 : 619 : Temporary_statement* temp = sut->temporary();
5669 : 619 : Bvariable* bvar = temp->get_backend_variable(context);
5670 : 619 : Bexpression* bvar_expr =
5671 : 619 : gogo->backend()->var_expression(bvar, loc);
5672 : 619 : Bexpression* bval = sut->expression()->get_backend(context);
5673 : :
5674 : 619 : Named_object* fn = context->function();
5675 : 619 : go_assert(fn != NULL);
5676 : 619 : Bfunction* bfn =
5677 : 619 : fn->func_value()->get_or_make_decl(gogo, fn);
5678 : 619 : Bstatement* bassign =
5679 : 619 : gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
5680 : 619 : Bexpression* bvar_addr =
5681 : 619 : gogo->backend()->address_expression(bvar_expr, loc);
5682 : 619 : return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
5683 : : }
5684 : : }
5685 : :
5686 : 3038510 : Bexpression* ret;
5687 : 3038510 : Bexpression* bexpr = this->expr_->get_backend(context);
5688 : 3038510 : Btype* btype = (this->type_ == NULL
5689 : 3038510 : ? this->expr_->type()->get_backend(gogo)
5690 : 102250 : : this->type_->get_backend(gogo));
5691 : 3038510 : switch (this->op_)
5692 : : {
5693 : 116 : case OPERATOR_PLUS:
5694 : 116 : ret = gogo->backend()->convert_expression(btype, bexpr, loc);
5695 : 116 : break;
5696 : :
5697 : 10894 : case OPERATOR_MINUS:
5698 : 10894 : ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
5699 : 10894 : ret = gogo->backend()->convert_expression(btype, ret, loc);
5700 : 10894 : break;
5701 : :
5702 : 97392 : case OPERATOR_NOT:
5703 : 97392 : case OPERATOR_XOR:
5704 : 97392 : ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
5705 : 97392 : ret = gogo->backend()->convert_expression(btype, ret, loc);
5706 : 97392 : break;
5707 : :
5708 : 1829297 : case OPERATOR_AND:
5709 : 1829297 : if (!this->create_temp_)
5710 : : {
5711 : : // We should not see a non-constant constructor here; cases
5712 : : // where we would see one should have been moved onto the
5713 : : // heap at parse time. Taking the address of a nonconstant
5714 : : // constructor will not do what the programmer expects.
5715 : :
5716 : 1793958 : go_assert(!this->expr_->is_composite_literal()
5717 : : || this->expr_->is_static_initializer());
5718 : 1793958 : if (this->expr_->classification() == EXPRESSION_UNARY)
5719 : : {
5720 : 3790 : Unary_expression* ue =
5721 : : static_cast<Unary_expression*>(this->expr_);
5722 : 3790 : go_assert(ue->op() != OPERATOR_AND);
5723 : : }
5724 : : }
5725 : :
5726 : 1829297 : if (this->is_gc_root_ || this->is_slice_init_)
5727 : : {
5728 : 289190 : std::string var_name;
5729 : 289190 : bool copy_to_heap = false;
5730 : 289190 : if (this->is_gc_root_)
5731 : : {
5732 : : // Build a decl for a GC root variable. GC roots are mutable, so
5733 : : // they cannot be represented as an immutable_struct in the
5734 : : // backend.
5735 : 2111 : var_name = gogo->gc_root_name();
5736 : : }
5737 : : else
5738 : : {
5739 : : // Build a decl for a slice value initializer. An immutable slice
5740 : : // value initializer may have to be copied to the heap if it
5741 : : // contains pointers in a non-constant context.
5742 : 287079 : var_name = gogo->initializer_name();
5743 : :
5744 : 287079 : Array_type* at = this->expr_->type()->array_type();
5745 : 0 : go_assert(at != NULL);
5746 : :
5747 : : // If we are not copying the value to the heap, we will only
5748 : : // initialize the value once, so we can use this directly
5749 : : // rather than copying it. In that case we can't make it
5750 : : // read-only, because the program is permitted to change it.
5751 : 287079 : copy_to_heap = (context->function() != NULL
5752 : 287079 : || context->is_const());
5753 : : }
5754 : 2111 : unsigned int flags = (Backend::variable_is_hidden
5755 : : | Backend::variable_address_is_taken);
5756 : 2111 : if (copy_to_heap)
5757 : : flags |= Backend::variable_is_constant;
5758 : 289190 : Bvariable* implicit =
5759 : 289190 : gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
5760 : 289190 : gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
5761 : : flags, bexpr);
5762 : 289190 : bexpr = gogo->backend()->var_expression(implicit, loc);
5763 : :
5764 : : // If we are not copying a slice initializer to the heap,
5765 : : // then it can be changed by the program, so if it can
5766 : : // contain pointers we must register it as a GC root.
5767 : 289190 : if (this->is_slice_init_
5768 : 287079 : && !copy_to_heap
5769 : 298053 : && this->expr_->type()->has_pointer())
5770 : : {
5771 : 2660 : Bexpression* root =
5772 : 2660 : gogo->backend()->var_expression(implicit, loc);
5773 : 2660 : root = gogo->backend()->address_expression(root, loc);
5774 : 2660 : Type* type = Type::make_pointer_type(this->expr_->type());
5775 : 2660 : gogo->add_gc_root(Expression::make_backend(root, type, loc));
5776 : : }
5777 : 289190 : }
5778 : 1540107 : else if ((this->expr_->is_composite_literal()
5779 : 1484708 : || this->expr_->string_expression() != NULL)
5780 : 2191062 : && this->expr_->is_static_initializer())
5781 : : {
5782 : 706354 : std::string var_name(gogo->initializer_name());
5783 : 706354 : unsigned int flags = (Backend::variable_is_hidden
5784 : : | Backend::variable_address_is_taken);
5785 : 706354 : Bvariable* decl =
5786 : 706354 : gogo->backend()->immutable_struct(var_name, "", flags, btype, loc);
5787 : 706354 : gogo->backend()->immutable_struct_set_init(decl, var_name, flags,
5788 : : btype, loc, bexpr);
5789 : 706354 : bexpr = gogo->backend()->var_expression(decl, loc);
5790 : 706354 : }
5791 : 833753 : else if (this->expr_->is_constant())
5792 : : {
5793 : 14716 : std::string var_name(gogo->initializer_name());
5794 : 14716 : unsigned int flags = (Backend::variable_is_hidden
5795 : : | Backend::variable_is_constant
5796 : : | Backend::variable_address_is_taken);
5797 : 14716 : Bvariable* decl =
5798 : 14716 : gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
5799 : 14716 : gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
5800 : : flags, bexpr);
5801 : 14716 : bexpr = gogo->backend()->var_expression(decl, loc);
5802 : 14716 : }
5803 : :
5804 : 1829297 : go_assert(!this->create_temp_ || this->expr_->is_multi_eval_safe());
5805 : 1829297 : ret = gogo->backend()->address_expression(bexpr, loc);
5806 : 1829297 : break;
5807 : :
5808 : 1100811 : case OPERATOR_MULT:
5809 : 1100811 : {
5810 : 1100811 : go_assert(this->expr_->type()->points_to() != NULL);
5811 : :
5812 : 1100811 : Type* ptype = this->expr_->type()->points_to();
5813 : 1100811 : Btype* pbtype = ptype->get_backend(gogo);
5814 : 1100811 : switch (this->requires_nil_check(gogo))
5815 : : {
5816 : : case NIL_CHECK_NOT_NEEDED:
5817 : : break;
5818 : 0 : case NIL_CHECK_ERROR_ENCOUNTERED:
5819 : 0 : {
5820 : 0 : go_assert(saw_errors());
5821 : 0 : return gogo->backend()->error_expression();
5822 : : }
5823 : 80150 : case NIL_CHECK_NEEDED:
5824 : 80150 : {
5825 : 80150 : go_assert(this->expr_->is_multi_eval_safe());
5826 : :
5827 : : // If we're nil-checking the result of a set-and-use-temporary
5828 : : // expression, then pick out the target temp and use that
5829 : : // for the final result of the conditional.
5830 : 80150 : Bexpression* tbexpr = bexpr;
5831 : 80150 : Bexpression* ubexpr = bexpr;
5832 : 80150 : Set_and_use_temporary_expression* sut =
5833 : 80150 : this->expr_->set_and_use_temporary_expression();
5834 : 0 : if (sut != NULL) {
5835 : 0 : Temporary_statement* temp = sut->temporary();
5836 : 0 : Bvariable* bvar = temp->get_backend_variable(context);
5837 : 0 : ubexpr = gogo->backend()->var_expression(bvar, loc);
5838 : : }
5839 : 80150 : Bexpression* nil =
5840 : 80150 : Expression::make_nil(loc)->get_backend(context);
5841 : 80150 : Bexpression* compare =
5842 : 80150 : gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr,
5843 : : nil, loc);
5844 : 80150 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM,
5845 : : loc, 0);
5846 : 80150 : crash->determine_type_no_context(gogo);
5847 : 80150 : Bexpression* bcrash = crash->get_backend(context);
5848 : 80150 : Bfunction* bfn = context->function()->func_value()->get_decl();
5849 : 80150 : bexpr = gogo->backend()->conditional_expression(bfn, btype,
5850 : : compare,
5851 : : bcrash, ubexpr,
5852 : : loc);
5853 : 80150 : break;
5854 : : }
5855 : 0 : case NIL_CHECK_DEFAULT:
5856 : 0 : go_unreachable();
5857 : : }
5858 : 1100811 : ret = gogo->backend()->indirect_expression(pbtype, bexpr, false, loc);
5859 : : }
5860 : 1100811 : break;
5861 : :
5862 : 0 : default:
5863 : 0 : go_unreachable();
5864 : : }
5865 : :
5866 : : return ret;
5867 : : }
5868 : :
5869 : : // Export a unary expression.
5870 : :
5871 : : void
5872 : 3143 : Unary_expression::do_export(Export_function_body* efb) const
5873 : : {
5874 : 3143 : switch (this->op_)
5875 : : {
5876 : 0 : case OPERATOR_PLUS:
5877 : 0 : efb->write_c_string("+");
5878 : 0 : break;
5879 : 112 : case OPERATOR_MINUS:
5880 : 112 : efb->write_c_string("-");
5881 : 112 : break;
5882 : 304 : case OPERATOR_NOT:
5883 : 304 : efb->write_c_string("!");
5884 : 304 : break;
5885 : 44 : case OPERATOR_XOR:
5886 : 44 : efb->write_c_string("^");
5887 : 44 : break;
5888 : 1003 : case OPERATOR_AND:
5889 : 1003 : efb->write_c_string("&");
5890 : 1003 : break;
5891 : 1680 : case OPERATOR_MULT:
5892 : 1680 : efb->write_c_string("*");
5893 : 1680 : break;
5894 : 0 : default:
5895 : 0 : go_unreachable();
5896 : : }
5897 : 3143 : this->expr_->export_expression(efb);
5898 : 3143 : }
5899 : :
5900 : : // Import a unary expression.
5901 : :
5902 : : Expression*
5903 : 9633 : Unary_expression::do_import(Import_expression* imp, Location loc)
5904 : : {
5905 : 9633 : Operator op;
5906 : 9633 : switch (imp->get_char())
5907 : : {
5908 : : case '+':
5909 : : op = OPERATOR_PLUS;
5910 : : break;
5911 : 7888 : case '-':
5912 : 7888 : op = OPERATOR_MINUS;
5913 : 7888 : break;
5914 : 537 : case '!':
5915 : 537 : op = OPERATOR_NOT;
5916 : 537 : break;
5917 : 74 : case '^':
5918 : 74 : op = OPERATOR_XOR;
5919 : 74 : break;
5920 : 640 : case '&':
5921 : 640 : op = OPERATOR_AND;
5922 : 640 : break;
5923 : 494 : case '*':
5924 : 494 : op = OPERATOR_MULT;
5925 : 494 : break;
5926 : 0 : default:
5927 : 0 : go_unreachable();
5928 : : }
5929 : 9633 : if (imp->version() < EXPORT_FORMAT_V3)
5930 : 0 : imp->require_c_string(" ");
5931 : 9633 : Expression* expr = Expression::import_expression(imp, loc);
5932 : 9633 : return Expression::make_unary(op, expr, loc);
5933 : : }
5934 : :
5935 : : // Dump ast representation of an unary expression.
5936 : :
5937 : : void
5938 : 0 : Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
5939 : : {
5940 : 0 : ast_dump_context->dump_operator(this->op_);
5941 : 0 : ast_dump_context->ostream() << "(";
5942 : 0 : ast_dump_context->dump_expression(this->expr_);
5943 : 0 : ast_dump_context->ostream() << ") ";
5944 : 0 : }
5945 : :
5946 : : // Make a unary expression.
5947 : :
5948 : : Expression*
5949 : 3784575 : Expression::make_unary(Operator op, Expression* expr, Location location)
5950 : : {
5951 : 3784575 : return new Unary_expression(op, expr, location);
5952 : : }
5953 : :
5954 : : Expression*
5955 : 998807 : Expression::make_dereference(Expression* ptr,
5956 : : Nil_check_classification docheck,
5957 : : Location location)
5958 : : {
5959 : 998807 : Expression* deref = Expression::make_unary(OPERATOR_MULT, ptr, location);
5960 : 998807 : if (docheck == NIL_CHECK_NEEDED)
5961 : 13135 : deref->unary_expression()->set_requires_nil_check(true);
5962 : 985672 : else if (docheck == NIL_CHECK_NOT_NEEDED)
5963 : 434313 : deref->unary_expression()->set_requires_nil_check(false);
5964 : 998807 : return deref;
5965 : : }
5966 : :
5967 : : // If this is an indirection through a pointer, return the expression
5968 : : // being pointed through. Otherwise return this.
5969 : :
5970 : : Expression*
5971 : 9703 : Expression::deref()
5972 : : {
5973 : 9703 : if (this->classification_ == EXPRESSION_UNARY)
5974 : : {
5975 : 4510 : Unary_expression* ue = static_cast<Unary_expression*>(this);
5976 : 4510 : if (ue->op() == OPERATOR_MULT)
5977 : 4510 : return ue->operand();
5978 : : }
5979 : : return this;
5980 : : }
5981 : :
5982 : : // Class Binary_expression.
5983 : :
5984 : : // Traversal.
5985 : :
5986 : : int
5987 : 13842494 : Binary_expression::do_traverse(Traverse* traverse)
5988 : : {
5989 : 13842494 : int t = Expression::traverse(&this->left_, traverse);
5990 : 13842494 : if (t == TRAVERSE_EXIT)
5991 : : return TRAVERSE_EXIT;
5992 : 13461002 : return Expression::traverse(&this->right_, traverse);
5993 : : }
5994 : :
5995 : : // Return whether a binary expression is untyped.
5996 : :
5997 : : bool
5998 : 103757582 : Binary_expression::do_is_untyped(Type** ptype) const
5999 : : {
6000 : 103757582 : if (this->type_ != NULL)
6001 : 13270 : return Expression::is_untyped_type(this->type_, ptype);
6002 : :
6003 : 103744312 : switch (this->op_)
6004 : : {
6005 : 668423 : case OPERATOR_EQEQ:
6006 : 668423 : case OPERATOR_NOTEQ:
6007 : 668423 : case OPERATOR_LT:
6008 : 668423 : case OPERATOR_LE:
6009 : 668423 : case OPERATOR_GT:
6010 : 668423 : case OPERATOR_GE:
6011 : : // Comparisons are untyped by default.
6012 : 668423 : *ptype = Type::make_boolean_type();
6013 : 668423 : return true;
6014 : :
6015 : 205047 : case OPERATOR_LSHIFT:
6016 : 205047 : case OPERATOR_RSHIFT:
6017 : : // A shift operation is untyped if the left hand expression is
6018 : : // untyped. The right hand expression is irrelevant.
6019 : 205047 : return this->left_->is_untyped(ptype);
6020 : :
6021 : 102870842 : default:
6022 : 102870842 : break;
6023 : : }
6024 : :
6025 : 102870842 : Type* tleft;
6026 : 102870842 : Type* tright;
6027 : 102870842 : if (!this->left_->is_untyped(&tleft)
6028 : 102870842 : || !this->right_->is_untyped(&tright))
6029 : 114846 : return false;
6030 : :
6031 : : // If both sides are numeric, pick a type based on the kind.
6032 : 102755996 : enum kind { INT, RUNE, FLOAT, COMPLEX };
6033 : 102755996 : enum kind kleft, kright;
6034 : :
6035 : 102755996 : if (tleft->integer_type() != NULL)
6036 : 35030 : kleft = tleft->integer_type()->is_rune() ? RUNE : INT;
6037 : 102738481 : else if (tleft->float_type() != NULL)
6038 : : kleft = FLOAT;
6039 : 102755997 : else if (tleft->complex_type() != NULL)
6040 : : kleft = COMPLEX;
6041 : : else
6042 : : {
6043 : : // Not numeric. If the types are different, we will report an
6044 : : // error later.
6045 : 102738133 : *ptype = tleft;
6046 : 102738133 : return true;
6047 : : }
6048 : :
6049 : 17863 : if (tright->integer_type() != NULL)
6050 : 34622 : kright = tright->integer_type()->is_rune() ? RUNE : INT;
6051 : 552 : else if (tright->float_type() != NULL)
6052 : : kright = FLOAT;
6053 : 17925 : else if (tright->complex_type() != NULL)
6054 : : kright = COMPLEX;
6055 : : else
6056 : : {
6057 : : // Types are different. We will report an error later.
6058 : 0 : *ptype = tleft;
6059 : 0 : return true;
6060 : : }
6061 : :
6062 : 17863 : if (kleft > kright)
6063 : 303 : *ptype = tleft;
6064 : : else
6065 : 17560 : *ptype = tright;
6066 : :
6067 : : return true;
6068 : : }
6069 : :
6070 : : // Return whether this expression may be used as a static initializer.
6071 : :
6072 : : bool
6073 : 471875 : Binary_expression::do_is_static_initializer() const
6074 : : {
6075 : 471875 : if (!this->left_->is_static_initializer()
6076 : 471875 : || !this->right_->is_static_initializer())
6077 : 351 : return false;
6078 : :
6079 : : // Addresses can be static initializers, but we can't implement
6080 : : // arbitray binary expressions of them.
6081 : 471524 : Unary_expression* lu = this->left_->unary_expression();
6082 : 471524 : Unary_expression* ru = this->right_->unary_expression();
6083 : 471524 : if (lu != NULL && lu->op() == OPERATOR_AND)
6084 : : {
6085 : 0 : if (ru != NULL && ru->op() == OPERATOR_AND)
6086 : 0 : return this->op_ == OPERATOR_MINUS;
6087 : : else
6088 : 0 : return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
6089 : : }
6090 : 471524 : else if (ru != NULL && ru->op() == OPERATOR_AND)
6091 : 0 : return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
6092 : :
6093 : : // Other cases should resolve in the backend.
6094 : : return true;
6095 : : }
6096 : :
6097 : : // Return the type to use for a binary operation on operands of
6098 : : // LEFT_TYPE and RIGHT_TYPE. These are the types of constants and as
6099 : : // such may be NULL or abstract.
6100 : :
6101 : : bool
6102 : 1303370 : Binary_expression::operation_type(Operator op, Type* left_type,
6103 : : Type* right_type, Type** result_type)
6104 : : {
6105 : 1303370 : if (left_type != right_type
6106 : 185472 : && !left_type->is_abstract()
6107 : 81373 : && !right_type->is_abstract()
6108 : 81090 : && left_type->base() != right_type->base()
6109 : : && op != OPERATOR_LSHIFT
6110 : 1310014 : && op != OPERATOR_RSHIFT)
6111 : : {
6112 : : // May be a type error--let it be diagnosed elsewhere.
6113 : : return false;
6114 : : }
6115 : :
6116 : 1303359 : if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
6117 : : {
6118 : 110634 : if (left_type->integer_type() != NULL)
6119 : 110625 : *result_type = left_type;
6120 : : else
6121 : 9 : *result_type = Type::make_abstract_integer_type();
6122 : : }
6123 : 1192725 : else if (!left_type->is_abstract() && left_type->named_type() != NULL)
6124 : 911554 : *result_type = left_type;
6125 : 281171 : else if (!right_type->is_abstract() && right_type->named_type() != NULL)
6126 : 306 : *result_type = right_type;
6127 : 280865 : else if (!left_type->is_abstract())
6128 : 0 : *result_type = left_type;
6129 : 280865 : else if (!right_type->is_abstract())
6130 : 0 : *result_type = right_type;
6131 : 280865 : else if (left_type->complex_type() != NULL)
6132 : 1431 : *result_type = left_type;
6133 : 279434 : else if (right_type->complex_type() != NULL)
6134 : 400 : *result_type = right_type;
6135 : 279034 : else if (left_type->float_type() != NULL)
6136 : 2613 : *result_type = left_type;
6137 : 276421 : else if (right_type->float_type() != NULL)
6138 : 148 : *result_type = right_type;
6139 : 463438 : else if (left_type->integer_type() != NULL
6140 : 187165 : && left_type->integer_type()->is_rune())
6141 : 2104 : *result_type = left_type;
6142 : 459230 : else if (right_type->integer_type() != NULL
6143 : 185061 : && right_type->integer_type()->is_rune())
6144 : 65 : *result_type = right_type;
6145 : : else
6146 : 274104 : *result_type = left_type;
6147 : :
6148 : : return true;
6149 : : }
6150 : :
6151 : : // Convert an integer comparison code and an operator to a boolean
6152 : : // value.
6153 : :
6154 : : bool
6155 : 2996 : Binary_expression::cmp_to_bool(Operator op, int cmp)
6156 : : {
6157 : 2996 : switch (op)
6158 : : {
6159 : 2268 : case OPERATOR_EQEQ:
6160 : 2268 : return cmp == 0;
6161 : 696 : break;
6162 : 696 : case OPERATOR_NOTEQ:
6163 : 696 : return cmp != 0;
6164 : 14 : break;
6165 : 14 : case OPERATOR_LT:
6166 : 14 : return cmp < 0;
6167 : 0 : break;
6168 : 0 : case OPERATOR_LE:
6169 : 0 : return cmp <= 0;
6170 : 8 : case OPERATOR_GT:
6171 : 8 : return cmp > 0;
6172 : 10 : case OPERATOR_GE:
6173 : 10 : return cmp >= 0;
6174 : 0 : default:
6175 : 0 : go_unreachable();
6176 : : }
6177 : : }
6178 : :
6179 : : // Compare constants according to OP.
6180 : :
6181 : : bool
6182 : 936 : Binary_expression::compare_constant(Operator op, Numeric_constant* left_nc,
6183 : : Numeric_constant* right_nc,
6184 : : Location location, bool* result)
6185 : : {
6186 : 936 : Type* left_type = left_nc->type();
6187 : 936 : Type* right_type = right_nc->type();
6188 : :
6189 : 936 : Type* type;
6190 : 936 : if (!Binary_expression::operation_type(op, left_type, right_type, &type))
6191 : : return false;
6192 : :
6193 : : // When comparing an untyped operand to a typed operand, we are
6194 : : // effectively coercing the untyped operand to the other operand's
6195 : : // type, so make sure that is valid.
6196 : 936 : if (!left_nc->set_type(type, true, location)
6197 : 936 : || !right_nc->set_type(type, true, location))
6198 : 0 : return false;
6199 : :
6200 : 936 : bool ret;
6201 : 936 : int cmp;
6202 : 936 : if (type->complex_type() != NULL)
6203 : : {
6204 : 7 : if (op != OPERATOR_EQEQ && op != OPERATOR_NOTEQ)
6205 : : return false;
6206 : 7 : ret = Binary_expression::compare_complex(left_nc, right_nc, &cmp);
6207 : : }
6208 : 929 : else if (type->float_type() != NULL)
6209 : 28 : ret = Binary_expression::compare_float(left_nc, right_nc, &cmp);
6210 : : else
6211 : 901 : ret = Binary_expression::compare_integer(left_nc, right_nc, &cmp);
6212 : :
6213 : 936 : if (ret)
6214 : 936 : *result = Binary_expression::cmp_to_bool(op, cmp);
6215 : :
6216 : : return ret;
6217 : : }
6218 : :
6219 : : // Compare integer constants.
6220 : :
6221 : : bool
6222 : 901 : Binary_expression::compare_integer(const Numeric_constant* left_nc,
6223 : : const Numeric_constant* right_nc,
6224 : : int* cmp)
6225 : : {
6226 : 901 : mpz_t left_val;
6227 : 901 : if (!left_nc->to_int(&left_val))
6228 : : return false;
6229 : 901 : mpz_t right_val;
6230 : 901 : if (!right_nc->to_int(&right_val))
6231 : : {
6232 : 0 : mpz_clear(left_val);
6233 : 0 : return false;
6234 : : }
6235 : :
6236 : 901 : *cmp = mpz_cmp(left_val, right_val);
6237 : :
6238 : 901 : mpz_clear(left_val);
6239 : 901 : mpz_clear(right_val);
6240 : :
6241 : 901 : return true;
6242 : : }
6243 : :
6244 : : // Compare floating point constants.
6245 : :
6246 : : bool
6247 : 28 : Binary_expression::compare_float(const Numeric_constant* left_nc,
6248 : : const Numeric_constant* right_nc,
6249 : : int* cmp)
6250 : : {
6251 : 28 : mpfr_t left_val;
6252 : 28 : if (!left_nc->to_float(&left_val))
6253 : : return false;
6254 : 28 : mpfr_t right_val;
6255 : 28 : if (!right_nc->to_float(&right_val))
6256 : : {
6257 : 0 : mpfr_clear(left_val);
6258 : 0 : return false;
6259 : : }
6260 : :
6261 : : // We already coerced both operands to the same type. If that type
6262 : : // is not an abstract type, we need to round the values accordingly.
6263 : 28 : Type* type = left_nc->type();
6264 : 28 : if (!type->is_abstract() && type->float_type() != NULL)
6265 : : {
6266 : 30 : int bits = type->float_type()->bits();
6267 : 15 : mpfr_prec_round(left_val, bits, MPFR_RNDN);
6268 : 15 : mpfr_prec_round(right_val, bits, MPFR_RNDN);
6269 : : }
6270 : :
6271 : 28 : *cmp = mpfr_cmp(left_val, right_val);
6272 : :
6273 : 28 : mpfr_clear(left_val);
6274 : 28 : mpfr_clear(right_val);
6275 : :
6276 : 28 : return true;
6277 : : }
6278 : :
6279 : : // Compare complex constants. Complex numbers may only be compared
6280 : : // for equality.
6281 : :
6282 : : bool
6283 : 7 : Binary_expression::compare_complex(const Numeric_constant* left_nc,
6284 : : const Numeric_constant* right_nc,
6285 : : int* cmp)
6286 : : {
6287 : 7 : mpc_t left_val;
6288 : 7 : if (!left_nc->to_complex(&left_val))
6289 : : return false;
6290 : 7 : mpc_t right_val;
6291 : 7 : if (!right_nc->to_complex(&right_val))
6292 : : {
6293 : 0 : mpc_clear(left_val);
6294 : 0 : return false;
6295 : : }
6296 : :
6297 : : // We already coerced both operands to the same type. If that type
6298 : : // is not an abstract type, we need to round the values accordingly.
6299 : 7 : Type* type = left_nc->type();
6300 : 7 : if (!type->is_abstract() && type->complex_type() != NULL)
6301 : : {
6302 : 4 : int bits = type->complex_type()->bits();
6303 : 2 : mpfr_prec_round(mpc_realref(left_val), bits / 2, MPFR_RNDN);
6304 : 2 : mpfr_prec_round(mpc_imagref(left_val), bits / 2, MPFR_RNDN);
6305 : 2 : mpfr_prec_round(mpc_realref(right_val), bits / 2, MPFR_RNDN);
6306 : 2 : mpfr_prec_round(mpc_imagref(right_val), bits / 2, MPFR_RNDN);
6307 : : }
6308 : :
6309 : 7 : *cmp = mpc_cmp(left_val, right_val) != 0;
6310 : :
6311 : 7 : mpc_clear(left_val);
6312 : 7 : mpc_clear(right_val);
6313 : :
6314 : 7 : return true;
6315 : : }
6316 : :
6317 : : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return
6318 : : // true if this could be done, false if not. Issue errors at LOCATION
6319 : : // as appropriate, and sets *ISSUED_ERROR if it did.
6320 : :
6321 : : bool
6322 : 293789 : Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
6323 : : Numeric_constant* right_nc,
6324 : : Location location, Numeric_constant* nc,
6325 : : bool* issued_error)
6326 : : {
6327 : 293789 : *issued_error = false;
6328 : 293789 : switch (op)
6329 : : {
6330 : : case OPERATOR_OROR:
6331 : : case OPERATOR_ANDAND:
6332 : : case OPERATOR_EQEQ:
6333 : : case OPERATOR_NOTEQ:
6334 : : case OPERATOR_LT:
6335 : : case OPERATOR_LE:
6336 : : case OPERATOR_GT:
6337 : : case OPERATOR_GE:
6338 : : // These return boolean values, not numeric.
6339 : : return false;
6340 : 293789 : default:
6341 : 293789 : break;
6342 : : }
6343 : :
6344 : 293789 : Type* left_type = left_nc->type();
6345 : 293789 : Type* right_type = right_nc->type();
6346 : :
6347 : 293789 : Type* type;
6348 : 293789 : if (!Binary_expression::operation_type(op, left_type, right_type, &type))
6349 : : return false;
6350 : :
6351 : 293789 : bool is_shift = op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT;
6352 : :
6353 : : // When combining an untyped operand with a typed operand, we are
6354 : : // effectively coercing the untyped operand to the other operand's
6355 : : // type, so make sure that is valid.
6356 : 293789 : if (!left_nc->set_type(type, true, location))
6357 : : return false;
6358 : 293789 : if (!is_shift && !right_nc->set_type(type, true, location))
6359 : : return false;
6360 : 293789 : if (is_shift
6361 : 293789 : && right_type->integer_type() == NULL
6362 : 293789 : && !right_type->is_abstract())
6363 : : return false;
6364 : :
6365 : 293789 : bool r;
6366 : 293789 : if (type->complex_type() != NULL)
6367 : 1017 : r = Binary_expression::eval_complex(op, left_nc, right_nc, location, nc,
6368 : : issued_error);
6369 : 292772 : else if (type->float_type() != NULL)
6370 : 1832 : r = Binary_expression::eval_float(op, left_nc, right_nc, location, nc,
6371 : : issued_error);
6372 : : else
6373 : 290940 : r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc,
6374 : : issued_error);
6375 : :
6376 : 293789 : if (r)
6377 : : {
6378 : 293789 : r = nc->set_type(type, true, location);
6379 : 293789 : if (!r)
6380 : 12 : *issued_error = true;
6381 : : }
6382 : :
6383 : : return r;
6384 : : }
6385 : :
6386 : : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
6387 : : // integer operations. Return true if this could be done, false if
6388 : : // not.
6389 : :
6390 : : bool
6391 : 290940 : Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
6392 : : const Numeric_constant* right_nc,
6393 : : Location location, Numeric_constant* nc,
6394 : : bool* issued_error)
6395 : : {
6396 : 290940 : mpz_t left_val;
6397 : 290940 : if (!left_nc->to_int(&left_val))
6398 : : return false;
6399 : 290940 : mpz_t right_val;
6400 : 290940 : if (!right_nc->to_int(&right_val))
6401 : : {
6402 : 0 : mpz_clear(left_val);
6403 : 0 : return false;
6404 : : }
6405 : :
6406 : 290940 : mpz_t val;
6407 : 290940 : mpz_init(val);
6408 : :
6409 : 290940 : switch (op)
6410 : : {
6411 : 37572 : case OPERATOR_PLUS:
6412 : 37572 : mpz_add(val, left_val, right_val);
6413 : 37572 : if (mpz_sizeinbase(val, 2) > 0x100000)
6414 : : {
6415 : 0 : go_error_at(location, "constant addition overflow");
6416 : 0 : nc->set_invalid();
6417 : 0 : mpz_set_ui(val, 1);
6418 : 0 : *issued_error = true;
6419 : : }
6420 : : break;
6421 : 27168 : case OPERATOR_MINUS:
6422 : 27168 : mpz_sub(val, left_val, right_val);
6423 : 27168 : if (mpz_sizeinbase(val, 2) > 0x100000)
6424 : : {
6425 : 0 : go_error_at(location, "constant subtraction overflow");
6426 : 0 : nc->set_invalid();
6427 : 0 : mpz_set_ui(val, 1);
6428 : 0 : *issued_error = true;
6429 : : }
6430 : : break;
6431 : 6872 : case OPERATOR_OR:
6432 : 6872 : mpz_ior(val, left_val, right_val);
6433 : 6872 : break;
6434 : 22 : case OPERATOR_XOR:
6435 : 22 : mpz_xor(val, left_val, right_val);
6436 : 22 : break;
6437 : 95429 : case OPERATOR_MULT:
6438 : 95429 : mpz_mul(val, left_val, right_val);
6439 : 95429 : if (mpz_sizeinbase(val, 2) > 0x100000)
6440 : : {
6441 : 1 : go_error_at(location, "constant multiplication overflow");
6442 : 1 : nc->set_invalid();
6443 : 1 : mpz_set_ui(val, 1);
6444 : 1 : *issued_error = true;
6445 : : }
6446 : : break;
6447 : 12095 : case OPERATOR_DIV:
6448 : 12095 : if (mpz_sgn(right_val) != 0)
6449 : 12095 : mpz_tdiv_q(val, left_val, right_val);
6450 : : else
6451 : : {
6452 : 0 : go_error_at(location, "division by zero");
6453 : 0 : nc->set_invalid();
6454 : 0 : mpz_set_ui(val, 0);
6455 : 0 : *issued_error = true;
6456 : : }
6457 : : break;
6458 : 118 : case OPERATOR_MOD:
6459 : 118 : if (mpz_sgn(right_val) != 0)
6460 : 118 : mpz_tdiv_r(val, left_val, right_val);
6461 : : else
6462 : : {
6463 : 0 : go_error_at(location, "division by zero");
6464 : 0 : nc->set_invalid();
6465 : 0 : mpz_set_ui(val, 0);
6466 : 0 : *issued_error = true;
6467 : : }
6468 : : break;
6469 : 103065 : case OPERATOR_LSHIFT:
6470 : 103065 : {
6471 : 103065 : unsigned long shift = mpz_get_ui(right_val);
6472 : 103065 : if (mpz_cmp_ui(right_val, shift) == 0 && shift <= 0x100000)
6473 : 103065 : mpz_mul_2exp(val, left_val, shift);
6474 : : else
6475 : : {
6476 : 0 : go_error_at(location, "shift count overflow");
6477 : 0 : nc->set_invalid();
6478 : 0 : mpz_set_ui(val, 1);
6479 : 0 : *issued_error = true;
6480 : : }
6481 : : break;
6482 : : }
6483 : : break;
6484 : 7569 : case OPERATOR_RSHIFT:
6485 : 7569 : {
6486 : 7569 : unsigned long shift = mpz_get_ui(right_val);
6487 : 7569 : if (mpz_cmp_ui(right_val, shift) != 0)
6488 : : {
6489 : 0 : go_error_at(location, "shift count overflow");
6490 : 0 : nc->set_invalid();
6491 : 0 : mpz_set_ui(val, 1);
6492 : 0 : *issued_error = true;
6493 : : }
6494 : : else
6495 : : {
6496 : 7569 : if (mpz_cmp_ui(left_val, 0) >= 0)
6497 : 7557 : mpz_tdiv_q_2exp(val, left_val, shift);
6498 : : else
6499 : 12 : mpz_fdiv_q_2exp(val, left_val, shift);
6500 : : }
6501 : : break;
6502 : : }
6503 : : break;
6504 : 964 : case OPERATOR_AND:
6505 : 964 : mpz_and(val, left_val, right_val);
6506 : 964 : break;
6507 : 66 : case OPERATOR_BITCLEAR:
6508 : 66 : {
6509 : 66 : mpz_t tval;
6510 : 66 : mpz_init(tval);
6511 : 66 : mpz_com(tval, right_val);
6512 : 66 : mpz_and(val, left_val, tval);
6513 : 66 : mpz_clear(tval);
6514 : : }
6515 : 66 : break;
6516 : 0 : default:
6517 : 0 : go_unreachable();
6518 : : }
6519 : :
6520 : 290940 : mpz_clear(left_val);
6521 : 290940 : mpz_clear(right_val);
6522 : :
6523 : 290940 : if (left_nc->is_rune()
6524 : 290940 : || (op != OPERATOR_LSHIFT
6525 : 289286 : && op != OPERATOR_RSHIFT
6526 : 178654 : && right_nc->is_rune()))
6527 : 1703 : nc->set_rune(NULL, val);
6528 : : else
6529 : 289237 : nc->set_int(NULL, val);
6530 : :
6531 : 290940 : mpz_clear(val);
6532 : :
6533 : 290940 : return true;
6534 : : }
6535 : :
6536 : : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
6537 : : // floating point operations. Return true if this could be done,
6538 : : // false if not.
6539 : :
6540 : : bool
6541 : 1832 : Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
6542 : : const Numeric_constant* right_nc,
6543 : : Location location, Numeric_constant* nc,
6544 : : bool* issued_error)
6545 : : {
6546 : 1832 : mpfr_t left_val;
6547 : 1832 : if (!left_nc->to_float(&left_val))
6548 : : return false;
6549 : 1832 : mpfr_t right_val;
6550 : 1832 : if (!right_nc->to_float(&right_val))
6551 : : {
6552 : 0 : mpfr_clear(left_val);
6553 : 0 : return false;
6554 : : }
6555 : :
6556 : 1832 : mpfr_t val;
6557 : 1832 : mpfr_init(val);
6558 : :
6559 : 1832 : bool ret = true;
6560 : 1832 : switch (op)
6561 : : {
6562 : 261 : case OPERATOR_PLUS:
6563 : 261 : mpfr_add(val, left_val, right_val, MPFR_RNDN);
6564 : 261 : break;
6565 : 179 : case OPERATOR_MINUS:
6566 : 179 : mpfr_sub(val, left_val, right_val, MPFR_RNDN);
6567 : 179 : break;
6568 : 0 : case OPERATOR_OR:
6569 : 0 : case OPERATOR_XOR:
6570 : 0 : case OPERATOR_AND:
6571 : 0 : case OPERATOR_BITCLEAR:
6572 : 0 : case OPERATOR_MOD:
6573 : 0 : case OPERATOR_LSHIFT:
6574 : 0 : case OPERATOR_RSHIFT:
6575 : 0 : mpfr_set_ui(val, 0, MPFR_RNDN);
6576 : 0 : ret = false;
6577 : 0 : break;
6578 : 480 : case OPERATOR_MULT:
6579 : 480 : mpfr_mul(val, left_val, right_val, MPFR_RNDN);
6580 : 480 : break;
6581 : 912 : case OPERATOR_DIV:
6582 : 912 : if (!mpfr_zero_p(right_val))
6583 : 911 : mpfr_div(val, left_val, right_val, MPFR_RNDN);
6584 : : else
6585 : : {
6586 : 1 : go_error_at(location, "division by zero");
6587 : 1 : nc->set_invalid();
6588 : 1 : mpfr_set_ui(val, 0, MPFR_RNDN);
6589 : 1 : *issued_error = true;
6590 : : }
6591 : : break;
6592 : 0 : default:
6593 : 0 : go_unreachable();
6594 : : }
6595 : :
6596 : 1832 : mpfr_clear(left_val);
6597 : 1832 : mpfr_clear(right_val);
6598 : :
6599 : 1832 : nc->set_float(NULL, val);
6600 : 1832 : mpfr_clear(val);
6601 : :
6602 : 1832 : return ret;
6603 : : }
6604 : :
6605 : : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
6606 : : // complex operations. Return true if this could be done, false if
6607 : : // not.
6608 : :
6609 : : bool
6610 : 1017 : Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
6611 : : const Numeric_constant* right_nc,
6612 : : Location location, Numeric_constant* nc,
6613 : : bool* issued_error)
6614 : : {
6615 : 1017 : mpc_t left_val;
6616 : 1017 : if (!left_nc->to_complex(&left_val))
6617 : : return false;
6618 : 1017 : mpc_t right_val;
6619 : 1017 : if (!right_nc->to_complex(&right_val))
6620 : : {
6621 : 0 : mpc_clear(left_val);
6622 : 0 : return false;
6623 : : }
6624 : :
6625 : 1017 : mpc_t val;
6626 : 1017 : mpc_init2(val, mpc_precision);
6627 : :
6628 : 1017 : bool ret = true;
6629 : 1017 : switch (op)
6630 : : {
6631 : 702 : case OPERATOR_PLUS:
6632 : 702 : mpc_add(val, left_val, right_val, MPC_RNDNN);
6633 : 702 : break;
6634 : 266 : case OPERATOR_MINUS:
6635 : 266 : mpc_sub(val, left_val, right_val, MPC_RNDNN);
6636 : 266 : break;
6637 : 0 : case OPERATOR_OR:
6638 : 0 : case OPERATOR_XOR:
6639 : 0 : case OPERATOR_AND:
6640 : 0 : case OPERATOR_BITCLEAR:
6641 : 0 : case OPERATOR_MOD:
6642 : 0 : case OPERATOR_LSHIFT:
6643 : 0 : case OPERATOR_RSHIFT:
6644 : 0 : mpc_set_ui(val, 0, MPC_RNDNN);
6645 : 0 : ret = false;
6646 : 0 : break;
6647 : 13 : case OPERATOR_MULT:
6648 : 13 : mpc_mul(val, left_val, right_val, MPC_RNDNN);
6649 : 13 : break;
6650 : 36 : case OPERATOR_DIV:
6651 : 36 : if (mpc_cmp_si(right_val, 0) == 0)
6652 : : {
6653 : 5 : go_error_at(location, "division by zero");
6654 : 5 : nc->set_invalid();
6655 : 5 : mpc_set_ui(val, 0, MPC_RNDNN);
6656 : 5 : *issued_error = true;
6657 : 5 : break;
6658 : : }
6659 : 31 : mpc_div(val, left_val, right_val, MPC_RNDNN);
6660 : 31 : break;
6661 : 0 : default:
6662 : 0 : go_unreachable();
6663 : : }
6664 : :
6665 : 1017 : mpc_clear(left_val);
6666 : 1017 : mpc_clear(right_val);
6667 : :
6668 : 1017 : nc->set_complex(NULL, val);
6669 : 1017 : mpc_clear(val);
6670 : :
6671 : 1017 : return ret;
6672 : : }
6673 : :
6674 : : // Lower a binary expression. We have to evaluate constant
6675 : : // expressions now, in order to implement Go's unlimited precision
6676 : : // constants.
6677 : :
6678 : : Expression*
6679 : 1495945 : Binary_expression::do_lower(Gogo* gogo, Named_object*,
6680 : : Statement_inserter* inserter)
6681 : : {
6682 : 1495945 : Location location = this->location();
6683 : :
6684 : 1495945 : if (this->is_error_expression())
6685 : 360 : return Expression::make_error(location);
6686 : :
6687 : 1495585 : Operator op = this->op_;
6688 : 1495585 : Expression* left = this->left_;
6689 : 1495585 : Expression* right = this->right_;
6690 : :
6691 : 1495585 : if (left->is_error_expression() || right->is_error_expression())
6692 : 186 : return Expression::make_error(location);
6693 : :
6694 : 1495399 : const bool is_comparison = (op == OPERATOR_EQEQ
6695 : : || op == OPERATOR_NOTEQ
6696 : : || op == OPERATOR_LT
6697 : : || op == OPERATOR_LE
6698 : : || op == OPERATOR_GT
6699 : 1495399 : || op == OPERATOR_GE);
6700 : :
6701 : : // Numeric constant expressions.
6702 : 1495399 : {
6703 : 1495399 : Numeric_constant left_nc;
6704 : 1495399 : Numeric_constant right_nc;
6705 : 1495399 : if (left->numeric_constant_value(&left_nc)
6706 : 1572541 : && right->numeric_constant_value(&right_nc))
6707 : : {
6708 : 42561 : Expression* ret;
6709 : 42561 : if (is_comparison)
6710 : : {
6711 : 936 : bool result;
6712 : 936 : if (!Binary_expression::compare_constant(op, &left_nc,
6713 : : &right_nc, location,
6714 : : &result))
6715 : 0 : return this;
6716 : 936 : ret = Expression::make_boolean(result, location);
6717 : : }
6718 : : else
6719 : : {
6720 : 41625 : Numeric_constant nc;
6721 : 41625 : bool issued_error;
6722 : 41625 : if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
6723 : : location, &nc,
6724 : : &issued_error))
6725 : : {
6726 : 12 : if (issued_error)
6727 : 12 : return Expression::make_error(location);
6728 : 0 : return this;
6729 : : }
6730 : 41613 : ret = nc.expression(location);
6731 : 41625 : }
6732 : :
6733 : 42549 : Type_context subcontext(this->type_, this->type_->is_abstract());
6734 : 42549 : ret->determine_type(gogo, &subcontext);
6735 : 42549 : ret->check_types(gogo);
6736 : 42549 : return ret;
6737 : : }
6738 : 1495399 : }
6739 : :
6740 : : // String constant expressions.
6741 : : //
6742 : : // Avoid constant folding here if the left and right types are incompatible
6743 : : // (leave the operation intact so that the type checker can complain about it
6744 : : // later on). If concatenating an abstract string with a named string type,
6745 : : // result type needs to be of the named type (see issue 31412).
6746 : 1452838 : if (left->type()->is_string_type()
6747 : 131954 : && right->type()->is_string_type()
6748 : 1584784 : && (left->type()->named_type() == NULL
6749 : 93524 : || right->type()->named_type() == NULL
6750 : 93524 : || left->type()->named_type() == right->type()->named_type()))
6751 : : {
6752 : 131946 : std::string left_string;
6753 : 131946 : std::string right_string;
6754 : 131946 : if (left->string_constant_value(&left_string)
6755 : 178147 : && right->string_constant_value(&right_string))
6756 : : {
6757 : 40346 : Expression* ret = NULL;
6758 : 40346 : if (op == OPERATOR_PLUS)
6759 : : {
6760 : 38286 : delete left;
6761 : 38286 : delete right;
6762 : 38286 : ret = Expression::make_string_typed(left_string + right_string,
6763 : : this->type_, location);
6764 : : }
6765 : 2060 : else if (is_comparison)
6766 : : {
6767 : 2060 : int cmp = left_string.compare(right_string);
6768 : 2060 : bool r = Binary_expression::cmp_to_bool(op, cmp);
6769 : 2060 : delete left;
6770 : 2060 : delete right;
6771 : 2060 : ret = Expression::make_boolean(r, location);
6772 : : }
6773 : :
6774 : 40346 : if (ret != NULL)
6775 : : {
6776 : 40346 : Type_context subcontext(this->type_, this->type_->is_abstract());
6777 : 40346 : ret->determine_type(gogo, &subcontext);
6778 : 40346 : ret->check_types(gogo);
6779 : 40346 : return ret;
6780 : : }
6781 : : }
6782 : 131946 : }
6783 : :
6784 : : // Lower struct, array, and some interface comparisons.
6785 : 1412492 : if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
6786 : : {
6787 : 493390 : if (left->type()->struct_type() != NULL
6788 : 8053 : && right->type()->struct_type() != NULL)
6789 : 8038 : return this->lower_struct_comparison(gogo, inserter);
6790 : 491618 : else if (left->type()->array_type() != NULL
6791 : 14319 : && !left->type()->is_slice_type()
6792 : 17684 : && right->type()->array_type() != NULL
6793 : 8835 : && !right->type()->is_slice_type())
6794 : 8835 : return this->lower_array_comparison(gogo, inserter);
6795 : 557751 : else if ((left->type()->interface_type() != NULL
6796 : 478894 : && right->type()->interface_type() == NULL)
6797 : 768784 : || (left->type()->interface_type() == NULL
6798 : 379177 : && right->type()->interface_type() != NULL))
6799 : 79140 : return this->lower_interface_value_comparison(gogo, inserter);
6800 : : }
6801 : :
6802 : : // Lower string concatenation to String_concat_expression, so that
6803 : : // we can group sequences of string additions.
6804 : 1316479 : if (this->left_->type()->is_string_type() && this->op_ == OPERATOR_PLUS)
6805 : : {
6806 : 16280 : Expression_list* exprs;
6807 : 16280 : String_concat_expression* left_sce =
6808 : 16280 : this->left_->string_concat_expression();
6809 : 16280 : if (left_sce != NULL)
6810 : 5359 : exprs = left_sce->exprs();
6811 : : else
6812 : : {
6813 : 10921 : exprs = new Expression_list();
6814 : 10921 : exprs->push_back(this->left_);
6815 : : }
6816 : :
6817 : 16280 : String_concat_expression* right_sce =
6818 : 16280 : this->right_->string_concat_expression();
6819 : 16280 : if (right_sce != NULL)
6820 : 401 : exprs->append(right_sce->exprs());
6821 : : else
6822 : 15879 : exprs->push_back(this->right_);
6823 : :
6824 : 16280 : return Expression::make_string_concat(exprs);
6825 : : }
6826 : :
6827 : 1300199 : return this;
6828 : : }
6829 : :
6830 : : // Lower a struct comparison.
6831 : :
6832 : : Expression*
6833 : 8038 : Binary_expression::lower_struct_comparison(Gogo* gogo,
6834 : : Statement_inserter* inserter)
6835 : : {
6836 : 8038 : Struct_type* st = this->left_->type()->struct_type();
6837 : 8038 : Struct_type* st2 = this->right_->type()->struct_type();
6838 : 8038 : if (st2 == NULL)
6839 : 0 : return this;
6840 : 8038 : if (st != st2
6841 : 8038 : && !Type::are_identical(st, st2,
6842 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
6843 : : NULL))
6844 : 0 : return this;
6845 : 8038 : if (!Type::are_compatible_for_comparison(true, this->left_->type(),
6846 : 8038 : this->right_->type(), NULL))
6847 : 0 : return this;
6848 : :
6849 : : // See if we can compare using memcmp. As a heuristic, we use
6850 : : // memcmp rather than field references and comparisons if there are
6851 : : // more than two fields.
6852 : 8038 : if (st->compare_is_identity(gogo) && st->total_field_count() > 2)
6853 : 549 : return this->lower_compare_to_memcmp(gogo, inserter);
6854 : :
6855 : 7489 : Location loc = this->location();
6856 : :
6857 : 7489 : Expression* left = this->left_;
6858 : 7489 : Temporary_statement* left_temp = NULL;
6859 : 7489 : if (left->var_expression() == NULL
6860 : 7489 : && left->temporary_reference_expression() == NULL)
6861 : : {
6862 : 7170 : left_temp = Statement::make_temporary(left->type(), NULL, loc);
6863 : 7170 : inserter->insert(left_temp);
6864 : 7170 : left = Expression::make_set_and_use_temporary(left_temp, left, loc);
6865 : : }
6866 : :
6867 : 7489 : Expression* right = this->right_;
6868 : 7489 : Temporary_statement* right_temp = NULL;
6869 : 7489 : if (right->var_expression() == NULL
6870 : 7489 : && right->temporary_reference_expression() == NULL)
6871 : : {
6872 : 7304 : right_temp = Statement::make_temporary(right->type(), NULL, loc);
6873 : 7304 : inserter->insert(right_temp);
6874 : 7304 : right = Expression::make_set_and_use_temporary(right_temp, right, loc);
6875 : : }
6876 : :
6877 : 7489 : Expression* ret = Expression::make_boolean(true, loc);
6878 : 7489 : const Struct_field_list* fields = st->fields();
6879 : 7489 : unsigned int field_index = 0;
6880 : 7489 : for (Struct_field_list::const_iterator pf = fields->begin();
6881 : 25197 : pf != fields->end();
6882 : 17708 : ++pf, ++field_index)
6883 : : {
6884 : 17708 : if (Gogo::is_sink_name(pf->field_name()))
6885 : 128 : continue;
6886 : :
6887 : 17580 : if (field_index > 0)
6888 : : {
6889 : 10408 : if (left_temp == NULL)
6890 : 554 : left = left->copy();
6891 : : else
6892 : 9854 : left = Expression::make_temporary_reference(left_temp, loc);
6893 : 10408 : if (right_temp == NULL)
6894 : 365 : right = right->copy();
6895 : : else
6896 : 10043 : right = Expression::make_temporary_reference(right_temp, loc);
6897 : : }
6898 : 17580 : Expression* f1 = Expression::make_field_reference(left, field_index,
6899 : : loc);
6900 : 17580 : Expression* f2 = Expression::make_field_reference(right, field_index,
6901 : : loc);
6902 : 17580 : Expression* cond = Expression::make_binary(OPERATOR_EQEQ, f1, f2, loc);
6903 : 17580 : ret = Expression::make_binary(OPERATOR_ANDAND, ret, cond, loc);
6904 : : }
6905 : :
6906 : 7489 : if (this->op_ == OPERATOR_NOTEQ)
6907 : 6403 : ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
6908 : :
6909 : 7489 : ret->determine_type_no_context(gogo);
6910 : :
6911 : 7489 : return ret;
6912 : : }
6913 : :
6914 : : // Lower an array comparison.
6915 : :
6916 : : Expression*
6917 : 8835 : Binary_expression::lower_array_comparison(Gogo* gogo,
6918 : : Statement_inserter* inserter)
6919 : : {
6920 : 8835 : Array_type* at = this->left_->type()->array_type();
6921 : 8835 : Array_type* at2 = this->right_->type()->array_type();
6922 : 8835 : if (at2 == NULL)
6923 : 0 : return this;
6924 : 8835 : if (at != at2
6925 : 8835 : && !Type::are_identical(at, at2,
6926 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
6927 : : NULL))
6928 : 0 : return this;
6929 : 8835 : if (!Type::are_compatible_for_comparison(true, this->left_->type(),
6930 : 8835 : this->right_->type(), NULL))
6931 : 0 : return this;
6932 : :
6933 : : // Call memcmp directly if possible. This may let the middle-end
6934 : : // optimize the call.
6935 : 8835 : if (at->compare_is_identity(gogo))
6936 : 7874 : return this->lower_compare_to_memcmp(gogo, inserter);
6937 : :
6938 : : // Call the array comparison function.
6939 : 961 : Named_object* equal_fn =
6940 : 961 : at->equal_function(gogo, this->left_->type()->named_type(), NULL);
6941 : :
6942 : 961 : Location loc = this->location();
6943 : :
6944 : 961 : Expression* func = Expression::make_func_reference(equal_fn, NULL, loc);
6945 : :
6946 : 961 : Expression_list* args = new Expression_list();
6947 : 961 : args->push_back(this->operand_address(inserter, this->left_));
6948 : 961 : args->push_back(this->operand_address(inserter, this->right_));
6949 : :
6950 : 961 : Call_expression* ce = Expression::make_call(func, args, false, loc);
6951 : :
6952 : : // Record that this is a call to a generated equality function. We
6953 : : // need to do this because a comparison returns an abstract boolean
6954 : : // type, but the function necessarily returns "bool". The
6955 : : // difference shows up in code like
6956 : : // type mybool bool
6957 : : // var b mybool = [10]string{} == [10]string{}
6958 : : // The comparison function returns "bool", but since a comparison
6959 : : // has an abstract boolean type we need an implicit conversion to
6960 : : // "mybool". The implicit conversion is inserted in
6961 : : // Call_expression::do_flatten.
6962 : 961 : ce->set_is_equal_function();
6963 : :
6964 : 961 : Expression* ret = ce;
6965 : 961 : if (this->op_ == OPERATOR_NOTEQ)
6966 : 485 : ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
6967 : :
6968 : 961 : ret->determine_type_no_context(gogo);
6969 : :
6970 : 961 : return ret;
6971 : : }
6972 : :
6973 : : // Lower an interface to value comparison.
6974 : :
6975 : : Expression*
6976 : 79140 : Binary_expression::lower_interface_value_comparison(Gogo*,
6977 : : Statement_inserter* inserter)
6978 : : {
6979 : 79140 : Type* left_type = this->left_->type();
6980 : 79140 : Type* right_type = this->right_->type();
6981 : 79140 : Interface_type* ift;
6982 : 79140 : if (left_type->interface_type() != NULL)
6983 : : {
6984 : 78857 : ift = left_type->interface_type();
6985 : 78857 : if (!ift->implements_interface(right_type, NULL))
6986 : 74700 : return this;
6987 : : }
6988 : : else
6989 : : {
6990 : 283 : ift = right_type->interface_type();
6991 : 283 : if (!ift->implements_interface(left_type, NULL))
6992 : 0 : return this;
6993 : : }
6994 : 4440 : if (!Type::are_compatible_for_comparison(true, left_type, right_type, NULL))
6995 : 0 : return this;
6996 : :
6997 : 4440 : Location loc = this->location();
6998 : :
6999 : 4440 : if (left_type->interface_type() == NULL
7000 : 283 : && left_type->points_to() == NULL
7001 : 89 : && !this->left_->is_addressable())
7002 : : {
7003 : 4 : Temporary_statement* temp =
7004 : 4 : Statement::make_temporary(left_type, NULL, loc);
7005 : 4 : inserter->insert(temp);
7006 : 4 : this->left_ =
7007 : 4 : Expression::make_set_and_use_temporary(temp, this->left_, loc);
7008 : : }
7009 : :
7010 : 4440 : if (right_type->interface_type() == NULL
7011 : 4157 : && right_type->points_to() == NULL
7012 : 3326 : && !this->right_->is_addressable())
7013 : : {
7014 : 2317 : Temporary_statement* temp =
7015 : 2317 : Statement::make_temporary(right_type, NULL, loc);
7016 : 2317 : inserter->insert(temp);
7017 : 2317 : this->right_ =
7018 : 2317 : Expression::make_set_and_use_temporary(temp, this->right_, loc);
7019 : : }
7020 : :
7021 : 4440 : return this;
7022 : : }
7023 : :
7024 : : // Lower a struct or array comparison to a call to memcmp.
7025 : :
7026 : : Expression*
7027 : 8423 : Binary_expression::lower_compare_to_memcmp(Gogo* gogo,
7028 : : Statement_inserter* inserter)
7029 : : {
7030 : 8423 : Location loc = this->location();
7031 : :
7032 : 8423 : Expression* a1 = this->operand_address(inserter, this->left_);
7033 : 8423 : Expression* a2 = this->operand_address(inserter, this->right_);
7034 : 8423 : Expression* len = Expression::make_type_info(this->left_->type(),
7035 : : TYPE_INFO_SIZE);
7036 : :
7037 : 8423 : Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP, loc, 3,
7038 : : a1, a2, len);
7039 : 8423 : Type* int32_type = Type::lookup_integer_type("int32");
7040 : 8423 : Expression* zero = Expression::make_integer_ul(0, int32_type, loc);
7041 : 8423 : Expression* ret = Expression::make_binary(this->op_, call, zero, loc);
7042 : 8423 : Type_context context(this->type_, this->type_->is_abstract());
7043 : 8423 : ret->determine_type(gogo, &context);
7044 : 8423 : return ret;
7045 : : }
7046 : :
7047 : : Expression*
7048 : 868761 : Binary_expression::do_flatten(Gogo* gogo, Named_object*,
7049 : : Statement_inserter* inserter)
7050 : : {
7051 : 868761 : Location loc = this->location();
7052 : 868761 : if (this->left_->type()->is_error_type()
7053 : 868761 : || this->right_->type()->is_error_type()
7054 : 868761 : || this->left_->is_error_expression()
7055 : 1737522 : || this->right_->is_error_expression())
7056 : : {
7057 : 0 : go_assert(saw_errors());
7058 : 0 : return Expression::make_error(loc);
7059 : : }
7060 : :
7061 : 868761 : Temporary_statement* temp;
7062 : :
7063 : 868761 : Type* left_type = this->left_->type();
7064 : 868761 : bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
7065 : 868761 : || this->op_ == OPERATOR_RSHIFT);
7066 : 868761 : bool is_idiv_op = ((this->op_ == OPERATOR_DIV &&
7067 : 1729948 : left_type->integer_type() != NULL)
7068 : 870362 : || this->op_ == OPERATOR_MOD);
7069 : 868761 : bool is_string_op = (left_type->is_string_type()
7070 : 1737522 : && this->right_->type()->is_string_type());
7071 : :
7072 : 46743 : if (is_string_op)
7073 : : {
7074 : : // Mark string([]byte) operands to reuse the backing store.
7075 : : // String comparison does not keep the reference, so it is safe.
7076 : 46743 : Type_conversion_expression* lce =
7077 : 46743 : this->left_->conversion_expression();
7078 : 1100 : if (lce != NULL && lce->expr()->type()->is_slice_type())
7079 : 1080 : lce->set_no_copy(true);
7080 : 46743 : Type_conversion_expression* rce =
7081 : 46743 : this->right_->conversion_expression();
7082 : 885 : if (rce != NULL && rce->expr()->type()->is_slice_type())
7083 : 395 : rce->set_no_copy(true);
7084 : : }
7085 : :
7086 : 868761 : if (is_shift_op
7087 : 843023 : || (is_idiv_op
7088 : 11890 : && (gogo->check_divide_by_zero() || gogo->check_divide_overflow()))
7089 : 1699894 : || is_string_op)
7090 : : {
7091 : 84371 : if (!this->left_->is_multi_eval_safe())
7092 : : {
7093 : 38136 : temp = Statement::make_temporary(NULL, this->left_, loc);
7094 : 38136 : inserter->insert(temp);
7095 : 38136 : this->left_ = Expression::make_temporary_reference(temp, loc);
7096 : : }
7097 : 84371 : if (!this->right_->is_multi_eval_safe())
7098 : : {
7099 : 43290 : temp =
7100 : 43290 : Statement::make_temporary(NULL, this->right_, loc);
7101 : 43290 : this->right_ = Expression::make_temporary_reference(temp, loc);
7102 : 43290 : inserter->insert(temp);
7103 : : }
7104 : : }
7105 : 868761 : return this;
7106 : : }
7107 : :
7108 : :
7109 : : // Return the address of EXPR, cast to unsafe.Pointer.
7110 : :
7111 : : Expression*
7112 : 18768 : Binary_expression::operand_address(Statement_inserter* inserter,
7113 : : Expression* expr)
7114 : : {
7115 : 18768 : Location loc = this->location();
7116 : :
7117 : 18768 : if (!expr->is_addressable())
7118 : : {
7119 : 2194 : Temporary_statement* temp = Statement::make_temporary(expr->type(), NULL,
7120 : : loc);
7121 : 2194 : inserter->insert(temp);
7122 : 2194 : expr = Expression::make_set_and_use_temporary(temp, expr, loc);
7123 : : }
7124 : 18768 : expr = Expression::make_unary(OPERATOR_AND, expr, loc);
7125 : 18768 : static_cast<Unary_expression*>(expr)->set_does_not_escape();
7126 : 18768 : Type* void_type = Type::make_void_type();
7127 : 18768 : Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
7128 : 18768 : return Expression::make_cast(unsafe_pointer_type, expr, loc);
7129 : : }
7130 : :
7131 : : // Return the numeric constant value, if it has one.
7132 : :
7133 : : bool
7134 : 726740 : Binary_expression::do_numeric_constant_value(Numeric_constant* nc)
7135 : : {
7136 : 726740 : if (this->is_error_expression())
7137 : : return false;
7138 : :
7139 : 726543 : Numeric_constant left_nc;
7140 : 726543 : if (!this->left_->numeric_constant_value(&left_nc))
7141 : : return false;
7142 : 276365 : Numeric_constant right_nc;
7143 : 276365 : if (!this->right_->numeric_constant_value(&right_nc))
7144 : : return false;
7145 : 252164 : bool issued_error;
7146 : 252164 : bool r = Binary_expression::eval_constant(this->op_, &left_nc, &right_nc,
7147 : : this->location(), nc,
7148 : : &issued_error);
7149 : 252164 : if (issued_error)
7150 : 1 : this->set_is_error();
7151 : : return r;
7152 : 726543 : }
7153 : :
7154 : : // Return the boolean constant value, if it has one.
7155 : :
7156 : : bool
7157 : 1103404 : Binary_expression::do_boolean_constant_value(bool* val)
7158 : : {
7159 : 1103404 : if (this->is_error_expression())
7160 : : return false;
7161 : :
7162 : 1103404 : bool is_comparison = false;
7163 : 1103404 : switch (this->op_)
7164 : : {
7165 : 672060 : case OPERATOR_EQEQ:
7166 : 672060 : case OPERATOR_NOTEQ:
7167 : 672060 : case OPERATOR_LT:
7168 : 672060 : case OPERATOR_LE:
7169 : 672060 : case OPERATOR_GT:
7170 : 672060 : case OPERATOR_GE:
7171 : 672060 : is_comparison = true;
7172 : 672060 : break;
7173 : : case OPERATOR_ANDAND:
7174 : : case OPERATOR_OROR:
7175 : : break;
7176 : : default:
7177 : : return false;
7178 : : }
7179 : :
7180 : 1675802 : Numeric_constant left_nc, right_nc;
7181 : 837901 : if (is_comparison
7182 : 672060 : && this->left_->numeric_constant_value(&left_nc)
7183 : 846499 : && this->right_->numeric_constant_value(&right_nc))
7184 : 0 : return Binary_expression::compare_constant(this->op_, &left_nc,
7185 : : &right_nc,
7186 : : this->location(),
7187 : 0 : val);
7188 : :
7189 : 1675802 : std::string left_str, right_str;
7190 : 837901 : if (is_comparison
7191 : 672060 : && this->left_->string_constant_value(&left_str)
7192 : 837965 : && this->right_->string_constant_value(&right_str))
7193 : : {
7194 : 0 : *val = Binary_expression::cmp_to_bool(this->op_,
7195 : : left_str.compare(right_str));
7196 : 0 : return true;
7197 : : }
7198 : :
7199 : 837901 : bool left_bval;
7200 : 837901 : if (this->left_->boolean_constant_value(&left_bval))
7201 : : {
7202 : 5727 : if (this->op_ == OPERATOR_ANDAND && !left_bval)
7203 : : {
7204 : 1789 : *val = false;
7205 : 2797 : return true;
7206 : : }
7207 : 3938 : else if (this->op_ == OPERATOR_OROR && left_bval)
7208 : : {
7209 : 167 : *val = true;
7210 : 167 : return true;
7211 : : }
7212 : :
7213 : 3771 : bool right_bval;
7214 : 3771 : if (this->right_->boolean_constant_value(&right_bval))
7215 : : {
7216 : 841 : switch (this->op_)
7217 : : {
7218 : 2 : case OPERATOR_EQEQ:
7219 : 2 : *val = (left_bval == right_bval);
7220 : 2 : return true;
7221 : 0 : case OPERATOR_NOTEQ:
7222 : 0 : *val = (left_bval != right_bval);
7223 : 0 : return true;
7224 : 839 : case OPERATOR_ANDAND:
7225 : 839 : case OPERATOR_OROR:
7226 : 839 : *val = right_bval;
7227 : 839 : return true;
7228 : 0 : default:
7229 : 0 : go_unreachable();
7230 : : }
7231 : : }
7232 : : }
7233 : :
7234 : : return false;
7235 : : }
7236 : :
7237 : : // Note that the value is being discarded.
7238 : :
7239 : : bool
7240 : 2 : Binary_expression::do_discarding_value()
7241 : : {
7242 : 2 : if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
7243 : 0 : return this->right_->discarding_value();
7244 : : else
7245 : : {
7246 : 2 : this->unused_value_error();
7247 : 2 : return false;
7248 : : }
7249 : : }
7250 : :
7251 : : // Get type.
7252 : :
7253 : : Type*
7254 : 7250558 : Binary_expression::do_type()
7255 : : {
7256 : 7250558 : if (this->type_ == NULL)
7257 : : {
7258 : 157 : go_assert(saw_errors());
7259 : 157 : return Type::make_error_type();
7260 : : }
7261 : :
7262 : : return this->type_;
7263 : : }
7264 : :
7265 : : // Set type for a binary expression.
7266 : :
7267 : : void
7268 : 2879019 : Binary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
7269 : : {
7270 : 2879019 : if (this->type_ != NULL)
7271 : 538430 : return;
7272 : :
7273 : : // For a shift operation, the type of the binary expression is the
7274 : : // type of the left operand. If the left operand is a constant,
7275 : : // then it gets its type from the context.
7276 : 2340707 : bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
7277 : 2340707 : || this->op_ == OPERATOR_RSHIFT);
7278 : :
7279 : : // For a comparison operation, the type of the binary expression is
7280 : : // a boolean type.
7281 : 2340707 : bool is_comparison = (this->op_ == OPERATOR_EQEQ
7282 : : || this->op_ == OPERATOR_NOTEQ
7283 : : || this->op_ == OPERATOR_LT
7284 : : || this->op_ == OPERATOR_LE
7285 : : || this->op_ == OPERATOR_GT
7286 : 2340707 : || this->op_ == OPERATOR_GE);
7287 : :
7288 : : // For constant expressions, the context of the result is not useful in
7289 : : // determining the types of the operands. It is only legal to use abstract
7290 : : // boolean, numeric, and string constants as operands where it is legal to
7291 : : // use non-abstract boolean, numeric, and string constants, respectively.
7292 : : // Any issues with the operation will be resolved in the check_types pass.
7293 : 2340707 : bool left_is_constant = this->left_->is_constant();
7294 : 2340707 : bool right_is_constant = this->right_->is_constant();
7295 : 2340707 : bool is_constant_expr = left_is_constant && right_is_constant;
7296 : :
7297 : 2340707 : Type_context subcontext(*context);
7298 : 2340707 : if (is_comparison)
7299 : 1291612 : subcontext.type = NULL;
7300 : :
7301 : 2340707 : Type* tleft;
7302 : 2340707 : bool left_is_untyped = this->left_->is_untyped(&tleft);
7303 : 2340707 : if (!left_is_untyped)
7304 : : {
7305 : 1954236 : this->left_->determine_type(gogo, &subcontext);
7306 : 1954236 : tleft = this->left_->type();
7307 : : }
7308 : :
7309 : 2340707 : Type* tright;
7310 : 2340707 : bool right_is_untyped = this->right_->is_untyped(&tright);
7311 : 2340707 : if (!right_is_untyped)
7312 : : {
7313 : : // For a shift operation, the right operand should always be an
7314 : : // integer.
7315 : 1767743 : if (is_shift_op)
7316 : : {
7317 : 191779 : subcontext.type = Type::lookup_integer_type("uint");
7318 : 191779 : subcontext.may_be_abstract = false;
7319 : : }
7320 : :
7321 : 1767743 : this->right_->determine_type(gogo, &subcontext);
7322 : 1767743 : tright = this->right_->type();
7323 : : }
7324 : :
7325 : : // For each operand we have the real type or, if the operand is a
7326 : : // untyped, a guess at the type. Use this to determine the types of
7327 : : // untyped operands.
7328 : :
7329 : 2340707 : subcontext = *context;
7330 : 2340707 : if (left_is_untyped && (right_is_untyped || is_shift_op) && is_constant_expr)
7331 : : {
7332 : : // We evaluate the operands of an untyped expression as untyped
7333 : : // values. Then we convert to the desired type. Otherwise we
7334 : : // may, for example, mishandle a floating-point constant
7335 : : // division as an integer division.
7336 : 123468 : subcontext.type = NULL;
7337 : 123468 : subcontext.may_be_abstract = true;
7338 : : }
7339 : 2217239 : else if (is_comparison)
7340 : : {
7341 : : // In a comparison, the context does not determine the types of
7342 : : // the operands.
7343 : 1290639 : subcontext.type = NULL;
7344 : : }
7345 : :
7346 : : // Set the context for the left hand operand.
7347 : :
7348 : 2340707 : if (is_shift_op)
7349 : : {
7350 : : // The right hand operand of a shift plays no role in
7351 : : // determining the type of the left hand operand.
7352 : 221877 : if (subcontext.type == NULL
7353 : 17096 : && right_is_constant
7354 : 16046 : && context->may_be_abstract)
7355 : 5694 : subcontext.type = Type::make_abstract_integer_type();
7356 : : }
7357 : 2118830 : else if (!tleft->is_abstract())
7358 : 1745141 : subcontext.type = tleft;
7359 : 373689 : else if (!tright->is_abstract())
7360 : 30913 : subcontext.type = tright;
7361 : 342776 : else if (subcontext.type == NULL)
7362 : : {
7363 : 324573 : if ((tleft->integer_type() != NULL && tright->integer_type() != NULL)
7364 : 2624215 : || (tleft->float_type() != NULL && tright->float_type() != NULL)
7365 : 2622698 : || (tleft->complex_type() != NULL && tright->complex_type() != NULL)
7366 : 281939 : || (tleft->is_boolean_type() && tright->is_boolean_type()))
7367 : : {
7368 : : // Both sides have an abstract integer, abstract float,
7369 : : // abstract complex, or abstract boolean type. Just let
7370 : : // CONTEXT determine whether they may remain abstract or not.
7371 : : }
7372 : 40093 : else if (tleft->complex_type() != NULL)
7373 : 8 : subcontext.type = tleft;
7374 : 40085 : else if (tright->complex_type() != NULL)
7375 : 818 : subcontext.type = tright;
7376 : 39267 : else if (tleft->float_type() != NULL)
7377 : 478 : subcontext.type = tleft;
7378 : 38789 : else if (tright->float_type() != NULL)
7379 : 360 : subcontext.type = tright;
7380 : : else
7381 : 38429 : subcontext.type = tleft;
7382 : : }
7383 : :
7384 : 2340707 : if (left_is_untyped)
7385 : : {
7386 : 386471 : this->left_->determine_type(gogo, &subcontext);
7387 : 386471 : tleft = this->left_->type();
7388 : : }
7389 : :
7390 : 2340707 : if (is_shift_op)
7391 : : {
7392 : : // We may have inherited an unusable type for the shift operand.
7393 : : // Give a useful error if that happened.
7394 : 221877 : if (left_is_untyped
7395 : 221877 : && !is_constant_expr
7396 : 1497 : && subcontext.type != NULL
7397 : 1402 : && !subcontext.may_be_abstract
7398 : 1402 : && subcontext.type->interface_type() == NULL
7399 : 223267 : && subcontext.type->integer_type() == NULL
7400 : 123 : && !tleft->is_error()
7401 : 222000 : && !tright->is_error())
7402 : 123 : this->report_error(("invalid context-determined non-integer type "
7403 : : "for left operand of shift"));
7404 : :
7405 : : // The context for the right hand operand is the same as for the
7406 : : // left hand operand, except for a shift operator.
7407 : 221877 : subcontext.type = Type::lookup_integer_type("uint");
7408 : 221877 : subcontext.may_be_abstract = false;
7409 : : }
7410 : :
7411 : 2340707 : if (right_is_untyped)
7412 : : {
7413 : 572964 : this->right_->determine_type(gogo, &subcontext);
7414 : 572964 : tright = this->right_->type();
7415 : : }
7416 : :
7417 : 2340707 : if (this->left_->is_error_expression()
7418 : 2340618 : || tleft->is_error()
7419 : 2340617 : || this->right_->is_error_expression()
7420 : 4681307 : || tright->is_error())
7421 : : {
7422 : 107 : this->set_is_error();
7423 : 107 : return;
7424 : : }
7425 : :
7426 : 2340600 : if (is_comparison)
7427 : : {
7428 : 1291561 : if (context->type != NULL && context->type->is_boolean_type())
7429 : 543286 : this->type_ = context->type;
7430 : 748275 : else if (!context->may_be_abstract)
7431 : 646318 : this->type_ = Type::lookup_bool_type();
7432 : : else
7433 : 101957 : this->type_ = Type::make_boolean_type();
7434 : : }
7435 : : else
7436 : : {
7437 : 1049039 : if (is_shift_op)
7438 : : {
7439 : : // Shifts only work with integers, so force an abstract
7440 : : // floating-point type (such as 1.0 << 1) into an integer.
7441 : 221870 : if (tleft->is_abstract()
7442 : 11363 : && tleft->integer_type() == NULL
7443 : 221958 : && context->type == NULL)
7444 : : {
7445 : 2 : this->type_ = Type::make_abstract_integer_type();
7446 : 2 : if (!context->may_be_abstract)
7447 : 2 : this->type_ = this->type_->make_non_abstract_type();
7448 : : }
7449 : : else
7450 : 221868 : this->type_ = tleft;
7451 : : }
7452 : : else
7453 : : {
7454 : 827169 : if (!Binary_expression::operation_type(this->op_, tleft, tright,
7455 : : &this->type_))
7456 : : {
7457 : 11 : this->report_error("incompatible types in binary expression");
7458 : 11 : this->type_ = Type::make_error_type();
7459 : 11 : return;
7460 : : }
7461 : : }
7462 : :
7463 : : // If this is an untyped expression in a typed context, use the
7464 : : // context type. If this doesn't work we'll report an error
7465 : : // later.
7466 : 1049028 : if (this->type_->is_abstract()
7467 : 122571 : && !context->may_be_abstract
7468 : 1120983 : && context->type != NULL)
7469 : : {
7470 : 21147 : if (context->type->interface_type() == NULL
7471 : 20910 : && ((this->type_->is_numeric_type()
7472 : 19320 : && context->type->is_numeric_type())
7473 : 1602 : || (this->type_->is_string_type()
7474 : 1253 : && context->type->is_string_type())
7475 : 381 : || (this->type_->is_boolean_type()
7476 : 337 : && context->type->is_boolean_type())))
7477 : 20866 : this->type_ = context->type;
7478 : 2340870 : else if (context->type->interface_type() != NULL)
7479 : 237 : this->type_ = this->type_->make_non_abstract_type();
7480 : : }
7481 : : }
7482 : : }
7483 : :
7484 : : // Report an error if the binary operator OP does not support TYPE.
7485 : : // OTYPE is the type of the other operand. Return whether the
7486 : : // operation is OK. This should not be used for shift.
7487 : :
7488 : : bool
7489 : 869126 : Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
7490 : : Location location)
7491 : : {
7492 : 869126 : switch (op)
7493 : : {
7494 : 64063 : case OPERATOR_OROR:
7495 : 64063 : case OPERATOR_ANDAND:
7496 : 64063 : if (!type->is_boolean_type()
7497 : 128126 : || !otype->is_boolean_type())
7498 : : {
7499 : 0 : go_error_at(location, "expected boolean type");
7500 : 0 : return false;
7501 : : }
7502 : : break;
7503 : :
7504 : 417882 : case OPERATOR_EQEQ:
7505 : 417882 : case OPERATOR_NOTEQ:
7506 : 417882 : {
7507 : 417882 : std::string reason;
7508 : 417882 : if (!Type::are_compatible_for_comparison(true, type, otype, &reason))
7509 : : {
7510 : 32 : go_error_at(location, "%s", reason.c_str());
7511 : 32 : return false;
7512 : : }
7513 : 32 : }
7514 : 417850 : break;
7515 : :
7516 : 152884 : case OPERATOR_LT:
7517 : 152884 : case OPERATOR_LE:
7518 : 152884 : case OPERATOR_GT:
7519 : 152884 : case OPERATOR_GE:
7520 : 152884 : {
7521 : 152884 : std::string reason;
7522 : 152884 : if (!Type::are_compatible_for_comparison(false, type, otype, &reason))
7523 : : {
7524 : 20 : go_error_at(location, "%s", reason.c_str());
7525 : 20 : return false;
7526 : : }
7527 : 20 : }
7528 : 152864 : break;
7529 : :
7530 : 118439 : case OPERATOR_PLUS:
7531 : 118439 : case OPERATOR_PLUSEQ:
7532 : 173032 : if ((!type->is_numeric_type() && !type->is_string_type())
7533 : 291471 : || (!otype->is_numeric_type() && !otype->is_string_type()))
7534 : : {
7535 : 0 : go_error_at(location,
7536 : : "expected integer, floating, complex, or string type");
7537 : 0 : return false;
7538 : : }
7539 : : break;
7540 : :
7541 : 76619 : case OPERATOR_MINUS:
7542 : 76619 : case OPERATOR_MINUSEQ:
7543 : 76619 : case OPERATOR_MULT:
7544 : 76619 : case OPERATOR_MULTEQ:
7545 : 76619 : case OPERATOR_DIV:
7546 : 76619 : case OPERATOR_DIVEQ:
7547 : 153237 : if (!type->is_numeric_type() || !otype->is_numeric_type())
7548 : : {
7549 : 1 : go_error_at(location, "expected integer, floating, or complex type");
7550 : 1 : return false;
7551 : : }
7552 : : break;
7553 : :
7554 : 39239 : case OPERATOR_MOD:
7555 : 39239 : case OPERATOR_MODEQ:
7556 : 39239 : case OPERATOR_OR:
7557 : 39239 : case OPERATOR_OREQ:
7558 : 39239 : case OPERATOR_AND:
7559 : 39239 : case OPERATOR_ANDEQ:
7560 : 39239 : case OPERATOR_XOR:
7561 : 39239 : case OPERATOR_XOREQ:
7562 : 39239 : case OPERATOR_BITCLEAR:
7563 : 39239 : case OPERATOR_BITCLEAREQ:
7564 : 78466 : if (type->integer_type() == NULL || otype->integer_type() == NULL)
7565 : : {
7566 : 12 : go_error_at(location, "expected integer type");
7567 : 12 : return false;
7568 : : }
7569 : : break;
7570 : :
7571 : 0 : default:
7572 : 0 : go_unreachable();
7573 : : }
7574 : :
7575 : : return true;
7576 : : }
7577 : :
7578 : : // Check types.
7579 : :
7580 : : void
7581 : 594775 : Binary_expression::do_check_types(Gogo*)
7582 : : {
7583 : 594775 : if (this->classification() == EXPRESSION_ERROR)
7584 : : return;
7585 : :
7586 : 594543 : Type* left_type = this->left_->type();
7587 : 594543 : Type* right_type = this->right_->type();
7588 : 594543 : if (left_type->is_error() || right_type->is_error())
7589 : : {
7590 : 1 : this->set_is_error();
7591 : 1 : return;
7592 : : }
7593 : :
7594 : 594542 : if (this->op_ == OPERATOR_EQEQ
7595 : : || this->op_ == OPERATOR_NOTEQ
7596 : : || this->op_ == OPERATOR_LT
7597 : : || this->op_ == OPERATOR_LE
7598 : : || this->op_ == OPERATOR_GT
7599 : 594542 : || this->op_ == OPERATOR_GE)
7600 : : {
7601 : 285441 : if (left_type->is_nil_type() && right_type->is_nil_type())
7602 : : {
7603 : 2 : this->report_error(_("invalid comparison of nil with nil"));
7604 : 2 : return;
7605 : : }
7606 : 285439 : if (!Type::are_assignable(left_type, right_type, NULL)
7607 : 285439 : && !Type::are_assignable(right_type, left_type, NULL))
7608 : : {
7609 : 32 : this->report_error(_("incompatible types in binary expression"));
7610 : 32 : return;
7611 : : }
7612 : 285407 : if (!Binary_expression::check_operator_type(this->op_, left_type,
7613 : : right_type,
7614 : : this->location())
7615 : 285407 : || !Binary_expression::check_operator_type(this->op_, right_type,
7616 : : left_type,
7617 : : this->location()))
7618 : : {
7619 : 52 : this->set_is_error();
7620 : 52 : return;
7621 : : }
7622 : : }
7623 : 309101 : else if (this->op_ != OPERATOR_LSHIFT && this->op_ != OPERATOR_RSHIFT)
7624 : : {
7625 : 274768 : if (!Type::are_compatible_for_binop(left_type, right_type))
7626 : : {
7627 : 16 : this->report_error(_("incompatible types in binary expression"));
7628 : 16 : return;
7629 : : }
7630 : 274752 : if (!Binary_expression::check_operator_type(this->op_, left_type,
7631 : : right_type,
7632 : : this->location()))
7633 : : {
7634 : 12 : this->set_is_error();
7635 : 12 : return;
7636 : : }
7637 : 274740 : if (this->op_ == OPERATOR_DIV || this->op_ == OPERATOR_MOD)
7638 : : {
7639 : : // Division by a zero integer constant is an error.
7640 : 15069 : Numeric_constant rconst;
7641 : 15069 : unsigned long rval;
7642 : 15069 : if (left_type->integer_type() != NULL
7643 : 12915 : && this->right_->numeric_constant_value(&rconst)
7644 : 9862 : && rconst.to_unsigned_long(&rval) == Numeric_constant::NC_UL_VALID
7645 : 9673 : && rval == 0)
7646 : : {
7647 : 2 : this->report_error(_("integer division by zero"));
7648 : 2 : return;
7649 : : }
7650 : 15069 : }
7651 : : }
7652 : : else
7653 : : {
7654 : 34333 : if (left_type->integer_type() == NULL
7655 : 41 : && !left_type->is_abstract()
7656 : 32 : && !this->is_constant())
7657 : 32 : this->report_error(_("shift of non-integer operand"));
7658 : :
7659 : 34333 : if (right_type->is_string_type())
7660 : 0 : this->report_error(_("shift count not integer"));
7661 : 34333 : else if (!right_type->is_abstract()
7662 : 34333 : && right_type->integer_type() == NULL)
7663 : 0 : this->report_error(_("shift count not integer"));
7664 : : else
7665 : : {
7666 : 34333 : Numeric_constant nc;
7667 : 34333 : if (this->right_->numeric_constant_value(&nc))
7668 : : {
7669 : 30591 : mpz_t val;
7670 : 30591 : if (!nc.to_int(&val))
7671 : 0 : this->report_error(_("shift count not integer"));
7672 : : else
7673 : : {
7674 : 30591 : if (mpz_sgn(val) < 0)
7675 : : {
7676 : 1 : this->report_error(_("negative shift count"));
7677 : 1 : Location rloc = this->right_->location();
7678 : 1 : this->right_ = Expression::make_integer_ul(0, right_type,
7679 : : rloc);
7680 : : }
7681 : 30591 : mpz_clear(val);
7682 : : }
7683 : : }
7684 : 34333 : }
7685 : : }
7686 : : }
7687 : :
7688 : : // Get the backend representation for a binary expression.
7689 : :
7690 : : Bexpression*
7691 : 1995203 : Binary_expression::do_get_backend(Translate_context* context)
7692 : : {
7693 : 1995203 : Gogo* gogo = context->gogo();
7694 : 1995203 : Location loc = this->location();
7695 : 1995203 : Type* left_type = this->left_->type();
7696 : 1995203 : Type* right_type = this->right_->type();
7697 : :
7698 : 1995203 : bool use_left_type = true;
7699 : 1995203 : bool is_shift_op = false;
7700 : 1995203 : bool is_idiv_op = false;
7701 : 1995203 : switch (this->op_)
7702 : : {
7703 : 1266882 : case OPERATOR_EQEQ:
7704 : 1266882 : case OPERATOR_NOTEQ:
7705 : 1266882 : case OPERATOR_LT:
7706 : 1266882 : case OPERATOR_LE:
7707 : 1266882 : case OPERATOR_GT:
7708 : 1266882 : case OPERATOR_GE:
7709 : 1266882 : return Expression::comparison(context, this->type_, this->op_,
7710 : 1266882 : this->left_, this->right_, loc);
7711 : :
7712 : : case OPERATOR_OROR:
7713 : : case OPERATOR_ANDAND:
7714 : 728321 : use_left_type = false;
7715 : : break;
7716 : : case OPERATOR_PLUS:
7717 : : case OPERATOR_MINUS:
7718 : : case OPERATOR_OR:
7719 : : case OPERATOR_XOR:
7720 : : case OPERATOR_MULT:
7721 : : break;
7722 : 8928 : case OPERATOR_DIV:
7723 : 744619 : if (left_type->float_type() != NULL || left_type->complex_type() != NULL)
7724 : : break;
7725 : : // Fall through.
7726 : : case OPERATOR_MOD:
7727 : : is_idiv_op = true;
7728 : : break;
7729 : 143148 : case OPERATOR_LSHIFT:
7730 : 143148 : case OPERATOR_RSHIFT:
7731 : 143148 : is_shift_op = true;
7732 : 143148 : break;
7733 : 2018 : case OPERATOR_BITCLEAR:
7734 : 2018 : this->right_ = Expression::make_unary(OPERATOR_XOR, this->right_, loc);
7735 : : case OPERATOR_AND:
7736 : : break;
7737 : 0 : default:
7738 : 0 : go_unreachable();
7739 : : }
7740 : :
7741 : : // The only binary operation for string is +, and that should have
7742 : : // been converted to a String_concat_expression in do_lower.
7743 : 728321 : go_assert(!left_type->is_string_type());
7744 : :
7745 : 728321 : Bexpression* left = this->left_->get_backend(context);
7746 : 728321 : Bexpression* right = this->right_->get_backend(context);
7747 : :
7748 : 728321 : Type* type = use_left_type ? left_type : right_type;
7749 : 728321 : Btype* btype = type->get_backend(gogo);
7750 : :
7751 : 728321 : Bexpression* ret =
7752 : 728321 : gogo->backend()->binary_expression(this->op_, left, right, loc);
7753 : 728321 : ret = gogo->backend()->convert_expression(btype, ret, loc);
7754 : :
7755 : : // Initialize overflow constants.
7756 : 728321 : Bexpression* overflow;
7757 : 728321 : mpz_t zero;
7758 : 728321 : mpz_init_set_ui(zero, 0UL);
7759 : 728321 : mpz_t one;
7760 : 728321 : mpz_init_set_ui(one, 1UL);
7761 : 728321 : mpz_t neg_one;
7762 : 728321 : mpz_init_set_si(neg_one, -1);
7763 : :
7764 : 728321 : Btype* left_btype = left_type->get_backend(gogo);
7765 : 728321 : Btype* right_btype = right_type->get_backend(gogo);
7766 : :
7767 : : // In Go, a shift larger than the size of the type is well-defined.
7768 : : // This is not true in C, so we need to insert a conditional.
7769 : : // We also need to check for a negative shift count.
7770 : 728321 : if (is_shift_op)
7771 : : {
7772 : 143148 : go_assert(left_type->integer_type() != NULL);
7773 : 143148 : go_assert(right_type->integer_type() != NULL);
7774 : :
7775 : 286296 : int bits = left_type->integer_type()->bits();
7776 : :
7777 : 143148 : Numeric_constant nc;
7778 : 143148 : unsigned long ul;
7779 : 143148 : if (!this->right_->numeric_constant_value(&nc)
7780 : 139198 : || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID
7781 : 282346 : || ul >= static_cast<unsigned long>(bits))
7782 : : {
7783 : 4368 : mpz_t bitsval;
7784 : 4368 : mpz_init_set_ui(bitsval, bits);
7785 : 4368 : Bexpression* bits_expr =
7786 : 4368 : gogo->backend()->integer_constant_expression(right_btype, bitsval);
7787 : 4368 : Bexpression* compare =
7788 : 4368 : gogo->backend()->binary_expression(OPERATOR_LT,
7789 : : right, bits_expr, loc);
7790 : :
7791 : 4368 : Bexpression* zero_expr =
7792 : 4368 : gogo->backend()->integer_constant_expression(left_btype, zero);
7793 : 4368 : overflow = zero_expr;
7794 : 4368 : Bfunction* bfn = context->function()->func_value()->get_decl();
7795 : 4368 : if (this->op_ == OPERATOR_RSHIFT
7796 : 5848 : && !left_type->integer_type()->is_unsigned())
7797 : : {
7798 : 344 : Bexpression* neg_expr =
7799 : 344 : gogo->backend()->binary_expression(OPERATOR_LT, left,
7800 : : zero_expr, loc);
7801 : 344 : Bexpression* neg_one_expr =
7802 : 344 : gogo->backend()->integer_constant_expression(left_btype,
7803 : : neg_one);
7804 : 344 : overflow = gogo->backend()->conditional_expression(bfn,
7805 : : btype,
7806 : : neg_expr,
7807 : : neg_one_expr,
7808 : : zero_expr,
7809 : : loc);
7810 : : }
7811 : 4368 : ret = gogo->backend()->conditional_expression(bfn, btype, compare,
7812 : : ret, overflow, loc);
7813 : 4368 : mpz_clear(bitsval);
7814 : : }
7815 : :
7816 : 286296 : if (!right_type->integer_type()->is_unsigned()
7817 : 143148 : && (!this->right_->numeric_constant_value(&nc)
7818 : 425 : || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID))
7819 : : {
7820 : 133 : Bexpression* zero_expr =
7821 : 133 : gogo->backend()->integer_constant_expression(right_btype, zero);
7822 : 133 : Bexpression* compare =
7823 : 133 : gogo->backend()->binary_expression(OPERATOR_LT, right, zero_expr,
7824 : : loc);
7825 : 133 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_SHIFT,
7826 : : loc, 0);
7827 : 133 : crash->determine_type_no_context(gogo);
7828 : 133 : Bexpression* bcrash = crash->get_backend(context);
7829 : 133 : Bfunction* bfn = context->function()->func_value()->get_decl();
7830 : 133 : ret = gogo->backend()->conditional_expression(bfn, btype, compare,
7831 : : bcrash, ret, loc);
7832 : : }
7833 : 143148 : }
7834 : :
7835 : : // Add checks for division by zero and division overflow as needed.
7836 : 728321 : if (is_idiv_op)
7837 : : {
7838 : 11583 : if (gogo->check_divide_by_zero())
7839 : : {
7840 : : // right == 0
7841 : 11583 : Bexpression* zero_expr =
7842 : 11583 : gogo->backend()->integer_constant_expression(right_btype, zero);
7843 : 11583 : Bexpression* check =
7844 : 11583 : gogo->backend()->binary_expression(OPERATOR_EQEQ,
7845 : : right, zero_expr, loc);
7846 : :
7847 : 11583 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_DIVIDE,
7848 : : loc, 0);
7849 : 11583 : crash->determine_type_no_context(gogo);
7850 : 11583 : Bexpression* bcrash = crash->get_backend(context);
7851 : :
7852 : : // right == 0 ? (panicdivide(), 0) : ret
7853 : 11583 : Bfunction* bfn = context->function()->func_value()->get_decl();
7854 : 11583 : ret = gogo->backend()->conditional_expression(bfn, btype,
7855 : : check, bcrash,
7856 : : ret, loc);
7857 : : }
7858 : :
7859 : 11583 : if (gogo->check_divide_overflow())
7860 : : {
7861 : : // right == -1
7862 : : // FIXME: It would be nice to say that this test is expected
7863 : : // to return false.
7864 : :
7865 : 11583 : Bexpression* neg_one_expr =
7866 : 11583 : gogo->backend()->integer_constant_expression(right_btype, neg_one);
7867 : 11583 : Bexpression* check =
7868 : 11583 : gogo->backend()->binary_expression(OPERATOR_EQEQ,
7869 : : right, neg_one_expr, loc);
7870 : :
7871 : 11583 : Bexpression* zero_expr =
7872 : 11583 : gogo->backend()->integer_constant_expression(btype, zero);
7873 : 11583 : Bexpression* one_expr =
7874 : 11583 : gogo->backend()->integer_constant_expression(btype, one);
7875 : 11583 : Bfunction* bfn = context->function()->func_value()->get_decl();
7876 : :
7877 : 23166 : if (type->integer_type()->is_unsigned())
7878 : : {
7879 : : // An unsigned -1 is the largest possible number, so
7880 : : // dividing is always 1 or 0.
7881 : :
7882 : 5288 : Bexpression* cmp =
7883 : 5288 : gogo->backend()->binary_expression(OPERATOR_EQEQ,
7884 : : left, right, loc);
7885 : 5288 : if (this->op_ == OPERATOR_DIV)
7886 : 3207 : overflow =
7887 : 3207 : gogo->backend()->conditional_expression(bfn, btype, cmp,
7888 : : one_expr, zero_expr,
7889 : : loc);
7890 : : else
7891 : 2081 : overflow =
7892 : 2081 : gogo->backend()->conditional_expression(bfn, btype, cmp,
7893 : : zero_expr, left,
7894 : : loc);
7895 : : }
7896 : : else
7897 : : {
7898 : : // Computing left / -1 is the same as computing - left,
7899 : : // which does not overflow since Go sets -fwrapv.
7900 : 6295 : if (this->op_ == OPERATOR_DIV)
7901 : : {
7902 : 4134 : Expression* negate_expr =
7903 : 4134 : Expression::make_unary(OPERATOR_MINUS, this->left_, loc);
7904 : 4134 : overflow = negate_expr->get_backend(context);
7905 : : }
7906 : : else
7907 : : overflow = zero_expr;
7908 : : }
7909 : 11583 : overflow = gogo->backend()->convert_expression(btype, overflow, loc);
7910 : :
7911 : : // right == -1 ? - left : ret
7912 : 11583 : ret = gogo->backend()->conditional_expression(bfn, btype,
7913 : : check, overflow,
7914 : : ret, loc);
7915 : : }
7916 : : }
7917 : :
7918 : 728321 : mpz_clear(zero);
7919 : 728321 : mpz_clear(one);
7920 : 728321 : mpz_clear(neg_one);
7921 : 728321 : return ret;
7922 : : }
7923 : :
7924 : : // Export a binary expression.
7925 : :
7926 : : void
7927 : 16026 : Binary_expression::do_export(Export_function_body* efb) const
7928 : : {
7929 : 16026 : efb->write_c_string("(");
7930 : 16026 : this->left_->export_expression(efb);
7931 : 16026 : switch (this->op_)
7932 : : {
7933 : 607 : case OPERATOR_OROR:
7934 : 607 : efb->write_c_string(" || ");
7935 : 607 : break;
7936 : 1193 : case OPERATOR_ANDAND:
7937 : 1193 : efb->write_c_string(" && ");
7938 : 1193 : break;
7939 : 2323 : case OPERATOR_EQEQ:
7940 : 2323 : efb->write_c_string(" == ");
7941 : 2323 : break;
7942 : 872 : case OPERATOR_NOTEQ:
7943 : 872 : efb->write_c_string(" != ");
7944 : 872 : break;
7945 : 1526 : case OPERATOR_LT:
7946 : 1526 : efb->write_c_string(" < ");
7947 : 1526 : break;
7948 : 785 : case OPERATOR_LE:
7949 : 785 : efb->write_c_string(" <= ");
7950 : 785 : break;
7951 : 355 : case OPERATOR_GT:
7952 : 355 : efb->write_c_string(" > ");
7953 : 355 : break;
7954 : 1052 : case OPERATOR_GE:
7955 : 1052 : efb->write_c_string(" >= ");
7956 : 1052 : break;
7957 : 1746 : case OPERATOR_PLUS:
7958 : 1746 : efb->write_c_string(" + ");
7959 : 1746 : break;
7960 : 1185 : case OPERATOR_MINUS:
7961 : 1185 : efb->write_c_string(" - ");
7962 : 1185 : break;
7963 : 430 : case OPERATOR_OR:
7964 : 430 : efb->write_c_string(" | ");
7965 : 430 : break;
7966 : 163 : case OPERATOR_XOR:
7967 : 163 : efb->write_c_string(" ^ ");
7968 : 163 : break;
7969 : 534 : case OPERATOR_MULT:
7970 : 534 : efb->write_c_string(" * ");
7971 : 534 : break;
7972 : 430 : case OPERATOR_DIV:
7973 : 430 : efb->write_c_string(" / ");
7974 : 430 : break;
7975 : 187 : case OPERATOR_MOD:
7976 : 187 : efb->write_c_string(" % ");
7977 : 187 : break;
7978 : 386 : case OPERATOR_LSHIFT:
7979 : 386 : efb->write_c_string(" << ");
7980 : 386 : break;
7981 : 1125 : case OPERATOR_RSHIFT:
7982 : 1125 : efb->write_c_string(" >> ");
7983 : 1125 : break;
7984 : 1046 : case OPERATOR_AND:
7985 : 1046 : efb->write_c_string(" & ");
7986 : 1046 : break;
7987 : 81 : case OPERATOR_BITCLEAR:
7988 : 81 : efb->write_c_string(" &^ ");
7989 : 81 : break;
7990 : 0 : default:
7991 : 0 : go_unreachable();
7992 : : }
7993 : 16026 : this->right_->export_expression(efb);
7994 : 16026 : efb->write_c_string(")");
7995 : 16026 : }
7996 : :
7997 : : // Import a binary expression.
7998 : :
7999 : : Expression*
8000 : 22026 : Binary_expression::do_import(Import_expression* imp, Location loc)
8001 : : {
8002 : 22026 : imp->require_c_string("(");
8003 : :
8004 : 22026 : Expression* left = Expression::import_expression(imp, loc);
8005 : :
8006 : 22026 : Operator op;
8007 : 22026 : if (imp->match_c_string(" || "))
8008 : : {
8009 : 652 : op = OPERATOR_OROR;
8010 : 652 : imp->advance(4);
8011 : : }
8012 : 21374 : else if (imp->match_c_string(" && "))
8013 : : {
8014 : 1823 : op = OPERATOR_ANDAND;
8015 : 1823 : imp->advance(4);
8016 : : }
8017 : 19551 : else if (imp->match_c_string(" == "))
8018 : : {
8019 : 3241 : op = OPERATOR_EQEQ;
8020 : 3241 : imp->advance(4);
8021 : : }
8022 : 16310 : else if (imp->match_c_string(" != "))
8023 : : {
8024 : 843 : op = OPERATOR_NOTEQ;
8025 : 843 : imp->advance(4);
8026 : : }
8027 : 15467 : else if (imp->match_c_string(" < "))
8028 : : {
8029 : 1154 : op = OPERATOR_LT;
8030 : 1154 : imp->advance(3);
8031 : : }
8032 : 14313 : else if (imp->match_c_string(" <= "))
8033 : : {
8034 : 988 : op = OPERATOR_LE;
8035 : 988 : imp->advance(4);
8036 : : }
8037 : 13325 : else if (imp->match_c_string(" > "))
8038 : : {
8039 : 226 : op = OPERATOR_GT;
8040 : 226 : imp->advance(3);
8041 : : }
8042 : 13099 : else if (imp->match_c_string(" >= "))
8043 : : {
8044 : 2482 : op = OPERATOR_GE;
8045 : 2482 : imp->advance(4);
8046 : : }
8047 : 10617 : else if (imp->match_c_string(" + "))
8048 : : {
8049 : 1789 : op = OPERATOR_PLUS;
8050 : 1789 : imp->advance(3);
8051 : : }
8052 : 8828 : else if (imp->match_c_string(" - "))
8053 : : {
8054 : 1554 : op = OPERATOR_MINUS;
8055 : 1554 : imp->advance(3);
8056 : : }
8057 : 7274 : else if (imp->match_c_string(" | "))
8058 : : {
8059 : 347 : op = OPERATOR_OR;
8060 : 347 : imp->advance(3);
8061 : : }
8062 : 6927 : else if (imp->match_c_string(" ^ "))
8063 : : {
8064 : 152 : op = OPERATOR_XOR;
8065 : 152 : imp->advance(3);
8066 : : }
8067 : 6775 : else if (imp->match_c_string(" * "))
8068 : : {
8069 : 573 : op = OPERATOR_MULT;
8070 : 573 : imp->advance(3);
8071 : : }
8072 : 6202 : else if (imp->match_c_string(" / "))
8073 : : {
8074 : 223 : op = OPERATOR_DIV;
8075 : 223 : imp->advance(3);
8076 : : }
8077 : 5979 : else if (imp->match_c_string(" % "))
8078 : : {
8079 : 40 : op = OPERATOR_MOD;
8080 : 40 : imp->advance(3);
8081 : : }
8082 : 5939 : else if (imp->match_c_string(" << "))
8083 : : {
8084 : 120 : op = OPERATOR_LSHIFT;
8085 : 120 : imp->advance(4);
8086 : : }
8087 : 5819 : else if (imp->match_c_string(" >> "))
8088 : : {
8089 : 941 : op = OPERATOR_RSHIFT;
8090 : 941 : imp->advance(4);
8091 : : }
8092 : 4878 : else if (imp->match_c_string(" & "))
8093 : : {
8094 : 940 : op = OPERATOR_AND;
8095 : 940 : imp->advance(3);
8096 : : }
8097 : 3938 : else if (imp->match_c_string(" &^ "))
8098 : : {
8099 : 74 : op = OPERATOR_BITCLEAR;
8100 : 74 : imp->advance(4);
8101 : : }
8102 : 3864 : else if (imp->match_c_string(")"))
8103 : : {
8104 : : // Not a binary operator after all.
8105 : 3864 : imp->advance(1);
8106 : 3864 : return left;
8107 : : }
8108 : : else
8109 : : {
8110 : 0 : go_error_at(imp->location(), "unrecognized binary operator");
8111 : 0 : return Expression::make_error(loc);
8112 : : }
8113 : :
8114 : 18162 : Expression* right = Expression::import_expression(imp, loc);
8115 : :
8116 : 18162 : imp->require_c_string(")");
8117 : :
8118 : 18162 : return Expression::make_binary(op, left, right, loc);
8119 : : }
8120 : :
8121 : : // Dump ast representation of a binary expression.
8122 : :
8123 : : void
8124 : 0 : Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
8125 : : {
8126 : 0 : ast_dump_context->ostream() << "(";
8127 : 0 : ast_dump_context->dump_expression(this->left_);
8128 : 0 : ast_dump_context->ostream() << " ";
8129 : 0 : ast_dump_context->dump_operator(this->op_);
8130 : 0 : ast_dump_context->ostream() << " ";
8131 : 0 : ast_dump_context->dump_expression(this->right_);
8132 : 0 : ast_dump_context->ostream() << ") ";
8133 : 0 : }
8134 : :
8135 : : // Make a binary expression.
8136 : :
8137 : : Expression*
8138 : 2340813 : Expression::make_binary(Operator op, Expression* left, Expression* right,
8139 : : Location location)
8140 : : {
8141 : 2340813 : return new Binary_expression(op, left, right, location);
8142 : : }
8143 : :
8144 : : // Implement a comparison.
8145 : :
8146 : : Bexpression*
8147 : 1266882 : Expression::comparison(Translate_context* context, Type* result_type,
8148 : : Operator op, Expression* left, Expression* right,
8149 : : Location location)
8150 : : {
8151 : 1266882 : Gogo* gogo = context->gogo();
8152 : 1266882 : Type* left_type = left->type();
8153 : 1266882 : Type* right_type = right->type();
8154 : :
8155 : 1266882 : Expression* zexpr = Expression::make_integer_ul(0, NULL, location);
8156 : :
8157 : 1266882 : if (left_type->is_string_type() && right_type->is_string_type())
8158 : : {
8159 : 45351 : go_assert(left->is_multi_eval_safe());
8160 : 45351 : go_assert(right->is_multi_eval_safe());
8161 : :
8162 : 45351 : if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
8163 : : {
8164 : : // (l.len == r.len
8165 : : // ? (l.ptr == r.ptr ? true : memcmp(l.ptr, r.ptr, r.len) == 0)
8166 : : // : false)
8167 : 44859 : Expression* llen = Expression::make_string_info(left,
8168 : : STRING_INFO_LENGTH,
8169 : : location);
8170 : 44859 : Expression* rlen = Expression::make_string_info(right,
8171 : : STRING_INFO_LENGTH,
8172 : : location);
8173 : 44859 : Expression* leneq = Expression::make_binary(OPERATOR_EQEQ, llen, rlen,
8174 : : location);
8175 : 44859 : Expression* lptr = Expression::make_string_info(left->copy(),
8176 : : STRING_INFO_DATA,
8177 : : location);
8178 : 44859 : Expression* rptr = Expression::make_string_info(right->copy(),
8179 : : STRING_INFO_DATA,
8180 : : location);
8181 : 44859 : Expression* ptreq = Expression::make_binary(OPERATOR_EQEQ, lptr, rptr,
8182 : : location);
8183 : 44859 : Expression* btrue = Expression::make_boolean(true, location);
8184 : 44859 : Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP,
8185 : : location, 3,
8186 : : lptr->copy(), rptr->copy(),
8187 : : rlen->copy());
8188 : 44859 : Type* int32_type = Type::lookup_integer_type("int32");
8189 : 44859 : Expression* zero = Expression::make_integer_ul(0, int32_type, location);
8190 : 44859 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, call, zero,
8191 : : location);
8192 : 44859 : Expression* cond = Expression::make_conditional(ptreq, btrue, cmp,
8193 : : location);
8194 : 44859 : Expression* bfalse = Expression::make_boolean(false, location);
8195 : 44859 : left = Expression::make_conditional(leneq, cond, bfalse, location);
8196 : 44859 : right = Expression::make_boolean(true, location);
8197 : : }
8198 : : else
8199 : : {
8200 : 492 : left = Runtime::make_call(gogo, Runtime::CMPSTRING, location, 2,
8201 : : left, right);
8202 : 492 : right = zexpr;
8203 : : }
8204 : : }
8205 : 1221531 : else if ((left_type->interface_type() != NULL
8206 : 60274 : && right_type->interface_type() == NULL
8207 : 52571 : && !right_type->is_nil_type())
8208 : 1219987 : || (left_type->interface_type() == NULL
8209 : 1161257 : && !left_type->is_nil_type()
8210 : 1161253 : && right_type->interface_type() != NULL))
8211 : : {
8212 : : // Comparing an interface value to a non-interface value.
8213 : 3236 : if (left_type->interface_type() == NULL)
8214 : : {
8215 : : std::swap(left_type, right_type);
8216 : : std::swap(left, right);
8217 : : }
8218 : :
8219 : : // The right operand is not an interface. We need to take its
8220 : : // address if it is not a direct interface type.
8221 : 1692 : Expression* pointer_arg = NULL;
8222 : 1692 : if (right_type->is_direct_iface_type())
8223 : 565 : pointer_arg = Expression::unpack_direct_iface(right, location);
8224 : : else
8225 : : {
8226 : 1127 : go_assert(right->is_addressable());
8227 : 1127 : pointer_arg = Expression::make_unary(OPERATOR_AND, right,
8228 : : location);
8229 : : }
8230 : :
8231 : 1692 : Expression* descriptor =
8232 : 1692 : Expression::make_type_descriptor(right_type, location);
8233 : 2990 : left = Runtime::make_call(gogo,
8234 : 3384 : (left_type->interface_type()->is_empty()
8235 : : ? Runtime::EFACEVALEQ
8236 : : : Runtime::IFACEVALEQ),
8237 : : location, 3, left, descriptor,
8238 : : pointer_arg);
8239 : 1692 : go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
8240 : 1692 : right = Expression::make_boolean(true, location);
8241 : : }
8242 : 1219839 : else if (left_type->interface_type() != NULL
8243 : 58730 : && right_type->interface_type() != NULL)
8244 : : {
8245 : 7703 : Runtime::Function compare_function;
8246 : 15406 : if (left_type->interface_type()->is_empty()
8247 : 8573 : && right_type->interface_type()->is_empty())
8248 : : compare_function = Runtime::EFACEEQ;
8249 : 13766 : else if (!left_type->interface_type()->is_empty()
8250 : 13716 : && !right_type->interface_type()->is_empty())
8251 : : compare_function = Runtime::IFACEEQ;
8252 : : else
8253 : : {
8254 : 104 : if (left_type->interface_type()->is_empty())
8255 : : {
8256 : 50 : std::swap(left_type, right_type);
8257 : 50 : std::swap(left, right);
8258 : : }
8259 : 104 : go_assert(!left_type->interface_type()->is_empty());
8260 : 104 : go_assert(right_type->interface_type()->is_empty());
8261 : : compare_function = Runtime::IFACEEFACEEQ;
8262 : : }
8263 : :
8264 : 7703 : left = Runtime::make_call(gogo, compare_function, location, 2,
8265 : : left, right);
8266 : 7703 : go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
8267 : 7703 : right = Expression::make_boolean(true, location);
8268 : : }
8269 : :
8270 : 1266882 : if (left_type->is_nil_type()
8271 : 1266882 : && (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ))
8272 : : {
8273 : : std::swap(left_type, right_type);
8274 : : std::swap(left, right);
8275 : : }
8276 : :
8277 : 1266882 : if (right_type->is_nil_type())
8278 : : {
8279 : 124823 : right = Expression::make_nil(location);
8280 : 124823 : if (left_type->array_type() != NULL
8281 : 6666 : && left_type->array_type()->length() == NULL)
8282 : : {
8283 : 3333 : Array_type* at = left_type->array_type();
8284 : 3333 : left = at->get_value_pointer(context->gogo(), left);
8285 : : }
8286 : 121490 : else if (left_type->interface_type() != NULL)
8287 : : {
8288 : : // An interface is nil if the first field is nil.
8289 : 51028 : left = Expression::make_field_reference(left, 0, location);
8290 : : }
8291 : : }
8292 : :
8293 : 1266882 : left->determine_type_no_context(gogo);
8294 : 1266882 : right->determine_type_no_context(gogo);
8295 : :
8296 : 1266882 : Bexpression* left_bexpr = left->get_backend(context);
8297 : 1266882 : Bexpression* right_bexpr = right->get_backend(context);
8298 : :
8299 : 1266882 : Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
8300 : : right_bexpr, location);
8301 : 1266882 : if (result_type != NULL)
8302 : 1266777 : ret = gogo->backend()->convert_expression(result_type->get_backend(gogo),
8303 : : ret, location);
8304 : 1266882 : return ret;
8305 : : }
8306 : :
8307 : : // Class String_concat_expression.
8308 : :
8309 : : bool
8310 : 1461 : String_concat_expression::do_is_constant() const
8311 : : {
8312 : 2295 : for (Expression_list::const_iterator pe = this->exprs_->begin();
8313 : 2295 : pe != this->exprs_->end();
8314 : 834 : ++pe)
8315 : : {
8316 : 2295 : if (!(*pe)->is_constant())
8317 : 1461 : return false;
8318 : : }
8319 : : return true;
8320 : : }
8321 : :
8322 : : bool
8323 : 403 : String_concat_expression::do_is_untyped(Type** ptype) const
8324 : : {
8325 : 403 : for (Expression_list::iterator pe = this->exprs_->begin();
8326 : 403 : pe != this->exprs_->end();
8327 : 0 : ++pe)
8328 : : {
8329 : 403 : if (!(*pe)->is_untyped(ptype))
8330 : 403 : return false;
8331 : : }
8332 : :
8333 : 0 : *ptype = Type::make_string_type();
8334 : 0 : return true;
8335 : : }
8336 : :
8337 : : bool
8338 : 6 : String_concat_expression::do_is_zero_value() const
8339 : : {
8340 : 6 : for (Expression_list::const_iterator pe = this->exprs_->begin();
8341 : 6 : pe != this->exprs_->end();
8342 : 0 : ++pe)
8343 : : {
8344 : 6 : if (!(*pe)->is_zero_value())
8345 : 6 : return false;
8346 : : }
8347 : : return true;
8348 : : }
8349 : :
8350 : : bool
8351 : 39 : String_concat_expression::do_is_static_initializer() const
8352 : : {
8353 : 52 : for (Expression_list::const_iterator pe = this->exprs_->begin();
8354 : 52 : pe != this->exprs_->end();
8355 : 13 : ++pe)
8356 : : {
8357 : 52 : if (!(*pe)->is_static_initializer())
8358 : 39 : return false;
8359 : : }
8360 : : return true;
8361 : : }
8362 : :
8363 : : Type*
8364 : 109310 : String_concat_expression::do_type()
8365 : : {
8366 : 109310 : Type* t = this->exprs_->front()->type();
8367 : 109310 : Expression_list::iterator pe = this->exprs_->begin();
8368 : 109310 : ++pe;
8369 : 290786 : for (; pe != this->exprs_->end(); ++pe)
8370 : : {
8371 : 181476 : Type* t1;
8372 : 181476 : if (!Binary_expression::operation_type(OPERATOR_PLUS, t,
8373 : 181476 : (*pe)->type(),
8374 : : &t1))
8375 : 0 : return Type::make_error_type();
8376 : 181476 : t = t1;
8377 : : }
8378 : : return t;
8379 : : }
8380 : :
8381 : : void
8382 : 3795 : String_concat_expression::do_determine_type(Gogo* gogo,
8383 : : const Type_context* context)
8384 : : {
8385 : 3795 : Type_context subcontext(*context);
8386 : 3795 : for (Expression_list::iterator pe = this->exprs_->begin();
8387 : 3795 : pe != this->exprs_->end();
8388 : 0 : ++pe)
8389 : : {
8390 : 3795 : Type* t = (*pe)->type();
8391 : 3795 : if (!t->is_abstract())
8392 : : {
8393 : 3795 : subcontext.type = t;
8394 : 3795 : break;
8395 : : }
8396 : : }
8397 : 3795 : if (subcontext.type == NULL)
8398 : 0 : subcontext.type = this->exprs_->front()->type();
8399 : 14101 : for (Expression_list::iterator pe = this->exprs_->begin();
8400 : 14101 : pe != this->exprs_->end();
8401 : 10306 : ++pe)
8402 : 10306 : (*pe)->determine_type(gogo, &subcontext);
8403 : 3795 : }
8404 : :
8405 : : void
8406 : 21 : String_concat_expression::do_check_types(Gogo*)
8407 : : {
8408 : 21 : if (this->is_error_expression())
8409 : : return;
8410 : 21 : Type* t = this->exprs_->front()->type();
8411 : 21 : if (t->is_error())
8412 : : {
8413 : 0 : this->set_is_error();
8414 : 0 : return;
8415 : : }
8416 : 21 : Expression_list::iterator pe = this->exprs_->begin();
8417 : 21 : ++pe;
8418 : 48 : for (; pe != this->exprs_->end(); ++pe)
8419 : : {
8420 : 27 : Type* t1 = (*pe)->type();
8421 : 27 : if (!Type::are_compatible_for_binop(t, t1))
8422 : : {
8423 : 0 : this->report_error("incompatible types in binary expression");
8424 : 0 : return;
8425 : : }
8426 : 27 : if (!Binary_expression::check_operator_type(OPERATOR_PLUS, t, t1,
8427 : : this->location()))
8428 : : {
8429 : 0 : this->set_is_error();
8430 : 0 : return;
8431 : : }
8432 : : }
8433 : : }
8434 : :
8435 : : Expression*
8436 : 10472 : String_concat_expression::do_flatten(Gogo* gogo, Named_object*,
8437 : : Statement_inserter* inserter)
8438 : : {
8439 : 10472 : if (this->is_error_expression())
8440 : 0 : return this;
8441 : 10472 : Location loc = this->location();
8442 : 10472 : Type* type = this->type();
8443 : :
8444 : : // Mark string([]byte) operands to reuse the backing store.
8445 : : // runtime.concatstrings does not keep the reference.
8446 : : //
8447 : : // Note: in the gc runtime, if all but one inputs are empty,
8448 : : // concatstrings returns the only nonempty input without copy.
8449 : : // So it is not safe to reuse the backing store if it is a
8450 : : // string([]byte) conversion. So the gc compiler does the
8451 : : // no-copy optimization only when there is at least one
8452 : : // constant nonempty input. Currently the gccgo runtime
8453 : : // doesn't do this, so we don't do the check.
8454 : 10472 : for (Expression_list::iterator p = this->exprs_->begin();
8455 : 37161 : p != this->exprs_->end();
8456 : 26689 : ++p)
8457 : : {
8458 : 27106 : Type_conversion_expression* tce = (*p)->conversion_expression();
8459 : 417 : if (tce != NULL)
8460 : 417 : tce->set_no_copy(true);
8461 : : }
8462 : :
8463 : 10472 : Expression* buf = NULL;
8464 : 10472 : Node* n = Node::make_node(this);
8465 : 10472 : if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
8466 : : {
8467 : 1205 : size_t size = 0;
8468 : 1205 : for (Expression_list::iterator p = this->exprs_->begin();
8469 : 4128 : p != this->exprs_->end();
8470 : 2923 : ++p)
8471 : : {
8472 : 2923 : std::string s;
8473 : 2923 : if ((*p)->string_constant_value(&s))
8474 : 1342 : size += s.length();
8475 : 2923 : }
8476 : : // Make a buffer on stack if the result does not escape.
8477 : : // But don't do this if we know it won't fit.
8478 : 1205 : if (size < (size_t)tmp_string_buf_size)
8479 : : {
8480 : 1129 : Type* byte_type = Type::lookup_integer_type("uint8");
8481 : 1129 : Expression* buflen =
8482 : 1129 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
8483 : 1129 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
8484 : 1129 : Type* array_type = Type::make_array_type(byte_type, buflen);
8485 : 1129 : buf = Expression::make_allocation(array_type, loc);
8486 : 1129 : buf->allocation_expression()->set_allocate_on_stack();
8487 : 1129 : buf->allocation_expression()->set_no_zero();
8488 : : }
8489 : : }
8490 : 1129 : if (buf == NULL)
8491 : 9343 : buf = Expression::make_nil(loc);
8492 : 10472 : go_assert(this->exprs_->size() > 1);
8493 : 10472 : Expression* len =
8494 : 10472 : Expression::make_integer_ul(this->exprs_->size(), NULL, loc);
8495 : 10472 : Array_type* array_type = Type::make_array_type(type, len);
8496 : 10472 : array_type->set_is_array_incomparable();
8497 : 10472 : Expression* array =
8498 : 10472 : Expression::make_array_composite_literal(array_type, this->exprs_,
8499 : : loc);
8500 : 10472 : Temporary_statement* ts =
8501 : 10472 : Statement::make_temporary(array_type, array, loc);
8502 : 10472 : ts->determine_types(gogo);
8503 : 10472 : inserter->insert(ts);
8504 : 10472 : Expression* ref = Expression::make_temporary_reference(ts, loc);
8505 : 10472 : ref = Expression::make_unary(OPERATOR_AND, ref, loc);
8506 : 10472 : Expression* call =
8507 : 10472 : Runtime::make_call(gogo, Runtime::CONCATSTRINGS, loc, 3, buf,
8508 : : ref, len->copy());
8509 : 10472 : Expression* ret = Expression::make_cast(type, call, loc);
8510 : 10472 : Type_context context(type, false);
8511 : 10472 : ret->determine_type(gogo, &context);
8512 : 10472 : return ret;
8513 : : }
8514 : :
8515 : : void
8516 : 0 : String_concat_expression::do_dump_expression(
8517 : : Ast_dump_context* ast_dump_context) const
8518 : : {
8519 : 0 : ast_dump_context->ostream() << "concat(";
8520 : 0 : ast_dump_context->dump_expression_list(this->exprs_, false);
8521 : 0 : ast_dump_context->ostream() << ")";
8522 : 0 : }
8523 : :
8524 : : Expression*
8525 : 16280 : Expression::make_string_concat(Expression_list* exprs)
8526 : : {
8527 : 16280 : return new String_concat_expression(exprs);
8528 : : }
8529 : :
8530 : : // Class Bound_method_expression.
8531 : :
8532 : : // Traversal.
8533 : :
8534 : : int
8535 : 401478 : Bound_method_expression::do_traverse(Traverse* traverse)
8536 : : {
8537 : 401478 : return Expression::traverse(&this->expr_, traverse);
8538 : : }
8539 : :
8540 : : // Return the type of a bound method expression. The type of this
8541 : : // object is simply the type of the method with no receiver.
8542 : :
8543 : : Type*
8544 : 2418516 : Bound_method_expression::do_type()
8545 : : {
8546 : 2418516 : Named_object* fn = this->method_->named_object();
8547 : 2418516 : Function_type* fntype;
8548 : 2418516 : if (fn->is_function())
8549 : 1356007 : fntype = fn->func_value()->type();
8550 : 1062509 : else if (fn->is_function_declaration())
8551 : 1062509 : fntype = fn->func_declaration_value()->type();
8552 : : else
8553 : 0 : return Type::make_error_type();
8554 : 2418516 : return fntype->copy_without_receiver();
8555 : : }
8556 : :
8557 : : // Determine the types of a method expression.
8558 : :
8559 : : void
8560 : 264971 : Bound_method_expression::do_determine_type(Gogo* gogo, const Type_context*)
8561 : : {
8562 : 264971 : Named_object* fn = this->method_->named_object();
8563 : 264971 : Function_type* fntype;
8564 : 264971 : if (fn->is_function())
8565 : 137245 : fntype = fn->func_value()->type();
8566 : 127726 : else if (fn->is_function_declaration())
8567 : 127726 : fntype = fn->func_declaration_value()->type();
8568 : : else
8569 : : fntype = NULL;
8570 : 264971 : if (fntype == NULL || !fntype->is_method())
8571 : 0 : this->expr_->determine_type_no_context(gogo);
8572 : : else
8573 : : {
8574 : 264971 : Type_context subcontext(fntype->receiver()->type(), false);
8575 : 264971 : this->expr_->determine_type(gogo, &subcontext);
8576 : : }
8577 : 264971 : }
8578 : :
8579 : : // Check the types of a method expression.
8580 : :
8581 : : void
8582 : 23671 : Bound_method_expression::do_check_types(Gogo*)
8583 : : {
8584 : 23671 : Named_object* fn = this->function();
8585 : 23671 : if (!fn->is_function() && !fn->is_function_declaration())
8586 : : {
8587 : 0 : this->report_error(_("object is not a method"));
8588 : 0 : return;
8589 : : }
8590 : :
8591 : 23671 : Function_type* fntype;
8592 : 23671 : if (fn->is_function())
8593 : 10989 : fntype = fn->func_value()->type();
8594 : 12682 : else if (fn->is_function_declaration())
8595 : 12682 : fntype = fn->func_declaration_value()->type();
8596 : : else
8597 : : go_unreachable();
8598 : 23671 : Type* rtype = fntype->receiver()->type()->deref();
8599 : 23671 : Type* etype = (this->expr_type_ != NULL
8600 : 23671 : ? this->expr_type_
8601 : 23671 : : this->expr_->type());
8602 : 23671 : etype = etype->deref();
8603 : 23671 : if (!Type::are_identical(rtype, etype, Type::COMPARE_TAGS, NULL))
8604 : 0 : this->report_error(_("method type does not match object type"));
8605 : : }
8606 : :
8607 : : // If a bound method expression is not simply called, then it is
8608 : : // represented as a closure. The closure will hold a single variable,
8609 : : // the receiver to pass to the method. The function will be a simple
8610 : : // thunk that pulls that value from the closure and calls the method
8611 : : // with the remaining arguments.
8612 : : //
8613 : : // Because method values are not common, we don't build all thunks for
8614 : : // every methods, but instead only build them as we need them. In
8615 : : // particular, we even build them on demand for methods defined in
8616 : : // other packages.
8617 : :
8618 : : Bound_method_expression::Method_value_thunks
8619 : : Bound_method_expression::method_value_thunks;
8620 : :
8621 : : // Find or create the thunk for FN.
8622 : :
8623 : : Named_object*
8624 : 934 : Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
8625 : : Named_object* fn)
8626 : : {
8627 : 934 : std::pair<Named_object*, Named_object*> val(fn, NULL);
8628 : 934 : std::pair<Method_value_thunks::iterator, bool> ins =
8629 : 934 : Bound_method_expression::method_value_thunks.insert(val);
8630 : 934 : if (!ins.second)
8631 : : {
8632 : : // We have seen this method before.
8633 : 287 : go_assert(ins.first->second != NULL);
8634 : : return ins.first->second;
8635 : : }
8636 : :
8637 : 647 : Location loc = fn->location();
8638 : :
8639 : 647 : Function_type* orig_fntype;
8640 : 647 : if (fn->is_function())
8641 : 541 : orig_fntype = fn->func_value()->type();
8642 : 106 : else if (fn->is_function_declaration())
8643 : 106 : orig_fntype = fn->func_declaration_value()->type();
8644 : : else
8645 : : orig_fntype = NULL;
8646 : :
8647 : 647 : if (orig_fntype == NULL || !orig_fntype->is_method())
8648 : : {
8649 : 0 : ins.first->second =
8650 : 0 : Named_object::make_erroneous_name(gogo->thunk_name());
8651 : 0 : return ins.first->second;
8652 : : }
8653 : :
8654 : 647 : Struct_field_list* sfl = new Struct_field_list();
8655 : : // The type here is wrong--it should be the C function type. But it
8656 : : // doesn't really matter.
8657 : 647 : Type* vt = Type::make_pointer_type(Type::make_void_type());
8658 : 647 : sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
8659 : 1294 : sfl->push_back(Struct_field(Typed_identifier("val",
8660 : : orig_fntype->receiver()->type(),
8661 : 647 : loc)));
8662 : 647 : Struct_type* st = Type::make_struct_type(sfl, loc);
8663 : 647 : st->set_is_struct_incomparable();
8664 : 647 : Type* closure_type = Type::make_pointer_type(st);
8665 : :
8666 : 647 : Function_type* new_fntype = orig_fntype->copy_with_names();
8667 : :
8668 : 647 : std::string thunk_name = gogo->thunk_name();
8669 : 647 : Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
8670 : : false, loc);
8671 : :
8672 : 647 : Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
8673 : 647 : cvar->set_is_used();
8674 : 647 : cvar->set_is_closure();
8675 : 647 : Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
8676 : : NULL, cvar);
8677 : 647 : new_no->func_value()->set_closure_var(cp);
8678 : :
8679 : 647 : gogo->start_block(loc);
8680 : :
8681 : : // Field 0 of the closure is the function code pointer, field 1 is
8682 : : // the value on which to invoke the method.
8683 : 647 : Expression* arg = Expression::make_var_reference(cp, loc);
8684 : 647 : arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
8685 : 647 : arg = Expression::make_field_reference(arg, 1, loc);
8686 : :
8687 : 647 : Expression* bme = Expression::make_bound_method(arg, method, fn, loc);
8688 : :
8689 : 647 : const Typed_identifier_list* orig_params = orig_fntype->parameters();
8690 : 647 : Expression_list* args;
8691 : 647 : if (orig_params == NULL || orig_params->empty())
8692 : : args = NULL;
8693 : : else
8694 : : {
8695 : 386 : const Typed_identifier_list* new_params = new_fntype->parameters();
8696 : 386 : args = new Expression_list();
8697 : 386 : for (Typed_identifier_list::const_iterator p = new_params->begin();
8698 : 1135 : p != new_params->end();
8699 : 749 : ++p)
8700 : : {
8701 : 749 : Named_object* p_no = gogo->lookup(p->name(), NULL);
8702 : 749 : go_assert(p_no != NULL
8703 : : && p_no->is_variable()
8704 : : && p_no->var_value()->is_parameter());
8705 : 749 : args->push_back(Expression::make_var_reference(p_no, loc));
8706 : : }
8707 : : }
8708 : :
8709 : 647 : Call_expression* call = Expression::make_call(bme, args,
8710 : 647 : orig_fntype->is_varargs(),
8711 : : loc);
8712 : 647 : call->set_varargs_are_lowered();
8713 : :
8714 : 647 : Statement* s = Statement::make_return_from_call(new_no, call, loc);
8715 : 647 : s->determine_types(gogo);
8716 : 647 : gogo->add_statement(s);
8717 : 647 : Block* b = gogo->finish_block(loc);
8718 : 647 : gogo->add_block(b, loc);
8719 : :
8720 : : // This is called after lowering.
8721 : 647 : gogo->lower_block(new_no, b);
8722 : :
8723 : 647 : gogo->finish_function(loc);
8724 : :
8725 : 647 : ins.first->second = new_no;
8726 : 647 : return new_no;
8727 : 647 : }
8728 : :
8729 : : // Look up a thunk for FN.
8730 : :
8731 : : Named_object*
8732 : 934 : Bound_method_expression::lookup_thunk(Named_object* fn)
8733 : : {
8734 : 934 : Method_value_thunks::const_iterator p =
8735 : 934 : Bound_method_expression::method_value_thunks.find(fn);
8736 : 934 : if (p == Bound_method_expression::method_value_thunks.end())
8737 : : return NULL;
8738 : 934 : return p->second;
8739 : : }
8740 : :
8741 : : // Return an expression to check *REF for nil while dereferencing
8742 : : // according to FIELD_INDEXES. Update *REF to build up the field
8743 : : // reference. This is a static function so that we don't have to
8744 : : // worry about declaring Field_indexes in expressions.h.
8745 : :
8746 : : static Expression*
8747 : 31 : bme_check_nil(const Method::Field_indexes* field_indexes, Location loc,
8748 : : Expression** ref)
8749 : : {
8750 : 31 : if (field_indexes == NULL)
8751 : 14 : return Expression::make_boolean(false, loc);
8752 : 17 : Expression* cond = bme_check_nil(field_indexes->next, loc, ref);
8753 : 34 : Struct_type* stype = (*ref)->type()->deref()->struct_type();
8754 : 17 : go_assert(stype != NULL
8755 : : && field_indexes->field_index < stype->field_count());
8756 : 17 : if ((*ref)->type()->struct_type() == NULL)
8757 : : {
8758 : 10 : go_assert((*ref)->type()->points_to() != NULL);
8759 : 10 : Expression* n = Expression::make_binary(OPERATOR_EQEQ, *ref,
8760 : : Expression::make_nil(loc),
8761 : : loc);
8762 : 10 : cond = Expression::make_binary(OPERATOR_OROR, cond, n, loc);
8763 : 10 : *ref = Expression::make_dereference(*ref, Expression::NIL_CHECK_DEFAULT,
8764 : : loc);
8765 : 20 : go_assert((*ref)->type()->struct_type() == stype);
8766 : : }
8767 : 17 : *ref = Expression::make_field_reference(*ref, field_indexes->field_index,
8768 : : loc);
8769 : 17 : return cond;
8770 : : }
8771 : :
8772 : : // Flatten a method value into a struct with nil checks. We can't do
8773 : : // this in the lowering phase, because if the method value is called
8774 : : // directly we don't need a thunk. That case will have been handled
8775 : : // by Call_expression::do_lower, so if we get here then we do need a
8776 : : // thunk.
8777 : :
8778 : : Expression*
8779 : 934 : Bound_method_expression::do_flatten(Gogo* gogo, Named_object*,
8780 : : Statement_inserter* inserter)
8781 : : {
8782 : 934 : Location loc = this->location();
8783 : :
8784 : 934 : Named_object* thunk = Bound_method_expression::lookup_thunk(this->function_);
8785 : :
8786 : : // The thunk should have been created during the
8787 : : // create_function_descriptors pass.
8788 : 934 : if (thunk == NULL || thunk->is_erroneous())
8789 : : {
8790 : 0 : go_assert(saw_errors());
8791 : 0 : return Expression::make_error(loc);
8792 : : }
8793 : :
8794 : : // Force the expression into a variable. This is only necessary if
8795 : : // we are going to do nil checks below, but it's easy enough to
8796 : : // always do it.
8797 : 934 : Expression* expr = this->expr_;
8798 : 934 : if (!expr->is_multi_eval_safe())
8799 : : {
8800 : 292 : Temporary_statement* etemp = Statement::make_temporary(NULL, expr, loc);
8801 : 292 : inserter->insert(etemp);
8802 : 292 : expr = Expression::make_temporary_reference(etemp, loc);
8803 : : }
8804 : :
8805 : : // If the method expects a value, and we have a pointer, we need to
8806 : : // dereference the pointer.
8807 : :
8808 : 934 : Named_object* fn = this->method_->named_object();
8809 : 934 : Function_type *fntype;
8810 : 934 : if (fn->is_function())
8811 : 814 : fntype = fn->func_value()->type();
8812 : 120 : else if (fn->is_function_declaration())
8813 : 120 : fntype = fn->func_declaration_value()->type();
8814 : : else
8815 : 0 : go_unreachable();
8816 : :
8817 : 934 : Expression* val = expr;
8818 : 934 : if (fntype->receiver()->type()->points_to() == NULL
8819 : 1135 : && val->type()->points_to() != NULL)
8820 : 25 : val = Expression::make_dereference(val, NIL_CHECK_DEFAULT, loc);
8821 : :
8822 : : // Note that we are ignoring this->expr_type_ here. The thunk will
8823 : : // expect a closure whose second field has type this->expr_type_ (if
8824 : : // that is not NULL). We are going to pass it a closure whose
8825 : : // second field has type this->expr_->type(). Since
8826 : : // this->expr_type_ is only not-NULL for pointer types, we can get
8827 : : // away with this.
8828 : :
8829 : 934 : Struct_field_list* fields = new Struct_field_list();
8830 : 934 : fields->push_back(Struct_field(Typed_identifier("fn",
8831 : 934 : thunk->func_value()->type(),
8832 : 934 : loc)));
8833 : 934 : fields->push_back(Struct_field(Typed_identifier("val", val->type(), loc)));
8834 : 934 : Struct_type* st = Type::make_struct_type(fields, loc);
8835 : 934 : st->set_is_struct_incomparable();
8836 : :
8837 : 934 : Expression_list* vals = new Expression_list();
8838 : 934 : vals->push_back(Expression::make_func_code_reference(thunk, loc));
8839 : 934 : vals->push_back(val);
8840 : :
8841 : 934 : Expression* ret = Expression::make_struct_composite_literal(st, vals, loc);
8842 : 934 : ret = Expression::make_heap_expression(ret, loc);
8843 : :
8844 : 934 : Node* node = Node::make_node(this);
8845 : 934 : if ((node->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
8846 : 417 : ret->heap_expression()->set_allocate_on_stack();
8847 : 517 : else if (gogo->compiling_runtime()
8848 : 0 : && gogo->package_name() == "runtime"
8849 : 517 : && !saw_errors())
8850 : 0 : go_error_at(loc, "%s escapes to heap, not allowed in runtime",
8851 : 0 : node->ast_format(gogo).c_str());
8852 : :
8853 : : // If necessary, check whether the expression or any embedded
8854 : : // pointers are nil.
8855 : :
8856 : 934 : Expression* nil_check = NULL;
8857 : 934 : if (this->method_->field_indexes() != NULL)
8858 : : {
8859 : 14 : Expression* ref = expr;
8860 : 14 : nil_check = bme_check_nil(this->method_->field_indexes(), loc, &ref);
8861 : 14 : expr = ref;
8862 : : }
8863 : :
8864 : 1135 : if (this->method_->is_value_method() && expr->type()->points_to() != NULL)
8865 : : {
8866 : 27 : Expression* n = Expression::make_binary(OPERATOR_EQEQ, expr,
8867 : : Expression::make_nil(loc),
8868 : : loc);
8869 : 27 : if (nil_check == NULL)
8870 : : nil_check = n;
8871 : : else
8872 : 6 : nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
8873 : : }
8874 : :
8875 : 934 : if (nil_check != NULL)
8876 : : {
8877 : 35 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
8878 : : // Fix the type of the conditional expression by pretending to
8879 : : // evaluate to RET either way through the conditional.
8880 : 35 : crash->determine_type_no_context(gogo);
8881 : 35 : crash = Expression::make_compound(crash, ret, loc);
8882 : 35 : ret = Expression::make_conditional(nil_check, crash, ret, loc);
8883 : : }
8884 : :
8885 : : // RET is a pointer to a struct, but we want a function type.
8886 : 934 : ret = Expression::make_unsafe_cast(this->type(), ret, loc);
8887 : :
8888 : 934 : ret->determine_type_no_context(gogo);
8889 : :
8890 : 934 : return ret;
8891 : : }
8892 : :
8893 : : // Dump ast representation of a bound method expression.
8894 : :
8895 : : void
8896 : 0 : Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
8897 : : const
8898 : : {
8899 : 0 : if (this->expr_type_ != NULL)
8900 : 0 : ast_dump_context->ostream() << "(";
8901 : 0 : ast_dump_context->dump_expression(this->expr_);
8902 : 0 : if (this->expr_type_ != NULL)
8903 : : {
8904 : 0 : ast_dump_context->ostream() << ":";
8905 : 0 : ast_dump_context->dump_type(this->expr_type_);
8906 : 0 : ast_dump_context->ostream() << ")";
8907 : : }
8908 : :
8909 : 0 : ast_dump_context->ostream() << "." << this->function_->name();
8910 : 0 : }
8911 : :
8912 : : // Make a method expression.
8913 : :
8914 : : Bound_method_expression*
8915 : 264730 : Expression::make_bound_method(Expression* expr, const Method* method,
8916 : : Named_object* function, Location location)
8917 : : {
8918 : 264730 : return new Bound_method_expression(expr, method, function, location);
8919 : : }
8920 : :
8921 : : // A general selector. This is a Parser_expression for LEFT.NAME. It
8922 : : // is lowered after we know the type of the left hand side.
8923 : :
8924 : : class Selector_expression : public Parser_expression
8925 : : {
8926 : : public:
8927 : 700127 : Selector_expression(Expression* left, const std::string& name,
8928 : : Location location)
8929 : 700127 : : Parser_expression(EXPRESSION_SELECTOR, location),
8930 : 700127 : left_(left), name_(name), resolved_(NULL)
8931 : 700127 : { }
8932 : :
8933 : : // Return the resolved selector. This will typically be a
8934 : : // Field_reference_expression or a Bound_method_expression or an
8935 : : // Interface_field_reference_expression.
8936 : : Expression*
8937 : 1156 : resolved()
8938 : 1156 : { return this->resolved_; }
8939 : :
8940 : : protected:
8941 : : int
8942 : 3601519 : do_traverse(Traverse* traverse)
8943 : 3601519 : { return Expression::traverse(&this->left_, traverse); }
8944 : :
8945 : : Type*
8946 : : do_type();
8947 : :
8948 : : void
8949 : : do_determine_type(Gogo*, const Type_context*);
8950 : :
8951 : : bool
8952 : : do_is_addressable() const;
8953 : :
8954 : : void
8955 : : do_issue_nil_check();
8956 : :
8957 : : Expression*
8958 : : do_lower(Gogo*, Named_object*, Statement_inserter*);
8959 : :
8960 : : Expression*
8961 : 0 : do_copy()
8962 : : {
8963 : 0 : return new Selector_expression(this->left_->copy(), this->name_,
8964 : 0 : this->location());
8965 : : }
8966 : :
8967 : : void
8968 : : do_dump_expression(Ast_dump_context* ast_dump_context) const;
8969 : :
8970 : : private:
8971 : : Expression*
8972 : : lower_method_expression(Gogo*);
8973 : :
8974 : : // The expression on the left hand side.
8975 : : Expression* left_;
8976 : : // The name on the right hand side.
8977 : : std::string name_;
8978 : : // The resolved expression.
8979 : : Expression* resolved_;
8980 : : };
8981 : :
8982 : : void
8983 : 807096 : Selector_expression::do_determine_type(Gogo* gogo, const Type_context* context)
8984 : : {
8985 : 807096 : if (this->is_error_expression() || this->resolved_ != NULL)
8986 : : return;
8987 : 700125 : Expression* left = this->left_;
8988 : 700125 : left->determine_type_no_context(gogo);
8989 : 700125 : if (left->is_error_expression())
8990 : 7 : this->set_is_error();
8991 : : else
8992 : : {
8993 : 700118 : if (left->is_type_expression())
8994 : 602 : this->resolved_ = this->lower_method_expression(gogo);
8995 : : else
8996 : 699516 : this->resolved_ = Type::bind_field_or_method(gogo, left->type(), left,
8997 : 699516 : this->name_,
8998 : : this->location());
8999 : 700118 : this->resolved_->determine_type(gogo, context);
9000 : : }
9001 : : }
9002 : :
9003 : : Type*
9004 : 2874842 : Selector_expression::do_type()
9005 : : {
9006 : 2874842 : if (this->is_error_expression())
9007 : 12 : return Type::make_error_type();
9008 : 2874830 : go_assert(this->resolved_ != NULL);
9009 : 2874830 : return this->resolved_->type();
9010 : : }
9011 : :
9012 : : bool
9013 : 141725 : Selector_expression::do_is_addressable() const
9014 : : {
9015 : 141725 : if (this->is_error_expression())
9016 : : return true;
9017 : 141724 : go_assert(this->resolved_ != NULL);
9018 : 141724 : return this->resolved_->is_addressable();
9019 : : }
9020 : :
9021 : : void
9022 : 16436 : Selector_expression::do_issue_nil_check()
9023 : : {
9024 : 16436 : if (this->is_error_expression())
9025 : : return;
9026 : 16436 : go_assert(this->resolved_ != NULL);
9027 : 16436 : this->resolved_->issue_nil_check();
9028 : : }
9029 : :
9030 : : // Lower a selector expression to the resolved value.
9031 : :
9032 : : Expression*
9033 : 771980 : Selector_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
9034 : : {
9035 : 771980 : if (this->is_error_expression() || this->resolved_ == NULL)
9036 : 5 : return Expression::make_error(this->location());
9037 : : return this->resolved_;
9038 : : }
9039 : :
9040 : : // Lower a method expression T.M or (*T).M. We turn this into a
9041 : : // function literal.
9042 : :
9043 : : Expression*
9044 : 602 : Selector_expression::lower_method_expression(Gogo* gogo)
9045 : : {
9046 : 602 : Location location = this->location();
9047 : 602 : Type* left_type = this->left_->type();
9048 : 602 : Type* type = left_type;
9049 : 602 : const std::string& name(this->name_);
9050 : :
9051 : 602 : bool is_pointer;
9052 : 602 : if (type->points_to() == NULL)
9053 : : is_pointer = false;
9054 : : else
9055 : : {
9056 : 407 : is_pointer = true;
9057 : 407 : type = type->points_to();
9058 : : }
9059 : :
9060 : 602 : Named_type* nt = type->named_type();
9061 : 602 : Struct_type* st = type->struct_type();
9062 : 602 : bool is_ambiguous = false;
9063 : 602 : Method* method = NULL;
9064 : 602 : if (nt != NULL)
9065 : 599 : method = nt->method_function(name, &is_ambiguous);
9066 : 3 : else if (st != NULL)
9067 : 1 : method = st->method_function(name, &is_ambiguous);
9068 : 602 : const Typed_identifier* imethod = NULL;
9069 : 602 : if (method == NULL && !is_pointer)
9070 : : {
9071 : 28 : Interface_type* it = type->interface_type();
9072 : 28 : if (it != NULL)
9073 : 28 : imethod = it->find_method(name);
9074 : : }
9075 : :
9076 : 602 : if ((method == NULL && imethod == NULL)
9077 : 602 : || (left_type->named_type() != NULL && left_type->points_to() != NULL))
9078 : : {
9079 : 3 : if (nt != NULL)
9080 : : {
9081 : 2 : if (!is_ambiguous)
9082 : 2 : go_error_at(location, "type %<%s%s%> has no method %qs",
9083 : : is_pointer ? "*" : "",
9084 : 4 : nt->message_name().c_str(),
9085 : 4 : Gogo::message_name(name).c_str());
9086 : : else
9087 : 0 : go_error_at(location, "method %<%s%s%> is ambiguous in type %qs",
9088 : 0 : Gogo::message_name(name).c_str(),
9089 : : is_pointer ? "*" : "",
9090 : 0 : nt->message_name().c_str());
9091 : : }
9092 : : else
9093 : : {
9094 : 1 : if (!is_ambiguous)
9095 : 1 : go_error_at(location, "type has no method %qs",
9096 : 2 : Gogo::message_name(name).c_str());
9097 : : else
9098 : 0 : go_error_at(location, "method %qs is ambiguous",
9099 : 0 : Gogo::message_name(name).c_str());
9100 : : }
9101 : 3 : return Expression::make_error(location);
9102 : : }
9103 : :
9104 : 599 : if (method != NULL && !is_pointer && !method->is_value_method())
9105 : : {
9106 : 1 : go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
9107 : 2 : nt->message_name().c_str(),
9108 : 1 : Gogo::message_name(name).c_str());
9109 : 1 : return Expression::make_error(location);
9110 : : }
9111 : :
9112 : : // Build a new function type in which the receiver becomes the first
9113 : : // argument.
9114 : 598 : Function_type* method_type;
9115 : 598 : if (method != NULL)
9116 : : {
9117 : 570 : method_type = method->type();
9118 : 570 : go_assert(method_type->is_method());
9119 : : }
9120 : : else
9121 : : {
9122 : 28 : method_type = imethod->type()->function_type();
9123 : 28 : go_assert(method_type != NULL && !method_type->is_method());
9124 : : }
9125 : :
9126 : 598 : const char* const receiver_name = "$this";
9127 : 598 : Typed_identifier_list* parameters = new Typed_identifier_list();
9128 : 1196 : parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
9129 : 598 : location));
9130 : :
9131 : 598 : const Typed_identifier_list* method_parameters = method_type->parameters();
9132 : 598 : if (method_parameters != NULL)
9133 : : {
9134 : 272 : int i = 0;
9135 : 272 : for (Typed_identifier_list::const_iterator p = method_parameters->begin();
9136 : 730 : p != method_parameters->end();
9137 : 458 : ++p, ++i)
9138 : : {
9139 : 458 : if (!p->name().empty() && !Gogo::is_sink_name(p->name()))
9140 : 439 : parameters->push_back(*p);
9141 : : else
9142 : : {
9143 : 19 : char buf[20];
9144 : 19 : snprintf(buf, sizeof buf, "$param%d", i);
9145 : 19 : parameters->push_back(Typed_identifier(buf, p->type(),
9146 : 38 : p->location()));
9147 : : }
9148 : : }
9149 : : }
9150 : :
9151 : 598 : const Typed_identifier_list* method_results = method_type->results();
9152 : 598 : Typed_identifier_list* results;
9153 : 598 : if (method_results == NULL)
9154 : : results = NULL;
9155 : : else
9156 : : {
9157 : 477 : results = new Typed_identifier_list();
9158 : 477 : for (Typed_identifier_list::const_iterator p = method_results->begin();
9159 : 1004 : p != method_results->end();
9160 : 527 : ++p)
9161 : 527 : results->push_back(*p);
9162 : : }
9163 : :
9164 : 598 : Function_type* fntype = Type::make_function_type(NULL, parameters, results,
9165 : : location);
9166 : 598 : if (method_type->is_varargs())
9167 : 3 : fntype->set_is_varargs();
9168 : :
9169 : : // We generate methods which always takes a pointer to the receiver
9170 : : // as their first argument. If this is for a pointer type, we can
9171 : : // simply reuse the existing function. We use an internal hack to
9172 : : // get the right type.
9173 : : // FIXME: This optimization is disabled because it doesn't yet work
9174 : : // with function descriptors when the method expression is not
9175 : : // directly called.
9176 : 598 : if (method != NULL && is_pointer && false)
9177 : : {
9178 : : Named_object* mno = (method->needs_stub_method()
9179 : : ? method->stub_object()
9180 : : : method->named_object());
9181 : : Expression* f = Expression::make_func_reference(mno, NULL, location);
9182 : : f = Expression::make_cast(fntype, f, location);
9183 : : Type_conversion_expression* tce =
9184 : : static_cast<Type_conversion_expression*>(f);
9185 : : tce->set_may_convert_function_types();
9186 : : return f;
9187 : : }
9188 : :
9189 : 598 : Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
9190 : : location);
9191 : :
9192 : 598 : Named_object* vno = gogo->lookup(receiver_name, NULL);
9193 : 598 : go_assert(vno != NULL);
9194 : 598 : Expression* ve = Expression::make_var_reference(vno, location);
9195 : 598 : Expression* bm;
9196 : 598 : if (method != NULL)
9197 : 570 : bm = Type::bind_field_or_method(gogo, type, ve, name, location);
9198 : : else
9199 : 28 : bm = Expression::make_interface_field_reference(ve, name, location);
9200 : :
9201 : : // Even though we found the method above, if it has an error type we
9202 : : // may see an error here.
9203 : 598 : if (bm->is_error_expression())
9204 : : {
9205 : 0 : gogo->finish_function(location);
9206 : 0 : return bm;
9207 : : }
9208 : :
9209 : 598 : Expression_list* args;
9210 : 598 : if (parameters->size() <= 1)
9211 : : args = NULL;
9212 : : else
9213 : : {
9214 : 272 : args = new Expression_list();
9215 : 272 : Typed_identifier_list::const_iterator p = parameters->begin();
9216 : 272 : ++p;
9217 : 730 : for (; p != parameters->end(); ++p)
9218 : : {
9219 : 458 : vno = gogo->lookup(p->name(), NULL);
9220 : 458 : go_assert(vno != NULL);
9221 : 458 : args->push_back(Expression::make_var_reference(vno, location));
9222 : : }
9223 : : }
9224 : :
9225 : 598 : gogo->start_block(location);
9226 : :
9227 : 598 : Call_expression* call = Expression::make_call(bm, args,
9228 : 598 : method_type->is_varargs(),
9229 : : location);
9230 : :
9231 : 598 : Statement* s = Statement::make_return_from_call(no, call, location);
9232 : 598 : s->determine_types(gogo);
9233 : 598 : gogo->add_statement(s);
9234 : :
9235 : 598 : Block* b = gogo->finish_block(location);
9236 : :
9237 : 598 : gogo->add_block(b, location);
9238 : :
9239 : 598 : gogo->finish_function(location);
9240 : :
9241 : 598 : return Expression::make_func_reference(no, NULL, location);
9242 : : }
9243 : :
9244 : : // Dump the ast for a selector expression.
9245 : :
9246 : : void
9247 : 0 : Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
9248 : : const
9249 : : {
9250 : 0 : ast_dump_context->dump_expression(this->left_);
9251 : 0 : ast_dump_context->ostream() << ".";
9252 : 0 : ast_dump_context->ostream() << this->name_;
9253 : 0 : }
9254 : :
9255 : : // Make a selector expression.
9256 : :
9257 : : Expression*
9258 : 700127 : Expression::make_selector(Expression* left, const std::string& name,
9259 : : Location location)
9260 : : {
9261 : 700127 : return new Selector_expression(left, name, location);
9262 : : }
9263 : :
9264 : : // Class Builtin_call_expression. This is used for a call to a
9265 : : // builtin function.
9266 : :
9267 : 240770 : Builtin_call_expression::Builtin_call_expression(Gogo* gogo,
9268 : : Expression* fn,
9269 : : Expression_list* args,
9270 : : bool is_varargs,
9271 : 240770 : Location location)
9272 : : : Call_expression(fn, args, is_varargs, location),
9273 : 240770 : gogo_(gogo), code_(BUILTIN_INVALID), seen_(false),
9274 : 240770 : recover_arg_is_set_(false)
9275 : : {
9276 : 240770 : const Named_object* no;
9277 : 240770 : if (fn->is_error_expression())
9278 : : {
9279 : : this->code_ = BUILTIN_INVALID;
9280 : : return;
9281 : : }
9282 : 240770 : else if (fn->func_expression() != NULL)
9283 : 240770 : no = fn->func_expression()->named_object();
9284 : 0 : else if (fn->unknown_expression() != NULL)
9285 : 0 : no = fn->unknown_expression()->named_object();
9286 : : else
9287 : 0 : go_unreachable();
9288 : :
9289 : 240770 : const std::string& name(no->name());
9290 : 240770 : if (name == "append")
9291 : 15751 : this->code_ = BUILTIN_APPEND;
9292 : 225019 : else if (name == "cap")
9293 : 16623 : this->code_ = BUILTIN_CAP;
9294 : 208396 : else if (name == "close")
9295 : 1094 : this->code_ = BUILTIN_CLOSE;
9296 : 207302 : else if (name == "complex")
9297 : 13722 : this->code_ = BUILTIN_COMPLEX;
9298 : 193580 : else if (name == "copy")
9299 : 4493 : this->code_ = BUILTIN_COPY;
9300 : 189087 : else if (name == "delete")
9301 : 943 : this->code_ = BUILTIN_DELETE;
9302 : 188144 : else if (name == "imag")
9303 : 555 : this->code_ = BUILTIN_IMAG;
9304 : 187589 : else if (name == "len")
9305 : 116380 : this->code_ = BUILTIN_LEN;
9306 : 71209 : else if (name == "make")
9307 : 15137 : this->code_ = BUILTIN_MAKE;
9308 : 56072 : else if (name == "new")
9309 : 21308 : this->code_ = BUILTIN_NEW;
9310 : 34764 : else if (name == "panic")
9311 : 15153 : this->code_ = BUILTIN_PANIC;
9312 : 19611 : else if (name == "print")
9313 : 2727 : this->code_ = BUILTIN_PRINT;
9314 : 16884 : else if (name == "println")
9315 : 13459 : this->code_ = BUILTIN_PRINTLN;
9316 : 3425 : else if (name == "real")
9317 : 493 : this->code_ = BUILTIN_REAL;
9318 : 2932 : else if (name == "recover")
9319 : 857 : this->code_ = BUILTIN_RECOVER;
9320 : 2075 : else if (name == "Add")
9321 : 9 : this->code_ = BUILTIN_ADD;
9322 : 2066 : else if (name == "Alignof")
9323 : 17 : this->code_ = BUILTIN_ALIGNOF;
9324 : 2049 : else if (name == "Offsetof")
9325 : 1161 : this->code_ = BUILTIN_OFFSETOF;
9326 : 888 : else if (name == "Sizeof")
9327 : 879 : this->code_ = BUILTIN_SIZEOF;
9328 : 9 : else if (name == "Slice")
9329 : 9 : this->code_ = BUILTIN_SLICE;
9330 : : else
9331 : 0 : go_unreachable();
9332 : : }
9333 : :
9334 : : // Return whether this is a call to recover. This is a virtual
9335 : : // function called from the parent class.
9336 : :
9337 : : bool
9338 : 1580 : Builtin_call_expression::do_is_recover_call() const
9339 : : {
9340 : 1580 : if (this->classification() == EXPRESSION_ERROR)
9341 : : return false;
9342 : 1580 : return this->code_ == BUILTIN_RECOVER;
9343 : : }
9344 : :
9345 : : // Set the argument for a call to recover.
9346 : :
9347 : : void
9348 : 857 : Builtin_call_expression::do_set_recover_arg(Expression* arg)
9349 : : {
9350 : 857 : const Expression_list* args = this->args();
9351 : 857 : go_assert(args == NULL || args->empty());
9352 : 857 : Expression_list* new_args = new Expression_list();
9353 : 857 : new_args->push_back(arg);
9354 : 857 : this->set_args(new_args);
9355 : 857 : this->recover_arg_is_set_ = true;
9356 : 857 : }
9357 : :
9358 : : // Lower a builtin call expression. This turns new and make into
9359 : : // specific expressions. We also convert to a constant if we can.
9360 : :
9361 : : Expression*
9362 : 449707 : Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
9363 : : Statement_inserter* inserter)
9364 : : {
9365 : 449707 : if (this->is_error_expression())
9366 : 995 : return this;
9367 : :
9368 : 448712 : Location loc = this->location();
9369 : :
9370 : 448712 : if (this->code_ == BUILTIN_OFFSETOF)
9371 : : {
9372 : 1154 : Expression* arg = this->one_arg();
9373 : 1154 : Field_reference_expression* farg = arg->field_reference_expression();
9374 : 2097 : while (farg != NULL)
9375 : : {
9376 : 2097 : if (!farg->implicit())
9377 : : break;
9378 : : // When the selector refers to an embedded field,
9379 : : // it must not be reached through pointer indirections.
9380 : 1841 : if (farg->expr()->deref() != farg->expr())
9381 : : {
9382 : 898 : this->report_error(_("argument of Offsetof implies "
9383 : : "indirection of an embedded field"));
9384 : 898 : return this;
9385 : : }
9386 : : // Go up until we reach the original base.
9387 : 3040 : farg = farg->expr()->field_reference_expression();
9388 : : }
9389 : : }
9390 : :
9391 : 447814 : if (this->is_constant())
9392 : : {
9393 : 15726 : Numeric_constant nc;
9394 : 15726 : if (this->numeric_constant_value(&nc))
9395 : : {
9396 : 15726 : Expression* ret = nc.expression(loc);
9397 : 15726 : Type_context subcontext;
9398 : 15726 : if (this->type() != NULL)
9399 : 1526 : subcontext = Type_context(this->type(),
9400 : 1526 : this->type()->is_abstract());
9401 : 15726 : ret->determine_type(gogo, &subcontext);
9402 : 15726 : return ret;
9403 : : }
9404 : 15726 : }
9405 : :
9406 : 432088 : switch (this->code_)
9407 : : {
9408 : : default:
9409 : : break;
9410 : :
9411 : 23188 : case BUILTIN_NEW:
9412 : 23188 : return Expression::make_allocation(this->one_arg()->type(), loc);
9413 : :
9414 : 15099 : case BUILTIN_MAKE:
9415 : 15099 : return this->lower_make(gogo, inserter);
9416 : :
9417 : 874 : case BUILTIN_RECOVER:
9418 : 874 : if (function != NULL)
9419 : 874 : function->func_value()->set_calls_recover();
9420 : : else
9421 : : {
9422 : : // Calling recover outside of a function always returns the
9423 : : // nil empty interface.
9424 : 0 : Type* eface = Type::make_empty_interface_type(loc);
9425 : 0 : return Expression::make_cast(eface, Expression::make_nil(loc), loc);
9426 : : }
9427 : 874 : break;
9428 : :
9429 : 1559 : case BUILTIN_DELETE:
9430 : 1559 : {
9431 : 1559 : const Expression_list* args = this->args();
9432 : 1559 : Type* key_type =
9433 : 3118 : args->front()->type()->map_type()->key_type();
9434 : 1559 : Expression_list::iterator pa = this->args()->begin();
9435 : 1559 : pa++;
9436 : 1559 : Type* arg_type = (*pa)->type();
9437 : 1559 : if (!Type::are_identical(key_type, arg_type, 0, NULL))
9438 : 16 : *pa = Expression::make_cast(key_type, *pa, loc);
9439 : : }
9440 : : break;
9441 : :
9442 : 17885 : case BUILTIN_PRINT:
9443 : 17885 : case BUILTIN_PRINTLN:
9444 : : // Force all the arguments into temporary variables, so that we
9445 : : // don't try to evaluate something while holding the print lock.
9446 : 17885 : if (this->args() == NULL)
9447 : : break;
9448 : 61881 : for (Expression_list::iterator pa = this->args()->begin();
9449 : 61881 : pa != this->args()->end();
9450 : 44065 : ++pa)
9451 : : {
9452 : 44065 : if (!(*pa)->is_multi_eval_safe())
9453 : : {
9454 : 27576 : Temporary_statement* temp =
9455 : 27576 : Statement::make_temporary(NULL, *pa, loc);
9456 : 27576 : inserter->insert(temp);
9457 : 27576 : *pa = Expression::make_temporary_reference(temp, loc);
9458 : : }
9459 : : }
9460 : : break;
9461 : : }
9462 : :
9463 : : return this;
9464 : : }
9465 : :
9466 : : // Flatten a builtin call expression. This turns the arguments of some
9467 : : // builtin calls into temporary expressions. Also expand copy and append
9468 : : // to runtime calls.
9469 : :
9470 : : Expression*
9471 : 210171 : Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
9472 : : Statement_inserter* inserter)
9473 : : {
9474 : 210171 : if (this->is_error_expression())
9475 : : {
9476 : 978 : go_assert(saw_errors());
9477 : 978 : return this;
9478 : : }
9479 : :
9480 : 209193 : Location loc = this->location();
9481 : :
9482 : 209193 : switch (this->code_)
9483 : : {
9484 : : default:
9485 : : break;
9486 : :
9487 : 2654 : case BUILTIN_APPEND:
9488 : 2654 : return this->flatten_append(gogo, function, inserter, NULL, NULL);
9489 : :
9490 : 4478 : case BUILTIN_COPY:
9491 : 4478 : {
9492 : 4478 : Type* at = this->args()->front()->type();
9493 : 13434 : for (Expression_list::iterator pa = this->args()->begin();
9494 : 13434 : pa != this->args()->end();
9495 : 8956 : ++pa)
9496 : : {
9497 : 8956 : if ((*pa)->is_error_expression())
9498 : : {
9499 : 0 : go_assert(saw_errors());
9500 : 0 : return Expression::make_error(loc);
9501 : : }
9502 : 8956 : if ((*pa)->is_nil_expression())
9503 : : {
9504 : 0 : Expression* nil = Expression::make_nil(loc);
9505 : 0 : Expression* zero = Expression::make_integer_ul(0, NULL, loc);
9506 : 0 : *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
9507 : : }
9508 : 8956 : if (!(*pa)->is_multi_eval_safe())
9509 : : {
9510 : 5001 : Temporary_statement* temp =
9511 : 5001 : Statement::make_temporary(NULL, *pa, loc);
9512 : 5001 : inserter->insert(temp);
9513 : 5001 : *pa = Expression::make_temporary_reference(temp, loc);
9514 : : }
9515 : : }
9516 : :
9517 : : // Lower to runtime call.
9518 : 4478 : const Expression_list* args = this->args();
9519 : 4478 : go_assert(args != NULL && args->size() == 2);
9520 : 4478 : Expression* arg1 = args->front();
9521 : 4478 : Expression* arg2 = args->back();
9522 : 4478 : go_assert(arg1->is_multi_eval_safe());
9523 : 4478 : go_assert(arg2->is_multi_eval_safe());
9524 : 4478 : bool arg2_is_string = arg2->type()->is_string_type();
9525 : :
9526 : 4478 : Expression* ret;
9527 : 8956 : Type* et = at->array_type()->element_type();
9528 : 4478 : if (et->has_pointer())
9529 : : {
9530 : 1649 : Expression* td = Expression::make_type_descriptor(et, loc);
9531 : 1649 : Expression* pd =
9532 : 1649 : Expression::make_slice_info(arg1, SLICE_INFO_VALUE_POINTER, loc);
9533 : 1649 : Expression* ld =
9534 : 1649 : Expression::make_slice_info(arg1, SLICE_INFO_LENGTH, loc);
9535 : 1649 : Expression* ps =
9536 : 1649 : Expression::make_slice_info(arg2, SLICE_INFO_VALUE_POINTER, loc);
9537 : 1649 : Expression* ls =
9538 : 1649 : Expression::make_slice_info(arg2, SLICE_INFO_LENGTH, loc);
9539 : 1649 : ret = Runtime::make_call(gogo, Runtime::TYPEDSLICECOPY, loc,
9540 : : 5, td, pd, ld, ps, ls);
9541 : : }
9542 : : else
9543 : : {
9544 : 2829 : Type* int_type = Type::lookup_integer_type("int");
9545 : 2829 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
9546 : :
9547 : : // l1 = len(arg1)
9548 : 2829 : Named_object* lenfn = gogo->lookup_global("len");
9549 : 2829 : Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
9550 : 2829 : Expression_list* len_args = new Expression_list();
9551 : 2829 : len_args->push_back(arg1->copy());
9552 : 2829 : Expression* len1 = Expression::make_call(lenref, len_args, false, loc);
9553 : 2829 : gogo->lower_expression(function, inserter, &len1);
9554 : 2829 : gogo->flatten_expression(function, inserter, &len1);
9555 : 2829 : Temporary_statement* l1tmp = Statement::make_temporary(int_type, len1, loc);
9556 : 2829 : l1tmp->determine_types(gogo);
9557 : 2829 : inserter->insert(l1tmp);
9558 : :
9559 : : // l2 = len(arg2)
9560 : 2829 : len_args = new Expression_list();
9561 : 2829 : len_args->push_back(arg2->copy());
9562 : 2829 : Expression* len2 = Expression::make_call(lenref, len_args, false, loc);
9563 : 2829 : gogo->lower_expression(function, inserter, &len2);
9564 : 2829 : gogo->flatten_expression(function, inserter, &len2);
9565 : 2829 : Temporary_statement* l2tmp = Statement::make_temporary(int_type, len2, loc);
9566 : 2829 : l2tmp->determine_types(gogo);
9567 : 2829 : inserter->insert(l2tmp);
9568 : :
9569 : : // n = (l1 < l2 ? l1 : l2)
9570 : 2829 : Expression* l1ref = Expression::make_temporary_reference(l1tmp, loc);
9571 : 2829 : Expression* l2ref = Expression::make_temporary_reference(l2tmp, loc);
9572 : 2829 : Expression* cond = Expression::make_binary(OPERATOR_LT, l1ref, l2ref, loc);
9573 : 2829 : Expression* n = Expression::make_conditional(cond,
9574 : : l1ref->copy(),
9575 : : l2ref->copy(),
9576 : : loc);
9577 : 2829 : Temporary_statement* ntmp = Statement::make_temporary(NULL, n, loc);
9578 : 2829 : ntmp->determine_types(gogo);
9579 : 2829 : inserter->insert(ntmp);
9580 : :
9581 : : // sz = n * sizeof(elem_type)
9582 : 2829 : Expression* nref = Expression::make_temporary_reference(ntmp, loc);
9583 : 2829 : nref = Expression::make_cast(uintptr_type, nref, loc);
9584 : 2829 : Expression* sz = Expression::make_type_info(et, TYPE_INFO_SIZE);
9585 : 2829 : sz = Expression::make_binary(OPERATOR_MULT, sz, nref, loc);
9586 : :
9587 : : // memmove(arg1.ptr, arg2.ptr, sz)
9588 : 2829 : Expression* p1 = Expression::make_slice_info(arg1,
9589 : : SLICE_INFO_VALUE_POINTER,
9590 : : loc);
9591 : 2829 : Expression* p2 = (arg2_is_string
9592 : 2829 : ? Expression::make_string_info(arg2,
9593 : : STRING_INFO_DATA,
9594 : : loc)
9595 : 2452 : : Expression::make_slice_info(arg2,
9596 : : SLICE_INFO_VALUE_POINTER,
9597 : 2829 : loc));
9598 : 2829 : Expression* call = Runtime::make_call(gogo,
9599 : : Runtime::BUILTIN_MEMMOVE,
9600 : : loc, 3,
9601 : : p1, p2, sz);
9602 : :
9603 : : // n is the return value of copy
9604 : 2829 : nref = Expression::make_temporary_reference(ntmp, loc);
9605 : 2829 : ret = Expression::make_compound(call, nref, loc);
9606 : : }
9607 : 4478 : ret->determine_type_no_context(gogo);
9608 : 4478 : return ret;
9609 : : }
9610 : 15370 : break;
9611 : :
9612 : 15370 : case BUILTIN_PANIC:
9613 : 15370 : for (Expression_list::iterator pa = this->args()->begin();
9614 : 30740 : pa != this->args()->end();
9615 : 15370 : ++pa)
9616 : : {
9617 : 15370 : if (!(*pa)->is_multi_eval_safe()
9618 : 30138 : && (*pa)->type()->interface_type() != NULL)
9619 : : {
9620 : 14768 : Temporary_statement* temp =
9621 : 14768 : Statement::make_temporary(NULL, *pa, loc);
9622 : 14768 : inserter->insert(temp);
9623 : 14768 : *pa = Expression::make_temporary_reference(temp, loc);
9624 : : }
9625 : : }
9626 : : break;
9627 : :
9628 : 154386 : case BUILTIN_LEN:
9629 : 154386 : case BUILTIN_CAP:
9630 : 154386 : {
9631 : 154386 : Expression_list::iterator pa = this->args()->begin();
9632 : 154386 : if (!(*pa)->is_multi_eval_safe()
9633 : 154386 : && ((*pa)->type()->map_type() != NULL
9634 : 15197 : || (*pa)->type()->channel_type() != NULL))
9635 : : {
9636 : 692 : Temporary_statement* temp =
9637 : 692 : Statement::make_temporary(NULL, *pa, loc);
9638 : 692 : inserter->insert(temp);
9639 : 692 : *pa = Expression::make_temporary_reference(temp, loc);
9640 : : }
9641 : : }
9642 : : break;
9643 : :
9644 : 867 : case BUILTIN_DELETE:
9645 : 867 : {
9646 : : // Lower to a runtime function call.
9647 : 867 : const Expression_list* args = this->args();
9648 : :
9649 : : // Since this function returns no value it must appear in
9650 : : // a statement by itself, so we don't have to worry about
9651 : : // order of evaluation of values around it. Evaluate the
9652 : : // map first to get order of evaluation right.
9653 : 867 : Map_type* mt = args->front()->type()->map_type();
9654 : 867 : Temporary_statement* map_temp =
9655 : 867 : Statement::make_temporary(mt, args->front(), loc);
9656 : 867 : inserter->insert(map_temp);
9657 : :
9658 : 867 : Temporary_statement* key_temp =
9659 : 867 : Statement::make_temporary(mt->key_type(), args->back(), loc);
9660 : 867 : inserter->insert(key_temp);
9661 : :
9662 : 867 : Expression* e1 = Expression::make_type_descriptor(mt, loc);
9663 : 867 : Expression* e2 = Expression::make_temporary_reference(map_temp,
9664 : : loc);
9665 : 867 : Expression* e3 = Expression::make_temporary_reference(key_temp,
9666 : : loc);
9667 : :
9668 : 867 : Runtime::Function code;
9669 : 867 : switch (mt->algorithm(gogo))
9670 : : {
9671 : 139 : case Map_type::MAP_ALG_FAST32:
9672 : 139 : case Map_type::MAP_ALG_FAST32PTR:
9673 : 139 : {
9674 : 139 : code = Runtime::MAPDELETE_FAST32;
9675 : 139 : Type* uint32_type = Type::lookup_integer_type("uint32");
9676 : 139 : Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
9677 : 139 : e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
9678 : 139 : e3 = Expression::make_unsafe_cast(uint32_ptr_type, e3,
9679 : : loc);
9680 : 139 : e3 = Expression::make_dereference(e3,
9681 : : Expression::NIL_CHECK_NOT_NEEDED,
9682 : : loc);
9683 : 139 : break;
9684 : : }
9685 : 211 : case Map_type::MAP_ALG_FAST64:
9686 : 211 : case Map_type::MAP_ALG_FAST64PTR:
9687 : 211 : {
9688 : 211 : code = Runtime::MAPDELETE_FAST64;
9689 : 211 : Type* uint64_type = Type::lookup_integer_type("uint64");
9690 : 211 : Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
9691 : 211 : e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
9692 : 211 : e3 = Expression::make_unsafe_cast(uint64_ptr_type, e3,
9693 : : loc);
9694 : 211 : e3 = Expression::make_dereference(e3,
9695 : : Expression::NIL_CHECK_NOT_NEEDED,
9696 : : loc);
9697 : 211 : break;
9698 : : }
9699 : : case Map_type::MAP_ALG_FASTSTR:
9700 : : code = Runtime::MAPDELETE_FASTSTR;
9701 : : break;
9702 : 177 : default:
9703 : 177 : code = Runtime::MAPDELETE;
9704 : :
9705 : : // If the call to delete is deferred, and is in a loop,
9706 : : // then the loop will only have a single instance of the
9707 : : // temporary variable. Passing the address of the
9708 : : // temporary variable here means that the deferred call
9709 : : // will see the last value in the loop, not the current
9710 : : // value. So for this unusual case copy the value into
9711 : : // the heap.
9712 : 177 : if (!this->is_deferred())
9713 : 144 : e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
9714 : : else
9715 : : {
9716 : 33 : Expression* a = Expression::make_allocation(mt->key_type(),
9717 : : loc);
9718 : 33 : Temporary_statement* atemp =
9719 : 33 : Statement::make_temporary(NULL, a, loc);
9720 : 33 : atemp->determine_types(gogo);
9721 : 33 : inserter->insert(atemp);
9722 : :
9723 : 33 : a = Expression::make_temporary_reference(atemp, loc);
9724 : 33 : a = Expression::make_dereference(a, NIL_CHECK_NOT_NEEDED, loc);
9725 : 33 : Statement* s = Statement::make_assignment(a, e3, loc);
9726 : 33 : s->determine_types(gogo);
9727 : 33 : inserter->insert(s);
9728 : :
9729 : 33 : e3 = Expression::make_temporary_reference(atemp, loc);
9730 : : }
9731 : : }
9732 : :
9733 : 867 : Expression* ret = Runtime::make_call(gogo, code, loc, 3, e1, e2, e3);
9734 : 867 : ret->determine_type_no_context(gogo);
9735 : 867 : return ret;
9736 : : }
9737 : :
9738 : 2 : case BUILTIN_ADD:
9739 : 2 : {
9740 : 2 : Expression* ptr = this->args()->front();
9741 : 2 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
9742 : 2 : ptr = Expression::make_cast(uintptr_type, ptr, loc);
9743 : 2 : Expression* len = this->args()->back();
9744 : 2 : len = Expression::make_cast(uintptr_type, len, loc);
9745 : 2 : Expression* add = Expression::make_binary(OPERATOR_PLUS, ptr, len,
9746 : : loc);
9747 : 2 : Expression* ret = Expression::make_cast(this->args()->front()->type(),
9748 : : add, loc);
9749 : 2 : ret->determine_type_no_context(gogo);
9750 : 2 : return ret;
9751 : : }
9752 : :
9753 : 9 : case BUILTIN_SLICE:
9754 : 9 : {
9755 : 9 : Expression* ptr = this->args()->front();
9756 : 9 : Temporary_statement* ptr_temp = NULL;
9757 : 9 : if (!ptr->is_multi_eval_safe())
9758 : : {
9759 : 8 : ptr_temp = Statement::make_temporary(NULL, ptr, loc);
9760 : 8 : inserter->insert(ptr_temp);
9761 : 8 : ptr = Expression::make_temporary_reference(ptr_temp, loc);
9762 : : }
9763 : :
9764 : 9 : Expression* len = this->args()->back();
9765 : 9 : Temporary_statement* len_temp = NULL;
9766 : 9 : if (!len->is_multi_eval_safe())
9767 : : {
9768 : 2 : len_temp = Statement::make_temporary(NULL, len, loc);
9769 : 2 : inserter->insert(len_temp);
9770 : 2 : len = Expression::make_temporary_reference(len_temp, loc);
9771 : : }
9772 : :
9773 : 9 : bool fits_in_int;
9774 : 9 : Numeric_constant nc;
9775 : 9 : if (this->args()->back()->numeric_constant_value(&nc))
9776 : : {
9777 : : // We gave an error for constants that don't fit in int in
9778 : : // check_types.
9779 : : fits_in_int = true;
9780 : : }
9781 : : else
9782 : : {
9783 : 2 : Integer_type* itype = this->args()->back()->type()->integer_type();
9784 : 0 : go_assert(itype != NULL);
9785 : 2 : int ebits = itype->bits();
9786 : 2 : int intbits =
9787 : 4 : Type::lookup_integer_type("int")->integer_type()->bits();
9788 : :
9789 : : // We can treat ebits == intbits as small even for an
9790 : : // unsigned integer type, because we will convert the
9791 : : // value to int and then reject it in the runtime if it is
9792 : : // negative.
9793 : :
9794 : 2 : fits_in_int = ebits <= intbits;
9795 : : }
9796 : :
9797 : 11 : Runtime::Function code = (fits_in_int
9798 : 2 : ? Runtime::UNSAFESLICE
9799 : : : Runtime::UNSAFESLICE64);
9800 : 9 : Expression* td =
9801 : 9 : Expression::make_type_descriptor(ptr->type()->points_to(), loc);
9802 : 9 : Expression* check = Runtime::make_call(gogo, code, loc, 3,
9803 : : td, ptr, len);
9804 : :
9805 : 9 : if (ptr_temp == NULL)
9806 : 1 : ptr = ptr->copy();
9807 : : else
9808 : 8 : ptr = Expression::make_temporary_reference(ptr_temp, loc);
9809 : 9 : Expression* nil = Expression::make_nil(loc);
9810 : 9 : nil = Expression::make_cast(ptr->type(), nil, loc);
9811 : 9 : Expression* is_nil = Expression::make_binary(OPERATOR_EQEQ, ptr, nil,
9812 : : loc);
9813 : :
9814 : 9 : if (len_temp == NULL)
9815 : 7 : len = len->copy();
9816 : : else
9817 : 2 : len = Expression::make_temporary_reference(len_temp, loc);
9818 : 9 : Expression* zero = Expression::make_integer_ul(0, len->type(), loc);
9819 : 9 : Expression* is_zero = Expression::make_binary(OPERATOR_EQEQ, len, zero,
9820 : : loc);
9821 : :
9822 : 9 : Expression* cond = Expression::make_binary(OPERATOR_ANDAND, is_nil,
9823 : : is_zero, loc);
9824 : :
9825 : 9 : Type* slice_type = Type::make_array_type(ptr->type()->points_to(),
9826 : : NULL);
9827 : 9 : nil = Expression::make_nil(loc);
9828 : 9 : Expression* nil_slice = Expression::make_cast(slice_type, nil, loc);
9829 : :
9830 : 9 : if (ptr_temp == NULL)
9831 : 1 : ptr = ptr->copy();
9832 : : else
9833 : 8 : ptr = Expression::make_temporary_reference(ptr_temp, loc);
9834 : :
9835 : 9 : if (len_temp == NULL)
9836 : 7 : len = len->copy();
9837 : : else
9838 : 2 : len = Expression::make_temporary_reference(len_temp, loc);
9839 : :
9840 : 9 : Expression* cap;
9841 : 9 : if (len_temp == NULL)
9842 : 7 : cap = len->copy();
9843 : : else
9844 : 2 : cap = Expression::make_temporary_reference(len_temp, loc);
9845 : :
9846 : 9 : Expression* slice = Expression::make_slice_value(slice_type, ptr,
9847 : : len, cap, loc);
9848 : :
9849 : 9 : slice = Expression::make_conditional(cond, nil_slice, slice, loc);
9850 : :
9851 : 9 : Expression* ret = Expression::make_compound(check, slice, loc);
9852 : 9 : ret->determine_type_no_context(gogo);
9853 : 9 : return ret;
9854 : 9 : }
9855 : : }
9856 : :
9857 : 201183 : return this;
9858 : : }
9859 : :
9860 : : // Lower a make expression.
9861 : :
9862 : : Expression*
9863 : 15099 : Builtin_call_expression::lower_make(Gogo* gogo, Statement_inserter* inserter)
9864 : : {
9865 : 15099 : Location loc = this->location();
9866 : :
9867 : 15099 : const Expression_list* args = this->args();
9868 : :
9869 : 15099 : Expression_list::const_iterator parg = args->begin();
9870 : :
9871 : 15099 : Expression* first_arg = *parg;
9872 : 15099 : go_assert(first_arg->is_type_expression());
9873 : 15099 : Type* type = first_arg->type();
9874 : :
9875 : 15099 : bool is_slice = false;
9876 : 15099 : bool is_map = false;
9877 : 15099 : bool is_chan = false;
9878 : 15099 : if (type->is_slice_type())
9879 : : is_slice = true;
9880 : 6609 : else if (type->map_type() != NULL)
9881 : : is_map = true;
9882 : 17862 : else if (type->channel_type() != NULL)
9883 : : is_chan = true;
9884 : : else
9885 : 0 : go_unreachable();
9886 : :
9887 : 15099 : ++parg;
9888 : 15099 : Expression* len_arg;
9889 : 15099 : bool len_small = false;
9890 : 15099 : if (parg == args->end())
9891 : : {
9892 : 4933 : go_assert(!is_slice);
9893 : 4933 : len_arg = Expression::make_integer_ul(0, NULL, loc);
9894 : 4933 : len_small = true;
9895 : : }
9896 : : else
9897 : : {
9898 : 10166 : len_arg = *parg;
9899 : 10166 : if (!this->check_int_value(len_arg, true, &len_small))
9900 : 8 : return Expression::make_error(this->location());
9901 : 10158 : ++parg;
9902 : : }
9903 : :
9904 : 15091 : Expression* cap_arg = NULL;
9905 : 15091 : bool cap_small = false;
9906 : 15091 : Numeric_constant nclen;
9907 : 15091 : Numeric_constant nccap;
9908 : 15091 : unsigned long vlen;
9909 : 15091 : unsigned long vcap;
9910 : 15091 : if (is_slice && parg != args->end())
9911 : : {
9912 : 1715 : cap_arg = *parg;
9913 : 1715 : if (!this->check_int_value(cap_arg, false, &cap_small))
9914 : 2 : return Expression::make_error(this->location());
9915 : :
9916 : 1713 : if (len_arg->numeric_constant_value(&nclen)
9917 : 1614 : && cap_arg->numeric_constant_value(&nccap)
9918 : 554 : && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
9919 : 554 : && nccap.to_unsigned_long(&vcap) == Numeric_constant::NC_UL_VALID
9920 : 2267 : && vlen > vcap)
9921 : : {
9922 : 1 : this->report_error(_("len larger than cap"));
9923 : 1 : return Expression::make_error(this->location());
9924 : : }
9925 : :
9926 : 1712 : ++parg;
9927 : : }
9928 : :
9929 : 15088 : go_assert(parg == args->end());
9930 : :
9931 : 15088 : Location type_loc = first_arg->location();
9932 : :
9933 : 15088 : Expression* call;
9934 : 15088 : if (is_slice)
9935 : : {
9936 : 8479 : Temporary_statement* len_temp = NULL;
9937 : 8479 : if (!len_arg->is_constant())
9938 : : {
9939 : 4458 : len_temp = Statement::make_temporary(NULL, len_arg, loc);
9940 : 4458 : inserter->insert(len_temp);
9941 : 4458 : len_arg = Expression::make_temporary_reference(len_temp, loc);
9942 : : }
9943 : :
9944 : 8479 : if (cap_arg == NULL)
9945 : : {
9946 : 6767 : cap_small = len_small;
9947 : 6767 : if (len_temp == NULL)
9948 : 2408 : cap_arg = len_arg->copy();
9949 : : else
9950 : 4359 : cap_arg = Expression::make_temporary_reference(len_temp, loc);
9951 : : }
9952 : 1712 : else if (!cap_arg->is_constant())
9953 : : {
9954 : 1138 : Temporary_statement* cap_temp = Statement::make_temporary(NULL,
9955 : : cap_arg,
9956 : : loc);
9957 : 1138 : inserter->insert(cap_temp);
9958 : 1138 : cap_arg = Expression::make_temporary_reference(cap_temp, loc);
9959 : : }
9960 : :
9961 : 16958 : Type* et = type->array_type()->element_type();
9962 : 8479 : Expression* type_arg = Expression::make_type_descriptor(et, type_loc);
9963 : 8479 : Runtime::Function code = Runtime::MAKESLICE;
9964 : 8479 : if (!len_small || !cap_small)
9965 : 120 : code = Runtime::MAKESLICE64;
9966 : 8479 : Expression* mem = Runtime::make_call(gogo, code, loc, 3,
9967 : : type_arg, len_arg, cap_arg);
9968 : 8479 : mem = Expression::make_unsafe_cast(Type::make_pointer_type(et), mem,
9969 : : loc);
9970 : 8479 : Type* int_type = Type::lookup_integer_type("int");
9971 : 8479 : len_arg = Expression::make_cast(int_type, len_arg->copy(), loc);
9972 : 8479 : cap_arg = Expression::make_cast(int_type, cap_arg->copy(), loc);
9973 : 8479 : call = Expression::make_slice_value(type, mem, len_arg, cap_arg, loc);
9974 : : }
9975 : 6609 : else if (is_map)
9976 : : {
9977 : 3846 : Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
9978 : 3846 : if (!len_small)
9979 : 2 : call = Runtime::make_call(gogo, Runtime::MAKEMAP64, loc, 3, type_arg,
9980 : : len_arg,
9981 : : Expression::make_nil(loc));
9982 : : else
9983 : : {
9984 : 3844 : if (len_arg->numeric_constant_value(&nclen)
9985 : 3485 : && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
9986 : 7329 : && vlen <= Map_type::bucket_size)
9987 : 3434 : call = Runtime::make_call(gogo, Runtime::MAKEMAP_SMALL, loc, 0);
9988 : : else
9989 : 410 : call = Runtime::make_call(gogo, Runtime::MAKEMAP, loc, 3, type_arg,
9990 : : len_arg,
9991 : : Expression::make_nil(loc));
9992 : : }
9993 : : }
9994 : 2763 : else if (is_chan)
9995 : : {
9996 : 2763 : Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
9997 : 2763 : Runtime::Function code = Runtime::MAKECHAN;
9998 : 2763 : if (!len_small)
9999 : 0 : code = Runtime::MAKECHAN64;
10000 : 2763 : call = Runtime::make_call(gogo, code, loc, 2, type_arg, len_arg);
10001 : : }
10002 : : else
10003 : 0 : go_unreachable();
10004 : :
10005 : 15088 : Expression* ret = Expression::make_unsafe_cast(type, call, loc);
10006 : 15088 : ret->determine_type_no_context(gogo);
10007 : 15088 : return ret;
10008 : 15091 : }
10009 : :
10010 : : // Flatten a call to the predeclared append function. We do this in
10011 : : // the flatten phase, not the lowering phase, so that we run after
10012 : : // type checking and after order_evaluations. If ASSIGN_LHS is not
10013 : : // NULL, this append is the right-hand-side of an assignment and
10014 : : // ASSIGN_LHS is the left-hand-side; in that case, set LHS directly
10015 : : // rather than returning a slice. This lets us omit a write barrier
10016 : : // in common cases like a = append(a, ...) when the slice does not
10017 : : // need to grow. ENCLOSING is not NULL iff ASSIGN_LHS is not NULL.
10018 : :
10019 : : Expression*
10020 : 15676 : Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
10021 : : Statement_inserter* inserter,
10022 : : Expression* assign_lhs,
10023 : : Block* enclosing)
10024 : : {
10025 : 15676 : if (this->is_error_expression())
10026 : 0 : return this;
10027 : :
10028 : 15676 : Location loc = this->location();
10029 : :
10030 : 15676 : const Expression_list* args = this->args();
10031 : 15676 : go_assert(args != NULL && !args->empty());
10032 : :
10033 : 15676 : Type* slice_type = args->front()->type();
10034 : 15676 : go_assert(slice_type->is_slice_type());
10035 : 31352 : Type* element_type = slice_type->array_type()->element_type();
10036 : :
10037 : 15676 : if (args->size() == 1)
10038 : : {
10039 : : // append(s) evaluates to s.
10040 : 23 : if (assign_lhs != NULL)
10041 : : return NULL;
10042 : 23 : return args->front();
10043 : : }
10044 : :
10045 : 15653 : Type* int_type = Type::lookup_integer_type("int");
10046 : 15653 : Type_context int_context(int_type, false);
10047 : 15653 : Type* uint_type = Type::lookup_integer_type("uint");
10048 : :
10049 : : // Implementing
10050 : : // append(s1, s2...)
10051 : : // or
10052 : : // append(s1, a1, a2, a3, ...)
10053 : :
10054 : : // s1tmp := s1
10055 : 15653 : Temporary_statement* s1tmp = Statement::make_temporary(NULL, args->front(),
10056 : : loc);
10057 : 15653 : inserter->insert(s1tmp);
10058 : :
10059 : : // l1tmp := len(s1tmp)
10060 : 15653 : Named_object* lenfn = gogo->lookup_global("len");
10061 : 15653 : Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
10062 : 15653 : Expression_list* call_args = new Expression_list();
10063 : 15653 : call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
10064 : 15653 : Expression* len = Expression::make_call(lenref, call_args, false, loc);
10065 : 15653 : len->determine_type(gogo, &int_context);
10066 : 15653 : gogo->lower_expression(function, inserter, &len);
10067 : 15653 : gogo->flatten_expression(function, inserter, &len);
10068 : 15653 : Temporary_statement* l1tmp = Statement::make_temporary(int_type, len, loc);
10069 : 15653 : inserter->insert(l1tmp);
10070 : :
10071 : 15653 : Temporary_statement* s2tmp = NULL;
10072 : 15653 : Temporary_statement* l2tmp = NULL;
10073 : 15653 : Expression_list* add = NULL;
10074 : 15653 : Expression* len2;
10075 : 15653 : Call_expression* makecall = NULL;
10076 : 15653 : if (this->is_varargs())
10077 : : {
10078 : 3556 : go_assert(args->size() == 2);
10079 : :
10080 : 3556 : std::pair<Call_expression*, Temporary_statement*> p =
10081 : 3556 : Expression::find_makeslice_call(args->back());
10082 : 3556 : makecall = p.first;
10083 : 3556 : if (makecall != NULL)
10084 : : {
10085 : : // We are handling
10086 : : // append(s, make([]T, len[, cap])...))
10087 : : // which has already been lowered to
10088 : : // append(s, runtime.makeslice(T, len, cap)).
10089 : : // We will optimize this to directly zeroing the tail,
10090 : : // instead of allocating a new slice then copy.
10091 : :
10092 : : // Retrieve the length and capacity. Cannot reference s2 as
10093 : : // we will remove the makeslice call.
10094 : 27 : Expression* len_arg = makecall->args()->at(1);
10095 : 27 : len_arg = Expression::make_cast(int_type, len_arg, loc);
10096 : 27 : l2tmp = Statement::make_temporary(int_type, len_arg, loc);
10097 : 27 : l2tmp->determine_types(gogo);
10098 : 27 : inserter->insert(l2tmp);
10099 : :
10100 : 27 : Expression* cap_arg = makecall->args()->at(2);
10101 : 27 : cap_arg = Expression::make_cast(int_type, cap_arg, loc);
10102 : 27 : Temporary_statement* c2tmp =
10103 : 27 : Statement::make_temporary(int_type, cap_arg, loc);
10104 : 27 : c2tmp->determine_types(gogo);
10105 : 27 : inserter->insert(c2tmp);
10106 : :
10107 : : // Check bad len/cap here.
10108 : : // checkmakeslice(type, len, cap)
10109 : : // (Note that if len and cap are constants, we won't see a
10110 : : // makeslice call here, as it will be rewritten to a stack
10111 : : // allocated array by Mark_address_taken::expression.)
10112 : 27 : Expression* elem = Expression::make_type_descriptor(element_type,
10113 : : loc);
10114 : 27 : len2 = Expression::make_temporary_reference(l2tmp, loc);
10115 : 27 : Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
10116 : 27 : Expression* check = Runtime::make_call(gogo,
10117 : : Runtime::CHECK_MAKE_SLICE,
10118 : 27 : loc, 3, elem, len2, cap2);
10119 : 27 : check->determine_type_no_context(gogo);
10120 : 27 : gogo->lower_expression(function, inserter, &check);
10121 : 27 : gogo->flatten_expression(function, inserter, &check);
10122 : 27 : Statement* s = Statement::make_statement(check, false);
10123 : 27 : inserter->insert(s);
10124 : :
10125 : : // Remove the original makeslice call.
10126 : 27 : Temporary_statement* ts = p.second;
10127 : 27 : if (ts != NULL && ts->uses() == 1)
10128 : 27 : ts->set_init(Expression::make_nil(loc));
10129 : : }
10130 : : else
10131 : : {
10132 : : // s2tmp := s2
10133 : 3529 : s2tmp = Statement::make_temporary(NULL, args->back(), loc);
10134 : 3529 : inserter->insert(s2tmp);
10135 : :
10136 : : // l2tmp := len(s2tmp)
10137 : 3529 : lenref = Expression::make_func_reference(lenfn, NULL, loc);
10138 : 3529 : call_args = new Expression_list();
10139 : 3529 : call_args->push_back(Expression::make_temporary_reference(s2tmp, loc));
10140 : 3529 : len = Expression::make_call(lenref, call_args, false, loc);
10141 : 3529 : len->determine_type(gogo, &int_context);
10142 : 3529 : gogo->lower_expression(function, inserter, &len);
10143 : 3529 : gogo->flatten_expression(function, inserter, &len);
10144 : 3529 : l2tmp = Statement::make_temporary(int_type, len, loc);
10145 : 3529 : l2tmp->determine_types(gogo);
10146 : 3529 : inserter->insert(l2tmp);
10147 : : }
10148 : :
10149 : : // len2 = l2tmp
10150 : 3556 : len2 = Expression::make_temporary_reference(l2tmp, loc);
10151 : : }
10152 : : else
10153 : : {
10154 : : // We have to ensure that all the arguments are in variables
10155 : : // now, because otherwise if one of them is an index expression
10156 : : // into the current slice we could overwrite it before we fetch
10157 : : // it.
10158 : 12097 : add = new Expression_list();
10159 : 12097 : Expression_list::const_iterator pa = args->begin();
10160 : 26301 : for (++pa; pa != args->end(); ++pa)
10161 : : {
10162 : 14204 : if ((*pa)->is_multi_eval_safe())
10163 : 7816 : add->push_back(*pa);
10164 : : else
10165 : : {
10166 : 6388 : Temporary_statement* tmp = Statement::make_temporary(NULL, *pa,
10167 : : loc);
10168 : 6388 : inserter->insert(tmp);
10169 : 6388 : add->push_back(Expression::make_temporary_reference(tmp, loc));
10170 : : }
10171 : : }
10172 : :
10173 : : // len2 = len(add)
10174 : 12097 : len2 = Expression::make_integer_ul(add->size(), int_type, loc);
10175 : : }
10176 : :
10177 : : // ntmp := l1tmp + len2
10178 : 15653 : Expression* ref = Expression::make_temporary_reference(l1tmp, loc);
10179 : 15653 : Expression* sum = Expression::make_binary(OPERATOR_PLUS, ref, len2, loc);
10180 : 15653 : sum->determine_type(gogo, &int_context);
10181 : 15653 : gogo->lower_expression(function, inserter, &sum);
10182 : 15653 : gogo->flatten_expression(function, inserter, &sum);
10183 : 15653 : Temporary_statement* ntmp = Statement::make_temporary(int_type, sum, loc);
10184 : 15653 : ntmp->determine_types(gogo);
10185 : 15653 : inserter->insert(ntmp);
10186 : :
10187 : : // s1tmp = uint(ntmp) > uint(cap(s1tmp)) ?
10188 : : // growslice(type, s1tmp, ntmp) :
10189 : : // s1tmp[:ntmp]
10190 : : // Using uint here means that if the computation of ntmp overflowed,
10191 : : // we will call growslice which will panic.
10192 : :
10193 : 15653 : Named_object* capfn = gogo->lookup_global("cap");
10194 : 15653 : Expression* capref = Expression::make_func_reference(capfn, NULL, loc);
10195 : 15653 : call_args = new Expression_list();
10196 : 15653 : call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
10197 : 15653 : Expression* cap = Expression::make_call(capref, call_args, false, loc);
10198 : 15653 : cap->determine_type(gogo, &int_context);
10199 : 15653 : gogo->lower_expression(function, inserter, &cap);
10200 : 15653 : gogo->flatten_expression(function, inserter, &cap);
10201 : 15653 : Temporary_statement* c1tmp = Statement::make_temporary(int_type, cap, loc);
10202 : 15653 : c1tmp->determine_types(gogo);
10203 : 15653 : inserter->insert(c1tmp);
10204 : :
10205 : 15653 : Expression* left = Expression::make_temporary_reference(ntmp, loc);
10206 : 15653 : left = Expression::make_cast(uint_type, left, loc);
10207 : 15653 : Expression* right = Expression::make_temporary_reference(c1tmp, loc);
10208 : 15653 : right = Expression::make_cast(uint_type, right, loc);
10209 : :
10210 : 15653 : Expression* cond = Expression::make_binary(OPERATOR_GT, left, right, loc);
10211 : :
10212 : 15653 : Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
10213 : 15653 : Expression* a1 = Expression::make_type_descriptor(element_type, loc);
10214 : 15653 : Expression* a2 = Expression::make_temporary_reference(s1tmp, loc);
10215 : 31306 : a2 = slice_type->array_type()->get_value_pointer(gogo, a2);
10216 : 15653 : a2 = Expression::make_cast(unsafe_ptr_type, a2, loc);
10217 : 15653 : Expression* a3 = Expression::make_temporary_reference(l1tmp, loc);
10218 : 15653 : Expression* a4 = Expression::make_temporary_reference(c1tmp, loc);
10219 : 15653 : Expression* a5 = Expression::make_temporary_reference(ntmp, loc);
10220 : 15653 : Expression* call = Runtime::make_call(gogo, Runtime::GROWSLICE, loc, 5,
10221 : 15653 : a1, a2, a3, a4, a5);
10222 : 15653 : call = Expression::make_unsafe_cast(slice_type, call, loc);
10223 : :
10224 : 15653 : ref = Expression::make_temporary_reference(s1tmp, loc);
10225 : 15653 : Expression* zero = Expression::make_integer_ul(0, int_type, loc);
10226 : 15653 : Expression* ref2 = Expression::make_temporary_reference(ntmp, loc);
10227 : 15653 : ref = Expression::make_array_index(ref, zero, ref2, NULL, loc);
10228 : 15653 : ref->array_index_expression()->set_needs_bounds_check(false);
10229 : :
10230 : 15653 : if (assign_lhs == NULL)
10231 : : {
10232 : 2631 : Expression* rhs = Expression::make_conditional(cond, call, ref, loc);
10233 : :
10234 : 2631 : rhs->determine_type_no_context(gogo);
10235 : 2631 : gogo->lower_expression(function, inserter, &rhs);
10236 : 2631 : gogo->flatten_expression(function, inserter, &rhs);
10237 : :
10238 : 2631 : ref = Expression::make_temporary_reference(s1tmp, loc);
10239 : 2631 : Statement* assign = Statement::make_assignment(ref, rhs, loc);
10240 : 2631 : assign->determine_types(gogo);
10241 : 2631 : inserter->insert(assign);
10242 : : }
10243 : : else
10244 : : {
10245 : 13022 : cond->determine_type_no_context(gogo);
10246 : 13022 : gogo->lower_expression(function, inserter, &cond);
10247 : 13022 : gogo->flatten_expression(function, inserter, &cond);
10248 : 13022 : call->determine_type_no_context(gogo);
10249 : 13022 : gogo->lower_expression(function, inserter, &call);
10250 : 13022 : gogo->flatten_expression(function, inserter, &call);
10251 : 13022 : ref->determine_type_no_context(gogo);
10252 : 13022 : gogo->lower_expression(function, inserter, &ref);
10253 : 13022 : gogo->flatten_expression(function, inserter, &ref);
10254 : :
10255 : 13022 : Block* then_block = new Block(enclosing, loc);
10256 : 13022 : Assignment_statement* assign =
10257 : 13022 : Statement::make_assignment(assign_lhs, call, loc);
10258 : 13022 : assign->determine_types(gogo);
10259 : 13022 : then_block->add_statement(assign);
10260 : :
10261 : 13022 : Block* else_block = new Block(enclosing, loc);
10262 : 13022 : assign = Statement::make_assignment(assign_lhs->copy(), ref, loc);
10263 : : // This assignment will not change the pointer value, so it does
10264 : : // not need a write barrier.
10265 : 13022 : assign->set_omit_write_barrier();
10266 : 13022 : assign->determine_types(gogo);
10267 : 13022 : else_block->add_statement(assign);
10268 : :
10269 : 13022 : Statement* s = Statement::make_if_statement(cond, then_block,
10270 : : else_block, loc);
10271 : 13022 : s->determine_types(gogo);
10272 : 13022 : inserter->insert(s);
10273 : :
10274 : 13022 : ref = Expression::make_temporary_reference(s1tmp, loc);
10275 : 13022 : assign = Statement::make_assignment(ref, assign_lhs->copy(), loc);
10276 : 13022 : assign->determine_types(gogo);
10277 : 13022 : inserter->insert(assign);
10278 : : }
10279 : :
10280 : 15653 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
10281 : :
10282 : 15653 : if (this->is_varargs())
10283 : : {
10284 : 3556 : if (makecall != NULL)
10285 : : {
10286 : : // memclr(&s1tmp[l1tmp], l2tmp*sizeof(elem))
10287 : 27 : a1 = Expression::make_temporary_reference(s1tmp, loc);
10288 : 27 : ref = Expression::make_temporary_reference(l1tmp, loc);
10289 : 27 : a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
10290 : 27 : a1->array_index_expression()->set_needs_bounds_check(false);
10291 : 27 : a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
10292 : :
10293 : 27 : ref = Expression::make_temporary_reference(l2tmp, loc);
10294 : 27 : ref = Expression::make_cast(uintptr_type, ref, loc);
10295 : 27 : a2 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
10296 : 27 : a2 = Expression::make_binary(OPERATOR_MULT, a2, ref, loc);
10297 : :
10298 : 27 : if (element_type->has_pointer())
10299 : 7 : call = Runtime::make_call(gogo, Runtime::MEMCLRHASPTR, loc, 2,
10300 : : a1, a2);
10301 : : else
10302 : : {
10303 : 20 : Type* int32_type = Type::lookup_integer_type("int32");
10304 : 20 : zero = Expression::make_integer_ul(0, int32_type, loc);
10305 : 20 : call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMSET, loc, 3,
10306 : : a1, zero, a2);
10307 : : }
10308 : :
10309 : 27 : if (element_type->has_pointer())
10310 : : {
10311 : : // For a slice containing pointers, growslice already zeroed
10312 : : // the memory. We only need to zero in non-growing case.
10313 : : // Note: growslice does not zero the memory in non-pointer case.
10314 : 7 : ref = Expression::make_temporary_reference(ntmp, loc);
10315 : 7 : ref = Expression::make_cast(uint_type, ref, loc);
10316 : 7 : ref2 = Expression::make_temporary_reference(c1tmp, loc);
10317 : 7 : ref2 = Expression::make_cast(uint_type, ref2, loc);
10318 : 7 : cond = Expression::make_binary(OPERATOR_GT, ref, ref2, loc);
10319 : 7 : zero = Expression::make_integer_ul(0, int_type, loc);
10320 : 7 : call = Expression::make_conditional(cond, zero, call, loc);
10321 : : }
10322 : : }
10323 : : else
10324 : : {
10325 : 3529 : if (element_type->has_pointer())
10326 : : {
10327 : : // copy(s1tmp[l1tmp:], s2tmp)
10328 : 1251 : a1 = Expression::make_temporary_reference(s1tmp, loc);
10329 : 1251 : ref = Expression::make_temporary_reference(l1tmp, loc);
10330 : 1251 : Expression* nil = Expression::make_nil(loc);
10331 : 1251 : a1 = Expression::make_array_index(a1, ref, nil, NULL, loc);
10332 : 1251 : a1->array_index_expression()->set_needs_bounds_check(false);
10333 : :
10334 : 1251 : a2 = Expression::make_temporary_reference(s2tmp, loc);
10335 : :
10336 : 1251 : Named_object* copyfn = gogo->lookup_global("copy");
10337 : 1251 : Expression* copyref = Expression::make_func_reference(copyfn, NULL, loc);
10338 : 1251 : call_args = new Expression_list();
10339 : 1251 : call_args->push_back(a1);
10340 : 1251 : call_args->push_back(a2);
10341 : 1251 : call = Expression::make_call(copyref, call_args, false, loc);
10342 : : }
10343 : : else
10344 : : {
10345 : : // memmove(&s1tmp[l1tmp], s2tmp.ptr, l2tmp*sizeof(elem))
10346 : 2278 : a1 = Expression::make_temporary_reference(s1tmp, loc);
10347 : 2278 : ref = Expression::make_temporary_reference(l1tmp, loc);
10348 : 2278 : a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
10349 : 2278 : a1->array_index_expression()->set_needs_bounds_check(false);
10350 : 2278 : a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
10351 : :
10352 : 2278 : a2 = Expression::make_temporary_reference(s2tmp, loc);
10353 : 2278 : a2 = (a2->type()->is_string_type()
10354 : 2278 : ? Expression::make_string_info(a2,
10355 : : STRING_INFO_DATA,
10356 : : loc)
10357 : 1314 : : Expression::make_slice_info(a2,
10358 : : SLICE_INFO_VALUE_POINTER,
10359 : : loc));
10360 : :
10361 : 2278 : ref = Expression::make_temporary_reference(l2tmp, loc);
10362 : 2278 : ref = Expression::make_cast(uintptr_type, ref, loc);
10363 : 2278 : a3 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
10364 : 2278 : a3 = Expression::make_binary(OPERATOR_MULT, a3, ref, loc);
10365 : :
10366 : 2278 : call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMMOVE, loc, 3,
10367 : : a1, a2, a3);
10368 : : }
10369 : : }
10370 : 3556 : call->determine_type_no_context(gogo);
10371 : 3556 : gogo->lower_expression(function, inserter, &call);
10372 : 3556 : gogo->flatten_expression(function, inserter, &call);
10373 : 3556 : inserter->insert(Statement::make_statement(call, false));
10374 : : }
10375 : : else
10376 : : {
10377 : : // For each argument:
10378 : : // s1tmp[l1tmp+i] = a
10379 : 12097 : unsigned long i = 0;
10380 : 12097 : for (Expression_list::const_iterator pa = add->begin();
10381 : 26301 : pa != add->end();
10382 : 14204 : ++pa, ++i)
10383 : : {
10384 : 14204 : ref = Expression::make_temporary_reference(s1tmp, loc);
10385 : 14204 : ref2 = Expression::make_temporary_reference(l1tmp, loc);
10386 : 14204 : Expression* off = Expression::make_integer_ul(i, int_type, loc);
10387 : 14204 : ref2 = Expression::make_binary(OPERATOR_PLUS, ref2, off, loc);
10388 : 14204 : Expression* lhs = Expression::make_array_index(ref, ref2, NULL,
10389 : 14204 : NULL, loc);
10390 : 14204 : lhs->array_index_expression()->set_needs_bounds_check(false);
10391 : 14204 : lhs->determine_type_no_context(gogo);
10392 : 14204 : gogo->lower_expression(function, inserter, &lhs);
10393 : 14204 : gogo->flatten_expression(function, inserter, &lhs);
10394 : 14204 : Expression* elem = *pa;
10395 : 14204 : if (!Type::are_identical(element_type, elem->type(), 0, NULL)
10396 : 14204 : && element_type->interface_type() != NULL)
10397 : 504 : elem = Expression::make_cast(element_type, elem, loc);
10398 : : // The flatten pass runs after the write barrier pass, so we
10399 : : // need to insert a write barrier here if necessary.
10400 : : // However, if ASSIGN_LHS is not NULL, we have been called
10401 : : // directly before the write barrier pass.
10402 : 14204 : Statement* assign;
10403 : 14204 : if (assign_lhs != NULL
10404 : 14204 : || !gogo->assign_needs_write_barrier(lhs, NULL))
10405 : 12988 : assign = Statement::make_assignment(lhs, elem, loc);
10406 : : else
10407 : : {
10408 : 1216 : Function* f = function == NULL ? NULL : function->func_value();
10409 : 1216 : assign = gogo->assign_with_write_barrier(f, NULL, inserter,
10410 : : lhs, elem, loc);
10411 : : }
10412 : 14204 : assign->determine_types(gogo);
10413 : 14204 : inserter->insert(assign);
10414 : : }
10415 : : }
10416 : :
10417 : 15653 : if (assign_lhs != NULL)
10418 : : return NULL;
10419 : :
10420 : 2631 : return Expression::make_temporary_reference(s1tmp, loc);
10421 : : }
10422 : :
10423 : : // Return whether an expression has an integer value. Report an error
10424 : : // if not. This is used when handling calls to the predeclared make
10425 : : // function. Set *SMALL if the value is known to fit in type "int".
10426 : :
10427 : : bool
10428 : 11881 : Builtin_call_expression::check_int_value(Expression* e, bool is_length,
10429 : : bool *small)
10430 : : {
10431 : 11881 : *small = false;
10432 : :
10433 : 11881 : Numeric_constant nc;
10434 : 11881 : if (e->numeric_constant_value(&nc))
10435 : : {
10436 : 5748 : unsigned long v;
10437 : 5748 : switch (nc.to_unsigned_long(&v))
10438 : : {
10439 : : case Numeric_constant::NC_UL_VALID:
10440 : : break;
10441 : 1 : case Numeric_constant::NC_UL_NOTINT:
10442 : 1 : go_error_at(e->location(), "non-integer %s argument to make",
10443 : : is_length ? "len" : "cap");
10444 : 1 : return false;
10445 : 2 : case Numeric_constant::NC_UL_NEGATIVE:
10446 : 2 : go_error_at(e->location(), "negative %s argument to make",
10447 : : is_length ? "len" : "cap");
10448 : 2 : return false;
10449 : : case Numeric_constant::NC_UL_BIG:
10450 : : // We don't want to give a compile-time error for a 64-bit
10451 : : // value on a 32-bit target.
10452 : : break;
10453 : : }
10454 : :
10455 : 5745 : mpz_t val;
10456 : 5745 : if (!nc.to_int(&val))
10457 : 0 : go_unreachable();
10458 : 5745 : int bits = mpz_sizeinbase(val, 2);
10459 : 5745 : mpz_clear(val);
10460 : 5745 : Type* int_type = Type::lookup_integer_type("int");
10461 : 11490 : if (bits >= int_type->integer_type()->bits())
10462 : : {
10463 : 1 : go_error_at(e->location(), "%s argument too large for make",
10464 : : is_length ? "len" : "cap");
10465 : 1 : return false;
10466 : : }
10467 : :
10468 : 5744 : *small = true;
10469 : 5744 : return true;
10470 : : }
10471 : :
10472 : 6133 : if (e->type()->integer_type() != NULL)
10473 : : {
10474 : 12254 : int ebits = e->type()->integer_type()->bits();
10475 : 12254 : int intbits = Type::lookup_integer_type("int")->integer_type()->bits();
10476 : :
10477 : : // We can treat ebits == intbits as small even for an unsigned
10478 : : // integer type, because we will convert the value to int and
10479 : : // then reject it in the runtime if it is negative.
10480 : 6127 : *small = ebits <= intbits;
10481 : :
10482 : 6127 : return true;
10483 : : }
10484 : :
10485 : 6 : go_error_at(e->location(), "non-integer %s argument to make",
10486 : : is_length ? "len" : "cap");
10487 : 6 : return false;
10488 : 11881 : }
10489 : :
10490 : : // Return the type of the real or imag functions, given the type of
10491 : : // the argument. We need to map complex64 to float32 and complex128
10492 : : // to float64, so it has to be done by name. This returns NULL if it
10493 : : // can't figure out the type.
10494 : :
10495 : : Type*
10496 : 22174 : Builtin_call_expression::real_imag_type(Type* arg_type)
10497 : : {
10498 : 22174 : if (arg_type == NULL || arg_type->is_abstract())
10499 : 95 : return NULL;
10500 : 22079 : Named_type* nt = arg_type->named_type();
10501 : 22079 : if (nt == NULL)
10502 : : return NULL;
10503 : 22080 : while (nt->real_type()->named_type() != NULL)
10504 : 5 : nt = nt->real_type()->named_type();
10505 : 22075 : if (nt->name() == "complex64")
10506 : 153 : return Type::lookup_float_type("float32");
10507 : 21922 : else if (nt->name() == "complex128")
10508 : 21859 : return Type::lookup_float_type("float64");
10509 : : else
10510 : : return NULL;
10511 : : }
10512 : :
10513 : : // Return the type of the complex function, given the type of one of the
10514 : : // argments. Like real_imag_type, we have to map by name.
10515 : :
10516 : : Type*
10517 : 88910 : Builtin_call_expression::complex_type(Type* arg_type)
10518 : : {
10519 : 88910 : if (arg_type == NULL || arg_type->is_abstract())
10520 : 305 : return NULL;
10521 : 88605 : Named_type* nt = arg_type->named_type();
10522 : 88605 : if (nt == NULL)
10523 : : return NULL;
10524 : 88599 : while (nt->real_type()->named_type() != NULL)
10525 : 2 : nt = nt->real_type()->named_type();
10526 : 88597 : if (nt->name() == "float32")
10527 : 117 : return Type::lookup_complex_type("complex64");
10528 : 88480 : else if (nt->name() == "float64")
10529 : 88470 : return Type::lookup_complex_type("complex128");
10530 : : else
10531 : : return NULL;
10532 : : }
10533 : :
10534 : : // Return a single argument, or NULL if there isn't one.
10535 : :
10536 : : Expression*
10537 : 593027 : Builtin_call_expression::one_arg() const
10538 : : {
10539 : 593027 : const Expression_list* args = this->args();
10540 : 593027 : if (args == NULL || args->size() != 1)
10541 : : return NULL;
10542 : 593027 : return args->front();
10543 : : }
10544 : :
10545 : : // A traversal class which looks for a call or receive expression.
10546 : :
10547 : 22831 : class Find_call_expression : public Traverse
10548 : : {
10549 : : public:
10550 : 22831 : Find_call_expression()
10551 : 22831 : : Traverse(traverse_expressions),
10552 : 22831 : found_(false)
10553 : : { }
10554 : :
10555 : : int
10556 : : expression(Expression**);
10557 : :
10558 : : bool
10559 : 22831 : found()
10560 : 22831 : { return this->found_; }
10561 : :
10562 : : private:
10563 : : bool found_;
10564 : : };
10565 : :
10566 : : int
10567 : 27379 : Find_call_expression::expression(Expression** pexpr)
10568 : : {
10569 : 27379 : Expression* expr = *pexpr;
10570 : 27379 : if (!expr->is_constant()
10571 : 54529 : && (expr->call_expression() != NULL
10572 : 52 : || expr->receive_expression() != NULL))
10573 : : {
10574 : 52 : this->found_ = true;
10575 : 52 : return TRAVERSE_EXIT;
10576 : : }
10577 : : return TRAVERSE_CONTINUE;
10578 : : }
10579 : :
10580 : : // Return whether calling len or cap on EXPR, of array type, is a
10581 : : // constant. The language spec says "the expressions len(s) and
10582 : : // cap(s) are constants if the type of s is an array or pointer to an
10583 : : // array and the expression s does not contain channel receives or
10584 : : // (non-constant) function calls."
10585 : :
10586 : : bool
10587 : 22831 : Builtin_call_expression::array_len_is_constant(Expression* expr)
10588 : : {
10589 : 91324 : go_assert(expr->type()->deref()->array_type() != NULL
10590 : : && !expr->type()->deref()->is_slice_type());
10591 : 22831 : if (expr->is_constant())
10592 : : return true;
10593 : 22831 : Find_call_expression find_call;
10594 : 22831 : Expression::traverse(&expr, &find_call);
10595 : 22831 : return !find_call.found();
10596 : 22831 : }
10597 : :
10598 : : // Return whether this is constant: len of a string constant, or len
10599 : : // or cap of an array, or unsafe.Sizeof, unsafe.Offsetof,
10600 : : // unsafe.Alignof.
10601 : :
10602 : : bool
10603 : 508659 : Builtin_call_expression::do_is_constant() const
10604 : : {
10605 : 508659 : if (this->is_error_expression())
10606 : : return true;
10607 : 508659 : switch (this->code_)
10608 : : {
10609 : 327550 : case BUILTIN_LEN:
10610 : 327550 : case BUILTIN_CAP:
10611 : 327550 : {
10612 : 327550 : if (this->seen_)
10613 : : return false;
10614 : :
10615 : 327550 : Expression* arg = this->one_arg();
10616 : 327550 : if (arg == NULL)
10617 : : return false;
10618 : :
10619 : : // We may be called before the determine_types pass.
10620 : 327550 : arg->determine_type_no_context(this->gogo_);
10621 : :
10622 : 327550 : Type* arg_type = arg->type();
10623 : 327550 : if (arg_type->is_error())
10624 : : return true;
10625 : :
10626 : 327547 : if (arg_type->points_to() != NULL
10627 : 9306 : && arg_type->points_to()->array_type() != NULL
10628 : 336847 : && !arg_type->points_to()->is_slice_type())
10629 : 9294 : arg_type = arg_type->points_to();
10630 : :
10631 : 601776 : if (arg_type->array_type() != NULL
10632 : 274229 : && arg_type->array_type()->length() != NULL)
10633 : : {
10634 : 13527 : this->seen_ = true;
10635 : 13527 : bool ret = Builtin_call_expression::array_len_is_constant(arg);
10636 : 13527 : this->seen_ = false;
10637 : 13527 : return ret;
10638 : : }
10639 : :
10640 : 594242 : if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
10641 : : {
10642 : 50230 : this->seen_ = true;
10643 : 50230 : bool ret = arg->is_constant();
10644 : 50230 : this->seen_ = false;
10645 : 50230 : return ret;
10646 : : }
10647 : : }
10648 : : break;
10649 : :
10650 : 1625 : case BUILTIN_SIZEOF:
10651 : 1625 : case BUILTIN_ALIGNOF:
10652 : 1625 : return this->one_arg() != NULL;
10653 : :
10654 : 1378 : case BUILTIN_OFFSETOF:
10655 : 1378 : {
10656 : 1378 : Expression* arg = this->one_arg();
10657 : 1378 : if (arg == NULL)
10658 : : return false;
10659 : 1378 : return (arg->field_reference_expression() != NULL
10660 : 1122 : || arg->classification() == Expression::EXPRESSION_SELECTOR);
10661 : : }
10662 : :
10663 : 49388 : case BUILTIN_COMPLEX:
10664 : 49388 : {
10665 : 49388 : const Expression_list* args = this->args();
10666 : 49388 : if (args != NULL && args->size() == 2)
10667 : 49388 : return args->front()->is_constant() && args->back()->is_constant();
10668 : : }
10669 : : break;
10670 : :
10671 : 2195 : case BUILTIN_REAL:
10672 : 2195 : case BUILTIN_IMAG:
10673 : 2195 : {
10674 : 2195 : Expression* arg = this->one_arg();
10675 : 4390 : return arg != NULL && arg->is_constant();
10676 : : }
10677 : :
10678 : : default:
10679 : : break;
10680 : : }
10681 : :
10682 : : return false;
10683 : : }
10684 : :
10685 : : // Return whether a builtin call is untyped. Most builtin functions
10686 : : // have a known type, but complex, real, and imag can be untyped.
10687 : :
10688 : : bool
10689 : 56988 : Builtin_call_expression::do_is_untyped(Type** ptype) const
10690 : : {
10691 : 56988 : if (this->is_error_expression())
10692 : : return false;
10693 : :
10694 : 56988 : switch (this->code_)
10695 : : {
10696 : : default:
10697 : : return false;
10698 : :
10699 : 13556 : case BUILTIN_COMPLEX:
10700 : 13556 : {
10701 : 13556 : const Expression_list* args = this->args();
10702 : 13556 : if (args == NULL || args->size() != 2)
10703 : : return false;
10704 : 13556 : Type* dummy;
10705 : 13556 : if (!args->front()->is_untyped(&dummy)
10706 : 13556 : || !args->back()->is_untyped(&dummy))
10707 : 12065 : return false;
10708 : 1491 : *ptype = Type::make_abstract_complex_type();
10709 : 1491 : return true;
10710 : : }
10711 : :
10712 : 1197 : case BUILTIN_REAL:
10713 : 1197 : case BUILTIN_IMAG:
10714 : 1197 : {
10715 : 1197 : Expression* arg = this->one_arg();
10716 : 1197 : if (arg == NULL)
10717 : : return false;
10718 : 1197 : if (!arg->is_untyped(ptype))
10719 : : return false;
10720 : 32 : *ptype = Type::make_abstract_float_type();
10721 : 32 : return true;
10722 : : }
10723 : : }
10724 : : }
10725 : :
10726 : : // Return a numeric constant if possible.
10727 : :
10728 : : bool
10729 : 148021 : Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc)
10730 : : {
10731 : 148021 : if (this->code_ == BUILTIN_LEN
10732 : 148021 : || this->code_ == BUILTIN_CAP)
10733 : : {
10734 : 142023 : Expression* arg = this->one_arg();
10735 : 142023 : if (arg == NULL)
10736 : : return false;
10737 : :
10738 : : // We may be called before the determine_types pass.
10739 : 142023 : arg->determine_type_no_context(this->gogo_);
10740 : :
10741 : 142023 : Type* arg_type = arg->type();
10742 : 142023 : if (arg_type->is_error())
10743 : : return false;
10744 : :
10745 : 282621 : if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
10746 : : {
10747 : 33992 : std::string sval;
10748 : 33992 : if (arg->string_constant_value(&sval))
10749 : : {
10750 : 2376 : nc->set_unsigned_long(Type::lookup_integer_type("int"),
10751 : : sval.length());
10752 : 2376 : return true;
10753 : : }
10754 : 33992 : }
10755 : :
10756 : 139647 : if (arg_type->points_to() != NULL
10757 : 9189 : && arg_type->points_to()->array_type() != NULL
10758 : 148836 : && !arg_type->points_to()->is_slice_type())
10759 : 9189 : arg_type = arg_type->points_to();
10760 : :
10761 : 244731 : if (arg_type->array_type() != NULL
10762 : 105084 : && arg_type->array_type()->length() != NULL)
10763 : : {
10764 : 12302 : if (this->seen_)
10765 : : return false;
10766 : :
10767 : 12302 : if (!arg_type->is_error())
10768 : : {
10769 : 24604 : Expression* e = arg_type->array_type()->length();
10770 : 12302 : this->seen_ = true;
10771 : 12302 : bool r = e->numeric_constant_value(nc);
10772 : 12302 : this->seen_ = false;
10773 : 12302 : if (r)
10774 : : {
10775 : 12302 : if (!nc->set_type(Type::lookup_integer_type("int"), false,
10776 : : this->location()))
10777 : 0 : r = false;
10778 : : }
10779 : 12302 : return r;
10780 : : }
10781 : : }
10782 : : }
10783 : : else if (this->code_ == BUILTIN_SIZEOF
10784 : : || this->code_ == BUILTIN_ALIGNOF)
10785 : : {
10786 : 1870 : Expression* arg = this->one_arg();
10787 : 1870 : if (arg == NULL)
10788 : : return false;
10789 : :
10790 : : // We may be called before the determine_types pass.
10791 : 1870 : arg->determine_type_no_context(this->gogo_);
10792 : :
10793 : 1870 : Type* arg_type = arg->type();
10794 : 1870 : if (arg_type->is_error())
10795 : : return false;
10796 : 1870 : if (arg_type->is_abstract())
10797 : 0 : arg_type = arg_type->make_non_abstract_type();
10798 : 1870 : if (this->seen_)
10799 : : return false;
10800 : :
10801 : 1870 : int64_t ret;
10802 : 1870 : if (this->code_ == BUILTIN_SIZEOF)
10803 : : {
10804 : 1859 : this->seen_ = true;
10805 : 1859 : bool ok = arg_type->backend_type_size(this->gogo_, &ret);
10806 : 1859 : this->seen_ = false;
10807 : 1859 : if (!ok)
10808 : : return false;
10809 : : }
10810 : 11 : else if (this->code_ == BUILTIN_ALIGNOF)
10811 : : {
10812 : 11 : bool ok;
10813 : 11 : this->seen_ = true;
10814 : 11 : if (arg->field_reference_expression() == NULL)
10815 : 5 : ok = arg_type->backend_type_align(this->gogo_, &ret);
10816 : : else
10817 : : {
10818 : : // Calling unsafe.Alignof(s.f) returns the alignment of
10819 : : // the type of f when it is used as a field in a struct.
10820 : 6 : ok = arg_type->backend_type_field_align(this->gogo_, &ret);
10821 : : }
10822 : 11 : this->seen_ = false;
10823 : 11 : if (!ok)
10824 : : return false;
10825 : : }
10826 : : else
10827 : 0 : go_unreachable();
10828 : :
10829 : 1870 : mpz_t zval;
10830 : 1870 : set_mpz_from_int64(&zval, ret);
10831 : 1870 : nc->set_int(Type::lookup_integer_type("uintptr"), zval);
10832 : 1870 : mpz_clear(zval);
10833 : 1870 : return true;
10834 : : }
10835 : : else if (this->code_ == BUILTIN_OFFSETOF)
10836 : : {
10837 : 804 : Expression* arg = this->one_arg();
10838 : 804 : if (arg == NULL)
10839 : : return false;
10840 : :
10841 : : // We may be called before the determine_types pass.
10842 : 804 : arg->determine_type_no_context(this->gogo_);
10843 : :
10844 : 804 : Field_reference_expression* farg = arg->field_reference_expression();
10845 : 256 : if (farg == NULL)
10846 : : return false;
10847 : 256 : if (this->seen_)
10848 : : return false;
10849 : :
10850 : : int64_t total_offset = 0;
10851 : 966 : while (true)
10852 : : {
10853 : 611 : Expression* struct_expr = farg->expr();
10854 : 611 : Type* st = struct_expr->type();
10855 : 611 : if (st->struct_type() == NULL)
10856 : 0 : return false;
10857 : 611 : if (st->named_type() != NULL)
10858 : 584 : st->named_type()->convert(this->gogo_);
10859 : 611 : if (st->is_error_type())
10860 : : {
10861 : 0 : go_assert(saw_errors());
10862 : : return false;
10863 : : }
10864 : 611 : int64_t offset;
10865 : 611 : this->seen_ = true;
10866 : 1222 : bool ok = st->struct_type()->backend_field_offset(this->gogo_,
10867 : : farg->field_index(),
10868 : : &offset);
10869 : 611 : this->seen_ = false;
10870 : 611 : if (!ok)
10871 : : return false;
10872 : 611 : total_offset += offset;
10873 : 611 : if (farg->implicit() && struct_expr->field_reference_expression() != NULL)
10874 : : {
10875 : : // Go up until we reach the original base.
10876 : 355 : farg = struct_expr->field_reference_expression();
10877 : 355 : continue;
10878 : : }
10879 : 256 : break;
10880 : : }
10881 : 256 : mpz_t zval;
10882 : 256 : set_mpz_from_int64(&zval, total_offset);
10883 : 256 : nc->set_int(Type::lookup_integer_type("uintptr"), zval);
10884 : 256 : mpz_clear(zval);
10885 : 256 : return true;
10886 : : }
10887 : : else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
10888 : : {
10889 : 636 : Expression* arg = this->one_arg();
10890 : 636 : if (arg == NULL)
10891 : : return false;
10892 : :
10893 : 636 : Numeric_constant argnc;
10894 : 636 : if (!arg->numeric_constant_value(&argnc))
10895 : : return false;
10896 : :
10897 : 42 : mpc_t val;
10898 : 42 : if (!argnc.to_complex(&val))
10899 : : return false;
10900 : :
10901 : 42 : Type* type = Builtin_call_expression::real_imag_type(argnc.type());
10902 : 42 : if (this->code_ == BUILTIN_REAL)
10903 : 22 : nc->set_float(type, mpc_realref(val));
10904 : : else
10905 : 20 : nc->set_float(type, mpc_imagref(val));
10906 : 42 : mpc_clear(val);
10907 : 42 : return true;
10908 : 636 : }
10909 : : else if (this->code_ == BUILTIN_COMPLEX)
10910 : : {
10911 : 1528 : const Expression_list* args = this->args();
10912 : 1528 : if (args == NULL || args->size() != 2)
10913 : : return false;
10914 : :
10915 : 1528 : Numeric_constant rnc;
10916 : 1528 : if (!args->front()->numeric_constant_value(&rnc))
10917 : : return false;
10918 : 1527 : Numeric_constant inc;
10919 : 1527 : if (!args->back()->numeric_constant_value(&inc))
10920 : : return false;
10921 : :
10922 : 1527 : if (rnc.type() != NULL
10923 : 1527 : && !rnc.type()->is_abstract()
10924 : 1506 : && inc.type() != NULL
10925 : 1506 : && !inc.type()->is_abstract()
10926 : 3033 : && !Type::are_identical(rnc.type(), inc.type(),
10927 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
10928 : : NULL))
10929 : : return false;
10930 : :
10931 : 1527 : mpfr_t r;
10932 : 1527 : if (!rnc.to_float(&r))
10933 : : return false;
10934 : 1527 : mpfr_t i;
10935 : 1527 : if (!inc.to_float(&i))
10936 : : {
10937 : 0 : mpfr_clear(r);
10938 : 0 : return false;
10939 : : }
10940 : :
10941 : 1527 : Type* arg_type = rnc.type();
10942 : 1527 : if (arg_type == NULL || arg_type->is_abstract())
10943 : 21 : arg_type = inc.type();
10944 : :
10945 : 1527 : mpc_t val;
10946 : 1527 : mpc_init2(val, mpc_precision);
10947 : 1527 : mpc_set_fr_fr(val, r, i, MPC_RNDNN);
10948 : 1527 : mpfr_clear(r);
10949 : 1527 : mpfr_clear(i);
10950 : :
10951 : 1527 : Type* type = Builtin_call_expression::complex_type(arg_type);
10952 : 1527 : nc->set_complex(type, val);
10953 : :
10954 : 1527 : mpc_clear(val);
10955 : :
10956 : 1527 : return true;
10957 : 1528 : }
10958 : :
10959 : : return false;
10960 : : }
10961 : :
10962 : : // Give an error if we are discarding the value of an expression which
10963 : : // should not normally be discarded. We don't give an error for
10964 : : // discarding the value of an ordinary function call, but we do for
10965 : : // builtin functions, purely for consistency with the gc compiler.
10966 : :
10967 : : bool
10968 : 34613 : Builtin_call_expression::do_discarding_value()
10969 : : {
10970 : 34613 : switch (this->code_)
10971 : : {
10972 : 0 : case BUILTIN_INVALID:
10973 : 0 : default:
10974 : 0 : go_unreachable();
10975 : :
10976 : 71 : case BUILTIN_APPEND:
10977 : 71 : case BUILTIN_CAP:
10978 : 71 : case BUILTIN_COMPLEX:
10979 : 71 : case BUILTIN_IMAG:
10980 : 71 : case BUILTIN_LEN:
10981 : 71 : case BUILTIN_MAKE:
10982 : 71 : case BUILTIN_NEW:
10983 : 71 : case BUILTIN_REAL:
10984 : 71 : case BUILTIN_ADD:
10985 : 71 : case BUILTIN_ALIGNOF:
10986 : 71 : case BUILTIN_OFFSETOF:
10987 : 71 : case BUILTIN_SIZEOF:
10988 : 71 : case BUILTIN_SLICE:
10989 : 71 : this->unused_value_error();
10990 : 71 : return false;
10991 : :
10992 : : case BUILTIN_CLOSE:
10993 : : case BUILTIN_COPY:
10994 : : case BUILTIN_DELETE:
10995 : : case BUILTIN_PANIC:
10996 : : case BUILTIN_PRINT:
10997 : : case BUILTIN_PRINTLN:
10998 : : case BUILTIN_RECOVER:
10999 : : return true;
11000 : : }
11001 : : }
11002 : :
11003 : : // Return the type.
11004 : :
11005 : : Type*
11006 : 1451500 : Builtin_call_expression::do_type()
11007 : : {
11008 : 1451500 : if (this->is_error_expression())
11009 : 1941 : return Type::make_error_type();
11010 : :
11011 : 1449559 : Type* type = this->type();
11012 : 1449559 : if (type != NULL)
11013 : : return type;
11014 : :
11015 : 1448018 : switch (this->code_)
11016 : : {
11017 : 0 : case BUILTIN_INVALID:
11018 : 0 : default:
11019 : 0 : return Type::make_error_type();
11020 : :
11021 : 14123 : case BUILTIN_NEW:
11022 : 14123 : {
11023 : 14123 : const Expression_list* args = this->args();
11024 : 14123 : if (args == NULL || args->empty())
11025 : 0 : return Type::make_error_type();
11026 : 14123 : return Type::make_pointer_type(args->front()->type());
11027 : : }
11028 : :
11029 : 24732 : case BUILTIN_MAKE:
11030 : 24732 : {
11031 : 24732 : const Expression_list* args = this->args();
11032 : 24732 : if (args == NULL || args->empty())
11033 : 0 : return Type::make_error_type();
11034 : 24732 : return args->front()->type();
11035 : : }
11036 : :
11037 : 1142751 : case BUILTIN_CAP:
11038 : 1142751 : case BUILTIN_COPY:
11039 : 1142751 : case BUILTIN_LEN:
11040 : 1142751 : return Type::lookup_integer_type("int");
11041 : :
11042 : 3750 : case BUILTIN_ALIGNOF:
11043 : 3750 : case BUILTIN_OFFSETOF:
11044 : 3750 : case BUILTIN_SIZEOF:
11045 : 3750 : return Type::lookup_integer_type("uintptr");
11046 : :
11047 : 75676 : case BUILTIN_CLOSE:
11048 : 75676 : case BUILTIN_DELETE:
11049 : 75676 : case BUILTIN_PANIC:
11050 : 75676 : case BUILTIN_PRINT:
11051 : 75676 : case BUILTIN_PRINTLN:
11052 : 75676 : return Type::make_void_type();
11053 : :
11054 : 6835 : case BUILTIN_RECOVER:
11055 : 6835 : return Type::make_empty_interface_type(Linemap::predeclared_location());
11056 : :
11057 : 85298 : case BUILTIN_APPEND:
11058 : 85298 : {
11059 : 85298 : const Expression_list* args = this->args();
11060 : 85298 : if (args == NULL || args->empty())
11061 : 0 : return Type::make_error_type();
11062 : 85298 : Type *ret = args->front()->type();
11063 : 85298 : if (!ret->is_slice_type())
11064 : 2 : return Type::make_error_type();
11065 : : return ret;
11066 : : }
11067 : :
11068 : 8427 : case BUILTIN_REAL:
11069 : 8427 : case BUILTIN_IMAG:
11070 : 8427 : {
11071 : 8427 : Expression* arg = this->one_arg();
11072 : 8427 : if (arg == NULL)
11073 : 0 : return Type::make_error_type();
11074 : 8427 : Type* t = arg->type();
11075 : 8427 : if (t->is_abstract())
11076 : 0 : t = t->make_non_abstract_type();
11077 : 8427 : t = Builtin_call_expression::real_imag_type(t);
11078 : 8427 : if (t == NULL)
11079 : 4 : t = Type::make_error_type();
11080 : : return t;
11081 : : }
11082 : :
11083 : 86335 : case BUILTIN_COMPLEX:
11084 : 86335 : {
11085 : 86335 : const Expression_list* args = this->args();
11086 : 86335 : if (args == NULL || args->size() != 2)
11087 : 0 : return Type::make_error_type();
11088 : 86335 : Type* t = args->front()->type();
11089 : 86335 : if (t->is_abstract())
11090 : : {
11091 : 0 : t = args->back()->type();
11092 : 0 : if (t->is_abstract())
11093 : 0 : t = t->make_non_abstract_type();
11094 : : }
11095 : 86335 : t = Builtin_call_expression::complex_type(t);
11096 : 86335 : if (t == NULL)
11097 : 1 : t = Type::make_error_type();
11098 : : return t;
11099 : : }
11100 : :
11101 : 41 : case BUILTIN_ADD:
11102 : 41 : return Type::make_pointer_type(Type::make_void_type());
11103 : :
11104 : 50 : case BUILTIN_SLICE:
11105 : 50 : const Expression_list* args = this->args();
11106 : 50 : if (args == NULL || args->size() != 2)
11107 : 0 : return Type::make_error_type();
11108 : 50 : Type* pt = args->front()->type()->points_to();
11109 : 50 : if (pt == NULL)
11110 : 0 : return Type::make_error_type();
11111 : 50 : return Type::make_array_type(pt, NULL);
11112 : : }
11113 : : }
11114 : :
11115 : : // Determine the type.
11116 : :
11117 : : void
11118 : 295515 : Builtin_call_expression::do_determine_type(Gogo* gogo,
11119 : : const Type_context* context)
11120 : : {
11121 : 295515 : if (!this->determining_types())
11122 : : return;
11123 : :
11124 : 226650 : this->fn()->determine_type_no_context(gogo);
11125 : :
11126 : 226650 : this->simplify_multiple_results(gogo);
11127 : :
11128 : 226650 : const Expression_list* args = this->args();
11129 : :
11130 : 226650 : bool is_print;
11131 : 226650 : Type* arg_type = NULL;
11132 : 226650 : Type* trailing_arg_types = NULL;
11133 : 226650 : switch (this->code_)
11134 : : {
11135 : 15117 : case BUILTIN_MAKE:
11136 : 15117 : trailing_arg_types = Type::lookup_integer_type("int");
11137 : 15117 : is_print = false;
11138 : 15117 : break;
11139 : :
11140 : 15153 : case BUILTIN_PANIC:
11141 : 15153 : arg_type =
11142 : 15153 : Type::make_empty_interface_type(Linemap::predeclared_location());
11143 : 15153 : is_print = false;
11144 : 15153 : break;
11145 : :
11146 : : case BUILTIN_PRINT:
11147 : : case BUILTIN_PRINTLN:
11148 : : // Do not force a large integer constant to "int".
11149 : : is_print = true;
11150 : : break;
11151 : :
11152 : 1048 : case BUILTIN_REAL:
11153 : 1048 : case BUILTIN_IMAG:
11154 : 1048 : {
11155 : : // We need the argument to determine the type, so check it now
11156 : : // before any call to the do_type method.
11157 : 1048 : const Expression_list* args = this->args();
11158 : 1048 : if (args == NULL || args->size() < 1)
11159 : : {
11160 : 0 : this->report_error(_("not enough arguments"));
11161 : 0 : return;
11162 : : }
11163 : 1048 : else if (args->size() > 1)
11164 : : {
11165 : 0 : this->report_error(_("too many arguments"));
11166 : 0 : return;
11167 : : }
11168 : :
11169 : 1048 : Type* dummy;
11170 : 1048 : if (context->type != NULL
11171 : 764 : && context->type->is_numeric_type()
11172 : 1803 : && this->is_untyped(&dummy))
11173 : : {
11174 : 28 : Type* type = context->type;
11175 : 28 : if (type->is_abstract() && !context->may_be_abstract)
11176 : 0 : type = type->make_non_abstract_type();
11177 : 28 : this->set_type(type);
11178 : : }
11179 : 1020 : else if (context->may_be_abstract && this->is_constant())
11180 : 5 : this->set_type(Type::make_abstract_float_type());
11181 : :
11182 : 1048 : arg_type = Builtin_call_expression::complex_type(context->type);
11183 : 1048 : if (arg_type == NULL)
11184 : : {
11185 : 301 : if (context->may_be_abstract)
11186 : 6 : arg_type = Type::make_abstract_complex_type();
11187 : : else
11188 : 295 : arg_type = Type::lookup_complex_type("complex128");
11189 : : }
11190 : :
11191 : 1048 : if (!args->front()->is_untyped(&dummy))
11192 : : {
11193 : 994 : Type_context subcontext(arg_type, context->may_be_abstract);
11194 : 994 : args->front()->determine_type(gogo, &subcontext);
11195 : : }
11196 : :
11197 : 1048 : is_print = false;
11198 : : }
11199 : 1048 : break;
11200 : :
11201 : 13710 : case BUILTIN_COMPLEX:
11202 : 13710 : {
11203 : : // We need the arguments to determine the type, so check them
11204 : : // now before any call to the do_type method.
11205 : 13710 : const Expression_list* args = this->args();
11206 : 13710 : if (args == NULL || args->size() < 2)
11207 : : {
11208 : 4 : this->report_error(_("not enough arguments"));
11209 : 9 : return;
11210 : : }
11211 : 13706 : else if (args->size() > 2)
11212 : : {
11213 : 1 : this->report_error(_("too many arguments"));
11214 : 1 : return;
11215 : : }
11216 : :
11217 : 13705 : Type* dummy;
11218 : 13705 : if (context->type != NULL
11219 : 13615 : && context->type->is_numeric_type()
11220 : 27259 : && this->is_untyped(&dummy))
11221 : : {
11222 : 1490 : Type* type = context->type;
11223 : 1490 : if (type->is_abstract() && !context->may_be_abstract)
11224 : 0 : type = type->make_non_abstract_type();
11225 : 1490 : this->set_type(type);
11226 : : }
11227 : 12215 : else if (context->may_be_abstract && this->is_constant())
11228 : 6 : this->set_type(Type::make_abstract_complex_type());
11229 : :
11230 : : // For the complex function the type of one operand can
11231 : : // determine the type of the other, as in a binary expression.
11232 : 13705 : arg_type = Builtin_call_expression::real_imag_type(context->type);
11233 : 13705 : if (arg_type == NULL)
11234 : : {
11235 : 153 : if (context->may_be_abstract)
11236 : 6 : arg_type = Type::make_abstract_float_type();
11237 : : else
11238 : 147 : arg_type = Type::lookup_float_type("float64");
11239 : : }
11240 : :
11241 : 13705 : Type_context subcontext(arg_type, context->may_be_abstract);
11242 : 13705 : if (!args->front()->is_untyped(&dummy))
11243 : : {
11244 : 11127 : args->front()->determine_type(gogo, &subcontext);
11245 : 11127 : arg_type = args->front()->type();
11246 : : }
11247 : 2578 : else if (!args->back()->is_untyped(&dummy))
11248 : : {
11249 : 1054 : args->back()->determine_type(gogo, &subcontext);
11250 : 1054 : arg_type = args->back()->type();
11251 : : }
11252 : :
11253 : 13705 : is_print = false;
11254 : : }
11255 : 13705 : break;
11256 : :
11257 : 15743 : case BUILTIN_APPEND:
11258 : 15743 : if (!this->is_varargs()
11259 : 12154 : && args != NULL
11260 : 27897 : && !args->empty())
11261 : : {
11262 : 12154 : args->front()->determine_type_no_context(gogo);
11263 : 12154 : if (args->front()->type()->is_slice_type())
11264 : 12152 : trailing_arg_types =
11265 : 24304 : args->front()->type()->array_type()->element_type();
11266 : : }
11267 : 12152 : is_print = false;
11268 : 12152 : break;
11269 : :
11270 : 18 : case BUILTIN_ADD:
11271 : 18 : case BUILTIN_SLICE:
11272 : : // Both unsafe.Add and unsafe.Slice take two arguments, and the
11273 : : // second arguments defaults to "int".
11274 : 18 : if (args != NULL && args->size() == 2)
11275 : : {
11276 : 18 : if (this->code_ == BUILTIN_SLICE)
11277 : 9 : args->front()->determine_type_no_context(gogo);
11278 : : else
11279 : : {
11280 : 9 : Type* pointer = Type::make_pointer_type(Type::make_void_type());
11281 : 9 : Type_context subcontext(pointer, false);
11282 : 9 : args->front()->determine_type(gogo, &subcontext);
11283 : : }
11284 : 18 : Type* int_type = Type::lookup_integer_type("int");
11285 : 18 : Type_context subcontext(int_type, false);
11286 : 18 : args->back()->determine_type(gogo, &subcontext);
11287 : 18 : return;
11288 : : }
11289 : : is_print = false;
11290 : : break;
11291 : :
11292 : 943 : case BUILTIN_DELETE:
11293 : 943 : if (args != NULL && args->size() == 2)
11294 : : {
11295 : 940 : args->front()->determine_type_no_context(gogo);
11296 : 940 : Map_type* mt = args->front()->type()->map_type();
11297 : 939 : if (mt != NULL)
11298 : 939 : trailing_arg_types = mt->key_type();
11299 : : }
11300 : : is_print = false;
11301 : : break;
11302 : :
11303 : : default:
11304 : 152325 : is_print = false;
11305 : : break;
11306 : : }
11307 : :
11308 : 226625 : if (args != NULL)
11309 : : {
11310 : 522951 : for (Expression_list::const_iterator pa = args->begin();
11311 : 522951 : pa != args->end();
11312 : 297236 : ++pa)
11313 : : {
11314 : 297236 : Type_context subcontext;
11315 : 297236 : subcontext.type = arg_type;
11316 : :
11317 : 297236 : if (is_print && (*pa)->is_constant())
11318 : : {
11319 : : // We want to print large constants, we so can't just
11320 : : // use the appropriate nonabstract type. Use uint64 for
11321 : : // an integer if we know it is nonnegative, otherwise
11322 : : // use int64 for a integer, otherwise use float64 for a
11323 : : // float or complex128 for a complex.
11324 : 26478 : Type* atype;
11325 : 26478 : if ((*pa)->is_untyped(&atype))
11326 : : {
11327 : 25189 : Type* want_type = NULL;
11328 : 25189 : if (atype->integer_type() != NULL)
11329 : : {
11330 : 505 : Numeric_constant nc;
11331 : 505 : if (this->numeric_constant_value(&nc))
11332 : : {
11333 : 0 : mpz_t val;
11334 : 0 : if (nc.to_int(&val))
11335 : : {
11336 : 0 : if (mpz_sgn(val) >= 0)
11337 : 0 : want_type = Type::lookup_integer_type("uint64");
11338 : 0 : mpz_clear(val);
11339 : : }
11340 : : }
11341 : 0 : if (want_type == NULL)
11342 : 505 : want_type = Type::lookup_integer_type("int64");
11343 : 505 : }
11344 : 24684 : else if (atype->float_type() != NULL)
11345 : 56 : want_type = Type::lookup_float_type("float64");
11346 : 24628 : else if (atype->complex_type() != NULL)
11347 : 14 : want_type = Type::lookup_complex_type("complex128");
11348 : 24614 : else if (atype->is_abstract_string_type())
11349 : 24588 : want_type = Type::lookup_string_type();
11350 : 26 : else if (atype->is_abstract_boolean_type())
11351 : 26 : want_type = Type::lookup_bool_type();
11352 : : else
11353 : 0 : go_unreachable();
11354 : 25189 : subcontext.type = want_type;
11355 : : }
11356 : : }
11357 : :
11358 : 297236 : (*pa)->determine_type(gogo, &subcontext);
11359 : :
11360 : 297236 : if (trailing_arg_types != NULL)
11361 : : {
11362 : 28208 : arg_type = trailing_arg_types;
11363 : 28208 : trailing_arg_types = NULL;
11364 : : }
11365 : : }
11366 : : }
11367 : : }
11368 : :
11369 : : // If there is exactly one argument, return true. Otherwise give an
11370 : : // error message and return false.
11371 : :
11372 : : bool
11373 : 80123 : Builtin_call_expression::check_one_arg()
11374 : : {
11375 : 80123 : const Expression_list* args = this->args();
11376 : 80123 : if (args == NULL || args->size() < 1)
11377 : : {
11378 : 0 : this->report_error(_("not enough arguments"));
11379 : 0 : return false;
11380 : : }
11381 : 80123 : else if (args->size() > 1)
11382 : : {
11383 : 0 : this->report_error(_("too many arguments"));
11384 : 0 : return false;
11385 : : }
11386 : 80123 : if (args->front()->is_error_expression()
11387 : 80123 : || args->front()->type()->is_error())
11388 : : {
11389 : 5 : this->set_is_error();
11390 : 5 : return false;
11391 : : }
11392 : : return true;
11393 : : }
11394 : :
11395 : : // Check argument types for a builtin function.
11396 : :
11397 : : void
11398 : 145801 : Builtin_call_expression::do_check_types(Gogo* gogo)
11399 : : {
11400 : 145801 : if (this->is_error_expression())
11401 : : return;
11402 : :
11403 : 145724 : if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
11404 : : {
11405 : 8 : go_error_at(this->location(),
11406 : : "invalid use of %<...%> with built-in function");
11407 : 8 : this->set_is_error();
11408 : 8 : return;
11409 : : }
11410 : :
11411 : 145716 : switch (this->code_)
11412 : : {
11413 : : case BUILTIN_INVALID:
11414 : : return;
11415 : :
11416 : 7322 : case BUILTIN_NEW:
11417 : 7322 : if (this->check_one_arg())
11418 : : {
11419 : 7322 : Expression* arg = this->one_arg();
11420 : 7322 : if (!arg->is_type_expression())
11421 : : {
11422 : 0 : go_error_at(arg->location(), "expected type");
11423 : 0 : this->set_is_error();
11424 : : }
11425 : : }
11426 : : break;
11427 : :
11428 : 15106 : case BUILTIN_MAKE:
11429 : 15106 : {
11430 : 15106 : const Expression_list* args = this->args();
11431 : 15106 : if (args == NULL || args->size() < 1)
11432 : : {
11433 : 0 : this->report_error(_("not enough arguments"));
11434 : 0 : return;
11435 : : }
11436 : :
11437 : 15106 : Expression* first_arg = args->front();
11438 : 15106 : if (!first_arg->is_type_expression())
11439 : : {
11440 : 0 : go_error_at(first_arg->location(), "expected type");
11441 : 0 : this->set_is_error();
11442 : 0 : return;
11443 : : }
11444 : :
11445 : 15106 : Type* type = first_arg->type();
11446 : 15106 : if (!type->in_heap())
11447 : 0 : go_error_at(first_arg->location(),
11448 : : "cannot make slice of go:notinheap type");
11449 : :
11450 : 15106 : bool is_slice = type->is_slice_type();
11451 : 15106 : if (!is_slice
11452 : 2766 : && type->map_type() == NULL
11453 : 21721 : && type->channel_type() == NULL)
11454 : : {
11455 : 0 : this->report_error(_("invalid type for make function"));
11456 : 0 : return;
11457 : : }
11458 : :
11459 : 15106 : Expression_list::const_iterator parg = args->begin();
11460 : 15106 : ++parg;
11461 : 15106 : if (parg == args->end())
11462 : : {
11463 : 4935 : if (is_slice)
11464 : : {
11465 : 0 : this->report_error(_("length required when "
11466 : : "allocating a slice"));
11467 : 0 : return;
11468 : : }
11469 : : }
11470 : : else
11471 : : {
11472 : 10171 : if ((*parg)->type()->integer_type() == NULL)
11473 : : {
11474 : 8 : go_error_at((*parg)->location(),
11475 : : "non-integer len argument in make");
11476 : 8 : return;
11477 : : }
11478 : 10163 : ++parg;
11479 : :
11480 : 10163 : if (is_slice && parg != args->end())
11481 : : {
11482 : 1716 : if ((*parg)->type()->integer_type() == NULL)
11483 : : {
11484 : 5 : go_error_at((*parg)->location(),
11485 : : "non-integer cap argument in make");
11486 : 5 : return;
11487 : : }
11488 : 1711 : ++parg;
11489 : : }
11490 : : }
11491 : :
11492 : 15093 : if (parg != args->end())
11493 : : {
11494 : 1 : this->report_error(_("too many arguments to make"));
11495 : 1 : return;
11496 : : }
11497 : : }
11498 : : break;
11499 : :
11500 : 892 : case BUILTIN_DELETE:
11501 : 892 : {
11502 : 892 : const Expression_list* args = this->args();
11503 : 892 : if (args == NULL || args->size() < 2)
11504 : 2 : this->report_error(_("not enough arguments"));
11505 : 890 : else if (args->size() > 2)
11506 : 1 : this->report_error(_("too many arguments"));
11507 : 889 : else if (args->front()->type()->map_type() == NULL)
11508 : 1 : this->report_error(_("argument 1 must be a map"));
11509 : : else
11510 : : {
11511 : 888 : Type* key_type =
11512 : 1776 : args->front()->type()->map_type()->key_type();
11513 : 888 : Expression_list::iterator pa = this->args()->begin();
11514 : 888 : pa++;
11515 : 888 : Type* arg_type = (*pa)->type();
11516 : 888 : std::string reason;
11517 : 888 : if (!Type::are_assignable(key_type, arg_type, &reason))
11518 : : {
11519 : 0 : if (reason.empty())
11520 : 0 : go_error_at(this->location(),
11521 : : "argument 2 has incompatible type");
11522 : : else
11523 : 0 : go_error_at(this->location(),
11524 : : "argument 2 has incompatible type (%s)",
11525 : : reason.c_str());
11526 : 0 : this->set_is_error();
11527 : : }
11528 : 888 : }
11529 : : }
11530 : : break;
11531 : :
11532 : 54786 : case BUILTIN_LEN:
11533 : 54786 : case BUILTIN_CAP:
11534 : 54786 : {
11535 : : // The single argument may be either a string or an array or a
11536 : : // map or a channel, or a pointer to a closed array.
11537 : 54786 : if (this->check_one_arg())
11538 : : {
11539 : 54783 : Type* arg_type = this->one_arg()->type();
11540 : 54783 : if (arg_type->points_to() != NULL
11541 : 204 : && arg_type->points_to()->array_type() != NULL
11542 : 54981 : && !arg_type->points_to()->is_slice_type())
11543 : 192 : arg_type = arg_type->points_to();
11544 : 54783 : if (this->code_ == BUILTIN_CAP)
11545 : : {
11546 : 944 : if (!arg_type->is_error()
11547 : 54 : && arg_type->array_type() == NULL
11548 : 944 : && arg_type->channel_type() == NULL)
11549 : 3 : this->report_error(_("argument must be array or slice "
11550 : : "or channel"));
11551 : : }
11552 : : else
11553 : : {
11554 : 53839 : if (!arg_type->is_error()
11555 : 53839 : && !arg_type->is_string_type()
11556 : 1230 : && arg_type->array_type() == NULL
11557 : 42 : && arg_type->map_type() == NULL
11558 : 53839 : && arg_type->channel_type() == NULL)
11559 : 9 : this->report_error(_("argument must be string or "
11560 : : "array or slice or map or channel"));
11561 : : }
11562 : : }
11563 : : }
11564 : : break;
11565 : :
11566 : 16165 : case BUILTIN_PRINT:
11567 : 16165 : case BUILTIN_PRINTLN:
11568 : 16165 : {
11569 : 16165 : const Expression_list* args = this->args();
11570 : 16165 : if (args != NULL)
11571 : : {
11572 : 16111 : for (Expression_list::const_iterator p = args->begin();
11573 : 54836 : p != args->end();
11574 : 38725 : ++p)
11575 : : {
11576 : 38725 : Type* type = (*p)->type();
11577 : 38725 : if (type->is_error()
11578 : 38712 : || type->is_string_type()
11579 : 39671 : || type->integer_type() != NULL
11580 : 39442 : || type->float_type() != NULL
11581 : 39366 : || type->complex_type() != NULL
11582 : 641 : || type->is_boolean_type()
11583 : 482 : || type->points_to() != NULL
11584 : 38752 : || type->interface_type() != NULL
11585 : 38750 : || type->channel_type() != NULL
11586 : 38747 : || type->map_type() != NULL
11587 : 38725 : || type->function_type() != NULL
11588 : 38745 : || type->is_slice_type())
11589 : : ;
11590 : 1 : else if ((*p)->is_type_expression())
11591 : : {
11592 : : // If this is a type expression it's going to give
11593 : : // an error anyhow, so we don't need one here.
11594 : : }
11595 : : else
11596 : : {
11597 : : // Report errors in the expression first.
11598 : 1 : (*p)->check_types(gogo);
11599 : 1 : if (!(*p)->is_error_expression())
11600 : 0 : this->report_error(_("unsupported argument type to "
11601 : : "builtin function"));
11602 : : }
11603 : : }
11604 : : }
11605 : : }
11606 : : break;
11607 : :
11608 : 863 : case BUILTIN_CLOSE:
11609 : 863 : if (this->check_one_arg())
11610 : : {
11611 : 863 : if (this->one_arg()->type()->channel_type() == NULL)
11612 : 1 : this->report_error(_("argument must be channel"));
11613 : 1724 : else if (!this->one_arg()->type()->channel_type()->may_send())
11614 : 1 : this->report_error(_("cannot close receive-only channel"));
11615 : : }
11616 : : break;
11617 : :
11618 : 14972 : case BUILTIN_PANIC:
11619 : 14972 : case BUILTIN_SIZEOF:
11620 : 14972 : case BUILTIN_ALIGNOF:
11621 : 14972 : if (this->check_one_arg())
11622 : : {
11623 : 14972 : Expression* arg = this->one_arg();
11624 : 14972 : if (arg->type()->is_void_type())
11625 : 0 : this->report_error(_("argument to builtin has void type"));
11626 : : }
11627 : : break;
11628 : :
11629 : 848 : case BUILTIN_RECOVER:
11630 : 848 : if (this->args() != NULL
11631 : 1 : && !this->args()->empty()
11632 : 849 : && !this->recover_arg_is_set_)
11633 : 0 : this->report_error(_("too many arguments"));
11634 : : break;
11635 : :
11636 : 1156 : case BUILTIN_OFFSETOF:
11637 : 1156 : if (this->check_one_arg())
11638 : : {
11639 : 1156 : Expression* arg = this->one_arg();
11640 : 1156 : if (arg->classification() == Expression::EXPRESSION_SELECTOR)
11641 : : {
11642 : 1156 : Selector_expression* se = static_cast<Selector_expression*>(arg);
11643 : 1156 : Expression* resolved = se->resolved();
11644 : 1156 : if (resolved != NULL)
11645 : 1156 : arg = resolved;
11646 : : }
11647 : 1156 : if (arg->is_error_expression())
11648 : : ;
11649 : 1156 : else if (arg->bound_method_expression() != NULL
11650 : 2 : || arg->interface_field_reference_expression() != NULL)
11651 : 2 : this->report_error(_("invalid use of method value as "
11652 : : "argument of Offsetof"));
11653 : 1154 : else if (arg->field_reference_expression() == NULL)
11654 : 0 : this->report_error(_("argument must be a field reference"));
11655 : : }
11656 : : break;
11657 : :
11658 : 3229 : case BUILTIN_COPY:
11659 : 3229 : {
11660 : 3229 : const Expression_list* args = this->args();
11661 : 3229 : if (args == NULL || args->size() < 2)
11662 : : {
11663 : 0 : this->report_error(_("not enough arguments"));
11664 : 0 : break;
11665 : : }
11666 : 3229 : else if (args->size() > 2)
11667 : : {
11668 : 0 : this->report_error(_("too many arguments"));
11669 : 0 : break;
11670 : : }
11671 : 3229 : Type* arg1_type = args->front()->type();
11672 : 3229 : Type* arg2_type = args->back()->type();
11673 : 3229 : if (arg1_type->is_error() || arg2_type->is_error())
11674 : : {
11675 : 0 : this->set_is_error();
11676 : 0 : break;
11677 : : }
11678 : :
11679 : 3229 : Type* e1;
11680 : 3229 : if (arg1_type->is_slice_type())
11681 : 6456 : e1 = arg1_type->array_type()->element_type();
11682 : : else
11683 : : {
11684 : 1 : this->report_error(_("left argument must be a slice"));
11685 : 1 : break;
11686 : : }
11687 : :
11688 : 3228 : if (arg2_type->is_slice_type())
11689 : : {
11690 : 5700 : Type* e2 = arg2_type->array_type()->element_type();
11691 : 2850 : if (!Type::are_identical(e1, e2, Type::COMPARE_TAGS, NULL))
11692 : 0 : this->report_error(_("element types must be the same"));
11693 : : }
11694 : 378 : else if (arg2_type->is_string_type())
11695 : : {
11696 : 1131 : if (e1->integer_type() == NULL || !e1->integer_type()->is_byte())
11697 : 0 : this->report_error(_("first argument must be []byte"));
11698 : : }
11699 : : else
11700 : 1 : this->report_error(_("second argument must be slice or string"));
11701 : : }
11702 : : break;
11703 : :
11704 : 15645 : case BUILTIN_APPEND:
11705 : 15645 : {
11706 : 15645 : const Expression_list* args = this->args();
11707 : 15645 : if (args == NULL || args->empty())
11708 : : {
11709 : 0 : this->report_error(_("not enough arguments"));
11710 : 0 : break;
11711 : : }
11712 : :
11713 : 15645 : Type* slice_type = args->front()->type();
11714 : 15645 : if (!slice_type->is_slice_type())
11715 : : {
11716 : 2 : if (slice_type->is_error_type())
11717 : : break;
11718 : 2 : if (slice_type->is_nil_type())
11719 : 1 : go_error_at(args->front()->location(), "use of untyped nil");
11720 : : else
11721 : 1 : go_error_at(args->front()->location(),
11722 : : "argument 1 must be a slice");
11723 : 2 : this->set_is_error();
11724 : 2 : break;
11725 : : }
11726 : :
11727 : 31286 : Type* element_type = slice_type->array_type()->element_type();
11728 : 15643 : if (!element_type->in_heap())
11729 : 0 : go_error_at(args->front()->location(),
11730 : : "cannot append to slice of go:notinheap type");
11731 : 15643 : if (this->is_varargs())
11732 : : {
11733 : 3553 : if (!args->back()->type()->is_slice_type()
11734 : 3553 : && !args->back()->type()->is_string_type())
11735 : : {
11736 : 0 : go_error_at(args->back()->location(),
11737 : : "invalid use of %<...%> with non-slice/non-string");
11738 : 0 : this->set_is_error();
11739 : 0 : break;
11740 : : }
11741 : :
11742 : 3553 : if (args->size() < 2)
11743 : : {
11744 : 0 : this->report_error(_("not enough arguments"));
11745 : 0 : break;
11746 : : }
11747 : 3553 : if (args->size() > 2)
11748 : : {
11749 : 0 : this->report_error(_("too many arguments"));
11750 : 0 : break;
11751 : : }
11752 : :
11753 : 3553 : if (args->back()->type()->is_string_type()
11754 : 942 : && element_type->integer_type() != NULL
11755 : 4495 : && element_type->integer_type()->is_byte())
11756 : : {
11757 : : // Permit append(s1, s2...) when s1 is a slice of
11758 : : // bytes and s2 is a string type.
11759 : : }
11760 : : else
11761 : : {
11762 : : // We have to test for assignment compatibility to a
11763 : : // slice of the element type, which is not necessarily
11764 : : // the same as the type of the first argument: the
11765 : : // first argument might have a named type.
11766 : 2611 : Type* check_type = Type::make_array_type(element_type, NULL);
11767 : 2611 : std::string reason;
11768 : 2611 : if (!Type::are_assignable(check_type, args->back()->type(),
11769 : : &reason))
11770 : : {
11771 : 0 : if (reason.empty())
11772 : 0 : go_error_at(args->back()->location(),
11773 : : "argument 2 has invalid type");
11774 : : else
11775 : 0 : go_error_at(args->back()->location(),
11776 : : "argument 2 has invalid type (%s)",
11777 : : reason.c_str());
11778 : 0 : this->set_is_error();
11779 : 0 : break;
11780 : : }
11781 : 2611 : }
11782 : : }
11783 : : else
11784 : : {
11785 : 12090 : Expression_list::const_iterator pa = args->begin();
11786 : 12090 : int i = 2;
11787 : 26264 : for (++pa; pa != args->end(); ++pa, ++i)
11788 : : {
11789 : 14174 : std::string reason;
11790 : 14174 : if (!Type::are_assignable(element_type, (*pa)->type(),
11791 : : &reason))
11792 : : {
11793 : 2 : if (reason.empty())
11794 : 0 : go_error_at((*pa)->location(),
11795 : : "argument %d has incompatible type", i);
11796 : : else
11797 : 2 : go_error_at((*pa)->location(),
11798 : : "argument %d has incompatible type (%s)",
11799 : : i, reason.c_str());
11800 : 2 : this->set_is_error();
11801 : : }
11802 : 14174 : }
11803 : : }
11804 : : }
11805 : : break;
11806 : :
11807 : 1024 : case BUILTIN_REAL:
11808 : 1024 : case BUILTIN_IMAG:
11809 : 1024 : if (this->check_one_arg())
11810 : : {
11811 : 1022 : if (this->one_arg()->type()->complex_type() == NULL)
11812 : 2 : this->report_error(_("argument must have complex type"));
11813 : : }
11814 : : break;
11815 : :
11816 : 13690 : case BUILTIN_COMPLEX:
11817 : 13690 : {
11818 : 13690 : const Expression_list* args = this->args();
11819 : 13690 : go_assert(args != NULL && args->size() == 2);
11820 : 13690 : if (args->front()->is_error_expression()
11821 : 13683 : || args->front()->type()->is_error()
11822 : 13683 : || args->back()->is_error_expression()
11823 : 27371 : || args->back()->type()->is_error())
11824 : 9 : this->set_is_error();
11825 : 13681 : else if (!Type::are_identical(args->front()->type(),
11826 : 13681 : args->back()->type(),
11827 : : Type::COMPARE_TAGS, NULL))
11828 : 6 : this->report_error(_("complex arguments must have identical types"));
11829 : 13675 : else if (args->front()->type()->float_type() == NULL)
11830 : 1 : this->report_error(_("complex arguments must have "
11831 : : "floating-point type"));
11832 : : }
11833 : : break;
11834 : :
11835 : 18 : case BUILTIN_ADD:
11836 : 18 : case BUILTIN_SLICE:
11837 : 18 : {
11838 : 18 : Numeric_constant nc;
11839 : 18 : unsigned long v;
11840 : 18 : const Expression_list* args = this->args();
11841 : 18 : if (args == NULL || args->size() < 2)
11842 : 0 : this->report_error(_("not enough arguments"));
11843 : 18 : else if (args->size() > 2)
11844 : 0 : this->report_error(_("too many arguments"));
11845 : 18 : else if (args->front()->is_error_expression()
11846 : 18 : || args->front()->type()->is_error()
11847 : 18 : || args->back()->is_error_expression()
11848 : 36 : || args->back()->type()->is_error())
11849 : 0 : this->set_is_error();
11850 : 18 : else if (args->back()->type()->integer_type() == NULL
11851 : 0 : && (!args->back()->type()->is_abstract()
11852 : 0 : || !args->back()->numeric_constant_value(&nc)
11853 : 0 : || (nc.to_unsigned_long(&v)
11854 : : == Numeric_constant::NC_UL_NOTINT)))
11855 : : {
11856 : 0 : if (this->code_ == BUILTIN_ADD)
11857 : 0 : go_error_at(args->back()->location(), "non-integer offset");
11858 : : else
11859 : 0 : go_error_at(args->back()->location(), "non-integer size");
11860 : : }
11861 : 18 : else if (this->code_ == BUILTIN_ADD)
11862 : : {
11863 : 9 : Type* pointer_type =
11864 : 9 : Type::make_pointer_type(Type::make_void_type());
11865 : 9 : std::string reason;
11866 : 9 : if (!Type::are_assignable(pointer_type, args->front()->type(),
11867 : : &reason))
11868 : : {
11869 : 0 : if (reason.empty())
11870 : 0 : go_error_at(args->front()->location(),
11871 : : "argument 1 has incompatible type");
11872 : : else
11873 : 0 : go_error_at(args->front()->location(),
11874 : : "argument 1 has incompatible type (%s)",
11875 : : reason.c_str());
11876 : 0 : this->set_is_error();
11877 : : }
11878 : 9 : }
11879 : : else
11880 : : {
11881 : 9 : if (args->front()->type()->points_to() == NULL)
11882 : : {
11883 : 0 : go_error_at(args->front()->location(),
11884 : : "argument 1 must be a pointer");
11885 : 0 : this->set_is_error();
11886 : : }
11887 : :
11888 : 9 : unsigned int int_bits =
11889 : 18 : Type::lookup_integer_type("int")->integer_type()->bits();
11890 : :
11891 : 9 : mpz_t ival;
11892 : 9 : if (args->back()->numeric_constant_value(&nc) && nc.to_int(&ival))
11893 : : {
11894 : 7 : if (mpz_sgn(ival) < 0
11895 : 7 : || mpz_sizeinbase(ival, 2) >= int_bits)
11896 : : {
11897 : 0 : go_error_at(args->back()->location(),
11898 : : "slice length out of range");
11899 : 0 : this->set_is_error();
11900 : : }
11901 : 7 : mpz_clear(ival);
11902 : : }
11903 : : }
11904 : 18 : }
11905 : 18 : break;
11906 : :
11907 : 0 : default:
11908 : 0 : go_unreachable();
11909 : : }
11910 : : }
11911 : :
11912 : : Expression*
11913 : 0 : Builtin_call_expression::do_copy()
11914 : : {
11915 : 0 : Call_expression* bce =
11916 : : new Builtin_call_expression(this->gogo_, this->fn()->copy(),
11917 : 0 : (this->args() == NULL
11918 : : ? NULL
11919 : 0 : : this->args()->copy()),
11920 : 0 : this->is_varargs(),
11921 : 0 : this->location());
11922 : :
11923 : 0 : if (this->varargs_are_lowered())
11924 : 0 : bce->set_varargs_are_lowered();
11925 : 0 : if (this->is_deferred())
11926 : 0 : bce->set_is_deferred();
11927 : 0 : if (this->is_concurrent())
11928 : 0 : bce->set_is_concurrent();
11929 : 0 : return bce;
11930 : : }
11931 : :
11932 : : // Return the backend representation for a builtin function.
11933 : :
11934 : : Bexpression*
11935 : 164888 : Builtin_call_expression::do_get_backend(Translate_context* context)
11936 : : {
11937 : 164888 : Gogo* gogo = context->gogo();
11938 : 164888 : Location location = this->location();
11939 : :
11940 : 164888 : if (this->is_erroneous_call())
11941 : : {
11942 : 29 : go_assert(saw_errors());
11943 : 29 : return gogo->backend()->error_expression();
11944 : : }
11945 : :
11946 : 164859 : switch (this->code_)
11947 : : {
11948 : 0 : case BUILTIN_INVALID:
11949 : 0 : case BUILTIN_NEW:
11950 : 0 : case BUILTIN_MAKE:
11951 : 0 : case BUILTIN_ADD:
11952 : 0 : case BUILTIN_SLICE:
11953 : 0 : go_unreachable();
11954 : :
11955 : 119501 : case BUILTIN_LEN:
11956 : 119501 : case BUILTIN_CAP:
11957 : 119501 : {
11958 : 119501 : const Expression_list* args = this->args();
11959 : 119501 : go_assert(args != NULL && args->size() == 1);
11960 : 119501 : Expression* arg = args->front();
11961 : 119501 : Type* arg_type = arg->type();
11962 : :
11963 : 119501 : if (this->seen_)
11964 : : {
11965 : 0 : go_assert(saw_errors());
11966 : 0 : return context->backend()->error_expression();
11967 : : }
11968 : 119501 : this->seen_ = true;
11969 : 119501 : this->seen_ = false;
11970 : 119501 : if (arg_type->points_to() != NULL)
11971 : : {
11972 : 6 : arg_type = arg_type->points_to();
11973 : 12 : go_assert(arg_type->array_type() != NULL
11974 : : && !arg_type->is_slice_type());
11975 : 6 : arg = Expression::make_dereference(arg, NIL_CHECK_DEFAULT,
11976 : : location);
11977 : : }
11978 : :
11979 : 119501 : Type* int_type = Type::lookup_integer_type("int");
11980 : 119501 : Expression* val;
11981 : 119501 : if (this->code_ == BUILTIN_LEN)
11982 : : {
11983 : 102918 : if (arg_type->is_string_type())
11984 : 16417 : val = Expression::make_string_info(arg, STRING_INFO_LENGTH,
11985 : : location);
11986 : 86501 : else if (arg_type->array_type() != NULL)
11987 : : {
11988 : 85290 : if (this->seen_)
11989 : : {
11990 : 0 : go_assert(saw_errors());
11991 : 0 : return context->backend()->error_expression();
11992 : : }
11993 : 85290 : this->seen_ = true;
11994 : 170580 : val = arg_type->array_type()->get_length(gogo, arg);
11995 : 85290 : this->seen_ = false;
11996 : : }
11997 : 1244 : else if (arg_type->map_type() != NULL
11998 : 1211 : || arg_type->channel_type() != NULL)
11999 : : {
12000 : : // The first field is the length. If the pointer is
12001 : : // nil, the length is zero.
12002 : 1211 : Type* pint_type = Type::make_pointer_type(int_type);
12003 : 1211 : arg = Expression::make_unsafe_cast(pint_type, arg, location);
12004 : 1211 : Expression* nil = Expression::make_nil(location);
12005 : 1211 : nil = Expression::make_cast(pint_type, nil, location);
12006 : 1211 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
12007 : : arg, nil, location);
12008 : 1211 : Expression* zero = Expression::make_integer_ul(0, int_type,
12009 : : location);
12010 : 1211 : Expression* indir =
12011 : 1211 : Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED,
12012 : : location);
12013 : 1211 : val = Expression::make_conditional(cmp, zero, indir, location);
12014 : : }
12015 : : else
12016 : 0 : go_unreachable();
12017 : : }
12018 : : else
12019 : : {
12020 : 16583 : if (arg_type->array_type() != NULL)
12021 : : {
12022 : 16532 : if (this->seen_)
12023 : : {
12024 : 0 : go_assert(saw_errors());
12025 : 0 : return context->backend()->error_expression();
12026 : : }
12027 : 16532 : this->seen_ = true;
12028 : 33064 : val = arg_type->array_type()->get_capacity(gogo, arg);
12029 : 16532 : this->seen_ = false;
12030 : : }
12031 : 51 : else if (arg_type->channel_type() != NULL)
12032 : : {
12033 : : // The second field is the capacity. If the pointer
12034 : : // is nil, the capacity is zero.
12035 : 51 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
12036 : 51 : Type* pint_type = Type::make_pointer_type(int_type);
12037 : 51 : Expression* parg = Expression::make_unsafe_cast(uintptr_type,
12038 : : arg,
12039 : : location);
12040 : 102 : int off = int_type->integer_type()->bits() / 8;
12041 : 51 : Expression* eoff = Expression::make_integer_ul(off,
12042 : : uintptr_type,
12043 : : location);
12044 : 51 : parg = Expression::make_binary(OPERATOR_PLUS, parg, eoff,
12045 : : location);
12046 : 51 : parg = Expression::make_unsafe_cast(pint_type, parg, location);
12047 : 51 : Expression* nil = Expression::make_nil(location);
12048 : 51 : nil = Expression::make_cast(pint_type, nil, location);
12049 : 51 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
12050 : : arg, nil, location);
12051 : 51 : Expression* zero = Expression::make_integer_ul(0, int_type,
12052 : : location);
12053 : 51 : Expression* indir =
12054 : 51 : Expression::make_dereference(parg, NIL_CHECK_NOT_NEEDED,
12055 : : location);
12056 : 51 : val = Expression::make_conditional(cmp, zero, indir, location);
12057 : : }
12058 : : else
12059 : 0 : go_unreachable();
12060 : : }
12061 : :
12062 : 119501 : Expression* e = Expression::make_cast(int_type, val, location);
12063 : 119501 : e->determine_type_no_context(gogo);
12064 : 119501 : return e->get_backend(context);
12065 : : }
12066 : :
12067 : 15643 : case BUILTIN_PRINT:
12068 : 15643 : case BUILTIN_PRINTLN:
12069 : 15643 : {
12070 : 15643 : const bool is_ln = this->code_ == BUILTIN_PRINTLN;
12071 : :
12072 : 15643 : Expression* print_stmts = Runtime::make_call(gogo, Runtime::PRINTLOCK,
12073 : : location, 0);
12074 : :
12075 : 15643 : const Expression_list* call_args = this->args();
12076 : 15643 : if (call_args != NULL)
12077 : : {
12078 : 15596 : for (Expression_list::const_iterator p = call_args->begin();
12079 : 52179 : p != call_args->end();
12080 : 36583 : ++p)
12081 : : {
12082 : 36583 : if (is_ln && p != call_args->begin())
12083 : : {
12084 : 15284 : Expression* print_space =
12085 : 15284 : Runtime::make_call(gogo, Runtime::PRINTSP, location, 0);
12086 : :
12087 : 15284 : print_stmts =
12088 : 15284 : Expression::make_compound(print_stmts, print_space,
12089 : : location);
12090 : : }
12091 : :
12092 : 36583 : Expression* arg = *p;
12093 : 36583 : Type* type = arg->type();
12094 : 36583 : Runtime::Function code;
12095 : 36583 : if (type->is_string_type())
12096 : : code = Runtime::PRINTSTRING;
12097 : 19704 : else if (type->integer_type() != NULL
12098 : 9466 : && type->integer_type()->is_unsigned())
12099 : : {
12100 : 4454 : Type* itype = Type::lookup_integer_type("uint64");
12101 : 4454 : arg = Expression::make_cast(itype, arg, location);
12102 : 8908 : if (gogo->compiling_runtime()
12103 : 1686 : && type->named_type() != NULL
12104 : 10594 : && gogo->unpack_hidden_name(type->named_type()->name())
12105 : 1686 : == "hex")
12106 : : code = Runtime::PRINTHEX;
12107 : : else
12108 : 3964 : code = Runtime::PRINTUINT;
12109 : : }
12110 : 5784 : else if (type->integer_type() != NULL)
12111 : : {
12112 : 5012 : Type* itype = Type::lookup_integer_type("int64");
12113 : 5012 : arg = Expression::make_cast(itype, arg, location);
12114 : 5012 : code = Runtime::PRINTINT;
12115 : : }
12116 : 772 : else if (type->float_type() != NULL)
12117 : : {
12118 : 220 : Type* dtype = Type::lookup_float_type("float64");
12119 : 220 : arg = Expression::make_cast(dtype, arg, location);
12120 : 220 : code = Runtime::PRINTFLOAT;
12121 : : }
12122 : 552 : else if (type->complex_type() != NULL)
12123 : : {
12124 : 76 : Type* ctype = Type::lookup_complex_type("complex128");
12125 : 76 : arg = Expression::make_cast(ctype, arg, location);
12126 : 76 : code = Runtime::PRINTCOMPLEX;
12127 : : }
12128 : 476 : else if (type->is_boolean_type())
12129 : : code = Runtime::PRINTBOOL;
12130 : 349 : else if (type->points_to() != NULL
12131 : 54 : || type->channel_type() != NULL
12132 : 351 : || type->map_type() != NULL
12133 : 356 : || type->function_type() != NULL)
12134 : : {
12135 : 300 : arg = Expression::make_cast(type, arg, location);
12136 : 300 : code = Runtime::PRINTPOINTER;
12137 : : }
12138 : 49 : else if (type->interface_type() != NULL)
12139 : : {
12140 : 60 : if (type->interface_type()->is_empty())
12141 : : code = Runtime::PRINTEFACE;
12142 : : else
12143 : 4 : code = Runtime::PRINTIFACE;
12144 : : }
12145 : 19 : else if (type->is_slice_type())
12146 : : code = Runtime::PRINTSLICE;
12147 : : else
12148 : : {
12149 : 0 : go_assert(saw_errors());
12150 : 0 : return context->backend()->error_expression();
12151 : : }
12152 : :
12153 : 36583 : Expression* call = Runtime::make_call(gogo, code, location, 1,
12154 : : arg);
12155 : 36583 : print_stmts = Expression::make_compound(print_stmts, call,
12156 : : location);
12157 : : }
12158 : : }
12159 : :
12160 : 15643 : if (is_ln)
12161 : : {
12162 : 13300 : Expression* print_nl =
12163 : 13300 : Runtime::make_call(gogo, Runtime::PRINTNL, location, 0);
12164 : 13300 : print_stmts = Expression::make_compound(print_stmts, print_nl,
12165 : : location);
12166 : : }
12167 : :
12168 : 15643 : Expression* unlock = Runtime::make_call(gogo, Runtime::PRINTUNLOCK,
12169 : : location, 0);
12170 : 15643 : print_stmts = Expression::make_compound(print_stmts, unlock, location);
12171 : :
12172 : 15643 : print_stmts->determine_type_no_context(gogo);
12173 : :
12174 : 15643 : return print_stmts->get_backend(context);
12175 : : }
12176 : :
12177 : 14856 : case BUILTIN_PANIC:
12178 : 14856 : {
12179 : 14856 : const Expression_list* args = this->args();
12180 : 14856 : go_assert(args != NULL && args->size() == 1);
12181 : 14856 : Expression* arg = args->front();
12182 : 14856 : Type *empty =
12183 : 14856 : Type::make_empty_interface_type(Linemap::predeclared_location());
12184 : 14856 : arg = Expression::convert_for_assignment(gogo, empty, arg, location);
12185 : :
12186 : 14856 : Expression* panic =
12187 : 14856 : Runtime::make_call(gogo, Runtime::GOPANIC, location, 1, arg);
12188 : 14856 : panic->determine_type_no_context(gogo);
12189 : 14856 : return panic->get_backend(context);
12190 : : }
12191 : :
12192 : 847 : case BUILTIN_RECOVER:
12193 : 847 : {
12194 : : // The argument is set when building recover thunks. It's a
12195 : : // boolean value which is true if we can recover a value now.
12196 : 847 : const Expression_list* args = this->args();
12197 : 847 : go_assert(args != NULL && args->size() == 1);
12198 : 847 : Expression* arg = args->front();
12199 : 847 : Type *empty =
12200 : 847 : Type::make_empty_interface_type(Linemap::predeclared_location());
12201 : :
12202 : 847 : Expression* nil = Expression::make_nil(location);
12203 : 847 : nil = Expression::make_interface_value(empty, nil, nil, location);
12204 : :
12205 : : // We need to handle a deferred call to recover specially,
12206 : : // because it changes whether it can recover a panic or not.
12207 : : // See test7 in test/recover1.go.
12208 : 847 : Expression* recover = Runtime::make_call(gogo,
12209 : 847 : (this->is_deferred()
12210 : : ? Runtime::DEFERREDRECOVER
12211 : : : Runtime::GORECOVER),
12212 : : location, 0);
12213 : 847 : Expression* cond =
12214 : 847 : Expression::make_conditional(arg, recover, nil, location);
12215 : 847 : cond->determine_type_no_context(gogo);
12216 : 847 : return cond->get_backend(context);
12217 : : }
12218 : :
12219 : 861 : case BUILTIN_CLOSE:
12220 : 861 : {
12221 : 861 : const Expression_list* args = this->args();
12222 : 861 : go_assert(args != NULL && args->size() == 1);
12223 : 861 : Expression* arg = args->front();
12224 : 861 : Expression* close = Runtime::make_call(gogo, Runtime::CLOSE, location,
12225 : : 1, arg);
12226 : 861 : close->determine_type_no_context(gogo);
12227 : 861 : return close->get_backend(context);
12228 : : }
12229 : :
12230 : 0 : case BUILTIN_SIZEOF:
12231 : 0 : case BUILTIN_OFFSETOF:
12232 : 0 : case BUILTIN_ALIGNOF:
12233 : 0 : {
12234 : 0 : Numeric_constant nc;
12235 : 0 : unsigned long val;
12236 : 0 : if (!this->numeric_constant_value(&nc)
12237 : 0 : || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
12238 : : {
12239 : 0 : go_assert(saw_errors());
12240 : 0 : return context->backend()->error_expression();
12241 : : }
12242 : 0 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
12243 : 0 : mpz_t ival;
12244 : 0 : nc.get_int(&ival);
12245 : 0 : Expression* int_cst =
12246 : 0 : Expression::make_integer_z(&ival, uintptr_type, location);
12247 : 0 : mpz_clear(ival);
12248 : 0 : return int_cst->get_backend(context);
12249 : 0 : }
12250 : :
12251 : 0 : case BUILTIN_COPY:
12252 : : // Handled in Builtin_call_expression::do_flatten.
12253 : 0 : go_unreachable();
12254 : :
12255 : 0 : case BUILTIN_APPEND:
12256 : : // Handled in Builtin_call_expression::flatten_append.
12257 : 0 : go_unreachable();
12258 : :
12259 : 986 : case BUILTIN_REAL:
12260 : 986 : case BUILTIN_IMAG:
12261 : 986 : {
12262 : 986 : const Expression_list* args = this->args();
12263 : 986 : go_assert(args != NULL && args->size() == 1);
12264 : :
12265 : 986 : Bexpression* ret;
12266 : 986 : Bexpression* bcomplex = args->front()->get_backend(context);
12267 : 986 : if (this->code_ == BUILTIN_REAL)
12268 : 460 : ret = gogo->backend()->real_part_expression(bcomplex, location);
12269 : : else
12270 : 526 : ret = gogo->backend()->imag_part_expression(bcomplex, location);
12271 : : return ret;
12272 : : }
12273 : :
12274 : 12165 : case BUILTIN_COMPLEX:
12275 : 12165 : {
12276 : 12165 : const Expression_list* args = this->args();
12277 : 12165 : go_assert(args != NULL && args->size() == 2);
12278 : 12165 : Bexpression* breal = args->front()->get_backend(context);
12279 : 12165 : Bexpression* bimag = args->back()->get_backend(context);
12280 : 12165 : return gogo->backend()->complex_expression(breal, bimag, location);
12281 : : }
12282 : :
12283 : 0 : default:
12284 : 0 : go_unreachable();
12285 : : }
12286 : : }
12287 : :
12288 : : // We have to support exporting a builtin call expression, because
12289 : : // code can set a constant to the result of a builtin expression.
12290 : :
12291 : : void
12292 : 4252 : Builtin_call_expression::do_export(Export_function_body* efb) const
12293 : : {
12294 : 4252 : if (this->code_ == BUILTIN_ADD || this->code_ == BUILTIN_SLICE)
12295 : : {
12296 : 0 : char buf[50];
12297 : 0 : snprintf(buf, sizeof buf, "<p%d>%s", efb->unsafe_package_index(),
12298 : : (this->code_ == BUILTIN_ADD ? "Add" : "Slice"));
12299 : 0 : efb->write_c_string(buf);
12300 : 0 : this->export_arguments(efb);
12301 : : }
12302 : : else
12303 : : {
12304 : 4252 : const char *s = NULL;
12305 : 4252 : switch (this->code_)
12306 : : {
12307 : 0 : default:
12308 : 0 : go_unreachable();
12309 : : case BUILTIN_APPEND:
12310 : : s = "append";
12311 : : break;
12312 : 54 : case BUILTIN_COPY:
12313 : 54 : s = "copy";
12314 : 54 : break;
12315 : 3177 : case BUILTIN_LEN:
12316 : 3177 : s = "len";
12317 : 3177 : break;
12318 : 14 : case BUILTIN_CAP:
12319 : 14 : s = "cap";
12320 : 14 : break;
12321 : 24 : case BUILTIN_DELETE:
12322 : 24 : s = "delete";
12323 : 24 : break;
12324 : 13 : case BUILTIN_PRINT:
12325 : 13 : s = "print";
12326 : 13 : break;
12327 : 17 : case BUILTIN_PRINTLN:
12328 : 17 : s = "println";
12329 : 17 : break;
12330 : 519 : case BUILTIN_PANIC:
12331 : 519 : s = "panic";
12332 : 519 : break;
12333 : 13 : case BUILTIN_RECOVER:
12334 : 13 : s = "recover";
12335 : 13 : break;
12336 : 9 : case BUILTIN_CLOSE:
12337 : 9 : s = "close";
12338 : 9 : break;
12339 : 64 : case BUILTIN_REAL:
12340 : 64 : s = "real";
12341 : 64 : break;
12342 : 76 : case BUILTIN_IMAG:
12343 : 76 : s = "imag";
12344 : 76 : break;
12345 : 66 : case BUILTIN_COMPLEX:
12346 : 66 : s = "complex";
12347 : 66 : break;
12348 : : }
12349 : 4252 : efb->write_c_string(s);
12350 : 4252 : this->export_arguments(efb);
12351 : : }
12352 : 4252 : }
12353 : :
12354 : : // Class Call_expression.
12355 : :
12356 : : // A Go function can be viewed in a couple of different ways. The
12357 : : // code of a Go function becomes a backend function with parameters
12358 : : // whose types are simply the backend representation of the Go types.
12359 : : // If there are multiple results, they are returned as a backend
12360 : : // struct.
12361 : :
12362 : : // However, when Go code refers to a function other than simply
12363 : : // calling it, the backend type of that function is actually a struct.
12364 : : // The first field of the struct points to the Go function code
12365 : : // (sometimes a wrapper as described below). The remaining fields
12366 : : // hold addresses of closed-over variables. This struct is called a
12367 : : // closure.
12368 : :
12369 : : // There are a few cases to consider.
12370 : :
12371 : : // A direct function call of a known function in package scope. In
12372 : : // this case there are no closed-over variables, and we know the name
12373 : : // of the function code. We can simply produce a backend call to the
12374 : : // function directly, and not worry about the closure.
12375 : :
12376 : : // A direct function call of a known function literal. In this case
12377 : : // we know the function code and we know the closure. We generate the
12378 : : // function code such that it expects an additional final argument of
12379 : : // the closure type. We pass the closure as the last argument, after
12380 : : // the other arguments.
12381 : :
12382 : : // An indirect function call. In this case we have a closure. We
12383 : : // load the pointer to the function code from the first field of the
12384 : : // closure. We pass the address of the closure as the last argument.
12385 : :
12386 : : // A call to a method of an interface. Type methods are always at
12387 : : // package scope, so we call the function directly, and don't worry
12388 : : // about the closure.
12389 : :
12390 : : // This means that for a function at package scope we have two cases.
12391 : : // One is the direct call, which has no closure. The other is the
12392 : : // indirect call, which does have a closure. We can't simply ignore
12393 : : // the closure, even though it is the last argument, because that will
12394 : : // fail on targets where the function pops its arguments. So when
12395 : : // generating a closure for a package-scope function we set the
12396 : : // function code pointer in the closure to point to a wrapper
12397 : : // function. This wrapper function accepts a final argument that
12398 : : // points to the closure, ignores it, and calls the real function as a
12399 : : // direct function call. This wrapper will normally be efficient, and
12400 : : // can often simply be a tail call to the real function.
12401 : :
12402 : : // We don't use GCC's static chain pointer because 1) we don't need
12403 : : // it; 2) GCC only permits using a static chain to call a known
12404 : : // function, so we can't use it for an indirect call anyhow. Since we
12405 : : // can't use it for an indirect call, we may as well not worry about
12406 : : // using it for a direct call either.
12407 : :
12408 : : // We pass the closure last rather than first because it means that
12409 : : // the function wrapper we put into a closure for a package-scope
12410 : : // function can normally just be a tail call to the real function.
12411 : :
12412 : : // For method expressions we generate a wrapper that loads the
12413 : : // receiver from the closure and then calls the method. This
12414 : : // unfortunately forces reshuffling the arguments, since there is a
12415 : : // new first argument, but we can't avoid reshuffling either for
12416 : : // method expressions or for indirect calls of package-scope
12417 : : // functions, and since the latter are more common we reshuffle for
12418 : : // method expressions.
12419 : :
12420 : : // Note that the Go code retains the Go types. The extra final
12421 : : // argument only appears when we convert to the backend
12422 : : // representation.
12423 : :
12424 : : // Traversal.
12425 : :
12426 : : int
12427 : 17227699 : Call_expression::do_traverse(Traverse* traverse)
12428 : : {
12429 : 17227699 : if (this->lowered_ != NULL)
12430 : 347105 : return Expression::traverse(&this->lowered_, traverse);
12431 : :
12432 : : // If we are calling a function in a different package that returns
12433 : : // an unnamed type, this may be the only chance we get to traverse
12434 : : // that type. We don't traverse this->type_ because it may be a
12435 : : // Call_multiple_result_type that will just lead back here.
12436 : 16880594 : if (this->type_ != NULL && !this->type_->is_error_type())
12437 : : {
12438 : 12522009 : Function_type *fntype = this->get_function_type();
12439 : 12522009 : if (fntype != NULL && Type::traverse(fntype, traverse) == TRAVERSE_EXIT)
12440 : : return TRAVERSE_EXIT;
12441 : : }
12442 : 16878454 : if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT)
12443 : : return TRAVERSE_EXIT;
12444 : 16279672 : if (this->args_ != NULL)
12445 : : {
12446 : 14758114 : if (this->args_->traverse(traverse) == TRAVERSE_EXIT)
12447 : : return TRAVERSE_EXIT;
12448 : : }
12449 : : return TRAVERSE_CONTINUE;
12450 : : }
12451 : :
12452 : : // Lower a Call_expression to a Builtin_call_expression. This happens
12453 : : // early on, before determine_types.
12454 : :
12455 : : Expression*
12456 : 3894136 : Call_expression::lower_builtin(Gogo* gogo)
12457 : : {
12458 : : // This is called before determine_types, so we can't call
12459 : : // this->fn_->type(). Fortunately builtin calls require a direct
12460 : : // reference to the builtin.
12461 : 3894136 : Expression* fn = this->fn_;
12462 : 3894136 : Named_object* no;
12463 : 3894136 : if (fn->func_expression() != NULL)
12464 : 2459179 : no = fn->func_expression()->named_object();
12465 : 1434957 : else if (fn->unknown_expression() != NULL)
12466 : : {
12467 : 446120 : no = fn->unknown_expression()->named_object();
12468 : 446120 : if (no->is_unknown())
12469 : : {
12470 : 446120 : no = no->unknown_value()->real_named_object();
12471 : 446120 : if (no == NULL)
12472 : 10 : return this;
12473 : : }
12474 : : }
12475 : : else
12476 : 988837 : return this;
12477 : :
12478 : 2905289 : if (!no->is_function_declaration())
12479 : 854569 : return this;
12480 : 2050720 : if (!no->func_declaration_value()->type()->is_builtin())
12481 : 1809950 : return this;
12482 : :
12483 : 240770 : if (fn->unknown_expression() != NULL)
12484 : 143737 : fn = Expression::make_func_reference(no, NULL, fn->location());
12485 : :
12486 : 240770 : Builtin_call_expression* bce = new Builtin_call_expression(gogo, fn,
12487 : : this->args_,
12488 : 240770 : this->is_varargs_,
12489 : 240770 : this->location());
12490 : 240770 : if (this->is_deferred_)
12491 : 344 : bce->set_is_deferred();
12492 : 240770 : if (this->is_concurrent_)
12493 : 27 : bce->set_is_concurrent();
12494 : : return bce;
12495 : : }
12496 : :
12497 : : // A type conversion can be a constant.
12498 : :
12499 : : bool
12500 : 177872 : Call_expression::do_is_constant() const
12501 : : {
12502 : 177872 : if (this->lowered_ != NULL)
12503 : 635 : return this->lowered_->is_constant();
12504 : 177237 : if (this->fn_->is_type_expression()
12505 : 40307 : && this->args_ != NULL
12506 : 217544 : && this->args_->size() == 1)
12507 : 40307 : return this->args_->front()->is_constant();
12508 : : return false;
12509 : : }
12510 : :
12511 : : bool
12512 : 172489 : Call_expression::do_is_untyped(Type** ptype) const
12513 : : {
12514 : 172489 : if (this->lowered_ != NULL)
12515 : 2 : return this->lowered_->is_untyped(ptype);
12516 : : return false;
12517 : : }
12518 : :
12519 : : bool
12520 : 132121 : Call_expression::do_numeric_constant_value(Numeric_constant* nc)
12521 : : {
12522 : 132121 : if (this->lowered_ != NULL)
12523 : 10307 : return this->lowered_->numeric_constant_value(nc);
12524 : 121814 : if (this->fn_->is_type_expression()
12525 : 34 : && this->args_ != NULL
12526 : 121848 : && this->args_->size() == 1)
12527 : : {
12528 : : // If we get here, it's before the determine_types pass, so we
12529 : : // have to pull apart the type carefully. This is a hack that
12530 : : // is needed because the finalize_methods needs to be able to
12531 : : // determine whether the length of an array is 1.
12532 : :
12533 : 34 : Type* type;
12534 : 34 : if (this->fn_->classification() == EXPRESSION_TYPE)
12535 : 0 : type = this->fn_->type();
12536 : 121815 : else if (this->fn_->unknown_expression() != NULL)
12537 : : {
12538 : 34 : Named_object* no = this->fn_->unknown_expression()->named_object();
12539 : 34 : if (no->is_unknown())
12540 : : {
12541 : 34 : no = no->unknown_value()->real_named_object();
12542 : 34 : go_assert(no != NULL);
12543 : : }
12544 : 34 : type = no->type_value();
12545 : : }
12546 : : else
12547 : : return false;
12548 : :
12549 : 34 : if (!type->is_numeric_type())
12550 : : return false;
12551 : 34 : if (!this->args_->front()->numeric_constant_value(nc))
12552 : : return false;
12553 : 33 : return nc->set_type(type, false, this->location());
12554 : : }
12555 : : return false;
12556 : : }
12557 : :
12558 : : bool
12559 : 243404 : Call_expression::do_discarding_value()
12560 : : {
12561 : 243404 : if (this->fn_->is_type_expression())
12562 : : {
12563 : 4 : this->unused_value_error();
12564 : 4 : return false;
12565 : : }
12566 : : return true;
12567 : : }
12568 : :
12569 : : // Lower a call statement.
12570 : :
12571 : : Expression*
12572 : 1493150 : Call_expression::do_lower(Gogo* gogo, Named_object*,
12573 : : Statement_inserter* inserter)
12574 : : {
12575 : 1493150 : if (this->lowered_ != NULL)
12576 : : return this->lowered_;
12577 : :
12578 : 1327899 : Location loc = this->location();
12579 : :
12580 : 1327899 : if (this->is_error_expression())
12581 : 96 : return Expression::make_error(loc);
12582 : :
12583 : : // Although we've already lowered calls to builtin functions, we may
12584 : : // still see calls generated to builtins elsewhere in the lowering
12585 : : // pass. It's simpler to handle them here.
12586 : 1327803 : Expression* builtin = this->lower_builtin(gogo);
12587 : 1327803 : if (builtin != this)
12588 : : return builtin;
12589 : :
12590 : : // If this call returns multiple results, create a temporary
12591 : : // variable to hold them.
12592 : 1308193 : if (this->result_count() > 1 && this->call_temp_ == NULL)
12593 : : {
12594 : 93382 : Struct_field_list* sfl = new Struct_field_list();
12595 : 93382 : const Typed_identifier_list* results =
12596 : 93382 : this->get_function_type()->results();
12597 : :
12598 : 93382 : int i = 0;
12599 : 93382 : char buf[20];
12600 : 93382 : for (Typed_identifier_list::const_iterator p = results->begin();
12601 : 290003 : p != results->end();
12602 : 196621 : ++p, ++i)
12603 : : {
12604 : 196621 : snprintf(buf, sizeof buf, "res%d", i);
12605 : 196621 : sfl->push_back(Struct_field(Typed_identifier(buf, p->type(), loc)));
12606 : : }
12607 : :
12608 : 93382 : Struct_type* st = Type::make_struct_type(sfl, loc);
12609 : 93382 : st->set_is_struct_incomparable();
12610 : 93382 : st->set_is_results_struct();
12611 : 93382 : this->call_temp_ = Statement::make_temporary(st, NULL, loc);
12612 : 93382 : inserter->insert(this->call_temp_);
12613 : : }
12614 : :
12615 : : // If this is call to a method, call the method directly passing the
12616 : : // object as the first parameter.
12617 : 1308193 : Bound_method_expression* bme = this->fn_->bound_method_expression();
12618 : 264234 : if (bme != NULL && !this->is_deferred_ && !this->is_concurrent_)
12619 : : {
12620 : 258280 : Named_object* methodfn = bme->function();
12621 : 258280 : Function_type* mft = (methodfn->is_function()
12622 : 258280 : ? methodfn->func_value()->type()
12623 : 123936 : : methodfn->func_declaration_value()->type());
12624 : 258280 : Expression* first_arg = bme->first_argument();
12625 : :
12626 : : // We always pass a pointer when calling a method, except for
12627 : : // direct interface types when calling a value method.
12628 : 258280 : if (!first_arg->type()->is_error()
12629 : 258279 : && first_arg->type()->points_to() == NULL
12630 : 298190 : && !first_arg->type()->is_direct_iface_type())
12631 : : {
12632 : 35412 : first_arg = Expression::make_unary(OPERATOR_AND, first_arg, loc);
12633 : : // We may need to create a temporary variable so that we can
12634 : : // take the address. We can't do that here because it will
12635 : : // mess up the order of evaluation.
12636 : 35412 : Unary_expression* ue = static_cast<Unary_expression*>(first_arg);
12637 : 35412 : ue->set_create_temp();
12638 : : }
12639 : 222868 : else if (mft->receiver()->type()->points_to() == NULL
12640 : 6612 : && first_arg->type()->points_to() != NULL
12641 : 224981 : && first_arg->type()->points_to()->is_direct_iface_type())
12642 : 45 : first_arg = Expression::make_dereference(first_arg,
12643 : : Expression::NIL_CHECK_DEFAULT,
12644 : : loc);
12645 : :
12646 : : // If we are calling a method which was inherited from an
12647 : : // embedded struct, and the method did not get a stub, then the
12648 : : // first type may be wrong.
12649 : 258280 : Type* fatype = bme->first_argument_type();
12650 : 258280 : if (fatype != NULL)
12651 : : {
12652 : 0 : if (fatype->points_to() == NULL)
12653 : 0 : fatype = Type::make_pointer_type(fatype);
12654 : 0 : first_arg = Expression::make_unsafe_cast(fatype, first_arg, loc);
12655 : : }
12656 : :
12657 : 258280 : first_arg->determine_type_no_context(gogo);
12658 : 258280 : first_arg->check_types(gogo);
12659 : :
12660 : 258280 : Expression_list* new_args = new Expression_list();
12661 : 258280 : new_args->push_back(first_arg);
12662 : 258280 : if (this->args_ != NULL)
12663 : : {
12664 : 156432 : for (Expression_list::const_iterator p = this->args_->begin();
12665 : 405779 : p != this->args_->end();
12666 : 249347 : ++p)
12667 : 249347 : new_args->push_back(*p);
12668 : : }
12669 : :
12670 : : // We have to change in place because this structure may be
12671 : : // referenced by Call_result_expressions. We can't delete the
12672 : : // old arguments, because we may be traversing them up in some
12673 : : // caller. FIXME.
12674 : 258280 : this->args_ = new_args;
12675 : 258280 : this->fn_ = Expression::make_func_reference(methodfn, NULL,
12676 : : bme->location());
12677 : : }
12678 : :
12679 : : // If this is a call to an imported function for which we have an
12680 : : // inlinable function body, add it to the list of functions to give
12681 : : // to the backend as inlining opportunities.
12682 : 1308193 : Func_expression* fe = this->fn_->func_expression();
12683 : 1199685 : if (fe != NULL
12684 : 1199685 : && fe->named_object()->is_function_declaration()
12685 : 718979 : && fe->named_object()->func_declaration_value()->has_imported_body())
12686 : 82297 : gogo->add_imported_inlinable_function(fe->named_object());
12687 : :
12688 : : return this;
12689 : : }
12690 : :
12691 : : // Flatten a call with multiple results into a temporary.
12692 : :
12693 : : Expression*
12694 : 1038869 : Call_expression::do_flatten(Gogo* gogo, Named_object*,
12695 : : Statement_inserter* inserter)
12696 : : {
12697 : 1038869 : if (this->is_erroneous_call())
12698 : : {
12699 : 3209 : go_assert(saw_errors());
12700 : 3209 : return Expression::make_error(this->location());
12701 : : }
12702 : :
12703 : 1035660 : if (this->is_flattened_)
12704 : 153795 : return this;
12705 : 881865 : this->is_flattened_ = true;
12706 : :
12707 : : // Add temporary variables for all arguments that require type
12708 : : // conversion.
12709 : 881865 : Function_type* fntype = this->get_function_type();
12710 : 881865 : if (fntype == NULL)
12711 : : {
12712 : 0 : go_assert(saw_errors());
12713 : 0 : return this;
12714 : : }
12715 : 829116 : if (this->args_ != NULL && !this->args_->empty()
12716 : 1702774 : && fntype->parameters() != NULL && !fntype->parameters()->empty())
12717 : : {
12718 : 719560 : bool is_interface_method =
12719 : 719560 : this->fn_->interface_field_reference_expression() != NULL;
12720 : :
12721 : 719560 : Expression_list *args = new Expression_list();
12722 : 719560 : Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
12723 : 719560 : Expression_list::const_iterator pa = this->args_->begin();
12724 : 719560 : if (!is_interface_method && fntype->is_method())
12725 : : {
12726 : : // The receiver argument.
12727 : 155666 : args->push_back(*pa);
12728 : 155666 : ++pa;
12729 : : }
12730 : 2247030 : for (; pa != this->args_->end(); ++pa, ++pp)
12731 : : {
12732 : 1527470 : go_assert(pp != fntype->parameters()->end());
12733 : 1527470 : if (Type::are_identical(pp->type(), (*pa)->type(),
12734 : : Type::COMPARE_TAGS, NULL))
12735 : 1511346 : args->push_back(*pa);
12736 : : else
12737 : : {
12738 : 16124 : Location loc = (*pa)->location();
12739 : 16124 : Expression* arg = *pa;
12740 : 16124 : if (!arg->is_multi_eval_safe())
12741 : : {
12742 : 14979 : Temporary_statement *temp =
12743 : 14979 : Statement::make_temporary(NULL, arg, loc);
12744 : 14979 : inserter->insert(temp);
12745 : 14979 : arg = Expression::make_temporary_reference(temp, loc);
12746 : : }
12747 : 16124 : arg = Expression::convert_for_assignment(gogo, pp->type(), arg,
12748 : : loc);
12749 : 16124 : args->push_back(arg);
12750 : : }
12751 : : }
12752 : 719560 : delete this->args_;
12753 : 719560 : this->args_ = args;
12754 : : }
12755 : :
12756 : : // Lower to compiler intrinsic if possible.
12757 : 881865 : Func_expression* fe = this->fn_->func_expression();
12758 : 879368 : if (!this->is_concurrent_ && !this->is_deferred_
12759 : 870843 : && fe != NULL
12760 : 1702231 : && (fe->named_object()->is_function_declaration()
12761 : 345640 : || fe->named_object()->is_function()))
12762 : : {
12763 : 820366 : Expression* ret = this->intrinsify(gogo, inserter);
12764 : 820366 : if (ret != NULL)
12765 : : {
12766 : 6161 : ret->determine_type_no_context(gogo);
12767 : 6161 : return ret;
12768 : : }
12769 : : }
12770 : :
12771 : : // Add an implicit conversion to a boolean type, if needed. See the
12772 : : // comment in Binary_expression::lower_array_comparison.
12773 : 875704 : if (this->is_equal_function_
12774 : 961 : && this->type_ != NULL
12775 : 876665 : && this->type_ != Type::lookup_bool_type())
12776 : 0 : return Expression::make_cast(this->type_, this, this->location());
12777 : :
12778 : 875704 : return this;
12779 : : }
12780 : :
12781 : : // Lower a call to a compiler intrinsic if possible.
12782 : : // Returns NULL if it is not an intrinsic.
12783 : :
12784 : : Expression*
12785 : 820366 : Call_expression::intrinsify(Gogo* gogo,
12786 : : Statement_inserter* inserter)
12787 : : {
12788 : 820366 : Func_expression* fe = this->fn_->func_expression();
12789 : 820366 : Named_object* no = fe->named_object();
12790 : 820366 : std::string name = Gogo::unpack_hidden_name(no->name());
12791 : 820366 : std::string package = (no->package() != NULL
12792 : 264844 : ? no->package()->pkgpath()
12793 : 1085210 : : gogo->pkgpath());
12794 : 820366 : bool is_method = ((no->is_function() && no->func_value()->is_method())
12795 : 1030902 : || (no->is_function_declaration()
12796 : 474726 : && no->func_declaration_value()->is_method()));
12797 : 820366 : Location loc = this->location();
12798 : :
12799 : 820366 : Type* int_type = Type::lookup_integer_type("int");
12800 : 820366 : Type* int32_type = Type::lookup_integer_type("int32");
12801 : 820366 : Type* int64_type = Type::lookup_integer_type("int64");
12802 : 820366 : Type* uint_type = Type::lookup_integer_type("uint");
12803 : 820366 : Type* uint8_type = Type::lookup_integer_type("uint8");
12804 : 820366 : Type* uint32_type = Type::lookup_integer_type("uint32");
12805 : 820366 : Type* uint64_type = Type::lookup_integer_type("uint64");
12806 : 820366 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
12807 : 820366 : Type* pointer_type = Type::make_pointer_type(Type::make_void_type());
12808 : :
12809 : 1640732 : int int_size = int_type->named_type()->real_type()->integer_type()->bits() / 8;
12810 : 1640732 : int ptr_size = uintptr_type->named_type()->real_type()->integer_type()->bits() / 8;
12811 : :
12812 : 820366 : if (package == "sync/atomic")
12813 : : {
12814 : 2095 : if (is_method)
12815 : : return NULL;
12816 : :
12817 : : // sync/atomic functions and runtime/internal/atomic functions
12818 : : // are very similar. In order not to duplicate code, we just
12819 : : // redirect to the latter and let the code below to handle them.
12820 : : // Note: no StorePointer, SwapPointer, and CompareAndSwapPointer,
12821 : : // as they need write barriers.
12822 : 1717 : if (name == "LoadInt32")
12823 : 201 : name = "Loadint32";
12824 : 1516 : else if (name == "LoadInt64")
12825 : 39 : name = "Loadint64";
12826 : 1477 : else if (name == "LoadUint32")
12827 : 147 : name = "Load";
12828 : 1330 : else if (name == "LoadUint64")
12829 : 104 : name = "Load64";
12830 : 1226 : else if (name == "LoadUintptr")
12831 : 16 : name = "Loaduintptr";
12832 : 1210 : else if (name == "LoadPointer")
12833 : 102 : name = "Loadp";
12834 : 1108 : else if (name == "StoreInt32")
12835 : 125 : name = "Storeint32";
12836 : 983 : else if (name == "StoreInt64")
12837 : 20 : name = "Storeint64";
12838 : 963 : else if (name == "StoreUint32")
12839 : 111 : name = "Store";
12840 : 852 : else if (name == "StoreUint64")
12841 : 25 : name = "Store64";
12842 : 827 : else if (name == "StoreUintptr")
12843 : 12 : name = "Storeuintptr";
12844 : 815 : else if (name == "AddInt32")
12845 : 161 : name = "Xaddint32";
12846 : 654 : else if (name == "AddInt64")
12847 : 40 : name = "Xaddint64";
12848 : 614 : else if (name == "AddUint32")
12849 : 52 : name = "Xadd";
12850 : 562 : else if (name == "AddUint64")
12851 : 57 : name = "Xadd64";
12852 : 505 : else if (name == "AddUintptr")
12853 : 14 : name = "Xadduintptr";
12854 : 491 : else if (name == "SwapInt32")
12855 : 6 : name = "Xchgint32";
12856 : 485 : else if (name == "SwapInt64")
12857 : 6 : name = "Xchgint64";
12858 : 479 : else if (name == "SwapUint32")
12859 : 7 : name = "Xchg";
12860 : 472 : else if (name == "SwapUint64")
12861 : 6 : name = "Xchg64";
12862 : 466 : else if (name == "SwapUintptr")
12863 : 7 : name = "Xchguintptr";
12864 : 459 : else if (name == "CompareAndSwapInt32")
12865 : 101 : name = "Casint32";
12866 : 358 : else if (name == "CompareAndSwapInt64")
12867 : 8 : name = "Casint64";
12868 : 350 : else if (name == "CompareAndSwapUint32")
12869 : 21 : name = "Cas";
12870 : 329 : else if (name == "CompareAndSwapUint64")
12871 : 60 : name = "Cas64";
12872 : 269 : else if (name == "CompareAndSwapUintptr")
12873 : 16 : name = "Casuintptr";
12874 : : else
12875 : : return NULL;
12876 : :
12877 : 1464 : package = "runtime/internal/atomic";
12878 : : }
12879 : :
12880 : 819735 : if (package == "runtime/internal/sys")
12881 : : {
12882 : 308 : if (is_method)
12883 : : return NULL;
12884 : :
12885 : : // runtime/internal/sys functions and math/bits functions
12886 : : // are very similar. In order not to duplicate code, we just
12887 : : // redirect to the latter and let the code below to handle them.
12888 : 308 : if (name == "Bswap32")
12889 : 2 : name = "ReverseBytes32";
12890 : 306 : else if (name == "Bswap64")
12891 : 2 : name = "ReverseBytes64";
12892 : 304 : else if (name == "Ctz32")
12893 : 5 : name = "TrailingZeros32";
12894 : 299 : else if (name == "Ctz64")
12895 : 27 : name = "TrailingZeros64";
12896 : : else
12897 : : return NULL;
12898 : :
12899 : 36 : package = "math/bits";
12900 : : }
12901 : :
12902 : 819463 : if (package == "runtime")
12903 : : {
12904 : 72984 : if (is_method)
12905 : : return NULL;
12906 : :
12907 : : // Handle a couple of special runtime functions. In the runtime
12908 : : // package, getcallerpc returns the PC of the caller, and
12909 : : // getcallersp returns the frame pointer of the caller. Implement
12910 : : // these by turning them into calls to GCC builtin functions. We
12911 : : // could implement them in normal code, but then we would have to
12912 : : // explicitly unwind the stack. These functions are intended to be
12913 : : // efficient. Note that this technique obviously only works for
12914 : : // direct calls, but that is the only way they are used.
12915 : 50898 : if (name == "getcallerpc"
12916 : 50898 : && (this->args_ == NULL || this->args_->size() == 0))
12917 : : {
12918 : 216 : Expression* arg = Expression::make_integer_ul(0, uint32_type, loc);
12919 : 216 : Expression* call =
12920 : 216 : Runtime::make_call(gogo, Runtime::BUILTIN_RETURN_ADDRESS, loc,
12921 : : 1, arg);
12922 : : // The builtin functions return void*, but the Go functions return uintptr.
12923 : 216 : return Expression::make_cast(uintptr_type, call, loc);
12924 : : }
12925 : 50682 : else if (name == "getcallersp"
12926 : 50682 : && (this->args_ == NULL || this->args_->size() == 0))
12927 : :
12928 : : {
12929 : 28 : Expression* call =
12930 : 28 : Runtime::make_call(gogo, Runtime::BUILTIN_DWARF_CFA, loc, 0);
12931 : : // The builtin functions return void*, but the Go functions return uintptr.
12932 : 28 : return Expression::make_cast(uintptr_type, call, loc);
12933 : : }
12934 : : }
12935 : 746479 : else if (package == "math/bits")
12936 : : {
12937 : 12928 : if (is_method)
12938 : : return NULL;
12939 : :
12940 : 12922 : if ((name == "ReverseBytes16" || name == "ReverseBytes32"
12941 : 12902 : || name == "ReverseBytes64" || name == "ReverseBytes")
12942 : 12988 : && this->args_ != NULL && this->args_->size() == 1)
12943 : : {
12944 : 66 : Runtime::Function code;
12945 : 66 : if (name == "ReverseBytes16")
12946 : : code = Runtime::BUILTIN_BSWAP16;
12947 : 60 : else if (name == "ReverseBytes32")
12948 : : code = Runtime::BUILTIN_BSWAP32;
12949 : 40 : else if (name == "ReverseBytes64")
12950 : : code = Runtime::BUILTIN_BSWAP64;
12951 : 4 : else if (name == "ReverseBytes")
12952 : 4 : code = (int_size == 8 ? Runtime::BUILTIN_BSWAP64 : Runtime::BUILTIN_BSWAP32);
12953 : : else
12954 : 0 : go_unreachable();
12955 : 66 : Expression* arg = this->args_->front();
12956 : 66 : Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
12957 : 66 : if (name == "ReverseBytes")
12958 : 4 : return Expression::make_cast(uint_type, call, loc);
12959 : : return call;
12960 : : }
12961 : 12856 : else if ((name == "TrailingZeros8" || name == "TrailingZeros16")
12962 : 12868 : && this->args_ != NULL && this->args_->size() == 1)
12963 : : {
12964 : : // GCC does not have a ctz8 or ctz16 intrinsic. We do
12965 : : // ctz32(0x100 | arg) or ctz32(0x10000 | arg).
12966 : 12 : Expression* arg = this->args_->front();
12967 : 12 : arg = Expression::make_cast(uint32_type, arg, loc);
12968 : 12 : unsigned long mask = (name == "TrailingZeros8" ? 0x100 : 0x10000);
12969 : 12 : Expression* c = Expression::make_integer_ul(mask, uint32_type, loc);
12970 : 12 : arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
12971 : 12 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
12972 : : loc, 1, arg);
12973 : 12 : return Expression::make_cast(int_type, call, loc);
12974 : : }
12975 : 12850 : else if ((name == "TrailingZeros32"
12976 : 12823 : || (name == "TrailingZeros" && int_size == 4))
12977 : 12861 : && this->args_ != NULL && this->args_->size() == 1)
12978 : : {
12979 : 38 : Expression* arg = this->args_->front();
12980 : 38 : if (!arg->is_multi_eval_safe())
12981 : : {
12982 : 28 : Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
12983 : 28 : inserter->insert(ts);
12984 : 28 : arg = Expression::make_temporary_reference(ts, loc);
12985 : : }
12986 : : // arg == 0 ? 32 : __builtin_ctz(arg)
12987 : 38 : Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
12988 : 38 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
12989 : 38 : Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
12990 : 38 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
12991 : : loc, 1, arg->copy());
12992 : 38 : call = Expression::make_cast(int_type, call, loc);
12993 : 38 : return Expression::make_conditional(cmp, c32, call, loc);
12994 : : }
12995 : 12812 : else if ((name == "TrailingZeros64"
12996 : 12747 : || (name == "TrailingZeros" && int_size == 8))
12997 : 12823 : && this->args_ != NULL && this->args_->size() == 1)
12998 : : {
12999 : 76 : Expression* arg = this->args_->front();
13000 : 76 : if (!arg->is_multi_eval_safe())
13001 : : {
13002 : 52 : Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
13003 : 52 : inserter->insert(ts);
13004 : 52 : arg = Expression::make_temporary_reference(ts, loc);
13005 : : }
13006 : : // arg == 0 ? 64 : __builtin_ctzll(arg)
13007 : 76 : Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
13008 : 76 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
13009 : 76 : Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
13010 : 76 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZLL,
13011 : : loc, 1, arg->copy());
13012 : 76 : call = Expression::make_cast(int_type, call, loc);
13013 : 76 : return Expression::make_conditional(cmp, c64, call, loc);
13014 : : }
13015 : 12730 : else if ((name == "LeadingZeros8" || name == "LeadingZeros16"
13016 : 12724 : || name == "Len8" || name == "Len16")
13017 : 12766 : && this->args_ != NULL && this->args_->size() == 1)
13018 : : {
13019 : : // GCC does not have a clz8 ir clz16 intrinsic. We do
13020 : : // clz32(arg<<24 | 0xffffff) or clz32(arg<<16 | 0xffff).
13021 : 36 : Expression* arg = this->args_->front();
13022 : 36 : arg = Expression::make_cast(uint32_type, arg, loc);
13023 : 36 : unsigned long shift =
13024 : 36 : ((name == "LeadingZeros8" || name == "Len8") ? 24 : 16);
13025 : 36 : Expression* c = Expression::make_integer_ul(shift, uint32_type, loc);
13026 : 36 : arg = Expression::make_binary(OPERATOR_LSHIFT, arg, c, loc);
13027 : 36 : unsigned long mask =
13028 : 36 : ((name == "LeadingZeros8" || name == "Len8") ? 0xffffff : 0xffff);
13029 : 36 : c = Expression::make_integer_ul(mask, uint32_type, loc);
13030 : 36 : arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
13031 : 36 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
13032 : : loc, 1, arg);
13033 : 36 : call = Expression::make_cast(int_type, call, loc);
13034 : : // len = width - clz
13035 : 36 : if (name == "Len8")
13036 : : {
13037 : 12 : c = Expression::make_integer_ul(8, int_type, loc);
13038 : 12 : return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
13039 : : }
13040 : 24 : else if (name == "Len16")
13041 : : {
13042 : 12 : c = Expression::make_integer_ul(16, int_type, loc);
13043 : 12 : return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
13044 : : }
13045 : : return call;
13046 : : }
13047 : 12694 : else if ((name == "LeadingZeros32" || name == "Len32"
13048 : 12669 : || ((name == "LeadingZeros" || name == "Len") && int_size == 4))
13049 : 12745 : && this->args_ != NULL && this->args_->size() == 1)
13050 : : {
13051 : 51 : Expression* arg = this->args_->front();
13052 : 51 : if (!arg->is_multi_eval_safe())
13053 : : {
13054 : 26 : Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
13055 : 26 : inserter->insert(ts);
13056 : 26 : arg = Expression::make_temporary_reference(ts, loc);
13057 : : }
13058 : : // arg == 0 ? 32 : __builtin_clz(arg)
13059 : 51 : Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
13060 : 51 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
13061 : 51 : Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
13062 : 51 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
13063 : : loc, 1, arg->copy());
13064 : 51 : call = Expression::make_cast(int_type, call, loc);
13065 : 51 : Expression* cond = Expression::make_conditional(cmp, c32, call, loc);
13066 : : // len = 32 - clz
13067 : 51 : if (name == "Len32" || name == "Len")
13068 : 40 : return Expression::make_binary(OPERATOR_MINUS, c32->copy(), cond, loc);
13069 : : return cond;
13070 : : }
13071 : 12569 : else if ((name == "LeadingZeros64" || name == "Len64"
13072 : 12485 : || ((name == "LeadingZeros" || name == "Len") && int_size == 8))
13073 : 12753 : && this->args_ != NULL && this->args_->size() == 1)
13074 : : {
13075 : 184 : Expression* arg = this->args_->front();
13076 : 184 : if (!arg->is_multi_eval_safe())
13077 : : {
13078 : 51 : Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
13079 : 51 : inserter->insert(ts);
13080 : 51 : arg = Expression::make_temporary_reference(ts, loc);
13081 : : }
13082 : : // arg == 0 ? 64 : __builtin_clzll(arg)
13083 : 184 : Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
13084 : 184 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
13085 : 184 : Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
13086 : 184 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZLL,
13087 : : loc, 1, arg->copy());
13088 : 184 : call = Expression::make_cast(int_type, call, loc);
13089 : 184 : Expression* cond = Expression::make_conditional(cmp, c64, call, loc);
13090 : : // len = 64 - clz
13091 : 184 : if (name == "Len64" || name == "Len")
13092 : 99 : return Expression::make_binary(OPERATOR_MINUS, c64->copy(), cond, loc);
13093 : : return cond;
13094 : : }
13095 : 12441 : else if ((name == "OnesCount8" || name == "OnesCount16"
13096 : 12435 : || name == "OnesCount32" || name == "OnesCount64"
13097 : 12411 : || name == "OnesCount")
13098 : 12501 : && this->args_ != NULL && this->args_->size() == 1)
13099 : : {
13100 : 60 : Runtime::Function code;
13101 : 60 : if (name == "OnesCount64")
13102 : : code = Runtime::BUILTIN_POPCOUNTLL;
13103 : 46 : else if (name == "OnesCount")
13104 : 6 : code = (int_size == 8 ? Runtime::BUILTIN_POPCOUNTLL : Runtime::BUILTIN_POPCOUNT);
13105 : : else
13106 : : code = Runtime::BUILTIN_POPCOUNT;
13107 : 60 : Expression* arg = this->args_->front();
13108 : 60 : Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
13109 : 60 : return Expression::make_cast(int_type, call, loc);
13110 : : }
13111 : : }
13112 : 733551 : else if (package == "runtime/internal/atomic")
13113 : : {
13114 : 6502 : int memorder = __ATOMIC_SEQ_CST;
13115 : :
13116 : 6502 : if (is_method)
13117 : : {
13118 : 580 : Function_type* ftype = (no->is_function()
13119 : 580 : ? no->func_value()->type()
13120 : 568 : : no->func_declaration_value()->type());
13121 : 580 : Type* rtype = ftype->receiver()->type()->deref();
13122 : 580 : go_assert(rtype->named_type() != NULL);
13123 : 580 : const std::string& rname(rtype->named_type()->name());
13124 : 580 : if (rname == "Int32")
13125 : : {
13126 : 42 : if (name == "Load")
13127 : 35 : name = "LoadInt32";
13128 : 7 : else if (name == "Store")
13129 : 7 : name = "Storeint32";
13130 : 0 : else if (name == "CompareAndSwap")
13131 : 0 : name = "Casint32";
13132 : 0 : else if (name == "Swap")
13133 : 0 : name = "Xchgint32";
13134 : 0 : else if (name == "Add")
13135 : 0 : name = "Xaddint32";
13136 : : else
13137 : 0 : go_unreachable();
13138 : : }
13139 : 538 : else if (rname == "Int64")
13140 : : {
13141 : 100 : if (name == "Load")
13142 : 42 : name = "LoadInt64";
13143 : 58 : else if (name == "Store")
13144 : 21 : name = "Storeint64";
13145 : 37 : else if (name == "CompareAndSwap")
13146 : 0 : name = "Casint64";
13147 : 37 : else if (name == "Swap")
13148 : 0 : name = "Xchgint64";
13149 : 37 : else if (name == "Add")
13150 : 37 : name = "Xaddint64";
13151 : : else
13152 : 0 : go_unreachable();
13153 : : }
13154 : 438 : else if (rname == "Uint8")
13155 : : {
13156 : 0 : if (name == "Load")
13157 : 0 : name = "Load8";
13158 : 0 : else if (name == "Store")
13159 : 0 : name = "Store8";
13160 : 0 : else if (name == "And")
13161 : 0 : name = "And8";
13162 : 0 : else if (name == "Or")
13163 : 0 : name = "Or8";
13164 : : else
13165 : 0 : go_unreachable();
13166 : : }
13167 : 438 : else if (rname == "Uint32")
13168 : : {
13169 : 119 : if (name == "Load")
13170 : 70 : name = "Load";
13171 : 49 : else if (name == "LoadAcquire")
13172 : 0 : name = "LoadAcq";
13173 : 49 : else if (name == "Store")
13174 : 14 : name = "Store";
13175 : 35 : else if (name == "CompareAndSwap")
13176 : 35 : name = "Cas";
13177 : 0 : else if (name == "CompareAndSwapRelease")
13178 : 0 : name = "CasRel";
13179 : 0 : else if (name == "Swap")
13180 : 0 : name = "Xchg";
13181 : 0 : else if (name == "And")
13182 : 0 : name = "And";
13183 : 0 : else if (name == "Or")
13184 : 0 : name = "Or";
13185 : 0 : else if (name == "Add")
13186 : 0 : name = "Xadd";
13187 : : else
13188 : 0 : go_unreachable();
13189 : : }
13190 : 319 : else if (rname == "Uint64")
13191 : : {
13192 : 120 : if (name == "Load")
13193 : 58 : name = "Load64";
13194 : 62 : else if (name == "Store")
13195 : 34 : name = "Store64";
13196 : 28 : else if (name == "CompareAndSwap")
13197 : 0 : name = "Cas64";
13198 : 28 : else if (name == "Swap")
13199 : 0 : name = "Xchgt64";
13200 : 28 : else if (name == "Add")
13201 : 28 : name = "Xadd64";
13202 : : else
13203 : 0 : go_unreachable();
13204 : : }
13205 : 199 : else if (rname == "Uintptr")
13206 : : {
13207 : 133 : if (name == "Load")
13208 : 49 : name = "Loaduintptr";
13209 : 84 : else if (name == "LoadAcquire")
13210 : 0 : name = "Loadacquintptr";
13211 : 84 : else if (name == "Store")
13212 : 35 : name = "Storeuintptr";
13213 : 49 : else if (name == "StoreRelease")
13214 : 0 : name = "StoreReluintptr";
13215 : 49 : else if (name == "CompareAndSwap")
13216 : 28 : name = "Casuintptr";
13217 : 21 : else if (name == "Swap")
13218 : 7 : name = "Xchguintptr";
13219 : 14 : else if (name == "Add")
13220 : 14 : name = "Xadduintptr";
13221 : : else
13222 : 0 : go_unreachable();
13223 : : }
13224 : 66 : else if (rname == "Float64")
13225 : : {
13226 : : // Needs unsafe type conversion. Don't intrinsify for now.
13227 : : return NULL;
13228 : : }
13229 : 0 : else if (rname == "UnsafePointer")
13230 : : {
13231 : 0 : if (name == "Load")
13232 : 0 : name = "Loadp";
13233 : 0 : else if (name == "StoreNoWB")
13234 : 0 : name = "StorepoWB";
13235 : 0 : else if (name == "CompareAndSwapNoWB")
13236 : 0 : name = "Casp1";
13237 : : else
13238 : 0 : go_unreachable();
13239 : : }
13240 : : else
13241 : 0 : go_unreachable();
13242 : : }
13243 : :
13244 : 5460 : if ((name == "Load" || name == "Load64" || name == "Loadint64" || name == "Loadp"
13245 : 4594 : || name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq"
13246 : 4321 : || name == "Loadint32" || name == "Load8")
13247 : 7827 : && this->args_ != NULL && this->args_->size() == 1)
13248 : : {
13249 : 2367 : if (int_size < 8 && (name == "Load64" || name == "Loadint64"))
13250 : : // On 32-bit architectures we need to check alignment.
13251 : : // Not intrinsify for now.
13252 : : return NULL;
13253 : :
13254 : 2075 : Runtime::Function code;
13255 : 2075 : Type* res_type;
13256 : 2075 : if (name == "Load")
13257 : : {
13258 : : code = Runtime::ATOMIC_LOAD_4;
13259 : : res_type = uint32_type;
13260 : : }
13261 : 1099 : else if (name == "Load64")
13262 : : {
13263 : : code = Runtime::ATOMIC_LOAD_8;
13264 : : res_type = uint64_type;
13265 : : }
13266 : 768 : else if (name == "Loadint32")
13267 : : {
13268 : : code = Runtime::ATOMIC_LOAD_4;
13269 : : res_type = int32_type;
13270 : : }
13271 : 561 : else if (name == "Loadint64")
13272 : : {
13273 : : code = Runtime::ATOMIC_LOAD_8;
13274 : : res_type = int64_type;
13275 : : }
13276 : 524 : else if (name == "Loaduint")
13277 : : {
13278 : 7 : code = (int_size == 8
13279 : 7 : ? Runtime::ATOMIC_LOAD_8
13280 : : : Runtime::ATOMIC_LOAD_4);
13281 : : res_type = uint_type;
13282 : : }
13283 : 517 : else if (name == "Loaduintptr")
13284 : : {
13285 : 211 : code = (ptr_size == 8
13286 : 211 : ? Runtime::ATOMIC_LOAD_8
13287 : : : Runtime::ATOMIC_LOAD_4);
13288 : : res_type = uintptr_type;
13289 : : }
13290 : 306 : else if (name == "Loadp")
13291 : : {
13292 : 206 : code = (ptr_size == 8
13293 : 206 : ? Runtime::ATOMIC_LOAD_8
13294 : : : Runtime::ATOMIC_LOAD_4);
13295 : : res_type = pointer_type;
13296 : : }
13297 : 100 : else if (name == "LoadAcq")
13298 : : {
13299 : : code = Runtime::ATOMIC_LOAD_4;
13300 : : res_type = uint32_type;
13301 : : memorder = __ATOMIC_ACQUIRE;
13302 : : }
13303 : 45 : else if (name == "Load8")
13304 : : {
13305 : : code = Runtime::ATOMIC_LOAD_1;
13306 : : res_type = uint8_type;
13307 : : }
13308 : : else
13309 : 0 : go_unreachable();
13310 : 2075 : Expression* a1 = this->args_->front();
13311 : 2075 : Expression* a2 = Expression::make_integer_ul(memorder, int32_type, loc);
13312 : 2075 : Expression* call = Runtime::make_call(gogo, code, loc, 2, a1, a2);
13313 : 2075 : return Expression::make_unsafe_cast(res_type, call, loc);
13314 : : }
13315 : :
13316 : 3586 : if ((name == "Store" || name == "Store64" || name == "StorepNoWB"
13317 : 3226 : || name == "Storeuintptr" || name == "StoreRel"
13318 : 3097 : || name == "Storeint32" || name == "Storeint64")
13319 : 4743 : && this->args_ != NULL && this->args_->size() == 2)
13320 : : {
13321 : 1157 : if (int_size < 8 && (name == "Store64" || name == "Storeint64"))
13322 : : return NULL;
13323 : :
13324 : 1019 : Runtime::Function code;
13325 : 1019 : Expression* a1 = this->args_->at(0);
13326 : 1019 : Expression* a2 = this->args_->at(1);
13327 : 1019 : if (name == "Store")
13328 : : code = Runtime::ATOMIC_STORE_4;
13329 : 536 : else if (name == "Store64")
13330 : : code = Runtime::ATOMIC_STORE_8;
13331 : 391 : else if (name == "Storeint32")
13332 : : code = Runtime::ATOMIC_STORE_4;
13333 : 253 : else if (name == "Storeint64")
13334 : : code = Runtime::ATOMIC_STORE_8;
13335 : 228 : else if (name == "Storeuintptr")
13336 : 102 : code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
13337 : 126 : else if (name == "StorepNoWB")
13338 : : {
13339 : 99 : code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
13340 : 99 : a2 = Expression::make_unsafe_cast(uintptr_type, a2, loc);
13341 : 99 : a2 = Expression::make_cast(uint64_type, a2, loc);
13342 : : }
13343 : 27 : else if (name == "StoreRel")
13344 : : {
13345 : : code = Runtime::ATOMIC_STORE_4;
13346 : : memorder = __ATOMIC_RELEASE;
13347 : : }
13348 : 0 : else if (name == "Store8")
13349 : : code = Runtime::ATOMIC_STORE_1;
13350 : : else
13351 : 0 : go_unreachable();
13352 : 1019 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13353 : 1019 : return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13354 : : }
13355 : :
13356 : 2848 : if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr"
13357 : 2798 : || name == "Xchgint32" || name == "Xchgint64")
13358 : 2986 : && this->args_ != NULL && this->args_->size() == 2)
13359 : : {
13360 : 138 : if (int_size < 8 && (name == "Xchg64" || name == "Xchgint64"))
13361 : : return NULL;
13362 : :
13363 : 118 : Runtime::Function code;
13364 : 118 : Type* res_type;
13365 : 118 : if (name == "Xchg")
13366 : : {
13367 : : code = Runtime::ATOMIC_EXCHANGE_4;
13368 : : res_type = uint32_type;
13369 : : }
13370 : 54 : else if (name == "Xchg64")
13371 : : {
13372 : : code = Runtime::ATOMIC_EXCHANGE_8;
13373 : : res_type = uint64_type;
13374 : : }
13375 : 38 : else if (name == "Xchgint32")
13376 : : {
13377 : : code = Runtime::ATOMIC_EXCHANGE_4;
13378 : : res_type = int32_type;
13379 : : }
13380 : 26 : else if (name == "Xchgint64")
13381 : : {
13382 : : code = Runtime::ATOMIC_EXCHANGE_8;
13383 : : res_type = int64_type;
13384 : : }
13385 : 20 : else if (name == "Xchguintptr")
13386 : : {
13387 : 20 : code = (ptr_size == 8
13388 : 20 : ? Runtime::ATOMIC_EXCHANGE_8
13389 : : : Runtime::ATOMIC_EXCHANGE_4);
13390 : : res_type = uintptr_type;
13391 : : }
13392 : : else
13393 : 0 : go_unreachable();
13394 : 118 : Expression* a1 = this->args_->at(0);
13395 : 118 : Expression* a2 = this->args_->at(1);
13396 : 118 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13397 : 118 : Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13398 : 118 : return Expression::make_cast(res_type, call, loc);
13399 : : }
13400 : :
13401 : 2197 : if ((name == "Cas" || name == "Cas64" || name == "Casuintptr"
13402 : 1963 : || name == "Casp1" || name == "CasRel"
13403 : 1923 : || name == "Casint32" || name == "Casint64")
13404 : 3176 : && this->args_ != NULL && this->args_->size() == 3)
13405 : : {
13406 : 979 : if (int_size < 8 && (name == "Cas64" || name == "Casint64"))
13407 : : return NULL;
13408 : :
13409 : 903 : Runtime::Function code;
13410 : 903 : Expression* a1 = this->args_->at(0);
13411 : :
13412 : : // Builtin cas takes a pointer to the old value.
13413 : : // Store it in a temporary and take the address.
13414 : 903 : Expression* a2 = this->args_->at(1);
13415 : 903 : Temporary_statement* ts = Statement::make_temporary(NULL, a2, loc);
13416 : 903 : inserter->insert(ts);
13417 : 903 : a2 = Expression::make_temporary_reference(ts, loc);
13418 : 903 : a2 = Expression::make_unary(OPERATOR_AND, a2, loc);
13419 : :
13420 : 903 : Expression* a3 = this->args_->at(2);
13421 : 903 : if (name == "Cas")
13422 : : code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
13423 : 326 : else if (name == "Cas64")
13424 : : code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
13425 : 250 : else if (name == "Casint32")
13426 : : code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
13427 : 143 : else if (name == "Casint64")
13428 : : code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
13429 : 132 : else if (name == "Casuintptr")
13430 : 92 : code = (ptr_size == 8
13431 : 92 : ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
13432 : : : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
13433 : 40 : else if (name == "Casp1")
13434 : : {
13435 : 12 : code = (ptr_size == 8
13436 : 6 : ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
13437 : : : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
13438 : 6 : a3 = Expression::make_unsafe_cast(uintptr_type, a3, loc);
13439 : 6 : a3 = Expression::make_cast(uint64_type, a3, loc);
13440 : : }
13441 : 34 : else if (name == "CasRel")
13442 : : {
13443 : : code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
13444 : : memorder = __ATOMIC_RELEASE;
13445 : : }
13446 : : else
13447 : 0 : go_unreachable();
13448 : 903 : Expression* a4 = Expression::make_boolean(false, loc);
13449 : 903 : Expression* a5 = Expression::make_integer_ul(memorder, int32_type, loc);
13450 : 903 : Expression* a6 = Expression::make_integer_ul(__ATOMIC_RELAXED, int32_type, loc);
13451 : 903 : return Runtime::make_call(gogo, code, loc, 6, a1, a2, a3, a4, a5, a6);
13452 : : }
13453 : :
13454 : 1287 : if ((name == "Xadd" || name == "Xadd64" || name == "Xaddint64"
13455 : 787 : || name == "Xadduintptr" || name == "Xaddint32")
13456 : 2581 : && this->args_ != NULL && this->args_->size() == 2)
13457 : : {
13458 : 1294 : if (int_size < 8 && (name == "Xadd64" || name == "Xaddint64"))
13459 : : return NULL;
13460 : :
13461 : 1079 : Runtime::Function code;
13462 : 1079 : Type* res_type;
13463 : 1079 : if (name == "Xadd")
13464 : : {
13465 : : code = Runtime::ATOMIC_ADD_FETCH_4;
13466 : : res_type = uint32_type;
13467 : : }
13468 : 571 : else if (name == "Xadd64")
13469 : : {
13470 : : code = Runtime::ATOMIC_ADD_FETCH_8;
13471 : : res_type = uint64_type;
13472 : : }
13473 : 432 : else if (name == "Xaddint32")
13474 : : {
13475 : : code = Runtime::ATOMIC_ADD_FETCH_4;
13476 : : res_type = int32_type;
13477 : : }
13478 : 265 : else if (name == "Xaddint64")
13479 : : {
13480 : : code = Runtime::ATOMIC_ADD_FETCH_8;
13481 : : res_type = int64_type;
13482 : : }
13483 : 119 : else if (name == "Xadduintptr")
13484 : : {
13485 : 119 : code = (ptr_size == 8
13486 : 119 : ? Runtime::ATOMIC_ADD_FETCH_8
13487 : : : Runtime::ATOMIC_ADD_FETCH_4);
13488 : : res_type = uintptr_type;
13489 : : }
13490 : : else
13491 : 0 : go_unreachable();
13492 : 1079 : Expression* a1 = this->args_->at(0);
13493 : 1079 : Expression* a2 = this->args_->at(1);
13494 : 1079 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13495 : 1079 : Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13496 : 1079 : return Expression::make_cast(res_type, call, loc);
13497 : : }
13498 : :
13499 : 457 : if ((name == "And8" || name == "Or8")
13500 : 580 : && this->args_ != NULL && this->args_->size() == 2)
13501 : : {
13502 : 123 : Runtime::Function code;
13503 : 123 : if (name == "And8")
13504 : : code = Runtime::ATOMIC_AND_FETCH_1;
13505 : 79 : else if (name == "Or8")
13506 : : code = Runtime::ATOMIC_OR_FETCH_1;
13507 : : else
13508 : 0 : go_unreachable();
13509 : 123 : Expression* a1 = this->args_->at(0);
13510 : 123 : Expression* a2 = this->args_->at(1);
13511 : 123 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13512 : 123 : return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13513 : : }
13514 : : }
13515 : 727049 : else if (package == "internal/abi"
13516 : 727049 : || package == "bootstrap/internal/abi") // for bootstrapping gc
13517 : : {
13518 : 77 : if (is_method)
13519 : : return NULL;
13520 : :
13521 : 71 : if ((name == "FuncPCABI0" || name == "FuncPCABIInternal")
13522 : 77 : && this->args_ != NULL
13523 : 154 : && this->args_->size() == 1)
13524 : : {
13525 : : // We expect to see a conversion from the expression to "any".
13526 : 77 : Expression* expr = this->args_->front();
13527 : 77 : Type_conversion_expression* tce = expr->conversion_expression();
13528 : 75 : if (tce != NULL)
13529 : 75 : expr = tce->expr();
13530 : 77 : Func_expression* fe = expr->func_expression();
13531 : 77 : Interface_field_reference_expression* interface_method =
13532 : 77 : expr->interface_field_reference_expression();
13533 : 77 : if (fe != NULL)
13534 : : {
13535 : 75 : Named_object* no = fe->named_object();
13536 : 75 : Expression* ref = Expression::make_func_code_reference(no, loc);
13537 : 75 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
13538 : 75 : return Expression::make_cast(uintptr_type, ref, loc);
13539 : : }
13540 : 2 : else if (interface_method != NULL)
13541 : 0 : return interface_method->get_function();
13542 : : else
13543 : : {
13544 : 2 : expr = this->args_->front();
13545 : 6 : go_assert(expr->type()->interface_type() != NULL
13546 : : && expr->type()->interface_type()->is_empty());
13547 : 2 : expr = Expression::make_interface_info(expr,
13548 : : INTERFACE_INFO_OBJECT,
13549 : : loc);
13550 : : // Trust that this is a function type, which means that
13551 : : // it is a direct iface type and we can use EXPR
13552 : : // directly. The backend representation of this
13553 : : // function is a pointer to a struct whose first field
13554 : : // is the actual function to call.
13555 : 2 : Type* pvoid = Type::make_pointer_type(Type::make_void_type());
13556 : 2 : Type* pfntype = Type::make_pointer_type(pvoid);
13557 : 2 : Expression* ref = make_unsafe_cast(pfntype, expr, loc);
13558 : 2 : return Expression::make_dereference(ref, NIL_CHECK_NOT_NEEDED,
13559 : 2 : loc);
13560 : : }
13561 : : }
13562 : : }
13563 : :
13564 : : return NULL;
13565 : 820366 : }
13566 : :
13567 : : // Make implicit type conversions explicit.
13568 : :
13569 : : void
13570 : 834520 : Call_expression::do_add_conversions()
13571 : : {
13572 : : // Skip call that requires a thunk. We generate conversions inside the thunk.
13573 : 834520 : if (this->is_concurrent_ || this->is_deferred_)
13574 : 304608 : return;
13575 : :
13576 : 820777 : if (this->args_ == NULL || this->args_->empty())
13577 : : return;
13578 : :
13579 : 760828 : Function_type* fntype = this->get_function_type();
13580 : 760828 : if (fntype == NULL)
13581 : : {
13582 : 0 : go_assert(saw_errors());
13583 : : return;
13584 : : }
13585 : 760828 : if (fntype->parameters() == NULL || fntype->parameters()->empty())
13586 : : return;
13587 : :
13588 : 529912 : Location loc = this->location();
13589 : 529912 : Expression_list::iterator pa = this->args_->begin();
13590 : 529912 : Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
13591 : 529912 : bool is_interface_method =
13592 : 529912 : this->fn_->interface_field_reference_expression() != NULL;
13593 : 529912 : size_t argcount = this->args_->size();
13594 : 529912 : if (!is_interface_method && fntype->is_method())
13595 : : {
13596 : : // Skip the receiver argument, which cannot be interface.
13597 : 155666 : pa++;
13598 : 155666 : argcount--;
13599 : : }
13600 : 529912 : if (argcount != fntype->parameters()->size())
13601 : : {
13602 : 0 : go_assert(saw_errors());
13603 : : return;
13604 : : }
13605 : 1522992 : for (; pa != this->args_->end(); ++pa, ++pp)
13606 : : {
13607 : 993080 : Type* pt = pp->type();
13608 : 993080 : if (!Type::are_identical(pt, (*pa)->type(), 0, NULL)
13609 : 1068799 : && pt->interface_type() != NULL)
13610 : 59595 : *pa = Expression::make_cast(pt, *pa, loc);
13611 : : }
13612 : : }
13613 : :
13614 : : // Get the function type. This can return NULL in error cases.
13615 : :
13616 : : Function_type*
13617 : 24772023 : Call_expression::get_function_type() const
13618 : : {
13619 : 24772023 : return this->fn_->type()->function_type();
13620 : : }
13621 : :
13622 : : // Return the number of values which this call will return.
13623 : :
13624 : : size_t
13625 : 2919421 : Call_expression::result_count() const
13626 : : {
13627 : 2919421 : const Function_type* fntype = this->get_function_type();
13628 : 2919421 : if (fntype == NULL)
13629 : : return 0;
13630 : 2907357 : if (fntype->results() == NULL)
13631 : : return 0;
13632 : 2330943 : return fntype->results()->size();
13633 : : }
13634 : :
13635 : : // Return the temporary that holds the result for a call with multiple
13636 : : // results.
13637 : :
13638 : : Temporary_statement*
13639 : 167662 : Call_expression::results() const
13640 : : {
13641 : 167662 : if (this->call_temp_ == NULL)
13642 : : {
13643 : 0 : go_assert(saw_errors());
13644 : : return NULL;
13645 : : }
13646 : : return this->call_temp_;
13647 : : }
13648 : :
13649 : : // Set the number of results expected from a call expression.
13650 : :
13651 : : void
13652 : 64962 : Call_expression::set_expected_result_count(size_t count)
13653 : : {
13654 : 64962 : go_assert(this->expected_result_count_ == 0);
13655 : 64962 : go_assert(!this->types_are_determined_);
13656 : 64962 : this->expected_result_count_ = count;
13657 : 64962 : }
13658 : :
13659 : : // Return whether this is a call to the predeclared function recover.
13660 : :
13661 : : bool
13662 : 16490 : Call_expression::is_recover_call() const
13663 : : {
13664 : 16490 : return this->do_is_recover_call();
13665 : : }
13666 : :
13667 : : // Set the argument to the recover function.
13668 : :
13669 : : void
13670 : 857 : Call_expression::set_recover_arg(Expression* arg)
13671 : : {
13672 : 857 : this->do_set_recover_arg(arg);
13673 : 857 : }
13674 : :
13675 : : // Virtual functions also implemented by Builtin_call_expression.
13676 : :
13677 : : bool
13678 : 14910 : Call_expression::do_is_recover_call() const
13679 : : {
13680 : 14910 : return false;
13681 : : }
13682 : :
13683 : : void
13684 : 0 : Call_expression::do_set_recover_arg(Expression*)
13685 : : {
13686 : 0 : go_unreachable();
13687 : : }
13688 : :
13689 : : // We have found an error with this call expression; return true if
13690 : : // we should report it.
13691 : :
13692 : : bool
13693 : 9 : Call_expression::issue_error()
13694 : : {
13695 : 9 : if (this->issued_error_)
13696 : : return false;
13697 : : else
13698 : : {
13699 : 5 : this->issued_error_ = true;
13700 : 5 : return true;
13701 : : }
13702 : : }
13703 : :
13704 : : // Whether or not this call contains errors, either in the call or the
13705 : : // arguments to the call.
13706 : :
13707 : : bool
13708 : 1203757 : Call_expression::is_erroneous_call()
13709 : : {
13710 : 1203757 : if (this->is_error_expression() || this->fn()->is_error_expression())
13711 : : return true;
13712 : :
13713 : 1203756 : if (this->args() == NULL)
13714 : : return false;
13715 : 3456475 : for (Expression_list::iterator pa = this->args()->begin();
13716 : 3456475 : pa != this->args()->end();
13717 : 2314801 : ++pa)
13718 : : {
13719 : 2318038 : if ((*pa)->type()->is_error_type() || (*pa)->is_error_expression())
13720 : 3238 : return true;
13721 : : }
13722 : : return false;
13723 : : }
13724 : :
13725 : : // Get the type.
13726 : :
13727 : : Type*
13728 : 6210384 : Call_expression::do_type()
13729 : : {
13730 : 6210384 : if (this->is_error_expression())
13731 : 36 : return Type::make_error_type();
13732 : 6210348 : if (this->lowered_ != NULL)
13733 : 140189 : return this->lowered_->type();
13734 : 6070159 : go_assert(this->type_ != NULL);
13735 : : return this->type_;
13736 : : }
13737 : :
13738 : : // Determine types for a call expression. We can use the function
13739 : : // parameter types to set the types of the arguments. We simplify
13740 : : // some of the call cases here, storing the result in the lowered_
13741 : : // field.
13742 : :
13743 : : void
13744 : 2243514 : Call_expression::do_determine_type(Gogo* gogo, const Type_context* context)
13745 : : {
13746 : 2243514 : if (!this->determining_types())
13747 : 2243514 : return;
13748 : :
13749 : 1729854 : if (this->lowered_== NULL)
13750 : : {
13751 : 1729854 : Expression* builtin = this->lower_builtin(gogo);
13752 : 1729854 : if (builtin != this)
13753 : 75182 : this->lowered_ = builtin;
13754 : : }
13755 : :
13756 : 1729854 : if (this->lowered_ != NULL)
13757 : : {
13758 : 75182 : this->lowered_->determine_type(gogo, context);
13759 : 75182 : return;
13760 : : }
13761 : :
13762 : 1654672 : this->fn_->determine_type_no_context(gogo);
13763 : :
13764 : : // Simplify a type conversion.
13765 : :
13766 : 1654672 : if (this->fn_->is_type_expression()
13767 : 89712 : && this->args_ != NULL
13768 : 89712 : && this->args_->size() == 1
13769 : 1744384 : && (this->expected_result_count_ == 0
13770 : : || this->expected_result_count_ == 1))
13771 : : {
13772 : 89712 : this->lowered_ = Expression::make_cast(this->fn_->type(),
13773 : 89712 : this->args_->front(),
13774 : : this->location());
13775 : 89712 : this->lowered_->determine_type(gogo, context);
13776 : 89712 : return;
13777 : : }
13778 : :
13779 : : // Get the type of the function we are calling.
13780 : :
13781 : 1564960 : Function_type* fntype = this->get_function_type();
13782 : 1564960 : if (fntype == NULL)
13783 : : {
13784 : : // We report the error here so that we can reasonably return an
13785 : : // error type in do_type.
13786 : 56 : if (!this->fn_->type()->is_error())
13787 : 5 : this->report_error(_("expected function"));
13788 : : else
13789 : 51 : this->set_is_error();
13790 : 56 : if (this->args_ != NULL)
13791 : : {
13792 : 34 : for (Expression_list::iterator p = this->args_->begin();
13793 : 34 : p != this->args_->end();
13794 : 18 : ++p)
13795 : 18 : (*p)->determine_type_no_context(gogo);
13796 : : }
13797 : 56 : return;
13798 : : }
13799 : :
13800 : : // Simplify f(g()) where g() returns multiple results.
13801 : :
13802 : 1564904 : this->simplify_multiple_results(gogo);
13803 : :
13804 : : // Set the type of this expression.
13805 : :
13806 : 1564904 : go_assert(this->type_ == NULL);
13807 : 1564904 : const Typed_identifier_list* results = fntype->results();
13808 : 1564904 : if (results == NULL || results->empty())
13809 : 889679 : this->type_ = Type::make_void_type();
13810 : 675225 : else if (results->size() == 1)
13811 : : {
13812 : : // If this is a call to a generated equality function, we
13813 : : // determine the type based on the context. See the comment in
13814 : : // Binary_expression::lower_array_comparison.
13815 : 581831 : if (this->is_equal_function_
13816 : 961 : && !context->may_be_abstract
13817 : 961 : && context->type != NULL
13818 : 581831 : && context->type->is_boolean_type())
13819 : 0 : this->type_ = context->type;
13820 : : else
13821 : 581831 : this->type_ = results->begin()->type();
13822 : : }
13823 : : else
13824 : 93394 : this->type_ = Type::make_call_multiple_result_type();
13825 : :
13826 : : // Determine the types of the arguments.
13827 : :
13828 : 1564904 : if (this->args_ == NULL)
13829 : : {
13830 : 165646 : if (fntype->is_varargs())
13831 : : {
13832 : 193 : if (!this->rewrite_varargs())
13833 : 0 : this->set_is_error();
13834 : : }
13835 : 165646 : return;
13836 : : }
13837 : :
13838 : 1399258 : const Typed_identifier_list* parameters = fntype->parameters();
13839 : 1399258 : Typed_identifier_list::const_iterator pt;
13840 : 1399258 : if (parameters != NULL)
13841 : 1236416 : pt = parameters->begin();
13842 : 1399258 : bool first = true;
13843 : 4173800 : for (Expression_list::const_iterator pa = this->args_->begin();
13844 : 4173800 : pa != this->args_->end();
13845 : 2774542 : ++pa)
13846 : : {
13847 : 2774542 : if (first)
13848 : : {
13849 : 1236416 : first = false;
13850 : : // If this is a method, the first argument is the
13851 : : // receiver.
13852 : 1236416 : if (fntype != NULL && fntype->is_method())
13853 : : {
13854 : 0 : Type* rtype = fntype->receiver()->type();
13855 : : // The receiver is always passed as a pointer.
13856 : 0 : if (rtype->points_to() == NULL)
13857 : 0 : rtype = Type::make_pointer_type(rtype);
13858 : 0 : Type_context subcontext(rtype, false);
13859 : 0 : (*pa)->determine_type(gogo, &subcontext);
13860 : 0 : continue;
13861 : 0 : }
13862 : : }
13863 : :
13864 : 2769927 : if ((this->is_varargs_ || this->varargs_are_lowered_)
13865 : 27434 : && fntype->is_varargs()
13866 : 4632 : && pa + 1 == this->args_->end()
13867 : 2308 : && parameters != NULL
13868 : 2776850 : && pt + 1 == parameters->end())
13869 : : {
13870 : 2308 : Type_context subcontext(pt->type(), false);
13871 : 2308 : (*pa)->determine_type(gogo, &subcontext);
13872 : 2308 : continue;
13873 : 2308 : }
13874 : :
13875 : 2772234 : if (!this->is_varargs_
13876 : 2769911 : && fntype->is_varargs()
13877 : 177215 : && parameters != NULL
13878 : 2949449 : && pt + 1 == parameters->end())
13879 : : {
13880 : 114906 : go_assert(pt->type()->is_slice_type());
13881 : 114906 : Type_context subcontext(pt->type()->array_type()->element_type(),
13882 : 229812 : false);
13883 : 114906 : (*pa)->determine_type(gogo, &subcontext);
13884 : 114906 : continue;
13885 : 114906 : }
13886 : :
13887 : 2657328 : if (parameters != NULL && pt != parameters->end())
13888 : : {
13889 : 2657326 : Type_context subcontext(pt->type(), false);
13890 : 2657326 : (*pa)->determine_type(gogo, &subcontext);
13891 : 2657326 : if (!fntype->is_varargs() || pt + 1 != parameters->end())
13892 : 2657323 : ++pt;
13893 : : }
13894 : : else
13895 : 2 : (*pa)->determine_type_no_context(gogo);
13896 : : }
13897 : :
13898 : 1399258 : if (fntype->is_varargs())
13899 : : {
13900 : 72617 : if (!this->rewrite_varargs())
13901 : 6 : this->set_is_error();
13902 : : }
13903 : : }
13904 : :
13905 : : // Called when determining types for a Call_expression. Return true
13906 : : // if we should go ahead, false if they have already been determined.
13907 : :
13908 : : bool
13909 : 2539029 : Call_expression::determining_types()
13910 : : {
13911 : 2539029 : if (this->types_are_determined_)
13912 : : return false;
13913 : : else
13914 : : {
13915 : 1956504 : this->types_are_determined_ = true;
13916 : 1956504 : return true;
13917 : : }
13918 : : }
13919 : :
13920 : : // Simplify f(g()) where g() returns multiple results. Called by
13921 : : // do_determine_types of both Call_expression and
13922 : : // Builtin_call_expression.
13923 : :
13924 : : void
13925 : 1791554 : Call_expression::simplify_multiple_results(Gogo* gogo)
13926 : : {
13927 : 1791554 : if (this->args_ == NULL || this->args_->size() != 1)
13928 : : return;
13929 : :
13930 : 489705 : Call_expression* call = this->args_->front()->call_expression();
13931 : 23895 : if (call == NULL || call->is_builtin())
13932 : 467170 : return;
13933 : :
13934 : 22535 : call->determine_type_no_context(gogo);
13935 : 22535 : size_t rc = call->result_count();
13936 : 22535 : Function_type* fntype = this->get_function_type();
13937 : 22535 : if (rc > 1
13938 : 22535 : && ((fntype->parameters() != NULL
13939 : 288 : && (fntype->parameters()->size() == rc
13940 : 16 : || (fntype->is_varargs()
13941 : 16 : && fntype->parameters()->size() - 1 <= rc)))
13942 : 12 : || fntype->is_builtin()))
13943 : : {
13944 : 300 : if (this->is_varargs_)
13945 : : {
13946 : 2 : go_error_at(call->location(),
13947 : : "multiple-value argument in single-value context");
13948 : 2 : this->set_is_error();
13949 : : }
13950 : :
13951 : 300 : call->set_is_multi_value_arg();
13952 : 300 : Expression_list* args = new Expression_list;
13953 : 987 : for (size_t i = 0; i < rc; ++i)
13954 : 687 : args->push_back(Expression::make_call_result(call, i));
13955 : : // We can't create a new Call_expression here because this
13956 : : // one may be referred to by Call_result expressions.
13957 : 300 : this->args_ = args;
13958 : : }
13959 : : }
13960 : :
13961 : : // Lower a call to a varargs function by rewriting the value(s) passed
13962 : : // to the varargs argument into a slice. Called during the
13963 : : // determine_types pass.
13964 : :
13965 : : bool
13966 : 72810 : Call_expression::rewrite_varargs()
13967 : : {
13968 : 72810 : if (this->varargs_are_lowered_)
13969 : : return true;
13970 : 72491 : this->varargs_are_lowered_ = true;
13971 : :
13972 : 72491 : Function_type* fntype = this->get_function_type();
13973 : :
13974 : 72491 : const Typed_identifier_list* parameters = fntype->parameters();
13975 : 72491 : go_assert(parameters != NULL && !parameters->empty());
13976 : 72491 : size_t param_count = parameters->size();
13977 : :
13978 : 72491 : Type* varargs_type = parameters->back().type();
13979 : 72491 : go_assert(varargs_type->is_slice_type());
13980 : :
13981 : 72491 : size_t arg_count = this->args_ == NULL ? 0 : this->args_->size();
13982 : 72491 : if (arg_count < param_count - 1)
13983 : : {
13984 : 0 : if (!this->is_error_expression())
13985 : 0 : this->report_error(_("not enough arguments"));
13986 : 0 : return false;
13987 : : }
13988 : :
13989 : 72491 : bool ret = true;
13990 : 72491 : Expression_list* old_args = this->args_;
13991 : 72491 : Expression_list* new_args = new Expression_list();
13992 : 72491 : bool push_empty_arg = false;
13993 : 72491 : if (old_args == NULL || old_args->empty())
13994 : : {
13995 : 193 : go_assert(param_count == 1);
13996 : : push_empty_arg = true;
13997 : : }
13998 : : else
13999 : : {
14000 : : Expression_list::const_iterator pa;
14001 : : size_t i = 1;
14002 : 136625 : for (pa = old_args->begin(); pa != old_args->end(); ++pa, ++i)
14003 : : {
14004 : 130282 : if (i == param_count)
14005 : : break;
14006 : 64327 : new_args->push_back(*pa);
14007 : : }
14008 : :
14009 : : // We have reached the varargs parameter.
14010 : :
14011 : 72298 : if (pa == old_args->end())
14012 : : push_empty_arg = true;
14013 : 65955 : else if (pa + 1 == old_args->end() && this->is_varargs_)
14014 : 1987 : new_args->push_back(*pa);
14015 : 63968 : else if (this->is_varargs_)
14016 : : {
14017 : 2 : if (!this->is_error_expression())
14018 : : {
14019 : 1 : if ((*pa)->type()->is_slice_type())
14020 : 1 : this->report_error(_("too many arguments"));
14021 : : else
14022 : : {
14023 : 0 : go_error_at(this->location(),
14024 : : "invalid use of %<...%> with non-slice");
14025 : 0 : this->set_is_error();
14026 : : }
14027 : : }
14028 : 2 : return false;
14029 : : }
14030 : : else
14031 : : {
14032 : 127932 : Type* element_type = varargs_type->array_type()->element_type();
14033 : 63966 : Expression_list* vals = new Expression_list;
14034 : 178872 : for (; pa != old_args->end(); ++pa, ++i)
14035 : : {
14036 : 114906 : Type* patype = (*pa)->type();
14037 : 114906 : Location paloc = (*pa)->location();
14038 : 114906 : if (!this->check_argument_type(i, element_type, patype, paloc))
14039 : : {
14040 : 4 : ret = false;
14041 : 4 : continue;
14042 : : }
14043 : 114902 : vals->push_back(*pa);
14044 : : }
14045 : 63966 : Expression* val =
14046 : 63966 : Expression::make_slice_composite_literal(varargs_type, vals,
14047 : : this->location());
14048 : 63966 : new_args->push_back(val);
14049 : : }
14050 : : }
14051 : :
14052 : 65953 : if (push_empty_arg)
14053 : 6536 : new_args->push_back(Expression::make_nil(this->location()));
14054 : :
14055 : : // We can't create a new Call_expression here because this
14056 : : // one may be referred to by Call_result expressions.
14057 : 72489 : this->args_ = new_args;
14058 : :
14059 : 72489 : return ret;
14060 : : }
14061 : :
14062 : : // Check types for parameter I.
14063 : :
14064 : : bool
14065 : 975034 : Call_expression::check_argument_type(int i, const Type* parameter_type,
14066 : : const Type* argument_type,
14067 : : Location argument_location)
14068 : : {
14069 : 975034 : std::string reason;
14070 : 975034 : if (!Type::are_assignable(parameter_type, argument_type, &reason))
14071 : : {
14072 : 27 : if (reason.empty())
14073 : 0 : go_error_at(argument_location, "argument %d has incompatible type", i);
14074 : : else
14075 : 27 : go_error_at(argument_location,
14076 : : "argument %d has incompatible type (%s)",
14077 : : i, reason.c_str());
14078 : 27 : this->set_is_error();
14079 : 27 : return false;
14080 : : }
14081 : : return true;
14082 : 975034 : }
14083 : :
14084 : : // Check types.
14085 : :
14086 : : void
14087 : 723630 : Call_expression::do_check_types(Gogo*)
14088 : : {
14089 : 723630 : if (this->is_error_expression()
14090 : 723565 : || this->fn_->is_error_expression()
14091 : 1447195 : || this->fn_->type()->is_error())
14092 : 66 : return;
14093 : 723564 : if (this->lowered_ != NULL)
14094 : : return;
14095 : :
14096 : 633882 : Function_type* fntype = this->get_function_type();
14097 : 633882 : go_assert(fntype != NULL);
14098 : :
14099 : 633882 : if (this->expected_result_count_ != 0
14100 : 633882 : && this->expected_result_count_ != this->result_count())
14101 : : {
14102 : 5 : if (this->issue_error())
14103 : 3 : this->report_error(_("function result count mismatch"));
14104 : 5 : this->set_is_error();
14105 : 5 : return;
14106 : : }
14107 : :
14108 : 633877 : if (this->is_varargs_ && !fntype->is_varargs())
14109 : : {
14110 : 1 : go_error_at(this->location(),
14111 : : "invalid use of %<...%> calling non-variadic function");
14112 : 1 : this->set_is_error();
14113 : 1 : return;
14114 : : }
14115 : :
14116 : 633876 : bool is_method = fntype->is_method();
14117 : 633876 : if (is_method)
14118 : : {
14119 : 1987 : go_assert(this->args_ != NULL && !this->args_->empty());
14120 : 1987 : Type* rtype = fntype->receiver()->type();
14121 : 1987 : Expression* first_arg = this->args_->front();
14122 : : // We dereference the values since receivers are always passed
14123 : : // as pointers.
14124 : 1987 : std::string reason;
14125 : 5961 : if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(),
14126 : : &reason))
14127 : : {
14128 : 0 : if (reason.empty())
14129 : 0 : this->report_error(_("incompatible type for receiver"));
14130 : : else
14131 : : {
14132 : 0 : go_error_at(this->location(),
14133 : : "incompatible type for receiver (%s)",
14134 : : reason.c_str());
14135 : 0 : this->set_is_error();
14136 : : }
14137 : : }
14138 : 1987 : }
14139 : :
14140 : 633876 : const Typed_identifier_list* parameters = fntype->parameters();
14141 : 633876 : if (this->args_ == NULL || this->args_->empty())
14142 : : {
14143 : 158039 : if (parameters != NULL && !parameters->empty())
14144 : 9 : this->report_error(_("not enough arguments"));
14145 : : }
14146 : 475837 : else if (parameters == NULL)
14147 : : {
14148 : 1170 : if (!is_method || this->args_->size() > 1)
14149 : 0 : this->report_error(_("too many arguments"));
14150 : : }
14151 : 474667 : else if (this->args_->size() == 1
14152 : 243598 : && this->args_->front()->call_expression() != NULL
14153 : 494588 : && this->args_->front()->call_expression()->result_count() > 1)
14154 : : {
14155 : : // This is F(G()) when G returns more than one result. If the
14156 : : // results can be matched to parameters, it would have been
14157 : : // rewritten in determine_types. If we get here we know there
14158 : : // is a mismatch.
14159 : 0 : if (this->args_->front()->call_expression()->result_count()
14160 : 0 : < parameters->size())
14161 : 0 : this->report_error(_("not enough arguments"));
14162 : : else
14163 : 0 : this->report_error(_("too many arguments"));
14164 : : }
14165 : : else
14166 : : {
14167 : 474667 : int i = 0;
14168 : 474667 : Expression_list::const_iterator pa = this->args_->begin();
14169 : 474667 : if (is_method)
14170 : 817 : ++pa;
14171 : 474667 : for (Typed_identifier_list::const_iterator pt = parameters->begin();
14172 : 1334795 : pt != parameters->end();
14173 : 860128 : ++pt, ++pa, ++i)
14174 : : {
14175 : 860129 : if (pa == this->args_->end())
14176 : : {
14177 : 1 : this->report_error(_("not enough arguments"));
14178 : 1 : return;
14179 : : }
14180 : 860128 : this->check_argument_type(i + 1, pt->type(), (*pa)->type(),
14181 : 860128 : (*pa)->location());
14182 : : }
14183 : 474666 : if (pa != this->args_->end())
14184 : 2 : this->report_error(_("too many arguments"));
14185 : : }
14186 : : }
14187 : :
14188 : : Expression*
14189 : 11 : Call_expression::do_copy()
14190 : : {
14191 : 11 : Call_expression* call =
14192 : 22 : Expression::make_call(this->fn_->copy(),
14193 : 11 : (this->args_ == NULL
14194 : : ? NULL
14195 : 11 : : this->args_->copy()),
14196 : 11 : this->is_varargs_, this->location());
14197 : :
14198 : 11 : if (this->varargs_are_lowered_)
14199 : 0 : call->set_varargs_are_lowered();
14200 : 11 : if (this->is_deferred_)
14201 : 0 : call->set_is_deferred();
14202 : 11 : if (this->is_concurrent_)
14203 : 0 : call->set_is_concurrent();
14204 : 11 : return call;
14205 : : }
14206 : :
14207 : : // Return whether we have to use a temporary variable to ensure that
14208 : : // we evaluate this call expression in order. If the call returns no
14209 : : // results then it will inevitably be executed last.
14210 : :
14211 : : bool
14212 : 973861 : Call_expression::do_must_eval_in_order() const
14213 : : {
14214 : 973861 : return this->result_count() > 0;
14215 : : }
14216 : :
14217 : : // Get the function and the first argument to use when calling an
14218 : : // interface method.
14219 : :
14220 : : Expression*
14221 : 31774 : Call_expression::interface_method_function(
14222 : : Interface_field_reference_expression* interface_method,
14223 : : Expression** first_arg_ptr,
14224 : : Location location)
14225 : : {
14226 : 31774 : Expression* object = interface_method->get_underlying_object();
14227 : 31774 : Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
14228 : 63548 : *first_arg_ptr =
14229 : 31774 : Expression::make_unsafe_cast(unsafe_ptr_type, object, location);
14230 : 31774 : return interface_method->get_function();
14231 : : }
14232 : :
14233 : : // Build the call expression.
14234 : :
14235 : : Bexpression*
14236 : 1754351 : Call_expression::do_get_backend(Translate_context* context)
14237 : : {
14238 : 1754351 : Location location = this->location();
14239 : :
14240 : 1754351 : if (this->call_ != NULL)
14241 : : {
14242 : : // If the call returns multiple results, make a new reference to
14243 : : // the temporary.
14244 : 95 : if (this->call_temp_ != NULL)
14245 : : {
14246 : 95 : Expression* ref =
14247 : 95 : Expression::make_temporary_reference(this->call_temp_, location);
14248 : 95 : return ref->get_backend(context);
14249 : : }
14250 : :
14251 : : return this->call_;
14252 : : }
14253 : :
14254 : 1754256 : Function_type* fntype = this->get_function_type();
14255 : 1754256 : if (fntype == NULL)
14256 : 0 : return context->backend()->error_expression();
14257 : :
14258 : 1754256 : if (this->fn_->is_error_expression())
14259 : 0 : return context->backend()->error_expression();
14260 : :
14261 : 1754256 : Gogo* gogo = context->gogo();
14262 : :
14263 : 1754256 : Func_expression* func = this->fn_->func_expression();
14264 : 1754256 : Interface_field_reference_expression* interface_method =
14265 : 1754256 : this->fn_->interface_field_reference_expression();
14266 : 1754256 : const bool has_closure = func != NULL && func->closure() != NULL;
14267 : 3453564 : const bool is_interface_method = interface_method != NULL;
14268 : :
14269 : 1753563 : bool has_closure_arg;
14270 : 1753563 : if (has_closure)
14271 : : has_closure_arg = true;
14272 : 1753563 : else if (func != NULL)
14273 : : has_closure_arg = false;
14274 : 54255 : else if (is_interface_method)
14275 : : has_closure_arg = false;
14276 : : else
14277 : : has_closure_arg = true;
14278 : :
14279 : 1722482 : Expression* first_arg = NULL;
14280 : 1722482 : if (!is_interface_method && fntype->is_method())
14281 : : {
14282 : 256652 : first_arg = this->args_->front();
14283 : 256652 : if (first_arg->type()->points_to() == NULL
14284 : 261195 : && first_arg->type()->is_direct_iface_type())
14285 : 4543 : first_arg = Expression::unpack_direct_iface(first_arg,
14286 : : first_arg->location());
14287 : : }
14288 : :
14289 : 1754256 : int nargs;
14290 : 1754256 : std::vector<Bexpression*> fn_args;
14291 : 1754256 : if (this->args_ == NULL || this->args_->empty())
14292 : : {
14293 : 215243 : nargs = is_interface_method ? 1 : 0;
14294 : 19932 : if (nargs > 0)
14295 : 19932 : fn_args.resize(1);
14296 : : }
14297 : 1539013 : else if (fntype->parameters() == NULL || fntype->parameters()->empty())
14298 : : {
14299 : : // Passing a receiver parameter.
14300 : 101195 : go_assert(!is_interface_method
14301 : : && fntype->is_method()
14302 : : && this->args_->size() == 1);
14303 : 101195 : nargs = 1;
14304 : 101195 : fn_args.resize(1);
14305 : 101195 : fn_args[0] = first_arg->get_backend(context);
14306 : : }
14307 : : else
14308 : : {
14309 : 1437818 : const Typed_identifier_list* params = fntype->parameters();
14310 : :
14311 : 1437818 : nargs = this->args_->size();
14312 : 1437818 : int i = is_interface_method ? 1 : 0;
14313 : 1437818 : nargs += i;
14314 : 1437818 : fn_args.resize(nargs);
14315 : :
14316 : 1437818 : Typed_identifier_list::const_iterator pp = params->begin();
14317 : 1437818 : Expression_list::const_iterator pe = this->args_->begin();
14318 : 1437818 : if (!is_interface_method && fntype->is_method())
14319 : : {
14320 : 155457 : fn_args[i] = first_arg->get_backend(context);
14321 : 155457 : ++pe;
14322 : 155457 : ++i;
14323 : : }
14324 : 4359714 : for (; pe != this->args_->end(); ++pe, ++pp, ++i)
14325 : : {
14326 : 2921896 : go_assert(pp != params->end());
14327 : 2921896 : Expression* arg =
14328 : 2921896 : Expression::convert_for_assignment(gogo, pp->type(), *pe,
14329 : : location);
14330 : 2921896 : fn_args[i] = arg->get_backend(context);
14331 : : }
14332 : 1437818 : go_assert(pp == params->end());
14333 : 1437818 : go_assert(i == nargs);
14334 : : }
14335 : :
14336 : 1754256 : Expression* fn;
14337 : 1754256 : Expression* closure = NULL;
14338 : 1754256 : if (func != NULL)
14339 : : {
14340 : 1700001 : Named_object* no = func->named_object();
14341 : 1700001 : fn = Expression::make_func_code_reference(no, location);
14342 : 1700001 : if (has_closure)
14343 : 693 : closure = func->closure();
14344 : : }
14345 : 54255 : else if (!is_interface_method)
14346 : : {
14347 : 22481 : closure = this->fn_;
14348 : :
14349 : : // The backend representation of this function type is a pointer
14350 : : // to a struct whose first field is the actual function to call.
14351 : 22481 : Type* pfntype =
14352 : 22481 : Type::make_pointer_type(
14353 : 22481 : Type::make_pointer_type(Type::make_void_type()));
14354 : 22481 : fn = Expression::make_unsafe_cast(pfntype, this->fn_, location);
14355 : 22481 : fn = Expression::make_dereference(fn, NIL_CHECK_NOT_NEEDED, location);
14356 : : }
14357 : : else
14358 : : {
14359 : 31774 : Expression* arg0;
14360 : 31774 : fn = this->interface_method_function(interface_method, &arg0,
14361 : : location);
14362 : 31774 : fn_args[0] = arg0->get_backend(context);
14363 : : }
14364 : :
14365 : 1754256 : Bexpression* bclosure = NULL;
14366 : 1754256 : if (has_closure_arg)
14367 : 23174 : bclosure = closure->get_backend(context);
14368 : : else
14369 : 1731082 : go_assert(closure == NULL);
14370 : :
14371 : 1754256 : Bexpression* bfn = fn->get_backend(context);
14372 : :
14373 : : // When not calling a named function directly, use a type conversion
14374 : : // in case the type of the function is a recursive type which refers
14375 : : // to itself. We don't do this for an interface method because 1)
14376 : : // an interface method never refers to itself, so we always have a
14377 : : // function type here; 2) we pass an extra first argument to an
14378 : : // interface method, so fntype is not correct.
14379 : 1754256 : if (func == NULL && !is_interface_method)
14380 : : {
14381 : 22481 : Btype* bft = fntype->get_backend_fntype(gogo);
14382 : 22481 : bfn = gogo->backend()->convert_expression(bft, bfn, location);
14383 : : }
14384 : :
14385 : 1754256 : Bfunction* bfunction = NULL;
14386 : 1754256 : if (context->function())
14387 : 1750256 : bfunction = context->function()->func_value()->get_decl();
14388 : 1754256 : Bexpression* call = gogo->backend()->call_expression(bfunction, bfn,
14389 : : fn_args, bclosure,
14390 : : location);
14391 : :
14392 : 1754256 : if (this->call_temp_ != NULL)
14393 : : {
14394 : : // This case occurs when the call returns multiple results.
14395 : :
14396 : 92971 : Expression* ref = Expression::make_temporary_reference(this->call_temp_,
14397 : : location);
14398 : 92971 : Bexpression* bref = ref->get_backend(context);
14399 : 92971 : Bstatement* bassn = gogo->backend()->assignment_statement(bfunction,
14400 : : bref, call,
14401 : : location);
14402 : :
14403 : 92971 : ref = Expression::make_temporary_reference(this->call_temp_, location);
14404 : 92971 : this->call_ = ref->get_backend(context);
14405 : :
14406 : 92971 : return gogo->backend()->compound_expression(bassn, this->call_,
14407 : 92971 : location);
14408 : : }
14409 : :
14410 : 1661285 : this->call_ = call;
14411 : 1661285 : return this->call_;
14412 : 1754256 : }
14413 : :
14414 : : // The cost of inlining a call expression.
14415 : :
14416 : : int
14417 : 915933 : Call_expression::do_inlining_cost() const
14418 : : {
14419 : 915933 : Func_expression* fn = this->fn_->func_expression();
14420 : :
14421 : : // FIXME: We don't yet support all kinds of calls.
14422 : 889808 : if (fn != NULL && fn->closure() != NULL)
14423 : : return 0x100000;
14424 : 1495720 : if (this->fn_->interface_field_reference_expression())
14425 : : return 0x100000;
14426 : 896180 : if (this->get_function_type()->is_method())
14427 : : return 0x100000;
14428 : :
14429 : : return 5;
14430 : : }
14431 : :
14432 : : // Export a call expression.
14433 : :
14434 : : void
14435 : 10850 : Call_expression::do_export(Export_function_body* efb) const
14436 : : {
14437 : 10850 : bool simple_call = (this->fn_->func_expression() != NULL);
14438 : 194 : if (!simple_call)
14439 : 194 : efb->write_c_string("(");
14440 : 10850 : this->fn_->export_expression(efb);
14441 : 10850 : if (!simple_call)
14442 : 194 : efb->write_c_string(")");
14443 : 10850 : this->export_arguments(efb);
14444 : 10850 : }
14445 : :
14446 : : // Export call expression arguments.
14447 : :
14448 : : void
14449 : 15102 : Call_expression::export_arguments(Export_function_body* efb) const
14450 : : {
14451 : 15102 : efb->write_c_string("(");
14452 : 15102 : if (this->args_ != NULL && !this->args_->empty())
14453 : : {
14454 : 12676 : Expression_list::const_iterator pa = this->args_->begin();
14455 : 12676 : (*pa)->export_expression(efb);
14456 : 22352 : for (pa++; pa != this->args_->end(); pa++)
14457 : : {
14458 : 9676 : efb->write_c_string(", ");
14459 : 9676 : (*pa)->export_expression(efb);
14460 : : }
14461 : 12676 : if (this->is_varargs_)
14462 : 199 : efb->write_c_string("...");
14463 : : }
14464 : 15102 : efb->write_c_string(")");
14465 : 15102 : }
14466 : :
14467 : : // Dump ast representation for a call expression.
14468 : :
14469 : : void
14470 : 0 : Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
14471 : : {
14472 : 0 : this->fn_->dump_expression(ast_dump_context);
14473 : 0 : ast_dump_context->ostream() << "(";
14474 : 0 : if (args_ != NULL)
14475 : 0 : ast_dump_context->dump_expression_list(this->args_);
14476 : :
14477 : 0 : ast_dump_context->ostream() << ") ";
14478 : 0 : }
14479 : :
14480 : : // Make a call expression.
14481 : :
14482 : : Call_expression*
14483 : 2128714 : Expression::make_call(Expression* fn, Expression_list* args, bool is_varargs,
14484 : : Location location)
14485 : : {
14486 : 2128714 : return new Call_expression(fn, args, is_varargs, location);
14487 : : }
14488 : :
14489 : : // Class Call_result_expression.
14490 : :
14491 : : // Traverse a call result.
14492 : :
14493 : : int
14494 : 3067286 : Call_result_expression::do_traverse(Traverse* traverse)
14495 : : {
14496 : 3067286 : if (traverse->remember_expression(this->call_))
14497 : : {
14498 : : // We have already traversed the call expression.
14499 : : return TRAVERSE_CONTINUE;
14500 : : }
14501 : 1669260 : return Expression::traverse(&this->call_, traverse);
14502 : : }
14503 : :
14504 : : // Get the type.
14505 : :
14506 : : Type*
14507 : 1990403 : Call_result_expression::do_type()
14508 : : {
14509 : 1990403 : if (this->classification() == EXPRESSION_ERROR)
14510 : 30 : return Type::make_error_type();
14511 : :
14512 : : // THIS->CALL_ can be replaced with a temporary reference due to
14513 : : // Call_expression::do_must_eval_in_order when there is an error.
14514 : 1990373 : Call_expression* ce = this->call_->call_expression();
14515 : 1990373 : if (ce == NULL)
14516 : : {
14517 : 12 : this->set_is_error();
14518 : 12 : return Type::make_error_type();
14519 : : }
14520 : 1990361 : Function_type* fntype = ce->get_function_type();
14521 : 1990361 : if (fntype == NULL)
14522 : : {
14523 : 0 : if (ce->issue_error())
14524 : : {
14525 : 0 : if (!ce->fn()->type()->is_error())
14526 : 0 : this->report_error(_("expected function"));
14527 : : }
14528 : 0 : this->set_is_error();
14529 : 0 : return Type::make_error_type();
14530 : : }
14531 : 1990361 : const Typed_identifier_list* results = fntype->results();
14532 : 1990361 : if (results == NULL || results->size() < 2)
14533 : : {
14534 : 4 : if (ce->issue_error())
14535 : 2 : this->report_error(_("number of results does not match "
14536 : : "number of values"));
14537 : 4 : return Type::make_error_type();
14538 : : }
14539 : : Typed_identifier_list::const_iterator pr = results->begin();
14540 : 3206421 : for (unsigned int i = 0; i < this->index_; ++i)
14541 : : {
14542 : 1216064 : if (pr == results->end())
14543 : : break;
14544 : 1216064 : ++pr;
14545 : : }
14546 : 1990357 : if (pr == results->end())
14547 : : {
14548 : 0 : if (ce->issue_error())
14549 : 0 : this->report_error(_("number of results does not match "
14550 : : "number of values"));
14551 : 0 : return Type::make_error_type();
14552 : : }
14553 : 1990357 : return pr->type();
14554 : : }
14555 : :
14556 : : // Check the type. Just make sure that we trigger the warning in
14557 : : // do_type.
14558 : :
14559 : : void
14560 : 146270 : Call_result_expression::do_check_types(Gogo*)
14561 : : {
14562 : 146270 : this->type();
14563 : 146270 : }
14564 : :
14565 : : // Determine the type. We have nothing to do here, but the 0 result
14566 : : // needs to pass down to the caller.
14567 : :
14568 : : void
14569 : 193148 : Call_result_expression::do_determine_type(Gogo* gogo, const Type_context*)
14570 : : {
14571 : 193148 : this->call_->determine_type_no_context(gogo);
14572 : 193148 : }
14573 : :
14574 : : // Return the backend representation. We just refer to the temporary set by the
14575 : : // call expression. We don't do this at lowering time because it makes it
14576 : : // hard to evaluate the call at the right time.
14577 : :
14578 : : Bexpression*
14579 : 167662 : Call_result_expression::do_get_backend(Translate_context* context)
14580 : : {
14581 : 167662 : Call_expression* ce = this->call_->call_expression();
14582 : 167662 : if (ce == NULL)
14583 : : {
14584 : 0 : go_assert(this->call_->is_error_expression());
14585 : 0 : return context->backend()->error_expression();
14586 : : }
14587 : 167662 : Temporary_statement* ts = ce->results();
14588 : 167662 : if (ts == NULL)
14589 : : {
14590 : 0 : go_assert(saw_errors());
14591 : 0 : return context->backend()->error_expression();
14592 : : }
14593 : 167662 : Expression* ref = Expression::make_temporary_reference(ts, this->location());
14594 : 167662 : ref = Expression::make_field_reference(ref, this->index_, this->location());
14595 : 167662 : return ref->get_backend(context);
14596 : : }
14597 : :
14598 : : // Dump ast representation for a call result expression.
14599 : :
14600 : : void
14601 : 0 : Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
14602 : : const
14603 : : {
14604 : : // FIXME: Wouldn't it be better if the call is assigned to a temporary
14605 : : // (struct) and the fields are referenced instead.
14606 : 0 : ast_dump_context->ostream() << this->index_ << "@(";
14607 : 0 : ast_dump_context->dump_expression(this->call_);
14608 : 0 : ast_dump_context->ostream() << ")";
14609 : 0 : }
14610 : :
14611 : : // Make a reference to a single result of a call which returns
14612 : : // multiple results.
14613 : :
14614 : : Expression*
14615 : 168017 : Expression::make_call_result(Call_expression* call, unsigned int index)
14616 : : {
14617 : 168017 : return new Call_result_expression(call, index);
14618 : : }
14619 : :
14620 : : // Class Index_expression.
14621 : :
14622 : : // Report whether EXPR is a map index expression. This is called when
14623 : : // types are determined but before lowering.
14624 : :
14625 : : bool
14626 : 34763 : Index_expression::is_map_index(Expression* expr)
14627 : : {
14628 : 34763 : if (expr->map_index_expression() != NULL)
14629 : : return true;
14630 : 34763 : if (expr->index_expression() != NULL)
14631 : 14232 : return expr->index_expression()->left_->type()->map_type() != NULL;
14632 : : return false;
14633 : : }
14634 : :
14635 : : // Traversal.
14636 : :
14637 : : int
14638 : 823151 : Index_expression::do_traverse(Traverse* traverse)
14639 : : {
14640 : 823151 : if (Expression::traverse(&this->left_, traverse) == TRAVERSE_EXIT
14641 : 823151 : || Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT
14642 : 823150 : || (this->end_ != NULL
14643 : 238856 : && Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
14644 : 1646301 : || (this->cap_ != NULL
14645 : 19045 : && Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT))
14646 : 1 : return TRAVERSE_EXIT;
14647 : : return TRAVERSE_CONTINUE;
14648 : : }
14649 : :
14650 : : void
14651 : 213061 : Index_expression::do_determine_type(Gogo* gogo, const Type_context*)
14652 : : {
14653 : 213061 : this->left_->determine_type_no_context(gogo);
14654 : :
14655 : 213061 : Type_context end_context;
14656 : 213061 : Type* type = this->left_->type();
14657 : 213061 : if (type->array_type() != NULL
14658 : 51651 : || (type->points_to() != NULL
14659 : 51652 : && type->points_to()->array_type() != NULL
14660 : 15822 : && !type->points_to()->is_slice_type())
14661 : 35829 : || type->is_string_type())
14662 : : {
14663 : 196990 : Type_context index_context(Type::lookup_integer_type("int"), false);
14664 : 196990 : this->start_->determine_type(gogo, &index_context);
14665 : 196990 : end_context = index_context;
14666 : : }
14667 : 16071 : else if (type->map_type() != NULL)
14668 : : {
14669 : 32128 : Type_context key_context(type->map_type()->key_type(), false);
14670 : 16064 : this->start_->determine_type(gogo, &key_context);
14671 : : }
14672 : 7 : else if (type->is_error())
14673 : 1 : this->set_is_error();
14674 : : else
14675 : : {
14676 : 6 : if (this->cap_ != NULL)
14677 : 0 : this->report_error(_("invalid 3-index slice of object "
14678 : : "that is not a slice"));
14679 : 6 : else if (this->end_ != NULL)
14680 : 5 : this->report_error(_("attempt to slice object that is not "
14681 : : "array, slice, or string"));
14682 : : else
14683 : 1 : this->report_error(_("attempt to index object that is not "
14684 : : "array, slice, string, or map"));
14685 : :
14686 : 6 : this->start_->determine_type_no_context(gogo);
14687 : : }
14688 : :
14689 : 213061 : if (this->end_ != NULL)
14690 : 50072 : this->end_->determine_type(gogo, &end_context);
14691 : 213061 : if (this->cap_ != NULL)
14692 : 3824 : this->cap_->determine_type(gogo, &end_context);
14693 : 213061 : }
14694 : :
14695 : : Type*
14696 : 364616 : Index_expression::do_type()
14697 : : {
14698 : 364616 : if (this->is_error_expression())
14699 : 10 : return Type::make_error_type();
14700 : :
14701 : 364606 : Type* type = this->left_->type();
14702 : 364606 : if (this->end_ != NULL)
14703 : : {
14704 : : // A slice of an array is a slice type. A slice of a slice or
14705 : : // string type is that same type.
14706 : 112050 : Array_type* at = type->deref()->array_type();
14707 : 43426 : if (at != NULL && !at->is_slice_type())
14708 : 16257 : return Type::make_array_type(at->element_type(), NULL);
14709 : 39768 : return type;
14710 : : }
14711 : 617162 : if (type->deref()->array_type() != NULL)
14712 : 816789 : return type->deref()->array_type()->element_type();
14713 : 36318 : else if (type->is_string_type())
14714 : 14018 : return Type::lookup_integer_type("byte");
14715 : 22300 : else if (type->map_type() != NULL)
14716 : 44600 : return type->map_type()->val_type();
14717 : : else
14718 : 0 : return Type::make_error_type();
14719 : : }
14720 : :
14721 : : void
14722 : 157136 : Index_expression::do_check_types(Gogo*)
14723 : : {
14724 : 157136 : if (this->is_error_expression())
14725 : : return;
14726 : :
14727 : 157129 : Type* ltype = this->left_->type();
14728 : 157129 : if (ltype->is_error())
14729 : : {
14730 : 0 : go_assert(saw_errors());
14731 : : return;
14732 : : }
14733 : :
14734 : 157129 : if (this->left_->is_type_expression())
14735 : : {
14736 : 0 : this->report_error(_("attempt to index type expression"));
14737 : 0 : return;
14738 : : }
14739 : :
14740 : 157129 : if (ltype->array_type() != NULL)
14741 : : {
14742 : 110274 : if (!Array_index_expression::check_indexes(this->left_, this->start_,
14743 : : this->end_, this->cap_,
14744 : : this->location()))
14745 : 1535 : this->set_is_error();
14746 : : }
14747 : 46855 : else if (ltype->points_to() != NULL
14748 : 15637 : && ltype->points_to()->array_type() != NULL
14749 : 62492 : && !ltype->points_to()->is_slice_type())
14750 : : {
14751 : 15637 : Expression* deref = Expression::make_dereference(this->left_,
14752 : : NIL_CHECK_DEFAULT,
14753 : : this->location());
14754 : 15637 : if (!Array_index_expression::check_indexes(deref, this->start_,
14755 : : this->end_, this->cap_,
14756 : : this->location()))
14757 : 979 : this->set_is_error();
14758 : 15637 : delete deref;
14759 : : }
14760 : 31218 : else if (ltype->is_string_type())
14761 : : {
14762 : 17514 : if (this->cap_ != NULL)
14763 : 8 : this->report_error(_("invalid 3-index slice of string"));
14764 : : else
14765 : : {
14766 : 17506 : if (!String_index_expression::check_indexes(this->left_,
14767 : : this->start_,
14768 : : this->end_,
14769 : : this->location()))
14770 : 15 : this->set_is_error();
14771 : : }
14772 : : }
14773 : 13704 : else if (ltype->map_type() != NULL)
14774 : : {
14775 : 13704 : if (this->end_ != NULL || this->cap_ != NULL)
14776 : 0 : this->report_error(_("invalid slice of map"));
14777 : : else
14778 : : {
14779 : 13704 : Map_type* mt = ltype->map_type();
14780 : 13704 : std::string reason;
14781 : 13704 : if (!Type::are_assignable(mt->key_type(), this->start_->type(),
14782 : : &reason))
14783 : : {
14784 : 1 : if (reason.empty())
14785 : 0 : this->report_error(_("incompatible type for map index"));
14786 : : else
14787 : : {
14788 : 1 : go_error_at(this->location(),
14789 : : "incompatible type for map index (%s)",
14790 : : reason.c_str());
14791 : 1 : this->set_is_error();
14792 : : }
14793 : : }
14794 : 13704 : }
14795 : : }
14796 : : else
14797 : 0 : go_unreachable();
14798 : : }
14799 : :
14800 : : bool
14801 : 40649 : Index_expression::do_is_addressable() const
14802 : : {
14803 : 40649 : if (this->is_error_expression())
14804 : : return true;
14805 : :
14806 : 40649 : Type* type = this->left_->type();
14807 : 40649 : if (type->is_error())
14808 : : return true;
14809 : :
14810 : : // A slice index is addressable, and an index of an addressable
14811 : : // array is addressable.
14812 : :
14813 : 40649 : bool is_pointer = false;
14814 : 40649 : if (type->points_to() != NULL
14815 : 3647 : && type->points_to()->array_type() != NULL
14816 : 44296 : && !type->points_to()->is_slice_type())
14817 : : {
14818 : 3647 : type = type->points_to();
14819 : 3647 : is_pointer = true;
14820 : : }
14821 : :
14822 : 46452 : if (type->array_type() == NULL)
14823 : : return false;
14824 : :
14825 : 34904 : if (this->end_ != NULL)
14826 : : return false;
14827 : 34850 : if (type->is_slice_type())
14828 : : return true;
14829 : 13523 : return is_pointer || this->left_->is_addressable();
14830 : : }
14831 : :
14832 : : // We need to do a nil check of any pointer dereference.
14833 : :
14834 : : void
14835 : 4655 : Index_expression::do_issue_nil_check()
14836 : : {
14837 : 4655 : this->left_->issue_nil_check();
14838 : 4655 : this->needs_nil_check_ = true;
14839 : 4655 : }
14840 : :
14841 : : // Lower an index expression. This converts the generic index
14842 : : // expression into an array index, a string index, or a map index.
14843 : :
14844 : : Expression*
14845 : 189160 : Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
14846 : : {
14847 : 189160 : if (this->is_error_expression())
14848 : 2543 : return Expression::make_error(this->location());
14849 : :
14850 : 186617 : Location location = this->location();
14851 : 186617 : Expression* left = this->left_;
14852 : 186617 : Expression* start = this->start_;
14853 : 186617 : Expression* end = this->end_;
14854 : 186617 : Expression* cap = this->cap_;
14855 : :
14856 : 186617 : Type* type = left->type();
14857 : 186617 : if (type->is_error())
14858 : : {
14859 : 1 : go_assert(saw_errors());
14860 : 1 : return Expression::make_error(location);
14861 : : }
14862 : 186616 : else if (type->array_type() != NULL)
14863 : 138128 : return Expression::make_array_index(left, start, end, cap, location);
14864 : 48488 : else if (type->points_to() != NULL
14865 : 14748 : && type->points_to()->array_type() != NULL
14866 : 63236 : && !type->points_to()->is_slice_type())
14867 : : {
14868 : 14748 : Expression* deref =
14869 : 14748 : Expression::make_dereference(left, NIL_CHECK_DEFAULT, location);
14870 : :
14871 : : // For an ordinary index into the array, the pointer will be
14872 : : // dereferenced. For a slice it will not--the resulting slice
14873 : : // will simply reuse the pointer, which is incorrect if that
14874 : : // pointer is nil. We may also be in a context that requires a
14875 : : // nil check.
14876 : 14748 : if (end != NULL || cap != NULL || this->needs_nil_check_)
14877 : 3964 : deref->issue_nil_check();
14878 : :
14879 : 14748 : return Expression::make_array_index(deref, start, end, cap, location);
14880 : : }
14881 : 33740 : else if (type->is_string_type())
14882 : : {
14883 : 19681 : go_assert(cap == NULL);
14884 : 19681 : return Expression::make_string_index(left, start, end, location);
14885 : : }
14886 : 14059 : else if (type->map_type() != NULL)
14887 : : {
14888 : 14059 : go_assert(end == NULL && cap == NULL);
14889 : 14059 : return Expression::make_map_index(left, start, location);
14890 : : }
14891 : : else
14892 : 0 : go_unreachable();
14893 : : }
14894 : :
14895 : : // Write an indexed expression
14896 : : // (expr[expr:expr:expr], expr[expr:expr] or expr[expr]) to a dump context.
14897 : :
14898 : : void
14899 : 0 : Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context,
14900 : : const Expression* expr,
14901 : : const Expression* start,
14902 : : const Expression* end,
14903 : : const Expression* cap)
14904 : : {
14905 : 0 : expr->dump_expression(ast_dump_context);
14906 : 0 : ast_dump_context->ostream() << "[";
14907 : 0 : start->dump_expression(ast_dump_context);
14908 : 0 : if (end != NULL)
14909 : : {
14910 : 0 : ast_dump_context->ostream() << ":";
14911 : 0 : end->dump_expression(ast_dump_context);
14912 : : }
14913 : 0 : if (cap != NULL)
14914 : : {
14915 : 0 : ast_dump_context->ostream() << ":";
14916 : 0 : cap->dump_expression(ast_dump_context);
14917 : : }
14918 : 0 : ast_dump_context->ostream() << "]";
14919 : 0 : }
14920 : :
14921 : : // Dump ast representation for an index expression.
14922 : :
14923 : : void
14924 : 0 : Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
14925 : : const
14926 : : {
14927 : 0 : Index_expression::dump_index_expression(ast_dump_context, this->left_,
14928 : 0 : this->start_, this->end_, this->cap_);
14929 : 0 : }
14930 : :
14931 : : // Make an index expression.
14932 : :
14933 : : Expression*
14934 : 181155 : Expression::make_index(Expression* left, Expression* start, Expression* end,
14935 : : Expression* cap, Location location)
14936 : : {
14937 : 181155 : return new Index_expression(left, start, end, cap, location);
14938 : : }
14939 : :
14940 : : // Class Array_index_expression.
14941 : :
14942 : : // Array index traversal.
14943 : :
14944 : : int
14945 : 2785745 : Array_index_expression::do_traverse(Traverse* traverse)
14946 : : {
14947 : 2785745 : if (Expression::traverse(&this->array_, traverse) == TRAVERSE_EXIT)
14948 : : return TRAVERSE_EXIT;
14949 : 2759773 : if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
14950 : : return TRAVERSE_EXIT;
14951 : 2756656 : if (this->end_ != NULL)
14952 : : {
14953 : 629217 : if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
14954 : : return TRAVERSE_EXIT;
14955 : : }
14956 : 2756562 : if (this->cap_ != NULL)
14957 : : {
14958 : 58788 : if (Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
14959 : : return TRAVERSE_EXIT;
14960 : : }
14961 : : return TRAVERSE_CONTINUE;
14962 : : }
14963 : :
14964 : : // Return the type of an array index.
14965 : :
14966 : : Type*
14967 : 2602583 : Array_index_expression::do_type()
14968 : : {
14969 : 2602583 : if (this->type_ == NULL)
14970 : : {
14971 : 218694 : Array_type* type = this->array_->type()->array_type();
14972 : 218694 : if (type == NULL)
14973 : 0 : this->type_ = Type::make_error_type();
14974 : 218694 : else if (this->end_ == NULL)
14975 : 166047 : this->type_ = type->element_type();
14976 : 52647 : else if (type->is_slice_type())
14977 : : {
14978 : : // A slice of a slice has the same type as the original
14979 : : // slice.
14980 : 79858 : this->type_ = this->array_->type()->deref();
14981 : : }
14982 : : else
14983 : : {
14984 : : // A slice of an array is a slice.
14985 : 12718 : this->type_ = Type::make_array_type(type->element_type(), NULL);
14986 : : }
14987 : : }
14988 : 2602583 : return this->type_;
14989 : : }
14990 : :
14991 : : // Set the type of an array index.
14992 : :
14993 : : void
14994 : 183534 : Array_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
14995 : : {
14996 : 183534 : this->array_->determine_type_no_context(gogo);
14997 : :
14998 : 183534 : Type_context index_context(Type::lookup_integer_type("int"), false);
14999 : 183534 : this->start_->determine_type(gogo, &index_context);
15000 : 183534 : if (this->end_ != NULL)
15001 : 56850 : this->end_->determine_type(gogo, &index_context);
15002 : 183534 : if (this->cap_ != NULL)
15003 : 3342 : this->cap_->determine_type(gogo, &index_context);
15004 : 183534 : }
15005 : :
15006 : : // Check types of an array index.
15007 : :
15008 : : void
15009 : 551 : Array_index_expression::do_check_types(Gogo*)
15010 : : {
15011 : 551 : if (!Array_index_expression::check_indexes(this->array_, this->start_,
15012 : : this->end_, this->cap_,
15013 : : this->location()))
15014 : 0 : this->set_is_error();
15015 : 551 : }
15016 : :
15017 : : // A static function to check array index types. This is also called
15018 : : // by Index_expression::do_check_types. It reports whether type
15019 : : // checking succeeded.
15020 : :
15021 : : bool
15022 : 126462 : Array_index_expression::check_indexes(Expression* array, Expression* start,
15023 : : Expression* end, Expression* cap,
15024 : : Location loc)
15025 : : {
15026 : 126462 : bool ret = true;
15027 : :
15028 : 126462 : Numeric_constant nc;
15029 : 126462 : unsigned long v;
15030 : 126467 : if (start->type()->integer_type() == NULL
15031 : 5 : && !start->type()->is_error()
15032 : 5 : && (!start->type()->is_abstract()
15033 : 0 : || !start->numeric_constant_value(&nc)
15034 : 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15035 : : {
15036 : 5 : go_error_at(loc, "index must be integer");
15037 : 5 : ret = false;
15038 : : }
15039 : :
15040 : 126462 : if (end != NULL
15041 : 53125 : && end->type()->integer_type() == NULL
15042 : 15763 : && !end->type()->is_error()
15043 : 15754 : && !end->is_nil_expression()
15044 : 0 : && !end->is_error_expression()
15045 : 126462 : && (!end->type()->is_abstract()
15046 : 0 : || !end->numeric_constant_value(&nc)
15047 : 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15048 : : {
15049 : 0 : go_error_at(loc, "slice end must be integer");
15050 : 0 : ret = false;
15051 : : }
15052 : :
15053 : 126462 : if (cap != NULL
15054 : 3809 : && cap->type()->integer_type() == NULL
15055 : 8 : && !cap->type()->is_error()
15056 : 0 : && !cap->is_nil_expression()
15057 : 0 : && !cap->is_error_expression()
15058 : 126462 : && (!cap->type()->is_abstract()
15059 : 0 : || !cap->numeric_constant_value(&nc)
15060 : 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15061 : : {
15062 : 0 : go_error_at(loc, "slice capacity must be integer");
15063 : 0 : ret = false;
15064 : : }
15065 : :
15066 : 126462 : Array_type* array_type = array->type()->array_type();
15067 : 126462 : if (array_type == NULL)
15068 : : {
15069 : 0 : go_assert(array->type()->is_error());
15070 : : return false;
15071 : : }
15072 : :
15073 : 126462 : unsigned int int_bits =
15074 : 252924 : Type::lookup_integer_type("int")->integer_type()->bits();
15075 : :
15076 : 126462 : Numeric_constant lvalnc;
15077 : 126462 : mpz_t lval;
15078 : 126462 : bool lval_valid = (array_type->length() != NULL
15079 : 51618 : && array_type->length()->numeric_constant_value(&lvalnc)
15080 : 178080 : && lvalnc.to_int(&lval));
15081 : 126462 : Numeric_constant inc;
15082 : 126462 : mpz_t ival;
15083 : 126462 : bool ival_valid = false;
15084 : 126462 : if (start->numeric_constant_value(&inc) && inc.to_int(&ival))
15085 : : {
15086 : 71376 : ival_valid = true;
15087 : 106799 : if (mpz_sgn(ival) < 0
15088 : 70400 : || mpz_sizeinbase(ival, 2) >= int_bits
15089 : 70398 : || (lval_valid
15090 : 24171 : && (end == NULL
15091 : 24171 : ? mpz_cmp(ival, lval) >= 0
15092 : 11252 : : mpz_cmp(ival, lval) > 0)))
15093 : : {
15094 : 1491 : go_error_at(start->location(), "array index out of bounds");
15095 : 1491 : ret = false;
15096 : : }
15097 : : }
15098 : :
15099 : 126462 : if (end != NULL && !end->is_nil_expression())
15100 : : {
15101 : 21608 : Numeric_constant enc;
15102 : 21608 : mpz_t eval;
15103 : 21608 : bool eval_valid = false;
15104 : 21608 : if (end->numeric_constant_value(&enc) && enc.to_int(&eval))
15105 : : {
15106 : 7697 : eval_valid = true;
15107 : 7697 : if (mpz_sgn(eval) < 0
15108 : 6723 : || mpz_sizeinbase(eval, 2) >= int_bits
15109 : 6721 : || (lval_valid && mpz_cmp(eval, lval) > 0))
15110 : : {
15111 : 1489 : go_error_at(end->location(), "array index out of bounds");
15112 : 1489 : ret = false;
15113 : : }
15114 : 6208 : else if (ival_valid && mpz_cmp(ival, eval) > 0)
15115 : : {
15116 : 14 : go_error_at(loc, "inverted slice range");
15117 : 14 : ret = false;
15118 : : }
15119 : : }
15120 : :
15121 : 21608 : Numeric_constant cnc;
15122 : 21608 : mpz_t cval;
15123 : 21608 : if (cap != NULL
15124 : 25409 : && cap->numeric_constant_value(&cnc) && cnc.to_int(&cval))
15125 : : {
15126 : 1201 : if (mpz_sgn(cval) < 0
15127 : 1201 : || mpz_sizeinbase(cval, 2) >= int_bits
15128 : 1201 : || (lval_valid && mpz_cmp(cval, lval) > 0))
15129 : : {
15130 : 3 : go_error_at(cap->location(), "array index out of bounds");
15131 : 3 : ret = false;
15132 : : }
15133 : 1198 : else if (ival_valid && mpz_cmp(ival, cval) > 0)
15134 : : {
15135 : 10 : go_error_at(cap->location(),
15136 : : "invalid slice index: capacity less than start");
15137 : 10 : ret = false;
15138 : : }
15139 : 1188 : else if (eval_valid && mpz_cmp(eval, cval) > 0)
15140 : : {
15141 : 6 : go_error_at(cap->location(),
15142 : : "invalid slice index: capacity less than length");
15143 : 6 : ret = false;
15144 : : }
15145 : 1201 : mpz_clear(cval);
15146 : : }
15147 : :
15148 : 21608 : if (eval_valid)
15149 : 7697 : mpz_clear(eval);
15150 : 21608 : }
15151 : 126462 : if (ival_valid)
15152 : 71376 : mpz_clear(ival);
15153 : 126462 : if (lval_valid)
15154 : 51618 : mpz_clear(lval);
15155 : :
15156 : : // A slice of an array requires an addressable array. A slice of a
15157 : : // slice is always possible.
15158 : 126462 : if (end != NULL && !array_type->is_slice_type())
15159 : : {
15160 : 14285 : if (!array->is_addressable())
15161 : : {
15162 : 4 : go_error_at(loc, "slice of unaddressable value");
15163 : 4 : ret = false;
15164 : : }
15165 : : else
15166 : : {
15167 : : // Set the array address taken but not escape. The escape
15168 : : // analysis will make it escape to heap when needed.
15169 : 14281 : array->address_taken(false);
15170 : : }
15171 : : }
15172 : :
15173 : 126462 : return ret;
15174 : 126462 : }
15175 : :
15176 : : // The subexpressions of an array index must be evaluated in order.
15177 : : // If this is indexing into an array, rather than a slice, then only
15178 : : // the index should be evaluated. Since this is called for values on
15179 : : // the left hand side of an assigment, evaluating the array, meaning
15180 : : // copying the array, will cause a different array to be modified.
15181 : :
15182 : : bool
15183 : 4166 : Array_index_expression::do_must_eval_subexpressions_in_order(
15184 : : int* skip) const
15185 : : {
15186 : 4166 : *skip = this->array_->type()->is_slice_type() ? 0 : 1;
15187 : 4166 : return true;
15188 : : }
15189 : :
15190 : : // Flatten array indexing: add temporary variables and bounds checks.
15191 : :
15192 : : Expression*
15193 : 249462 : Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
15194 : : Statement_inserter* inserter)
15195 : : {
15196 : 249462 : if (this->is_flattened_)
15197 : 40350 : return this;
15198 : 209112 : this->is_flattened_ = true;
15199 : :
15200 : 209112 : Location loc = this->location();
15201 : :
15202 : 209112 : if (this->is_error_expression())
15203 : 0 : return Expression::make_error(loc);
15204 : :
15205 : 209112 : Expression* array = this->array_;
15206 : 209112 : Expression* start = this->start_;
15207 : 209112 : Expression* end = this->end_;
15208 : 209112 : Expression* cap = this->cap_;
15209 : 209112 : if (array->is_error_expression()
15210 : 209112 : || array->type()->is_error_type()
15211 : 209112 : || start->is_error_expression()
15212 : 208675 : || start->type()->is_error_type()
15213 : 208675 : || (end != NULL
15214 : 104236 : && (end->is_error_expression() || end->type()->is_error_type()))
15215 : 417491 : || (cap != NULL
15216 : 7536 : && (cap->is_error_expression() || cap->type()->is_error_type())))
15217 : : {
15218 : 737 : go_assert(saw_errors());
15219 : 737 : return Expression::make_error(loc);
15220 : : }
15221 : :
15222 : 208375 : Array_type* array_type = this->array_->type()->array_type();
15223 : 208375 : if (array_type == NULL)
15224 : : {
15225 : 0 : go_assert(saw_errors());
15226 : 0 : return Expression::make_error(loc);
15227 : : }
15228 : :
15229 : 208375 : Temporary_statement* temp;
15230 : 208375 : if (array_type->is_slice_type() && !array->is_multi_eval_safe())
15231 : : {
15232 : 18925 : temp = Statement::make_temporary(NULL, array, loc);
15233 : 18925 : inserter->insert(temp);
15234 : 18925 : this->array_ = Expression::make_temporary_reference(temp, loc);
15235 : 18925 : array = this->array_;
15236 : : }
15237 : 208375 : if (!start->is_multi_eval_safe())
15238 : : {
15239 : 28762 : temp = Statement::make_temporary(NULL, start, loc);
15240 : 28762 : inserter->insert(temp);
15241 : 28762 : this->start_ = Expression::make_temporary_reference(temp, loc);
15242 : 28762 : start = this->start_;
15243 : : }
15244 : 208375 : if (end != NULL
15245 : 51966 : && !end->is_nil_expression()
15246 : 243893 : && !end->is_multi_eval_safe())
15247 : : {
15248 : 3946 : temp = Statement::make_temporary(NULL, end, loc);
15249 : 3946 : inserter->insert(temp);
15250 : 3946 : this->end_ = Expression::make_temporary_reference(temp, loc);
15251 : 3946 : end = this->end_;
15252 : : }
15253 : 208375 : if (cap != NULL && !cap->is_multi_eval_safe())
15254 : : {
15255 : 328 : temp = Statement::make_temporary(NULL, cap, loc);
15256 : 328 : inserter->insert(temp);
15257 : 328 : this->cap_ = Expression::make_temporary_reference(temp, loc);
15258 : 328 : cap = this->cap_;
15259 : : }
15260 : :
15261 : 208375 : if (!this->needs_bounds_check_)
15262 : 33694 : return this;
15263 : :
15264 : 174681 : Expression* len;
15265 : 174681 : if (!array_type->is_slice_type())
15266 : : {
15267 : 80221 : len = array_type->get_length(gogo, this->array_);
15268 : 80221 : go_assert(len->is_constant());
15269 : : }
15270 : : else
15271 : : {
15272 : 94460 : len = array_type->get_length(gogo, this->array_->copy());
15273 : 94460 : temp = Statement::make_temporary(NULL, len, loc);
15274 : 94460 : temp->determine_types(gogo);
15275 : 94460 : inserter->insert(temp);
15276 : 94460 : len = Expression::make_temporary_reference(temp, loc);
15277 : : }
15278 : :
15279 : 174681 : Expression* scap = NULL;
15280 : 174681 : if (array_type->is_slice_type())
15281 : : {
15282 : 94460 : scap = array_type->get_capacity(gogo, this->array_->copy());
15283 : 94460 : temp = Statement::make_temporary(NULL, scap, loc);
15284 : 94460 : temp->determine_types(gogo);
15285 : 94460 : inserter->insert(temp);
15286 : 94460 : scap = Expression::make_temporary_reference(temp, loc);
15287 : : }
15288 : :
15289 : : // The order of bounds checks here matches the order used by the gc
15290 : : // compiler, as tested by issue30116[u].go.
15291 : :
15292 : 174681 : if (cap != NULL)
15293 : : {
15294 : 3766 : if (array_type->is_slice_type())
15295 : 2260 : Expression::check_bounds(gogo, cap, OPERATOR_LE, scap,
15296 : : Runtime::PANIC_SLICE3_ACAP,
15297 : : Runtime::PANIC_SLICE3_ACAP_U,
15298 : : Runtime::PANIC_EXTEND_SLICE3_ACAP,
15299 : : Runtime::PANIC_EXTEND_SLICE3_ACAP_U,
15300 : : inserter, loc);
15301 : : else
15302 : 1506 : Expression::check_bounds(gogo, cap, OPERATOR_LE, len,
15303 : : Runtime::PANIC_SLICE3_ALEN,
15304 : : Runtime::PANIC_SLICE3_ALEN_U,
15305 : : Runtime::PANIC_EXTEND_SLICE3_ALEN,
15306 : : Runtime::PANIC_EXTEND_SLICE3_ALEN_U,
15307 : : inserter, loc);
15308 : :
15309 : 3766 : Expression* start_bound = cap;
15310 : 3766 : if (end != NULL && !end->is_nil_expression())
15311 : : {
15312 : 3766 : Expression::check_bounds(gogo, end, OPERATOR_LE, cap,
15313 : : Runtime::PANIC_SLICE3_B,
15314 : : Runtime::PANIC_SLICE3_B_U,
15315 : : Runtime::PANIC_EXTEND_SLICE3_B,
15316 : : Runtime::PANIC_EXTEND_SLICE3_B_U,
15317 : : inserter, loc);
15318 : 3766 : start_bound = end;
15319 : : }
15320 : :
15321 : 3766 : Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
15322 : : Runtime::PANIC_SLICE3_C,
15323 : : Runtime::PANIC_SLICE3_C_U,
15324 : : Runtime::PANIC_EXTEND_SLICE3_C,
15325 : : Runtime::PANIC_EXTEND_SLICE3_C_U,
15326 : : inserter, loc);
15327 : : }
15328 : 170915 : else if (end != NULL && !end->is_nil_expression())
15329 : : {
15330 : 16099 : if (array_type->is_slice_type())
15331 : 11950 : Expression::check_bounds(gogo, end, OPERATOR_LE, scap,
15332 : : Runtime::PANIC_SLICE_ACAP,
15333 : : Runtime::PANIC_SLICE_ACAP_U,
15334 : : Runtime::PANIC_EXTEND_SLICE_ACAP,
15335 : : Runtime::PANIC_EXTEND_SLICE_ACAP_U,
15336 : : inserter, loc);
15337 : : else
15338 : 4149 : Expression::check_bounds(gogo, end, OPERATOR_LE, len,
15339 : : Runtime::PANIC_SLICE_ALEN,
15340 : : Runtime::PANIC_SLICE_ALEN_U,
15341 : : Runtime::PANIC_EXTEND_SLICE_ALEN,
15342 : : Runtime::PANIC_EXTEND_SLICE_ALEN_U,
15343 : : inserter, loc);
15344 : :
15345 : 16099 : Expression::check_bounds(gogo, start, OPERATOR_LE, end,
15346 : : Runtime::PANIC_SLICE_B,
15347 : : Runtime::PANIC_SLICE_B_U,
15348 : : Runtime::PANIC_EXTEND_SLICE_B,
15349 : : Runtime::PANIC_EXTEND_SLICE_B_U,
15350 : : inserter, loc);
15351 : : }
15352 : 154816 : else if (end != NULL)
15353 : : {
15354 : 15197 : Expression* start_bound;
15355 : 15197 : if (array_type->is_slice_type())
15356 : : start_bound = scap;
15357 : : else
15358 : 6666 : start_bound = len;
15359 : 15197 : Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
15360 : : Runtime::PANIC_SLICE_B,
15361 : : Runtime::PANIC_SLICE_B_U,
15362 : : Runtime::PANIC_EXTEND_SLICE_B,
15363 : : Runtime::PANIC_EXTEND_SLICE_B_U,
15364 : : inserter, loc);
15365 : : }
15366 : : else
15367 : 139619 : Expression::check_bounds(gogo, start, OPERATOR_LT, len,
15368 : : Runtime::PANIC_INDEX,
15369 : : Runtime::PANIC_INDEX_U,
15370 : : Runtime::PANIC_EXTEND_INDEX,
15371 : : Runtime::PANIC_EXTEND_INDEX_U,
15372 : : inserter, loc);
15373 : :
15374 : 174681 : return this;
15375 : : }
15376 : :
15377 : : // Return whether this expression is addressable.
15378 : :
15379 : : bool
15380 : 1158 : Array_index_expression::do_is_addressable() const
15381 : : {
15382 : : // A slice expression is not addressable.
15383 : 1158 : if (this->end_ != NULL)
15384 : : return false;
15385 : :
15386 : : // An index into a slice is addressable.
15387 : 1104 : if (this->array_->type()->is_slice_type())
15388 : : return true;
15389 : :
15390 : : // An index into an array is addressable if the array is
15391 : : // addressable.
15392 : 432 : return this->array_->is_addressable();
15393 : : }
15394 : :
15395 : : void
15396 : 13984 : Array_index_expression::do_address_taken(bool escapes)
15397 : : {
15398 : : // In &x[0], if x is a slice, then x's address is not taken.
15399 : 13984 : if (!this->array_->type()->is_slice_type())
15400 : 4590 : this->array_->address_taken(escapes);
15401 : 13984 : }
15402 : :
15403 : : // Get the backend representation for an array index.
15404 : :
15405 : : Bexpression*
15406 : 207326 : Array_index_expression::do_get_backend(Translate_context* context)
15407 : : {
15408 : 207326 : Array_type* array_type = this->array_->type()->array_type();
15409 : 207326 : if (array_type == NULL)
15410 : : {
15411 : 0 : go_assert(this->array_->type()->is_error());
15412 : 0 : return context->backend()->error_expression();
15413 : : }
15414 : 207326 : go_assert(!array_type->is_slice_type()
15415 : : || this->array_->is_multi_eval_safe());
15416 : :
15417 : 207326 : Location loc = this->location();
15418 : 207326 : Gogo* gogo = context->gogo();
15419 : :
15420 : 207326 : Type* int_type = Type::lookup_integer_type("int");
15421 : 207326 : Btype* int_btype = int_type->get_backend(gogo);
15422 : :
15423 : : // Convert the length and capacity to "int". FIXME: Do we need to
15424 : : // do this?
15425 : 207326 : Bexpression* length = NULL;
15426 : 207326 : if (this->end_ == NULL || this->end_->is_nil_expression())
15427 : : {
15428 : 171814 : Expression* len = array_type->get_length(gogo, this->array_);
15429 : 171814 : length = len->get_backend(context);
15430 : 171814 : length = gogo->backend()->convert_expression(int_btype, length, loc);
15431 : : }
15432 : :
15433 : 207326 : Bexpression* capacity = NULL;
15434 : 207326 : if (this->end_ != NULL)
15435 : : {
15436 : 51960 : Expression* cap = array_type->get_capacity(gogo, this->array_);
15437 : 51960 : capacity = cap->get_backend(context);
15438 : 51960 : capacity = gogo->backend()->convert_expression(int_btype, capacity, loc);
15439 : : }
15440 : :
15441 : 207326 : Bexpression* cap_arg = capacity;
15442 : 207326 : if (this->cap_ != NULL)
15443 : : {
15444 : 3766 : cap_arg = this->cap_->get_backend(context);
15445 : 3766 : cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
15446 : : }
15447 : :
15448 : 207326 : if (length == NULL)
15449 : 35512 : length = cap_arg;
15450 : :
15451 : 207326 : if (this->start_->type()->integer_type() == NULL
15452 : 0 : && !Type::are_convertible(int_type, this->start_->type(), NULL))
15453 : : {
15454 : 0 : go_assert(saw_errors());
15455 : 0 : return context->backend()->error_expression();
15456 : : }
15457 : :
15458 : 207326 : Bexpression* start = this->start_->get_backend(context);
15459 : 207326 : start = gogo->backend()->convert_expression(int_btype, start, loc);
15460 : :
15461 : 207326 : Bfunction* bfn = context->function()->func_value()->get_decl();
15462 : 207326 : if (this->end_ == NULL)
15463 : : {
15464 : : // Simple array indexing.
15465 : 155366 : Bexpression* ret;
15466 : 155366 : if (!array_type->is_slice_type())
15467 : : {
15468 : 66928 : Bexpression* array = this->array_->get_backend(context);
15469 : 66928 : ret = gogo->backend()->array_index_expression(array, start, loc);
15470 : : }
15471 : : else
15472 : : {
15473 : 88438 : Expression* valptr = array_type->get_value_pointer(gogo,
15474 : : this->array_);
15475 : 88438 : Bexpression* ptr = valptr->get_backend(context);
15476 : 88438 : ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
15477 : :
15478 : 176876 : Type* ele_type = this->array_->type()->array_type()->element_type();
15479 : 88438 : Btype* ele_btype = ele_type->get_backend(gogo);
15480 : 88438 : ret = gogo->backend()->indirect_expression(ele_btype, ptr, false,
15481 : : loc);
15482 : : }
15483 : 155366 : return ret;
15484 : : }
15485 : :
15486 : : // Slice expression.
15487 : :
15488 : 51960 : Bexpression* end;
15489 : 51960 : if (this->end_->is_nil_expression())
15490 : : end = length;
15491 : : else
15492 : : {
15493 : 35512 : end = this->end_->get_backend(context);
15494 : 35512 : end = gogo->backend()->convert_expression(int_btype, end, loc);
15495 : : }
15496 : :
15497 : 51960 : Bexpression* result_length =
15498 : 51960 : gogo->backend()->binary_expression(OPERATOR_MINUS, end, start, loc);
15499 : :
15500 : 51960 : Bexpression* result_capacity =
15501 : 51960 : gogo->backend()->binary_expression(OPERATOR_MINUS, cap_arg, start, loc);
15502 : :
15503 : : // If the new capacity is zero, don't change val. Otherwise we can
15504 : : // get a pointer to the next object in memory, keeping it live
15505 : : // unnecessarily. When the capacity is zero, the actual pointer
15506 : : // value doesn't matter.
15507 : 51960 : Bexpression* zero =
15508 : 51960 : Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
15509 : 51960 : Bexpression* cond =
15510 : 51960 : gogo->backend()->binary_expression(OPERATOR_EQEQ, result_capacity, zero,
15511 : : loc);
15512 : 51960 : Bexpression* offset = gogo->backend()->conditional_expression(bfn, int_btype,
15513 : : cond, zero,
15514 : : start, loc);
15515 : 51960 : Expression* valptr = array_type->get_value_pointer(gogo, this->array_);
15516 : 51960 : Bexpression* val = valptr->get_backend(context);
15517 : 51960 : val = gogo->backend()->pointer_offset_expression(val, offset, loc);
15518 : :
15519 : 51960 : Btype* struct_btype = this->type()->get_backend(gogo);
15520 : 51960 : std::vector<Bexpression*> init;
15521 : 51960 : init.push_back(val);
15522 : 51960 : init.push_back(result_length);
15523 : 51960 : init.push_back(result_capacity);
15524 : :
15525 : 51960 : return gogo->backend()->constructor_expression(struct_btype, init, loc);
15526 : 51960 : }
15527 : :
15528 : : // Export an array index expression.
15529 : :
15530 : : void
15531 : 3549 : Array_index_expression::do_export(Export_function_body* efb) const
15532 : : {
15533 : 3549 : efb->write_c_string("(");
15534 : 3549 : this->array_->export_expression(efb);
15535 : 3549 : efb->write_c_string(")[");
15536 : :
15537 : 3549 : Type* old_context = efb->type_context();
15538 : 3549 : efb->set_type_context(Type::lookup_integer_type("int"));
15539 : :
15540 : 3549 : this->start_->export_expression(efb);
15541 : 3549 : if (this->end_ == NULL)
15542 : 2760 : go_assert(this->cap_ == NULL);
15543 : : else
15544 : : {
15545 : 789 : efb->write_c_string(":");
15546 : 789 : if (!this->end_->is_nil_expression())
15547 : 427 : this->end_->export_expression(efb);
15548 : 789 : if (this->cap_ != NULL)
15549 : : {
15550 : 0 : efb->write_c_string(":");
15551 : 0 : this->cap_->export_expression(efb);
15552 : : }
15553 : : }
15554 : :
15555 : 3549 : efb->set_type_context(old_context);
15556 : :
15557 : 3549 : efb->write_c_string("]");
15558 : 3549 : }
15559 : :
15560 : : // Dump ast representation for an array index expression.
15561 : :
15562 : : void
15563 : 0 : Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
15564 : : const
15565 : : {
15566 : 0 : Index_expression::dump_index_expression(ast_dump_context, this->array_,
15567 : 0 : this->start_, this->end_, this->cap_);
15568 : 0 : }
15569 : :
15570 : : // Make an array index expression. END and CAP may be NULL.
15571 : :
15572 : : Expression*
15573 : 218694 : Expression::make_array_index(Expression* array, Expression* start,
15574 : : Expression* end, Expression* cap,
15575 : : Location location)
15576 : : {
15577 : 218694 : return new Array_index_expression(array, start, end, cap, location);
15578 : : }
15579 : :
15580 : : // Class String_index_expression.
15581 : :
15582 : : // String index traversal.
15583 : :
15584 : : int
15585 : 314914 : String_index_expression::do_traverse(Traverse* traverse)
15586 : : {
15587 : 314914 : if (Expression::traverse(&this->string_, traverse) == TRAVERSE_EXIT)
15588 : : return TRAVERSE_EXIT;
15589 : 314671 : if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
15590 : : return TRAVERSE_EXIT;
15591 : 314622 : if (this->end_ != NULL)
15592 : : {
15593 : 179740 : if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
15594 : : return TRAVERSE_EXIT;
15595 : : }
15596 : : return TRAVERSE_CONTINUE;
15597 : : }
15598 : :
15599 : : Expression*
15600 : 21435 : String_index_expression::do_flatten(Gogo* gogo, Named_object*,
15601 : : Statement_inserter* inserter)
15602 : : {
15603 : 21435 : if (this->is_flattened_)
15604 : 1203 : return this;
15605 : 20232 : this->is_flattened_ = true;
15606 : :
15607 : 20232 : Location loc = this->location();
15608 : :
15609 : 20232 : if (this->is_error_expression())
15610 : 0 : return Expression::make_error(loc);
15611 : :
15612 : 20232 : Expression* string = this->string_;
15613 : 20232 : Expression* start = this->start_;
15614 : 20232 : Expression* end = this->end_;
15615 : 20232 : if (string->is_error_expression()
15616 : 20232 : || string->type()->is_error_type()
15617 : 20232 : || start->is_error_expression()
15618 : 20229 : || start->type()->is_error_type()
15619 : 40461 : || (end != NULL
15620 : 22840 : && (end->is_error_expression() || end->type()->is_error_type())))
15621 : : {
15622 : 3 : go_assert(saw_errors());
15623 : 3 : return Expression::make_error(loc);
15624 : : }
15625 : :
15626 : 20229 : Temporary_statement* temp;
15627 : 20229 : if (!string->is_multi_eval_safe())
15628 : : {
15629 : 3072 : temp = Statement::make_temporary(NULL, string, loc);
15630 : 3072 : inserter->insert(temp);
15631 : 3072 : this->string_ = Expression::make_temporary_reference(temp, loc);
15632 : 3072 : string = this->string_;
15633 : : }
15634 : 20229 : if (!start->is_multi_eval_safe())
15635 : : {
15636 : 4291 : temp = Statement::make_temporary(NULL, start, loc);
15637 : 4291 : inserter->insert(temp);
15638 : 4291 : this->start_ = Expression::make_temporary_reference(temp, loc);
15639 : 4291 : start = this->start_;
15640 : : }
15641 : 20229 : if (end != NULL
15642 : 11420 : && !end->is_nil_expression()
15643 : 26163 : && !end->is_multi_eval_safe())
15644 : : {
15645 : 1800 : temp = Statement::make_temporary(NULL, end, loc);
15646 : 1800 : inserter->insert(temp);
15647 : 1800 : this->end_ = Expression::make_temporary_reference(temp, loc);
15648 : 1800 : end = this->end_;
15649 : : }
15650 : :
15651 : 20229 : Expression* len = Expression::make_string_info(string->copy(),
15652 : : STRING_INFO_LENGTH, loc);
15653 : 20229 : temp = Statement::make_temporary(NULL, len, loc);
15654 : 20229 : temp->determine_types(gogo);
15655 : 20229 : inserter->insert(temp);
15656 : 20229 : len = Expression::make_temporary_reference(temp, loc);
15657 : :
15658 : : // The order of bounds checks here matches the order used by the gc
15659 : : // compiler, as tested by issue30116[u].go.
15660 : :
15661 : 20229 : if (end != NULL && !end->is_nil_expression())
15662 : : {
15663 : 5934 : Expression::check_bounds(gogo, end, OPERATOR_LE, len,
15664 : : Runtime::PANIC_SLICE_ALEN,
15665 : : Runtime::PANIC_SLICE_ALEN_U,
15666 : : Runtime::PANIC_EXTEND_SLICE_ALEN,
15667 : : Runtime::PANIC_EXTEND_SLICE_ALEN_U,
15668 : : inserter, loc);
15669 : 5934 : Expression::check_bounds(gogo, start, OPERATOR_LE, end,
15670 : : Runtime::PANIC_SLICE_B,
15671 : : Runtime::PANIC_SLICE_B_U,
15672 : : Runtime::PANIC_EXTEND_SLICE_B,
15673 : : Runtime::PANIC_EXTEND_SLICE_B_U,
15674 : : inserter, loc);
15675 : : }
15676 : 14295 : else if (end != NULL)
15677 : 5486 : Expression::check_bounds(gogo, start, OPERATOR_LE, len,
15678 : : Runtime::PANIC_SLICE_B,
15679 : : Runtime::PANIC_SLICE_B_U,
15680 : : Runtime::PANIC_EXTEND_SLICE_B,
15681 : : Runtime::PANIC_EXTEND_SLICE_B_U,
15682 : : inserter, loc);
15683 : : else
15684 : 8809 : Expression::check_bounds(gogo, start, OPERATOR_LT, len,
15685 : : Runtime::PANIC_INDEX,
15686 : : Runtime::PANIC_INDEX_U,
15687 : : Runtime::PANIC_EXTEND_INDEX,
15688 : : Runtime::PANIC_EXTEND_INDEX_U,
15689 : : inserter, loc);
15690 : :
15691 : 20229 : return this;
15692 : : }
15693 : :
15694 : : // Return the type of a string index.
15695 : :
15696 : : Type*
15697 : 256128 : String_index_expression::do_type()
15698 : : {
15699 : 256128 : if (this->end_ == NULL)
15700 : 120127 : return Type::lookup_integer_type("byte");
15701 : : else
15702 : 136001 : return this->string_->type();
15703 : : }
15704 : :
15705 : : // Determine the type of a string index.
15706 : :
15707 : : void
15708 : 10575 : String_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
15709 : : {
15710 : 10575 : this->string_->determine_type_no_context(gogo);
15711 : :
15712 : 10575 : Type_context index_context(Type::lookup_integer_type("int"), false);
15713 : 10575 : this->start_->determine_type(gogo, &index_context);
15714 : 10575 : if (this->end_ != NULL)
15715 : 4547 : this->end_->determine_type(gogo, &index_context);
15716 : 10575 : }
15717 : :
15718 : : // Check types of a string index.
15719 : :
15720 : : void
15721 : 0 : String_index_expression::do_check_types(Gogo*)
15722 : : {
15723 : 0 : if (!String_index_expression::check_indexes(this->string_, this->start_,
15724 : : this->end_, this->location()))
15725 : 0 : this->set_is_error();
15726 : 0 : }
15727 : :
15728 : : // A static function to check string index types. This is also called
15729 : : // by Index_expression::do_check_types. It reports whether type
15730 : : // checking succeeded.
15731 : :
15732 : : bool
15733 : 17506 : String_index_expression::check_indexes(Expression* string, Expression* start,
15734 : : Expression* end, Location loc)
15735 : : {
15736 : 17506 : bool ret = true;
15737 : :
15738 : 17506 : Numeric_constant nc;
15739 : 17506 : unsigned long v;
15740 : 17509 : if (start->type()->integer_type() == NULL
15741 : 3 : && !start->type()->is_error()
15742 : 3 : && (!start->type()->is_abstract()
15743 : 0 : || !start->numeric_constant_value(&nc)
15744 : 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15745 : : {
15746 : 3 : go_error_at(loc, "index must be integer");
15747 : 3 : ret = false;
15748 : : }
15749 : :
15750 : 17506 : if (end != NULL
15751 : 14387 : && end->type()->integer_type() == NULL
15752 : 4709 : && !end->type()->is_error()
15753 : 4709 : && !end->is_nil_expression()
15754 : 0 : && !end->is_error_expression()
15755 : 17506 : && (!end->type()->is_abstract()
15756 : 0 : || !end->numeric_constant_value(&nc)
15757 : 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15758 : : {
15759 : 0 : go_error_at(loc, "slice end must be integer");
15760 : 0 : ret = false;
15761 : : }
15762 : :
15763 : 17506 : std::string sval;
15764 : 17506 : bool sval_valid = string->string_constant_value(&sval);
15765 : :
15766 : 17506 : Numeric_constant inc;
15767 : 17506 : mpz_t ival;
15768 : 17506 : bool ival_valid = false;
15769 : 17506 : if (start->numeric_constant_value(&inc) && inc.to_int(&ival))
15770 : : {
15771 : 9360 : ival_valid = true;
15772 : 9360 : if (mpz_sgn(ival) < 0
15773 : 9360 : || (sval_valid
15774 : 21 : && (end == NULL
15775 : 21 : ? mpz_cmp_ui(ival, sval.length()) >= 0
15776 : 811 : : mpz_cmp_ui(ival, sval.length()) > 0)))
15777 : : {
15778 : 7 : go_error_at(start->location(), "string index out of bounds");
15779 : 7 : ret = false;
15780 : : }
15781 : : }
15782 : :
15783 : 17506 : if (end != NULL && !end->is_nil_expression())
15784 : : {
15785 : 4969 : Numeric_constant enc;
15786 : 4969 : mpz_t eval;
15787 : 4969 : if (end->numeric_constant_value(&enc) && enc.to_int(&eval))
15788 : : {
15789 : 1334 : if (mpz_sgn(eval) < 0
15790 : 1334 : || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
15791 : : {
15792 : 5 : go_error_at(end->location(), "string index out of bounds");
15793 : 5 : ret = false;
15794 : : }
15795 : 1329 : else if (ival_valid && mpz_cmp(ival, eval) > 0)
15796 : : {
15797 : 2 : go_error_at(loc, "inverted slice range");
15798 : 2 : ret = false;
15799 : : }
15800 : 1334 : mpz_clear(eval);
15801 : : }
15802 : 4969 : }
15803 : 17506 : if (ival_valid)
15804 : 9360 : mpz_clear(ival);
15805 : :
15806 : 35012 : return ret;
15807 : 17506 : }
15808 : :
15809 : : // Get the backend representation for a string index.
15810 : :
15811 : : Bexpression*
15812 : 20228 : String_index_expression::do_get_backend(Translate_context* context)
15813 : : {
15814 : 20228 : Location loc = this->location();
15815 : 20228 : Gogo* gogo = context->gogo();
15816 : :
15817 : 20228 : Type* int_type = Type::lookup_integer_type("int");
15818 : :
15819 : : // It is possible that an error occurred earlier because the start index
15820 : : // cannot be represented as an integer type. In this case, we shouldn't
15821 : : // try casting the starting index into an integer since
15822 : : // Type_conversion_expression will fail to get the backend representation.
15823 : : // FIXME.
15824 : 20228 : if (this->start_->type()->integer_type() == NULL
15825 : 0 : && !Type::are_convertible(int_type, this->start_->type(), NULL))
15826 : : {
15827 : 0 : go_assert(saw_errors());
15828 : 0 : return context->backend()->error_expression();
15829 : : }
15830 : :
15831 : 20228 : go_assert(this->string_->is_multi_eval_safe());
15832 : 20228 : go_assert(this->start_->is_multi_eval_safe());
15833 : :
15834 : 20228 : Expression* start = Expression::make_cast(int_type, this->start_, loc);
15835 : 20228 : Bfunction* bfn = context->function()->func_value()->get_decl();
15836 : :
15837 : 20228 : Expression* length =
15838 : 20228 : Expression::make_string_info(this->string_, STRING_INFO_LENGTH, loc);
15839 : 20228 : Expression* bytes =
15840 : 20228 : Expression::make_string_info(this->string_, STRING_INFO_DATA, loc);
15841 : :
15842 : 20228 : Bexpression* bstart = start->get_backend(context);
15843 : 20228 : Bexpression* ptr = bytes->get_backend(context);
15844 : :
15845 : 20228 : if (this->end_ == NULL)
15846 : : {
15847 : 8808 : ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
15848 : 8808 : Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
15849 : 8808 : return gogo->backend()->indirect_expression(ubtype, ptr, false, loc);
15850 : : }
15851 : :
15852 : 11420 : Expression* end = NULL;
15853 : 11420 : if (this->end_->is_nil_expression())
15854 : : end = length;
15855 : : else
15856 : : {
15857 : 5934 : go_assert(this->end_->is_multi_eval_safe());
15858 : 5934 : end = Expression::make_cast(int_type, this->end_, loc);
15859 : : }
15860 : :
15861 : 11420 : end = end->copy();
15862 : 11420 : Bexpression* bend = end->get_backend(context);
15863 : 11420 : Bexpression* new_length =
15864 : 11420 : gogo->backend()->binary_expression(OPERATOR_MINUS, bend, bstart, loc);
15865 : :
15866 : : // If the new length is zero, don't change pointer. Otherwise we can
15867 : : // get a pointer to the next object in memory, keeping it live
15868 : : // unnecessarily. When the length is zero, the actual pointer
15869 : : // value doesn't matter.
15870 : 11420 : Btype* int_btype = int_type->get_backend(gogo);
15871 : 11420 : Bexpression* zero =
15872 : 11420 : Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
15873 : 11420 : Bexpression* cond =
15874 : 11420 : gogo->backend()->binary_expression(OPERATOR_EQEQ, new_length, zero,
15875 : : loc);
15876 : 11420 : Bexpression* offset =
15877 : 11420 : gogo->backend()->conditional_expression(bfn, int_btype, cond, zero,
15878 : : bstart, loc);
15879 : :
15880 : 11420 : ptr = gogo->backend()->pointer_offset_expression(ptr, offset, loc);
15881 : :
15882 : 11420 : Btype* str_btype = this->type()->get_backend(gogo);
15883 : 11420 : std::vector<Bexpression*> init;
15884 : 11420 : init.push_back(ptr);
15885 : 11420 : init.push_back(new_length);
15886 : 11420 : return gogo->backend()->constructor_expression(str_btype, init, loc);
15887 : 11420 : }
15888 : :
15889 : : // Export a string index expression.
15890 : :
15891 : : void
15892 : 944 : String_index_expression::do_export(Export_function_body* efb) const
15893 : : {
15894 : 944 : efb->write_c_string("(");
15895 : 944 : this->string_->export_expression(efb);
15896 : 944 : efb->write_c_string(")[");
15897 : :
15898 : 944 : Type* old_context = efb->type_context();
15899 : 944 : efb->set_type_context(Type::lookup_integer_type("int"));
15900 : :
15901 : 944 : this->start_->export_expression(efb);
15902 : 944 : if (this->end_ != NULL)
15903 : : {
15904 : 550 : efb->write_c_string(":");
15905 : 550 : if (!this->end_->is_nil_expression())
15906 : 340 : this->end_->export_expression(efb);
15907 : : }
15908 : :
15909 : 944 : efb->set_type_context(old_context);
15910 : :
15911 : 944 : efb->write_c_string("]");
15912 : 944 : }
15913 : :
15914 : : // Dump ast representation for a string index expression.
15915 : :
15916 : : void
15917 : 0 : String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
15918 : : const
15919 : : {
15920 : 0 : Index_expression::dump_index_expression(ast_dump_context, this->string_,
15921 : 0 : this->start_, this->end_, NULL);
15922 : 0 : }
15923 : :
15924 : : // Make a string index expression. END may be NULL.
15925 : :
15926 : : Expression*
15927 : 20293 : Expression::make_string_index(Expression* string, Expression* start,
15928 : : Expression* end, Location location)
15929 : : {
15930 : 20293 : return new String_index_expression(string, start, end, location);
15931 : : }
15932 : :
15933 : : // Class Map_index.
15934 : :
15935 : : // Get the type of the map.
15936 : :
15937 : : Map_type*
15938 : 107930 : Map_index_expression::get_map_type() const
15939 : : {
15940 : 107930 : Map_type* mt = this->map_->type()->map_type();
15941 : 0 : if (mt == NULL)
15942 : 0 : go_assert(saw_errors());
15943 : 107930 : return mt;
15944 : : }
15945 : :
15946 : : // Map index traversal.
15947 : :
15948 : : int
15949 : 115905 : Map_index_expression::do_traverse(Traverse* traverse)
15950 : : {
15951 : 115905 : if (Expression::traverse(&this->map_, traverse) == TRAVERSE_EXIT)
15952 : : return TRAVERSE_EXIT;
15953 : 105985 : return Expression::traverse(&this->index_, traverse);
15954 : : }
15955 : :
15956 : : void
15957 : 2555 : Map_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
15958 : : {
15959 : 2555 : this->map_->determine_type_no_context(gogo);
15960 : 2555 : Map_type* mt = this->map_->type()->map_type();
15961 : 0 : go_assert(mt != NULL);
15962 : 2555 : Type_context index_context(mt->key_type(), false);
15963 : 2555 : this->index_->determine_type(gogo, &index_context);
15964 : 2555 : if (this->value_pointer_ != NULL)
15965 : 686 : this->value_pointer_->determine_type_no_context(gogo);
15966 : 2555 : }
15967 : :
15968 : : void
15969 : 15 : Map_index_expression::do_check_types(Gogo*)
15970 : : {
15971 : : // Types should have been checked before this was created, so this
15972 : : // will probably never be called. Check it anyhow to be sure.
15973 : 15 : Map_type* mt = this->map_->type()->map_type();
15974 : 0 : go_assert(mt != NULL);
15975 : 15 : if (!Type::are_assignable(mt->key_type(), this->index_->type(), NULL))
15976 : 0 : this->report_error(_("incompatible type for map index"));
15977 : 15 : }
15978 : :
15979 : : // We need to pass in a pointer to the key, so flatten the index into a
15980 : : // temporary variable if it isn't already. The value pointer will be
15981 : : // dereferenced and checked for nil, so flatten into a temporary to avoid
15982 : : // recomputation.
15983 : :
15984 : : Expression*
15985 : 6260 : Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
15986 : : Statement_inserter* inserter)
15987 : : {
15988 : 6260 : Location loc = this->location();
15989 : 6260 : Map_type* mt = this->get_map_type();
15990 : 6260 : if (this->index()->is_error_expression()
15991 : 6260 : || this->index()->type()->is_error_type()
15992 : 12520 : || mt->is_error_type())
15993 : : {
15994 : 0 : go_assert(saw_errors());
15995 : 0 : return Expression::make_error(loc);
15996 : : }
15997 : :
15998 : : // Avoid copy for string([]byte) conversions used in map keys.
15999 : : // mapaccess doesn't keep the reference, so this is safe.
16000 : 6260 : Type_conversion_expression* ce = this->index_->conversion_expression();
16001 : 209 : if (ce != NULL && ce->type()->is_string_type()
16002 : 68 : && ce->expr()->type()->is_slice_type())
16003 : 52 : ce->set_no_copy(true);
16004 : :
16005 : 6260 : if (!Type::are_identical(mt->key_type(), this->index_->type(),
16006 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
16007 : : NULL))
16008 : : {
16009 : 6 : if (this->index_->type()->interface_type() != NULL
16010 : 0 : && !this->index_->is_multi_eval_safe())
16011 : : {
16012 : 0 : Temporary_statement* temp =
16013 : 0 : Statement::make_temporary(NULL, this->index_, loc);
16014 : 0 : inserter->insert(temp);
16015 : 0 : this->index_ = Expression::make_temporary_reference(temp, loc);
16016 : : }
16017 : 6 : this->index_ = Expression::convert_for_assignment(gogo, mt->key_type(),
16018 : : this->index_, loc);
16019 : : }
16020 : :
16021 : 6260 : if (!this->index_->is_multi_eval_safe())
16022 : : {
16023 : 2178 : Temporary_statement* temp = Statement::make_temporary(NULL, this->index_,
16024 : : loc);
16025 : 2178 : inserter->insert(temp);
16026 : 2178 : this->index_ = Expression::make_temporary_reference(temp, loc);
16027 : : }
16028 : :
16029 : 6260 : if (this->value_pointer_ == NULL)
16030 : 5862 : this->get_value_pointer(gogo);
16031 : 6260 : if (this->value_pointer_->is_error_expression()
16032 : 6260 : || this->value_pointer_->type()->is_error_type())
16033 : 0 : return Expression::make_error(loc);
16034 : 6260 : if (!this->value_pointer_->is_multi_eval_safe())
16035 : : {
16036 : 5862 : Temporary_statement* temp =
16037 : 5862 : Statement::make_temporary(NULL, this->value_pointer_, loc);
16038 : 5862 : inserter->insert(temp);
16039 : 5862 : this->value_pointer_ = Expression::make_temporary_reference(temp, loc);
16040 : : }
16041 : :
16042 : 6260 : return this;
16043 : : }
16044 : :
16045 : : // Return the type of a map index.
16046 : :
16047 : : Type*
16048 : 81619 : Map_index_expression::do_type()
16049 : : {
16050 : 81619 : Map_type* mt = this->get_map_type();
16051 : 81619 : if (mt == NULL)
16052 : 0 : return Type::make_error_type();
16053 : 81619 : return mt->val_type();
16054 : : }
16055 : :
16056 : : // Add explicit type conversions.
16057 : :
16058 : : void
16059 : 5862 : Map_index_expression::do_add_conversions()
16060 : : {
16061 : 5862 : Map_type* mt = this->get_map_type();
16062 : 5862 : if (mt == NULL)
16063 : : return;
16064 : 5862 : Type* lt = mt->key_type();
16065 : 5862 : Type* rt = this->index_->type();
16066 : 5862 : if (!Type::are_identical(lt, rt, 0, NULL)
16067 : 5862 : && lt->interface_type() != NULL)
16068 : 123 : this->index_ = Expression::make_cast(lt, this->index_, this->location());
16069 : : }
16070 : :
16071 : : // Get the backend representation for a map index.
16072 : :
16073 : : Bexpression*
16074 : 5866 : Map_index_expression::do_get_backend(Translate_context* context)
16075 : : {
16076 : 5866 : Map_type* type = this->get_map_type();
16077 : 5866 : if (type == NULL)
16078 : : {
16079 : 0 : go_assert(saw_errors());
16080 : 0 : return context->backend()->error_expression();
16081 : : }
16082 : :
16083 : 5866 : go_assert(this->value_pointer_ != NULL
16084 : : && this->value_pointer_->is_multi_eval_safe());
16085 : :
16086 : 5866 : Expression* val = Expression::make_dereference(this->value_pointer_,
16087 : : NIL_CHECK_NOT_NEEDED,
16088 : : this->location());
16089 : 5866 : return val->get_backend(context);
16090 : : }
16091 : :
16092 : : // Get an expression for the map index. This returns an expression
16093 : : // that evaluates to a pointer to a value. If the key is not in the
16094 : : // map, the pointer will point to a zero value.
16095 : :
16096 : : Expression*
16097 : 5862 : Map_index_expression::get_value_pointer(Gogo* gogo)
16098 : : {
16099 : 5862 : if (this->value_pointer_ == NULL)
16100 : : {
16101 : 5862 : Map_type* type = this->get_map_type();
16102 : 5862 : if (type == NULL)
16103 : : {
16104 : 0 : go_assert(saw_errors());
16105 : 0 : return Expression::make_error(this->location());
16106 : : }
16107 : :
16108 : 5862 : Location loc = this->location();
16109 : 5862 : Expression* map_ref = this->map_;
16110 : :
16111 : 5862 : Expression* index_ptr = Expression::make_unary(OPERATOR_AND,
16112 : : this->index_,
16113 : : loc);
16114 : :
16115 : 5862 : Expression* type_expr = Expression::make_type_descriptor(type, loc);
16116 : 5862 : Expression* zero = type->fat_zero_value(gogo);
16117 : 5862 : Expression* map_index;
16118 : 5862 : if (zero == NULL)
16119 : : {
16120 : 5859 : Runtime::Function code;
16121 : 5859 : Expression* key;
16122 : 5859 : switch (type->algorithm(gogo))
16123 : : {
16124 : 614 : case Map_type::MAP_ALG_FAST32:
16125 : 614 : case Map_type::MAP_ALG_FAST32PTR:
16126 : 614 : {
16127 : 614 : Type* uint32_type = Type::lookup_integer_type("uint32");
16128 : 614 : Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
16129 : 614 : key = Expression::make_unsafe_cast(uint32_ptr_type, index_ptr,
16130 : : loc);
16131 : 614 : key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
16132 : : loc);
16133 : 614 : code = Runtime::MAPACCESS1_FAST32;
16134 : 614 : break;
16135 : : }
16136 : 1169 : case Map_type::MAP_ALG_FAST64:
16137 : 1169 : case Map_type::MAP_ALG_FAST64PTR:
16138 : 1169 : {
16139 : 1169 : Type* uint64_type = Type::lookup_integer_type("uint64");
16140 : 1169 : Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
16141 : 1169 : key = Expression::make_unsafe_cast(uint64_ptr_type, index_ptr,
16142 : : loc);
16143 : 1169 : key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
16144 : : loc);
16145 : 1169 : code = Runtime::MAPACCESS1_FAST64;
16146 : 1169 : break;
16147 : : }
16148 : 2897 : case Map_type::MAP_ALG_FASTSTR:
16149 : 2897 : key = this->index_;
16150 : 2897 : code = Runtime::MAPACCESS1_FASTSTR;
16151 : 2897 : break;
16152 : : default:
16153 : : key = index_ptr;
16154 : : code = Runtime::MAPACCESS1;
16155 : : break;
16156 : : }
16157 : 5859 : map_index = Runtime::make_call(gogo, code, loc, 3,
16158 : : type_expr, map_ref, key);
16159 : : }
16160 : : else
16161 : 3 : map_index = Runtime::make_call(gogo, Runtime::MAPACCESS1_FAT, loc, 4,
16162 : : type_expr, map_ref, index_ptr, zero);
16163 : :
16164 : 5862 : Type* val_type = type->val_type();
16165 : 11724 : this->value_pointer_ =
16166 : 5862 : Expression::make_unsafe_cast(Type::make_pointer_type(val_type),
16167 : : map_index, this->location());
16168 : 5862 : this->value_pointer_->determine_type_no_context(gogo);
16169 : : }
16170 : :
16171 : 5862 : return this->value_pointer_;
16172 : : }
16173 : :
16174 : : // Export a map index expression.
16175 : :
16176 : : void
16177 : 96 : Map_index_expression::do_export(Export_function_body* efb) const
16178 : : {
16179 : 96 : efb->write_c_string("(");
16180 : 96 : this->map_->export_expression(efb);
16181 : 96 : efb->write_c_string(")[");
16182 : :
16183 : 96 : Type* old_context = efb->type_context();
16184 : 96 : efb->set_type_context(this->get_map_type()->key_type());
16185 : :
16186 : 96 : this->index_->export_expression(efb);
16187 : :
16188 : 96 : efb->set_type_context(old_context);
16189 : :
16190 : 96 : efb->write_c_string("]");
16191 : 96 : }
16192 : :
16193 : : // Dump ast representation for a map index expression
16194 : :
16195 : : void
16196 : 0 : Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
16197 : : const
16198 : : {
16199 : 0 : Index_expression::dump_index_expression(ast_dump_context, this->map_,
16200 : 0 : this->index_, NULL, NULL);
16201 : 0 : }
16202 : :
16203 : : // Make a map index expression.
16204 : :
16205 : : Map_index_expression*
16206 : 14200 : Expression::make_map_index(Expression* map, Expression* index,
16207 : : Location location)
16208 : : {
16209 : 14200 : return new Map_index_expression(map, index, location);
16210 : : }
16211 : :
16212 : : // Class Field_reference_expression.
16213 : :
16214 : : // Lower a field reference expression. There is nothing to lower, but
16215 : : // this is where we generate the tracking information for fields with
16216 : : // the magic go:"track" tag.
16217 : :
16218 : : Expression*
16219 : 1328355 : Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
16220 : : Statement_inserter* inserter)
16221 : : {
16222 : 1328355 : Struct_type* struct_type = this->expr_->type()->struct_type();
16223 : 1328355 : if (struct_type == NULL)
16224 : : {
16225 : : // Error will be reported elsewhere.
16226 : 2 : return this;
16227 : : }
16228 : 1328353 : const Struct_field* field = struct_type->field(this->field_index_);
16229 : 1328353 : if (field == NULL)
16230 : 0 : return this;
16231 : 1328353 : if (!field->has_tag())
16232 : 1309397 : return this;
16233 : 18956 : if (field->tag().find("go:\"track\"") == std::string::npos)
16234 : 18956 : return this;
16235 : :
16236 : : // References from functions generated by the compiler don't count.
16237 : 0 : if (function != NULL && function->func_value()->is_type_specific_function())
16238 : 0 : return this;
16239 : :
16240 : : // We have found a reference to a tracked field. Build a call to
16241 : : // the runtime function __go_fieldtrack with a string that describes
16242 : : // the field. FIXME: We should only call this once per referenced
16243 : : // field per function, not once for each reference to the field.
16244 : :
16245 : 0 : if (this->called_fieldtrack_)
16246 : 0 : return this;
16247 : 0 : this->called_fieldtrack_ = true;
16248 : :
16249 : 0 : Location loc = this->location();
16250 : :
16251 : 0 : std::string s = "fieldtrack \"";
16252 : 0 : Named_type* nt = this->expr_->type()->unalias()->named_type();
16253 : 0 : if (nt == NULL || nt->named_object()->package() == NULL)
16254 : 0 : s.append(gogo->pkgpath());
16255 : : else
16256 : 0 : s.append(nt->named_object()->package()->pkgpath());
16257 : 0 : s.push_back('.');
16258 : 0 : if (nt != NULL)
16259 : 0 : s.append(Gogo::unpack_hidden_name(nt->name()));
16260 : 0 : s.push_back('.');
16261 : 0 : s.append(Gogo::unpack_hidden_name(field->field_name()));
16262 : 0 : s.push_back('"');
16263 : :
16264 : : // We can't use a string here, because internally a string holds a
16265 : : // pointer to the actual bytes; when the linker garbage collects the
16266 : : // string, it won't garbage collect the bytes. So we use a
16267 : : // [...]byte.
16268 : :
16269 : 0 : Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc);
16270 : :
16271 : 0 : Type* byte_type = Type::lookup_integer_type("byte");
16272 : 0 : Array_type* array_type = Type::make_array_type(byte_type, length_expr);
16273 : 0 : array_type->set_is_array_incomparable();
16274 : :
16275 : 0 : Expression_list* bytes = new Expression_list();
16276 : 0 : for (std::string::const_iterator p = s.begin(); p != s.end(); p++)
16277 : : {
16278 : 0 : unsigned char c = static_cast<unsigned char>(*p);
16279 : 0 : bytes->push_back(Expression::make_integer_ul(c, NULL, loc));
16280 : : }
16281 : :
16282 : 0 : Expression* e = Expression::make_composite_literal(array_type, 0, false,
16283 : : bytes, false, loc);
16284 : :
16285 : 0 : Variable* var = new Variable(array_type, e, true, false, false, loc);
16286 : :
16287 : 0 : static int count;
16288 : 0 : char buf[50];
16289 : 0 : snprintf(buf, sizeof buf, "fieldtrack.%d", count);
16290 : 0 : ++count;
16291 : :
16292 : 0 : Named_object* no = gogo->add_variable(buf, var);
16293 : 0 : e = Expression::make_var_reference(no, loc);
16294 : 0 : e = Expression::make_unary(OPERATOR_AND, e, loc);
16295 : :
16296 : 0 : Expression* call = Runtime::make_call(gogo, Runtime::FIELDTRACK, loc, 1, e);
16297 : 0 : call->determine_type_no_context(gogo);
16298 : 0 : gogo->lower_expression(function, inserter, &call);
16299 : 0 : inserter->insert(Statement::make_statement(call, false));
16300 : :
16301 : : // Put this function, and the global variable we just created, into
16302 : : // unique sections. This will permit the linker to garbage collect
16303 : : // them if they are not referenced. The effect is that the only
16304 : : // strings, indicating field references, that will wind up in the
16305 : : // executable will be those for functions that are actually needed.
16306 : 0 : if (function != NULL)
16307 : 0 : function->func_value()->set_in_unique_section();
16308 : 0 : var->set_in_unique_section();
16309 : :
16310 : 0 : return this;
16311 : 0 : }
16312 : :
16313 : : // Return the type of a field reference.
16314 : :
16315 : : Type*
16316 : 12700296 : Field_reference_expression::do_type()
16317 : : {
16318 : 12700296 : Type* type = this->expr_->type();
16319 : 12700296 : if (type->is_error())
16320 : : return type;
16321 : 12700276 : Struct_type* struct_type = type->struct_type();
16322 : 0 : go_assert(struct_type != NULL);
16323 : 12700276 : return struct_type->field(this->field_index_)->type();
16324 : : }
16325 : :
16326 : : // Check the types for a field reference.
16327 : :
16328 : : void
16329 : 43952 : Field_reference_expression::do_check_types(Gogo*)
16330 : : {
16331 : 43952 : Type* type = this->expr_->type();
16332 : 43952 : if (type->is_error())
16333 : : return;
16334 : 43951 : Struct_type* struct_type = type->struct_type();
16335 : 0 : go_assert(struct_type != NULL);
16336 : 43951 : go_assert(struct_type->field(this->field_index_) != NULL);
16337 : : }
16338 : :
16339 : : // Get the backend representation for a field reference.
16340 : :
16341 : : Bexpression*
16342 : 981774 : Field_reference_expression::do_get_backend(Translate_context* context)
16343 : : {
16344 : 981774 : Bexpression* bstruct = this->expr_->get_backend(context);
16345 : 981774 : return context->gogo()->backend()->struct_field_expression(bstruct,
16346 : 981774 : this->field_index_,
16347 : 981774 : this->location());
16348 : : }
16349 : :
16350 : : // Dump ast representation for a field reference expression.
16351 : :
16352 : : void
16353 : 0 : Field_reference_expression::do_dump_expression(
16354 : : Ast_dump_context* ast_dump_context) const
16355 : : {
16356 : 0 : this->expr_->dump_expression(ast_dump_context);
16357 : 0 : ast_dump_context->ostream() << "." << this->field_index_;
16358 : 0 : }
16359 : :
16360 : : // Make a reference to a qualified identifier in an expression.
16361 : :
16362 : : Field_reference_expression*
16363 : 986824 : Expression::make_field_reference(Expression* expr, unsigned int field_index,
16364 : : Location location)
16365 : : {
16366 : 986824 : return new Field_reference_expression(expr, field_index, location);
16367 : : }
16368 : :
16369 : : // Class Interface_field_reference_expression.
16370 : :
16371 : : // Return an expression for the pointer to the function to call.
16372 : :
16373 : : Expression*
16374 : 31774 : Interface_field_reference_expression::get_function()
16375 : : {
16376 : 31774 : Expression* ref = this->expr_;
16377 : 31774 : Location loc = this->location();
16378 : 31774 : if (ref->type()->points_to() != NULL)
16379 : 1160 : ref = Expression::make_dereference(ref, NIL_CHECK_DEFAULT, loc);
16380 : :
16381 : 31774 : Expression* mtable =
16382 : 31774 : Expression::make_interface_info(ref, INTERFACE_INFO_METHODS, loc);
16383 : 31774 : Struct_type* mtable_type = mtable->type()->points_to()->struct_type();
16384 : :
16385 : 31774 : std::string name = Gogo::unpack_hidden_name(this->name_);
16386 : 31774 : unsigned int index;
16387 : 31774 : const Struct_field* field = mtable_type->find_local_field(name, &index);
16388 : 31774 : go_assert(field != NULL);
16389 : :
16390 : 31774 : mtable = Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, loc);
16391 : 31774 : return Expression::make_field_reference(mtable, index, loc);
16392 : 31774 : }
16393 : :
16394 : : // Return an expression for the first argument to pass to the interface
16395 : : // function.
16396 : :
16397 : : Expression*
16398 : 31774 : Interface_field_reference_expression::get_underlying_object()
16399 : : {
16400 : 31774 : Expression* expr = this->expr_;
16401 : 31774 : if (expr->type()->points_to() != NULL)
16402 : 1160 : expr = Expression::make_dereference(expr, NIL_CHECK_DEFAULT,
16403 : : this->location());
16404 : 31774 : return Expression::make_interface_info(expr, INTERFACE_INFO_OBJECT,
16405 : 31774 : this->location());
16406 : : }
16407 : :
16408 : : // Traversal.
16409 : :
16410 : : int
16411 : 495980 : Interface_field_reference_expression::do_traverse(Traverse* traverse)
16412 : : {
16413 : 495980 : return Expression::traverse(&this->expr_, traverse);
16414 : : }
16415 : :
16416 : : // Lower the expression. If this expression is not called, we need to
16417 : : // evaluate the expression twice when converting to the backend
16418 : : // interface. So introduce a temporary variable if necessary.
16419 : :
16420 : : Expression*
16421 : 39774 : Interface_field_reference_expression::do_flatten(Gogo*, Named_object*,
16422 : : Statement_inserter* inserter)
16423 : : {
16424 : 39774 : if (this->expr_->is_error_expression()
16425 : 39774 : || this->expr_->type()->is_error_type())
16426 : : {
16427 : 1 : go_assert(saw_errors());
16428 : 1 : return Expression::make_error(this->location());
16429 : : }
16430 : :
16431 : 39773 : if (!this->expr_->is_multi_eval_safe())
16432 : : {
16433 : 10225 : Temporary_statement* temp =
16434 : 10225 : Statement::make_temporary(NULL, this->expr_, this->location());
16435 : 10225 : inserter->insert(temp);
16436 : 10225 : this->expr_ = Expression::make_temporary_reference(temp, this->location());
16437 : : }
16438 : 39773 : return this;
16439 : : }
16440 : :
16441 : : // Return the type of an interface field reference.
16442 : :
16443 : : Type*
16444 : 1455651 : Interface_field_reference_expression::do_type()
16445 : : {
16446 : 1455651 : Type* expr_type = this->expr_->type();
16447 : :
16448 : 1455651 : Type* points_to = expr_type->points_to();
16449 : 1455651 : if (points_to != NULL)
16450 : 66180 : expr_type = points_to;
16451 : :
16452 : 1455651 : Interface_type* interface_type = expr_type->interface_type();
16453 : 1455651 : if (interface_type == NULL)
16454 : 16 : return Type::make_error_type();
16455 : :
16456 : 1455635 : const Typed_identifier* method = interface_type->find_method(this->name_);
16457 : 1455635 : if (method == NULL)
16458 : 0 : return Type::make_error_type();
16459 : :
16460 : 1455635 : return method->type();
16461 : : }
16462 : :
16463 : : // Determine types.
16464 : :
16465 : : void
16466 : 33019 : Interface_field_reference_expression::do_determine_type(Gogo* gogo,
16467 : : const Type_context*)
16468 : : {
16469 : 33019 : this->expr_->determine_type_no_context(gogo);
16470 : 33019 : }
16471 : :
16472 : : // Check the types for an interface field reference.
16473 : :
16474 : : void
16475 : 1292 : Interface_field_reference_expression::do_check_types(Gogo*)
16476 : : {
16477 : 1292 : Type* type = this->expr_->type();
16478 : :
16479 : 1292 : Type* points_to = type->points_to();
16480 : 1292 : if (points_to != NULL)
16481 : 1160 : type = points_to;
16482 : :
16483 : 1292 : Interface_type* interface_type = type->interface_type();
16484 : 1292 : if (interface_type == NULL)
16485 : : {
16486 : 1 : if (!type->is_error_type())
16487 : 0 : this->report_error(_("expected interface or pointer to interface"));
16488 : : }
16489 : : else
16490 : : {
16491 : 1291 : const Typed_identifier* method =
16492 : 1291 : interface_type->find_method(this->name_);
16493 : 1291 : if (method == NULL)
16494 : : {
16495 : 0 : go_error_at(this->location(), "method %qs not in interface",
16496 : 0 : Gogo::message_name(this->name_).c_str());
16497 : 0 : this->set_is_error();
16498 : : }
16499 : : }
16500 : 1292 : }
16501 : :
16502 : : // If an interface field reference is not simply called, then it is
16503 : : // represented as a closure. The closure will hold a single variable,
16504 : : // the value of the interface on which the method should be called.
16505 : : // The function will be a simple thunk that pulls the value from the
16506 : : // closure and calls the method with the remaining arguments.
16507 : :
16508 : : // Because method values are not common, we don't build all thunks for
16509 : : // all possible interface methods, but instead only build them as we
16510 : : // need them. In particular, we even build them on demand for
16511 : : // interface methods defined in other packages.
16512 : :
16513 : : Interface_field_reference_expression::Interface_method_thunks
16514 : : Interface_field_reference_expression::interface_method_thunks;
16515 : :
16516 : : // Find or create the thunk to call method NAME on TYPE.
16517 : :
16518 : : Named_object*
16519 : 105 : Interface_field_reference_expression::create_thunk(Gogo* gogo,
16520 : : Interface_type* type,
16521 : : const std::string& name)
16522 : : {
16523 : 105 : std::pair<Interface_type*, Method_thunks*> val(type, NULL);
16524 : 105 : std::pair<Interface_method_thunks::iterator, bool> ins =
16525 : 105 : Interface_field_reference_expression::interface_method_thunks.insert(val);
16526 : 105 : if (ins.second)
16527 : : {
16528 : : // This is the first time we have seen this interface.
16529 : 52 : ins.first->second = new Method_thunks();
16530 : : }
16531 : :
16532 : 114 : for (Method_thunks::const_iterator p = ins.first->second->begin();
16533 : 114 : p != ins.first->second->end();
16534 : 9 : p++)
16535 : 53 : if (p->first == name)
16536 : 44 : return p->second;
16537 : :
16538 : 61 : Location loc = type->location();
16539 : :
16540 : 61 : const Typed_identifier* method_id = type->find_method(name);
16541 : 61 : if (method_id == NULL)
16542 : 0 : return Named_object::make_erroneous_name(gogo->thunk_name());
16543 : :
16544 : 61 : Function_type* orig_fntype = method_id->type()->function_type();
16545 : 61 : if (orig_fntype == NULL)
16546 : 0 : return Named_object::make_erroneous_name(gogo->thunk_name());
16547 : :
16548 : 61 : Struct_field_list* sfl = new Struct_field_list();
16549 : : // The type here is wrong--it should be the C function type. But it
16550 : : // doesn't really matter.
16551 : 61 : Type* vt = Type::make_pointer_type(Type::make_void_type());
16552 : 61 : sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
16553 : 61 : sfl->push_back(Struct_field(Typed_identifier("val", type, loc)));
16554 : 61 : Struct_type* st = Type::make_struct_type(sfl, loc);
16555 : 61 : st->set_is_struct_incomparable();
16556 : 61 : Type* closure_type = Type::make_pointer_type(st);
16557 : :
16558 : 61 : Function_type* new_fntype = orig_fntype->copy_with_names();
16559 : :
16560 : 61 : std::string thunk_name = gogo->thunk_name();
16561 : 61 : Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
16562 : 61 : false, loc);
16563 : :
16564 : 61 : Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
16565 : 61 : cvar->set_is_used();
16566 : 61 : cvar->set_is_closure();
16567 : 61 : Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
16568 : : NULL, cvar);
16569 : 61 : new_no->func_value()->set_closure_var(cp);
16570 : :
16571 : 61 : gogo->start_block(loc);
16572 : :
16573 : : // Field 0 of the closure is the function code pointer, field 1 is
16574 : : // the value on which to invoke the method.
16575 : 61 : Expression* arg = Expression::make_var_reference(cp, loc);
16576 : 61 : arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
16577 : 61 : arg = Expression::make_field_reference(arg, 1, loc);
16578 : :
16579 : 61 : Expression *ifre = Expression::make_interface_field_reference(arg, name,
16580 : : loc);
16581 : :
16582 : 61 : const Typed_identifier_list* orig_params = orig_fntype->parameters();
16583 : 61 : Expression_list* args;
16584 : 61 : if (orig_params == NULL || orig_params->empty())
16585 : : args = NULL;
16586 : : else
16587 : : {
16588 : 38 : const Typed_identifier_list* new_params = new_fntype->parameters();
16589 : 38 : args = new Expression_list();
16590 : 38 : for (Typed_identifier_list::const_iterator p = new_params->begin();
16591 : 92 : p != new_params->end();
16592 : 54 : ++p)
16593 : : {
16594 : 54 : Named_object* p_no = gogo->lookup(p->name(), NULL);
16595 : 54 : go_assert(p_no != NULL
16596 : : && p_no->is_variable()
16597 : : && p_no->var_value()->is_parameter());
16598 : 54 : args->push_back(Expression::make_var_reference(p_no, loc));
16599 : : }
16600 : : }
16601 : :
16602 : 61 : Call_expression* call = Expression::make_call(ifre, args,
16603 : 61 : orig_fntype->is_varargs(),
16604 : : loc);
16605 : 61 : call->set_varargs_are_lowered();
16606 : :
16607 : 61 : Statement* s = Statement::make_return_from_call(new_no, call, loc);
16608 : 61 : s->determine_types(gogo);
16609 : 61 : gogo->add_statement(s);
16610 : 61 : Block* b = gogo->finish_block(loc);
16611 : 61 : gogo->add_block(b, loc);
16612 : :
16613 : : // This is called after lowering.
16614 : 61 : gogo->lower_block(new_no, b);
16615 : :
16616 : 61 : gogo->finish_function(loc);
16617 : :
16618 : 61 : ins.first->second->push_back(std::make_pair(name, new_no));
16619 : 61 : return new_no;
16620 : 61 : }
16621 : :
16622 : : // Lookup a thunk to call method NAME on TYPE.
16623 : :
16624 : : Named_object*
16625 : 105 : Interface_field_reference_expression::lookup_thunk(Interface_type* type,
16626 : : const std::string& name)
16627 : : {
16628 : 105 : Interface_method_thunks::const_iterator p =
16629 : 105 : Interface_field_reference_expression::interface_method_thunks.find(type);
16630 : 105 : if (p == Interface_field_reference_expression::interface_method_thunks.end())
16631 : : return NULL;
16632 : 114 : for (Method_thunks::const_iterator pm = p->second->begin();
16633 : 114 : pm != p->second->end();
16634 : 9 : ++pm)
16635 : 114 : if (pm->first == name)
16636 : 105 : return pm->second;
16637 : : return NULL;
16638 : : }
16639 : :
16640 : : // Get the backend representation for a method value.
16641 : :
16642 : : Bexpression*
16643 : 105 : Interface_field_reference_expression::do_get_backend(Translate_context* context)
16644 : : {
16645 : 105 : Interface_type* type = this->expr_->type()->interface_type();
16646 : 105 : if (type == NULL)
16647 : : {
16648 : 0 : go_assert(saw_errors());
16649 : 0 : return context->backend()->error_expression();
16650 : : }
16651 : :
16652 : 105 : Named_object* thunk =
16653 : 105 : Interface_field_reference_expression::lookup_thunk(type, this->name_);
16654 : :
16655 : : // The thunk should have been created during the
16656 : : // create_function_descriptors pass.
16657 : 105 : if (thunk == NULL || thunk->is_erroneous())
16658 : : {
16659 : 0 : go_assert(saw_errors());
16660 : 0 : return context->backend()->error_expression();
16661 : : }
16662 : :
16663 : : // FIXME: We should lower this earlier, but we can't it lower it in
16664 : : // the lowering pass because at that point we don't know whether we
16665 : : // need to create the thunk or not. If the expression is called, we
16666 : : // don't need the thunk.
16667 : :
16668 : 105 : Location loc = this->location();
16669 : :
16670 : 105 : Struct_field_list* fields = new Struct_field_list();
16671 : 105 : fields->push_back(Struct_field(Typed_identifier("fn",
16672 : 105 : thunk->func_value()->type(),
16673 : 105 : loc)));
16674 : 105 : fields->push_back(Struct_field(Typed_identifier("val",
16675 : 105 : this->expr_->type(),
16676 : 105 : loc)));
16677 : 105 : Struct_type* st = Type::make_struct_type(fields, loc);
16678 : 105 : st->set_is_struct_incomparable();
16679 : :
16680 : 105 : Expression_list* vals = new Expression_list();
16681 : 105 : vals->push_back(Expression::make_func_code_reference(thunk, loc));
16682 : 105 : vals->push_back(this->expr_);
16683 : :
16684 : 105 : Expression* expr = Expression::make_struct_composite_literal(st, vals, loc);
16685 : 105 : Bexpression* bclosure =
16686 : 105 : Expression::make_heap_expression(expr, loc)->get_backend(context);
16687 : :
16688 : 105 : Gogo* gogo = context->gogo();
16689 : 105 : Btype* btype = this->type()->get_backend(gogo);
16690 : 105 : bclosure = gogo->backend()->convert_expression(btype, bclosure, loc);
16691 : :
16692 : 105 : Expression* nil_check =
16693 : 105 : Expression::make_binary(OPERATOR_EQEQ, this->expr_,
16694 : : Expression::make_nil(loc), loc);
16695 : 105 : Bexpression* bnil_check = nil_check->get_backend(context);
16696 : :
16697 : 105 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
16698 : 105 : crash->determine_type_no_context(gogo);
16699 : 105 : Bexpression* bcrash = crash->get_backend(context);
16700 : :
16701 : 105 : Bfunction* bfn = context->function()->func_value()->get_decl();
16702 : 105 : Bexpression* bcond =
16703 : 105 : gogo->backend()->conditional_expression(bfn, NULL,
16704 : : bnil_check, bcrash, NULL, loc);
16705 : 105 : Bfunction* bfunction = context->function()->func_value()->get_decl();
16706 : 105 : Bstatement* cond_statement =
16707 : 105 : gogo->backend()->expression_statement(bfunction, bcond);
16708 : 105 : return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
16709 : : }
16710 : :
16711 : : // Dump ast representation for an interface field reference.
16712 : :
16713 : : void
16714 : 0 : Interface_field_reference_expression::do_dump_expression(
16715 : : Ast_dump_context* ast_dump_context) const
16716 : : {
16717 : 0 : this->expr_->dump_expression(ast_dump_context);
16718 : 0 : ast_dump_context->ostream() << "." << this->name_;
16719 : 0 : }
16720 : :
16721 : : // Make a reference to a field in an interface.
16722 : :
16723 : : Expression*
16724 : 32971 : Expression::make_interface_field_reference(Expression* expr,
16725 : : const std::string& field,
16726 : : Location location)
16727 : : {
16728 : 32971 : return new Interface_field_reference_expression(expr, field, location);
16729 : : }
16730 : :
16731 : : // Class Allocation_expression.
16732 : :
16733 : : int
16734 : 132214 : Allocation_expression::do_traverse(Traverse* traverse)
16735 : : {
16736 : 132214 : return Type::traverse(this->type_, traverse);
16737 : : }
16738 : :
16739 : : Type*
16740 : 150456 : Allocation_expression::do_type()
16741 : : {
16742 : 150456 : return Type::make_pointer_type(this->type_);
16743 : : }
16744 : :
16745 : : void
16746 : 1911 : Allocation_expression::do_check_types(Gogo*)
16747 : : {
16748 : 1911 : if (!this->type_->in_heap())
16749 : 0 : go_error_at(this->location(), "cannot heap allocate go:notinheap type");
16750 : 1911 : }
16751 : :
16752 : : // Make a copy of an allocation expression.
16753 : :
16754 : : Expression*
16755 : 0 : Allocation_expression::do_copy()
16756 : : {
16757 : 0 : Allocation_expression* alloc =
16758 : 0 : new Allocation_expression(this->type_->copy_expressions(),
16759 : 0 : this->location());
16760 : 0 : if (this->allocate_on_stack_)
16761 : 0 : alloc->set_allocate_on_stack();
16762 : 0 : if (this->no_zero_)
16763 : 0 : alloc->set_no_zero();
16764 : 0 : return alloc;
16765 : : }
16766 : :
16767 : : // Return the backend representation for an allocation expression.
16768 : :
16769 : : Bexpression*
16770 : 239416 : Allocation_expression::do_get_backend(Translate_context* context)
16771 : : {
16772 : 239416 : Gogo* gogo = context->gogo();
16773 : 239416 : Location loc = this->location();
16774 : 239416 : Btype* btype = this->type_->get_backend(gogo);
16775 : :
16776 : 239416 : if (this->allocate_on_stack_)
16777 : : {
16778 : 35031 : int64_t size;
16779 : 35031 : bool ok = this->type_->backend_type_size(gogo, &size);
16780 : 35031 : if (!ok)
16781 : : {
16782 : 0 : go_assert(saw_errors());
16783 : 0 : return gogo->backend()->error_expression();
16784 : : }
16785 : 35031 : Bstatement* decl;
16786 : 35031 : Named_object* fn = context->function();
16787 : 35031 : go_assert(fn != NULL);
16788 : 35031 : Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
16789 : 35031 : Bexpression* init = (this->no_zero_
16790 : 35031 : ? NULL
16791 : 21813 : : gogo->backend()->zero_expression(btype));
16792 : 35031 : Bvariable* temp =
16793 : 35031 : gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
16794 : : init,
16795 : : Backend::variable_address_is_taken,
16796 : : loc, &decl);
16797 : 35031 : Bexpression* ret = gogo->backend()->var_expression(temp, loc);
16798 : 35031 : ret = gogo->backend()->address_expression(ret, loc);
16799 : 35031 : ret = gogo->backend()->compound_expression(decl, ret, loc);
16800 : 35031 : return ret;
16801 : : }
16802 : :
16803 : 204385 : Bexpression* space =
16804 : 204385 : gogo->allocate_memory(this->type_, loc)->get_backend(context);
16805 : 204385 : Btype* pbtype = gogo->backend()->pointer_type(btype);
16806 : 204385 : return gogo->backend()->convert_expression(pbtype, space, loc);
16807 : : }
16808 : :
16809 : : // Dump ast representation for an allocation expression.
16810 : :
16811 : : void
16812 : 0 : Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
16813 : : const
16814 : : {
16815 : 0 : ast_dump_context->ostream() << "new(";
16816 : 0 : ast_dump_context->dump_type(this->type_);
16817 : 0 : ast_dump_context->ostream() << ")";
16818 : 0 : }
16819 : :
16820 : : // Make an allocation expression.
16821 : :
16822 : : Expression*
16823 : 241333 : Expression::make_allocation(Type* type, Location location)
16824 : : {
16825 : 241333 : return new Allocation_expression(type, location);
16826 : : }
16827 : :
16828 : : // Class Ordered_value_list.
16829 : :
16830 : : int
16831 : 5308929 : Ordered_value_list::traverse_vals(Traverse* traverse)
16832 : : {
16833 : 5308929 : if (this->vals_ != NULL)
16834 : : {
16835 : 5125530 : if (this->traverse_order_ == NULL)
16836 : : {
16837 : 4272759 : if (this->vals_->traverse(traverse) == TRAVERSE_EXIT)
16838 : : return TRAVERSE_EXIT;
16839 : : }
16840 : : else
16841 : : {
16842 : 2357104 : for (std::vector<unsigned long>::const_iterator p =
16843 : 852771 : this->traverse_order_->begin();
16844 : 3209875 : p != this->traverse_order_->end();
16845 : 2357104 : ++p)
16846 : : {
16847 : 2365003 : if (Expression::traverse(&this->vals_->at(*p), traverse)
16848 : : == TRAVERSE_EXIT)
16849 : 38154 : return TRAVERSE_EXIT;
16850 : : }
16851 : : }
16852 : : }
16853 : : return TRAVERSE_CONTINUE;
16854 : : }
16855 : :
16856 : : // Class Struct_construction_expression.
16857 : :
16858 : : // Traversal.
16859 : :
16860 : : int
16861 : 3301508 : Struct_construction_expression::do_traverse(Traverse* traverse)
16862 : : {
16863 : 3301508 : if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
16864 : : return TRAVERSE_EXIT;
16865 : 3283870 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
16866 : : return TRAVERSE_EXIT;
16867 : : return TRAVERSE_CONTINUE;
16868 : : }
16869 : :
16870 : : // Return whether this is a constant initializer.
16871 : :
16872 : : bool
16873 : 0 : Struct_construction_expression::is_constant_struct() const
16874 : : {
16875 : 0 : if (this->vals() == NULL)
16876 : : return true;
16877 : 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
16878 : 0 : pv != this->vals()->end();
16879 : 0 : ++pv)
16880 : : {
16881 : 0 : if (*pv != NULL
16882 : 0 : && !(*pv)->is_constant()
16883 : 0 : && (!(*pv)->is_composite_literal()
16884 : 0 : || (*pv)->is_nonconstant_composite_literal()))
16885 : 0 : return false;
16886 : : }
16887 : :
16888 : 0 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16889 : 0 : for (Struct_field_list::const_iterator pf = fields->begin();
16890 : 0 : pf != fields->end();
16891 : 0 : ++pf)
16892 : : {
16893 : : // There are no constant constructors for interfaces.
16894 : 0 : if (pf->type()->interface_type() != NULL)
16895 : 0 : return false;
16896 : : }
16897 : :
16898 : : return true;
16899 : : }
16900 : :
16901 : : // Return whether this is a zero value.
16902 : :
16903 : : bool
16904 : 36 : Struct_construction_expression::do_is_zero_value() const
16905 : : {
16906 : 36 : if (this->vals() == NULL)
16907 : : return true;
16908 : 9 : for (Expression_list::const_iterator pv = this->vals()->begin();
16909 : 9 : pv != this->vals()->end();
16910 : 0 : ++pv)
16911 : 9 : if (*pv != NULL && !(*pv)->is_zero_value())
16912 : 9 : return false;
16913 : :
16914 : 0 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16915 : 0 : for (Struct_field_list::const_iterator pf = fields->begin();
16916 : 0 : pf != fields->end();
16917 : 0 : ++pf)
16918 : : {
16919 : : // Interface conversion may cause a zero value being converted
16920 : : // to a non-zero value, like interface{}(0). Be conservative.
16921 : 0 : if (pf->type()->interface_type() != NULL)
16922 : 9 : return false;
16923 : : }
16924 : :
16925 : : return true;
16926 : : }
16927 : :
16928 : : // Return whether this struct can be used as a constant initializer.
16929 : :
16930 : : bool
16931 : 866861 : Struct_construction_expression::do_is_static_initializer() const
16932 : : {
16933 : 866861 : if (this->vals() == NULL)
16934 : : return true;
16935 : 4566318 : for (Expression_list::const_iterator pv = this->vals()->begin();
16936 : 4566318 : pv != this->vals()->end();
16937 : 3700036 : ++pv)
16938 : : {
16939 : 3704338 : if (*pv != NULL && !(*pv)->is_static_initializer())
16940 : 4374 : return false;
16941 : : }
16942 : :
16943 : 1723960 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16944 : 861980 : for (Struct_field_list::const_iterator pf = fields->begin();
16945 : 4557187 : pf != fields->end();
16946 : 3695207 : ++pf)
16947 : : {
16948 : : // There are no constant constructors for interfaces.
16949 : 7390486 : if (pf->type()->interface_type() != NULL)
16950 : 4374 : return false;
16951 : : }
16952 : :
16953 : : return true;
16954 : : }
16955 : :
16956 : : // Final type determination.
16957 : :
16958 : : void
16959 : 1799616 : Struct_construction_expression::do_determine_type(Gogo* gogo,
16960 : : const Type_context*)
16961 : : {
16962 : 1799616 : if (this->vals() == NULL)
16963 : : return;
16964 : 3584074 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16965 : 1792037 : Expression_list::const_iterator pv = this->vals()->begin();
16966 : 1792037 : for (Struct_field_list::const_iterator pf = fields->begin();
16967 : 11660080 : pf != fields->end();
16968 : 9868043 : ++pf, ++pv)
16969 : : {
16970 : 9868043 : if (pv == this->vals()->end())
16971 : 1799616 : return;
16972 : 9868043 : if (*pv != NULL)
16973 : : {
16974 : 9820576 : Type_context subcontext(pf->type(), false);
16975 : 9820576 : (*pv)->determine_type(gogo, &subcontext);
16976 : : }
16977 : : }
16978 : : // Extra values are an error we will report elsewhere; we still want
16979 : : // to determine the type to avoid knockon errors.
16980 : 1830683 : for (; pv != this->vals()->end(); ++pv)
16981 : 38646 : (*pv)->determine_type_no_context(gogo);
16982 : : }
16983 : :
16984 : : // Check types.
16985 : :
16986 : : void
16987 : 29829 : Struct_construction_expression::do_check_types(Gogo* gogo)
16988 : : {
16989 : 29829 : Struct_construction_expression::check_value_types(gogo, this->type_,
16990 : : this->vals(),
16991 : : this->location());
16992 : 29829 : }
16993 : :
16994 : : // Check types. This static function is also called by
16995 : : // Composite_literal_expression::do_check_types. Reports whether type
16996 : : // checking succeeded.
16997 : :
16998 : : bool
16999 : 203788 : Struct_construction_expression::check_value_types(Gogo* gogo,
17000 : : Type* type,
17001 : : Expression_list* vals,
17002 : : Location loc)
17003 : : {
17004 : 203788 : if (vals == NULL || vals->empty())
17005 : : return true;
17006 : :
17007 : 194860 : Struct_type* st = type->struct_type();
17008 : 194860 : if (vals->size() > st->field_count())
17009 : : {
17010 : 4 : go_error_at(loc, "too many expressions for struct");
17011 : 4 : return false;
17012 : : }
17013 : :
17014 : 194856 : bool imported_type =
17015 : 194856 : (type->named_type() != NULL
17016 : 194856 : && type->named_type()->named_object()->package() != NULL);
17017 : :
17018 : 194856 : bool ret = true;
17019 : 194856 : const Struct_field_list* fields = st->fields();
17020 : 194856 : Expression_list::const_iterator pv = vals->begin();
17021 : 194856 : int i = 0;
17022 : 194856 : for (Struct_field_list::const_iterator pf = fields->begin();
17023 : 819930 : pf != fields->end();
17024 : 625074 : ++pf, ++pv, ++i)
17025 : : {
17026 : 625077 : if (pv == vals->end())
17027 : : {
17028 : 3 : go_error_at(loc, "too few expressions for struct");
17029 : 3 : return false;
17030 : : }
17031 : :
17032 : 625074 : if (*pv == NULL)
17033 : 95941 : continue;
17034 : :
17035 : 529133 : if (imported_type
17036 : 529133 : && (Gogo::is_hidden_name(pf->field_name())
17037 : 60732 : || pf->is_embedded_builtin(gogo)))
17038 : : {
17039 : 2 : go_error_at(loc,
17040 : : "assignment of unexported field %qs in %qs literal",
17041 : 4 : Gogo::message_name(pf->field_name()).c_str(),
17042 : 2 : type->named_type()->message_name().c_str());
17043 : 2 : ret = false;
17044 : : }
17045 : :
17046 : 529133 : std::string reason;
17047 : 529133 : if (!Type::are_assignable(pf->type(), (*pv)->type(), &reason))
17048 : : {
17049 : 4 : if (reason.empty())
17050 : 0 : go_error_at((*pv)->location(),
17051 : : "incompatible type for field %d in struct construction",
17052 : : i + 1);
17053 : : else
17054 : 4 : go_error_at((*pv)->location(),
17055 : : ("incompatible type for field %d in "
17056 : : "struct construction (%s)"),
17057 : : i + 1, reason.c_str());
17058 : : ret = false;
17059 : : }
17060 : 529133 : }
17061 : 194853 : go_assert(pv == vals->end());
17062 : : return ret;
17063 : : }
17064 : :
17065 : : // Copy.
17066 : :
17067 : : Expression*
17068 : 0 : Struct_construction_expression::do_copy()
17069 : : {
17070 : 0 : Struct_construction_expression* ret =
17071 : 0 : new Struct_construction_expression(this->type_->copy_expressions(),
17072 : 0 : (this->vals() == NULL
17073 : : ? NULL
17074 : 0 : : this->vals()->copy()),
17075 : 0 : this->location());
17076 : 0 : if (this->traverse_order() != NULL)
17077 : 0 : ret->set_traverse_order(this->traverse_order());
17078 : 0 : return ret;
17079 : : }
17080 : :
17081 : : // Make implicit type conversions explicit.
17082 : :
17083 : : void
17084 : 186522 : Struct_construction_expression::do_add_conversions()
17085 : : {
17086 : 186522 : if (this->vals() == NULL)
17087 : 7698 : return;
17088 : :
17089 : 178824 : Location loc = this->location();
17090 : 357648 : const Struct_field_list* fields = this->type_->struct_type()->fields();
17091 : 178824 : Expression_list::iterator pv = this->vals()->begin();
17092 : 178824 : for (Struct_field_list::const_iterator pf = fields->begin();
17093 : 778681 : pf != fields->end();
17094 : 599857 : ++pf, ++pv)
17095 : : {
17096 : 599857 : if (pv == this->vals()->end())
17097 : : break;
17098 : 599857 : if (*pv != NULL)
17099 : : {
17100 : 503873 : Type* ft = pf->type();
17101 : 503873 : if (!Type::are_identical(ft, (*pv)->type(), 0, NULL)
17102 : 618120 : && ft->interface_type() != NULL)
17103 : 15177 : *pv = Expression::make_cast(ft, *pv, loc);
17104 : : }
17105 : : }
17106 : : }
17107 : :
17108 : : // Return the backend representation for constructing a struct.
17109 : :
17110 : : Bexpression*
17111 : 1134056 : Struct_construction_expression::do_get_backend(Translate_context* context)
17112 : : {
17113 : 1134056 : Gogo* gogo = context->gogo();
17114 : :
17115 : 1134056 : Btype* btype = this->type_->get_backend(gogo);
17116 : 1134056 : if (this->vals() == NULL)
17117 : 7690 : return gogo->backend()->zero_expression(btype);
17118 : :
17119 : 2252732 : const Struct_field_list* fields = this->type_->struct_type()->fields();
17120 : 1126366 : Expression_list::const_iterator pv = this->vals()->begin();
17121 : 1126366 : std::vector<Bexpression*> init;
17122 : 6878669 : for (Struct_field_list::const_iterator pf = fields->begin();
17123 : 6878669 : pf != fields->end();
17124 : 5752303 : ++pf)
17125 : : {
17126 : 5752303 : Btype* fbtype = pf->type()->get_backend(gogo);
17127 : 5752303 : if (pv == this->vals()->end())
17128 : 0 : init.push_back(gogo->backend()->zero_expression(fbtype));
17129 : 5752303 : else if (*pv == NULL)
17130 : : {
17131 : 95958 : init.push_back(gogo->backend()->zero_expression(fbtype));
17132 : 95958 : ++pv;
17133 : : }
17134 : : else
17135 : : {
17136 : 5656345 : Expression* val =
17137 : 5656345 : Expression::convert_for_assignment(gogo, pf->type(),
17138 : 5656345 : *pv, this->location());
17139 : 5656345 : init.push_back(val->get_backend(context));
17140 : 5656345 : ++pv;
17141 : : }
17142 : : }
17143 : 2252732 : if (this->type_->struct_type()->has_padding())
17144 : : {
17145 : : // Feed an extra value if there is a padding field.
17146 : 250 : Btype *fbtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
17147 : 250 : init.push_back(gogo->backend()->zero_expression(fbtype));
17148 : : }
17149 : 1126366 : return gogo->backend()->constructor_expression(btype, init, this->location());
17150 : 1126366 : }
17151 : :
17152 : : // Export a struct construction.
17153 : :
17154 : : void
17155 : 0 : Struct_construction_expression::do_export(Export_function_body* efb) const
17156 : : {
17157 : 0 : efb->write_c_string("$convert(");
17158 : 0 : efb->write_type(this->type_);
17159 : 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
17160 : 0 : pv != this->vals()->end();
17161 : 0 : ++pv)
17162 : : {
17163 : 0 : efb->write_c_string(", ");
17164 : 0 : if (*pv != NULL)
17165 : 0 : (*pv)->export_expression(efb);
17166 : : }
17167 : 0 : efb->write_c_string(")");
17168 : 0 : }
17169 : :
17170 : : // Dump ast representation of a struct construction expression.
17171 : :
17172 : : void
17173 : 0 : Struct_construction_expression::do_dump_expression(
17174 : : Ast_dump_context* ast_dump_context) const
17175 : : {
17176 : 0 : ast_dump_context->dump_type(this->type_);
17177 : 0 : ast_dump_context->ostream() << "{";
17178 : 0 : ast_dump_context->dump_expression_list(this->vals());
17179 : 0 : ast_dump_context->ostream() << "}";
17180 : 0 : }
17181 : :
17182 : : // Make a struct composite literal. This used by the thunk code.
17183 : :
17184 : : Expression*
17185 : 1370143 : Expression::make_struct_composite_literal(Type* type, Expression_list* vals,
17186 : : Location location)
17187 : : {
17188 : 1370143 : go_assert(type->struct_type() != NULL);
17189 : 1370143 : return new Struct_construction_expression(type, vals, location);
17190 : : }
17191 : :
17192 : : // Class Array_construction_expression.
17193 : :
17194 : : // Traversal.
17195 : :
17196 : : int
17197 : 2007421 : Array_construction_expression::do_traverse(Traverse* traverse)
17198 : : {
17199 : 2007421 : if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
17200 : : return TRAVERSE_EXIT;
17201 : 1986905 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
17202 : : return TRAVERSE_EXIT;
17203 : : return TRAVERSE_CONTINUE;
17204 : : }
17205 : :
17206 : : // Return whether this is a constant initializer.
17207 : :
17208 : : bool
17209 : 0 : Array_construction_expression::is_constant_array() const
17210 : : {
17211 : 0 : if (this->vals() == NULL)
17212 : : return true;
17213 : :
17214 : : // There are no constant constructors for interfaces.
17215 : 0 : if (this->type_->array_type()->element_type()->interface_type() != NULL)
17216 : : return false;
17217 : :
17218 : 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
17219 : 0 : pv != this->vals()->end();
17220 : 0 : ++pv)
17221 : : {
17222 : 0 : if (*pv != NULL
17223 : 0 : && !(*pv)->is_constant()
17224 : 0 : && (!(*pv)->is_composite_literal()
17225 : 0 : || (*pv)->is_nonconstant_composite_literal()))
17226 : 0 : return false;
17227 : : }
17228 : : return true;
17229 : : }
17230 : :
17231 : : // Return whether this is a zero value.
17232 : :
17233 : : bool
17234 : 10 : Array_construction_expression::do_is_zero_value() const
17235 : : {
17236 : 10 : if (this->vals() == NULL)
17237 : : return true;
17238 : :
17239 : : // Interface conversion may cause a zero value being converted
17240 : : // to a non-zero value, like interface{}(0). Be conservative.
17241 : 12 : if (this->type_->array_type()->element_type()->interface_type() != NULL)
17242 : : return false;
17243 : :
17244 : 4 : for (Expression_list::const_iterator pv = this->vals()->begin();
17245 : 4 : pv != this->vals()->end();
17246 : 0 : ++pv)
17247 : 4 : if (*pv != NULL && !(*pv)->is_zero_value())
17248 : 4 : return false;
17249 : :
17250 : : return true;
17251 : : }
17252 : :
17253 : : // Return whether this can be used a constant initializer.
17254 : :
17255 : : bool
17256 : 860706 : Array_construction_expression::do_is_static_initializer() const
17257 : : {
17258 : 860706 : if (this->vals() == NULL)
17259 : : return true;
17260 : :
17261 : : // There are no constant constructors for interfaces.
17262 : 1384509 : if (this->type_->array_type()->element_type()->interface_type() != NULL)
17263 : : return false;
17264 : :
17265 : 2774077 : for (Expression_list::const_iterator pv = this->vals()->begin();
17266 : 2774077 : pv != this->vals()->end();
17267 : 2193248 : ++pv)
17268 : : {
17269 : 2236309 : if (*pv != NULL && !(*pv)->is_static_initializer())
17270 : 102991 : return false;
17271 : : }
17272 : : return true;
17273 : : }
17274 : :
17275 : : // Final type determination.
17276 : :
17277 : : void
17278 : 494264 : Array_construction_expression::do_determine_type(Gogo* gogo,
17279 : : const Type_context*)
17280 : : {
17281 : 494264 : if (this->is_error_expression())
17282 : : {
17283 : 0 : go_assert(saw_errors());
17284 : 148651 : return;
17285 : : }
17286 : :
17287 : 494264 : if (this->vals() == NULL)
17288 : : return;
17289 : 345613 : Array_type* at = this->type_->array_type();
17290 : 345613 : if (at == NULL || at->is_error() || at->element_type()->is_error())
17291 : : {
17292 : 0 : go_assert(saw_errors());
17293 : 0 : this->set_is_error();
17294 : 0 : return;
17295 : : }
17296 : 345613 : Type_context subcontext(at->element_type(), false);
17297 : 1555029 : for (Expression_list::const_iterator pv = this->vals()->begin();
17298 : 1555029 : pv != this->vals()->end();
17299 : 1209416 : ++pv)
17300 : : {
17301 : 1209416 : if (*pv != NULL)
17302 : 1209416 : (*pv)->determine_type(gogo, &subcontext);
17303 : : }
17304 : : }
17305 : :
17306 : : // Check types.
17307 : :
17308 : : void
17309 : 64037 : Array_construction_expression::do_check_types(Gogo*)
17310 : : {
17311 : 64037 : if (this->is_error_expression())
17312 : : {
17313 : 0 : go_assert(saw_errors());
17314 : : return;
17315 : : }
17316 : :
17317 : 64037 : if (this->vals() == NULL)
17318 : : return;
17319 : :
17320 : 64028 : Array_type* at = this->type_->array_type();
17321 : 64028 : if (at == NULL || at->is_error() || at->element_type()->is_error())
17322 : : {
17323 : 0 : go_assert(saw_errors());
17324 : 0 : this->set_is_error();
17325 : 0 : return;
17326 : : }
17327 : 64028 : int i = 0;
17328 : 64028 : Type* element_type = at->element_type();
17329 : 64028 : for (Expression_list::const_iterator pv = this->vals()->begin();
17330 : 179313 : pv != this->vals()->end();
17331 : 115285 : ++pv, ++i)
17332 : : {
17333 : 115285 : if (*pv != NULL
17334 : 115285 : && !Type::are_assignable(element_type, (*pv)->type(), NULL))
17335 : : {
17336 : 0 : go_error_at((*pv)->location(),
17337 : : "incompatible type for element %d in composite literal",
17338 : : i + 1);
17339 : 0 : this->set_is_error();
17340 : : }
17341 : : }
17342 : : }
17343 : :
17344 : : // Make implicit type conversions explicit.
17345 : :
17346 : : void
17347 : 117250 : Array_construction_expression::do_add_conversions()
17348 : : {
17349 : 117250 : if (this->is_error_expression())
17350 : : {
17351 : 0 : go_assert(saw_errors());
17352 : 57385 : return;
17353 : : }
17354 : :
17355 : 117250 : if (this->vals() == NULL)
17356 : : return;
17357 : :
17358 : 226692 : Type* et = this->type_->array_type()->element_type();
17359 : 170731 : if (et->interface_type() == NULL)
17360 : : return;
17361 : :
17362 : 59865 : Location loc = this->location();
17363 : 169313 : for (Expression_list::iterator pv = this->vals()->begin();
17364 : 169313 : pv != this->vals()->end();
17365 : 109448 : ++pv)
17366 : 109448 : if (!Type::are_identical(et, (*pv)->type(), 0, NULL))
17367 : 107390 : *pv = Expression::make_cast(et, *pv, loc);
17368 : : }
17369 : :
17370 : : // Get a constructor expression for the array values.
17371 : :
17372 : : Bexpression*
17373 : 434332 : Array_construction_expression::get_constructor(Translate_context* context,
17374 : : Btype* array_btype)
17375 : : {
17376 : 868664 : Type* element_type = this->type_->array_type()->element_type();
17377 : :
17378 : 434332 : std::vector<unsigned long> indexes;
17379 : 434332 : std::vector<Bexpression*> vals;
17380 : 434332 : Gogo* gogo = context->gogo();
17381 : 434332 : if (this->vals() != NULL)
17382 : : {
17383 : 362797 : size_t i = 0;
17384 : 362797 : std::vector<unsigned long>::const_iterator pi;
17385 : 362797 : if (this->indexes_ != NULL)
17386 : 448 : pi = this->indexes_->begin();
17387 : 362797 : for (Expression_list::const_iterator pv = this->vals()->begin();
17388 : 2053772 : pv != this->vals()->end();
17389 : 1690975 : ++pv, ++i)
17390 : : {
17391 : 1690975 : if (this->indexes_ != NULL)
17392 : 110395 : go_assert(pi != this->indexes_->end());
17393 : :
17394 : 1690975 : if (this->indexes_ == NULL)
17395 : 1580580 : indexes.push_back(i);
17396 : : else
17397 : 110395 : indexes.push_back(*pi);
17398 : 1690975 : if (*pv == NULL)
17399 : : {
17400 : 0 : Btype* ebtype = element_type->get_backend(gogo);
17401 : 0 : Bexpression *zv = gogo->backend()->zero_expression(ebtype);
17402 : 0 : vals.push_back(zv);
17403 : : }
17404 : : else
17405 : : {
17406 : 1690975 : Expression* val_expr =
17407 : 1690975 : Expression::convert_for_assignment(gogo, element_type, *pv,
17408 : : this->location());
17409 : 1690975 : vals.push_back(val_expr->get_backend(context));
17410 : : }
17411 : 1690975 : if (this->indexes_ != NULL)
17412 : 110395 : ++pi;
17413 : : }
17414 : 362797 : if (this->indexes_ != NULL)
17415 : 448 : go_assert(pi == this->indexes_->end());
17416 : : }
17417 : 434332 : return gogo->backend()->array_constructor_expression(array_btype, indexes,
17418 : 434332 : vals, this->location());
17419 : 434332 : }
17420 : :
17421 : : // Export an array construction.
17422 : :
17423 : : void
17424 : 0 : Array_construction_expression::do_export(Export_function_body* efb) const
17425 : : {
17426 : 0 : efb->write_c_string("$convert(");
17427 : 0 : efb->write_type(this->type_);
17428 : 0 : if (this->vals() != NULL)
17429 : : {
17430 : 0 : std::vector<unsigned long>::const_iterator pi;
17431 : 0 : if (this->indexes_ != NULL)
17432 : 0 : pi = this->indexes_->begin();
17433 : 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
17434 : 0 : pv != this->vals()->end();
17435 : 0 : ++pv)
17436 : : {
17437 : 0 : efb->write_c_string(", ");
17438 : :
17439 : 0 : if (this->indexes_ != NULL)
17440 : : {
17441 : 0 : char buf[100];
17442 : 0 : snprintf(buf, sizeof buf, "%lu", *pi);
17443 : 0 : efb->write_c_string(buf);
17444 : 0 : efb->write_c_string(":");
17445 : : }
17446 : :
17447 : 0 : if (*pv != NULL)
17448 : 0 : (*pv)->export_expression(efb);
17449 : :
17450 : 0 : if (this->indexes_ != NULL)
17451 : 0 : ++pi;
17452 : : }
17453 : : }
17454 : 0 : efb->write_c_string(")");
17455 : 0 : }
17456 : :
17457 : : // Dump ast representation of an array construction expression.
17458 : :
17459 : : void
17460 : 0 : Array_construction_expression::do_dump_expression(
17461 : : Ast_dump_context* ast_dump_context) const
17462 : : {
17463 : 0 : Expression* length = this->type_->array_type()->length();
17464 : :
17465 : 0 : ast_dump_context->ostream() << "[" ;
17466 : 0 : if (length != NULL)
17467 : : {
17468 : 0 : ast_dump_context->dump_expression(length);
17469 : : }
17470 : 0 : ast_dump_context->ostream() << "]" ;
17471 : 0 : ast_dump_context->dump_type(this->type_);
17472 : 0 : this->dump_slice_storage_expression(ast_dump_context);
17473 : 0 : ast_dump_context->ostream() << "{" ;
17474 : 0 : if (this->indexes_ == NULL)
17475 : 0 : ast_dump_context->dump_expression_list(this->vals());
17476 : : else
17477 : : {
17478 : 0 : Expression_list::const_iterator pv = this->vals()->begin();
17479 : 0 : for (std::vector<unsigned long>::const_iterator pi =
17480 : 0 : this->indexes_->begin();
17481 : 0 : pi != this->indexes_->end();
17482 : 0 : ++pi, ++pv)
17483 : : {
17484 : 0 : if (pi != this->indexes_->begin())
17485 : 0 : ast_dump_context->ostream() << ", ";
17486 : 0 : ast_dump_context->ostream() << *pi << ':';
17487 : 0 : ast_dump_context->dump_expression(*pv);
17488 : : }
17489 : : }
17490 : 0 : ast_dump_context->ostream() << "}" ;
17491 : :
17492 : 0 : }
17493 : :
17494 : : // Class Fixed_array_construction_expression.
17495 : :
17496 : 434372 : Fixed_array_construction_expression::Fixed_array_construction_expression(
17497 : : Type* type, const std::vector<unsigned long>* indexes,
17498 : 434372 : Expression_list* vals, Location location)
17499 : : : Array_construction_expression(EXPRESSION_FIXED_ARRAY_CONSTRUCTION,
17500 : 434372 : type, indexes, vals, location)
17501 : 868744 : { go_assert(type->array_type() != NULL && !type->is_slice_type()); }
17502 : :
17503 : :
17504 : : // Copy.
17505 : :
17506 : : Expression*
17507 : 0 : Fixed_array_construction_expression::do_copy()
17508 : : {
17509 : 0 : Type* t = this->type()->copy_expressions();
17510 : 0 : return new Fixed_array_construction_expression(t, this->indexes(),
17511 : 0 : (this->vals() == NULL
17512 : : ? NULL
17513 : 0 : : this->vals()->copy()),
17514 : 0 : this->location());
17515 : : }
17516 : :
17517 : : // Return the backend representation for constructing a fixed array.
17518 : :
17519 : : Bexpression*
17520 : 434332 : Fixed_array_construction_expression::do_get_backend(Translate_context* context)
17521 : : {
17522 : 434332 : Type* type = this->type();
17523 : 434332 : Btype* btype = type->get_backend(context->gogo());
17524 : 434332 : return this->get_constructor(context, btype);
17525 : : }
17526 : :
17527 : : Expression*
17528 : 36250 : Expression::make_array_composite_literal(Type* type, Expression_list* vals,
17529 : : Location location)
17530 : : {
17531 : 72500 : go_assert(type->array_type() != NULL && !type->is_slice_type());
17532 : 36250 : return new Fixed_array_construction_expression(type, NULL, vals, location);
17533 : : }
17534 : :
17535 : : // Class Slice_construction_expression.
17536 : :
17537 : 434071 : Slice_construction_expression::Slice_construction_expression(
17538 : : Type* type, const std::vector<unsigned long>* indexes,
17539 : 434071 : Expression_list* vals, Location location)
17540 : : : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
17541 : : type, indexes, vals, location),
17542 : 434071 : valtype_(NULL), array_val_(NULL), slice_storage_(NULL),
17543 : 434071 : storage_escapes_(true)
17544 : : {
17545 : 434071 : go_assert(type->is_slice_type());
17546 : :
17547 : 434071 : unsigned long lenval;
17548 : 434071 : Expression* length;
17549 : 434071 : if (vals == NULL || vals->empty())
17550 : : lenval = 0;
17551 : : else
17552 : : {
17553 : 345094 : if (this->indexes() == NULL)
17554 : 344964 : lenval = vals->size();
17555 : : else
17556 : 130 : lenval = indexes->back() + 1;
17557 : : }
17558 : 434071 : Type* int_type = Type::lookup_integer_type("int");
17559 : 434071 : length = Expression::make_integer_ul(lenval, int_type, location);
17560 : 868142 : Type* element_type = type->array_type()->element_type();
17561 : 434071 : Array_type* array_type = Type::make_array_type(element_type, length);
17562 : 434071 : array_type->set_is_array_incomparable();
17563 : 434071 : this->valtype_ = array_type;
17564 : 434071 : }
17565 : :
17566 : : // Traversal.
17567 : :
17568 : : int
17569 : 1644060 : Slice_construction_expression::do_traverse(Traverse* traverse)
17570 : : {
17571 : 1644060 : if (this->Array_construction_expression::do_traverse(traverse)
17572 : : == TRAVERSE_EXIT)
17573 : : return TRAVERSE_EXIT;
17574 : 1626367 : if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
17575 : : return TRAVERSE_EXIT;
17576 : 1624835 : if (this->array_val_ != NULL
17577 : 1624835 : && Expression::traverse(&this->array_val_, traverse) == TRAVERSE_EXIT)
17578 : : return TRAVERSE_EXIT;
17579 : 1624835 : if (this->slice_storage_ != NULL
17580 : 1624835 : && Expression::traverse(&this->slice_storage_, traverse) == TRAVERSE_EXIT)
17581 : : return TRAVERSE_EXIT;
17582 : : return TRAVERSE_CONTINUE;
17583 : : }
17584 : :
17585 : : // Helper routine to create fixed array value underlying the slice literal.
17586 : : // May be called during flattening, or later during do_get_backend().
17587 : :
17588 : : Expression*
17589 : 377447 : Slice_construction_expression::create_array_val()
17590 : : {
17591 : 377447 : Array_type* array_type = this->type()->array_type();
17592 : 377447 : if (array_type == NULL)
17593 : : {
17594 : 0 : go_assert(this->type()->is_error());
17595 : : return NULL;
17596 : : }
17597 : :
17598 : 377447 : Location loc = this->location();
17599 : 377447 : go_assert(this->valtype_ != NULL);
17600 : :
17601 : 377447 : Expression_list* vals = this->vals();
17602 : 377447 : return new Fixed_array_construction_expression(
17603 : 377447 : this->valtype_, this->indexes(), vals, loc);
17604 : : }
17605 : :
17606 : : // If we're previous established that the slice storage does not
17607 : : // escape, then create a separate array temp val here for it. We
17608 : : // need to do this as part of flattening so as to be able to insert
17609 : : // the new temp statement.
17610 : :
17611 : : Expression*
17612 : 113370 : Slice_construction_expression::do_flatten(Gogo*, Named_object*,
17613 : : Statement_inserter* inserter)
17614 : : {
17615 : 113370 : if (this->type()->array_type() == NULL)
17616 : : {
17617 : 0 : go_assert(saw_errors());
17618 : 0 : return Expression::make_error(this->location());
17619 : : }
17620 : :
17621 : : // Create a stack-allocated storage temp if storage won't escape
17622 : 113370 : if (!this->storage_escapes_
17623 : 35047 : && this->slice_storage_ == NULL
17624 : 146335 : && this->element_count() > 0)
17625 : : {
17626 : 32759 : Location loc = this->location();
17627 : 32759 : this->array_val_ = this->create_array_val();
17628 : 32759 : go_assert(this->array_val_ != NULL);
17629 : 32759 : Temporary_statement* temp =
17630 : 32759 : Statement::make_temporary(this->valtype_, this->array_val_, loc);
17631 : 32759 : inserter->insert(temp);
17632 : 32759 : this->slice_storage_ = Expression::make_temporary_reference(temp, loc);
17633 : : }
17634 : : return this;
17635 : : }
17636 : :
17637 : : // When dumping a slice construction expression that has an explicit
17638 : : // storeage temp, emit the temp here (if we don't do this the storage
17639 : : // temp appears unused in the AST dump).
17640 : :
17641 : : void
17642 : 0 : Slice_construction_expression::
17643 : : dump_slice_storage_expression(Ast_dump_context* ast_dump_context) const
17644 : : {
17645 : 0 : if (this->slice_storage_ == NULL)
17646 : : return;
17647 : 0 : ast_dump_context->ostream() << "storage=" ;
17648 : 0 : ast_dump_context->dump_expression(this->slice_storage_);
17649 : : }
17650 : :
17651 : : // Copy.
17652 : :
17653 : : Expression*
17654 : 0 : Slice_construction_expression::do_copy()
17655 : : {
17656 : 0 : return new Slice_construction_expression(this->type()->copy_expressions(),
17657 : : this->indexes(),
17658 : 0 : (this->vals() == NULL
17659 : : ? NULL
17660 : 0 : : this->vals()->copy()),
17661 : 0 : this->location());
17662 : : }
17663 : :
17664 : : // Return the backend representation for constructing a slice.
17665 : :
17666 : : Bexpression*
17667 : 377443 : Slice_construction_expression::do_get_backend(Translate_context* context)
17668 : : {
17669 : 377443 : if (this->array_val_ == NULL)
17670 : 344688 : this->array_val_ = this->create_array_val();
17671 : 377443 : if (this->array_val_ == NULL)
17672 : : {
17673 : 0 : go_assert(this->type()->is_error());
17674 : 0 : return context->backend()->error_expression();
17675 : : }
17676 : :
17677 : 377443 : Location loc = this->location();
17678 : :
17679 : 377443 : bool is_static_initializer = this->array_val_->is_static_initializer();
17680 : :
17681 : : // We have to copy the initial values into heap memory if we are in
17682 : : // a function or if the values are not constants.
17683 : 377443 : bool copy_to_heap = context->function() != NULL || !is_static_initializer;
17684 : :
17685 : 377443 : Expression* space;
17686 : :
17687 : 377443 : if (this->slice_storage_ != NULL)
17688 : : {
17689 : 32755 : go_assert(!this->storage_escapes_);
17690 : 32755 : space = Expression::make_unary(OPERATOR_AND, this->slice_storage_, loc);
17691 : : }
17692 : 344688 : else if (!copy_to_heap)
17693 : : {
17694 : : // The initializer will only run once.
17695 : 287079 : space = Expression::make_unary(OPERATOR_AND, this->array_val_, loc);
17696 : 287079 : space->unary_expression()->set_is_slice_init();
17697 : : }
17698 : : else
17699 : : {
17700 : 57609 : go_assert(this->storage_escapes_ || this->element_count() == 0);
17701 : 57609 : space = Expression::make_heap_expression(this->array_val_, loc);
17702 : : }
17703 : 377443 : Array_type* at = this->valtype_->array_type();
17704 : 377443 : Type* et = at->element_type();
17705 : 377443 : space = Expression::make_unsafe_cast(Type::make_pointer_type(et),
17706 : : space, loc);
17707 : :
17708 : : // Build a constructor for the slice.
17709 : 377443 : Expression* len = at->length();
17710 : 377443 : Expression* slice_val =
17711 : 377443 : Expression::make_slice_value(this->type(), space, len, len, loc);
17712 : 377443 : return slice_val->get_backend(context);
17713 : : }
17714 : :
17715 : : // Make a slice composite literal. This is used by the type
17716 : : // descriptor code.
17717 : :
17718 : : Slice_construction_expression*
17719 : 402776 : Expression::make_slice_composite_literal(Type* type, Expression_list* vals,
17720 : : Location location)
17721 : : {
17722 : 402776 : go_assert(type->is_slice_type());
17723 : 402776 : return new Slice_construction_expression(type, NULL, vals, location);
17724 : : }
17725 : :
17726 : : // Class Map_construction_expression.
17727 : :
17728 : : // Traversal.
17729 : :
17730 : : int
17731 : 53169 : Map_construction_expression::do_traverse(Traverse* traverse)
17732 : : {
17733 : 53169 : if (this->vals_ != NULL
17734 : 53169 : && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
17735 : : return TRAVERSE_EXIT;
17736 : 52785 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
17737 : : return TRAVERSE_EXIT;
17738 : : return TRAVERSE_CONTINUE;
17739 : : }
17740 : :
17741 : : void
17742 : 2433 : Map_construction_expression::do_determine_type(Gogo* gogo, const Type_context*)
17743 : : {
17744 : 2433 : Map_type* mt = this->type_->map_type();
17745 : 0 : go_assert(mt != NULL);
17746 : 2433 : Type_context key_context(mt->key_type(), false);
17747 : 2433 : Type_context val_context(mt->val_type(), false);
17748 : 2433 : if (this->vals_ != NULL)
17749 : : {
17750 : 29823 : for (Expression_list::const_iterator pv = this->vals_->begin();
17751 : 29823 : pv != this->vals_->end();
17752 : 27748 : ++pv)
17753 : : {
17754 : 27748 : (*pv)->determine_type(gogo, &key_context);
17755 : 27748 : ++pv;
17756 : 27748 : (*pv)->determine_type(gogo, &val_context);
17757 : : }
17758 : : }
17759 : 2433 : }
17760 : :
17761 : : void
17762 : 0 : Map_construction_expression::do_check_types(Gogo*)
17763 : : {
17764 : : // Types should have been checked before this was created, so this
17765 : : // will probably never be called. Check it anyhow to be sure.
17766 : :
17767 : 0 : if (this->vals_ == NULL)
17768 : : return;
17769 : :
17770 : 0 : Map_type* mt = this->type_->map_type();
17771 : 0 : go_assert(mt != NULL);
17772 : 0 : Type* key_type = mt->key_type();
17773 : 0 : Type* val_type = mt->val_type();
17774 : 0 : for (Expression_list::const_iterator pv = this->vals_->begin();
17775 : 0 : pv != this->vals_->end();
17776 : 0 : ++pv)
17777 : : {
17778 : 0 : if (!Type::are_assignable(key_type, (*pv)->type(), NULL))
17779 : : {
17780 : 0 : go_error_at((*pv)->location(),
17781 : : "incompatible type for key in map composite literal");
17782 : 0 : this->set_is_error();
17783 : : }
17784 : 0 : ++pv;
17785 : 0 : if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
17786 : : {
17787 : 0 : go_error_at((*pv)->location(),
17788 : : "incompatible type for value in map composite literal");
17789 : 0 : this->set_is_error();
17790 : : }
17791 : : }
17792 : : }
17793 : :
17794 : : // Flatten constructor initializer into a temporary variable since
17795 : : // we need to take its address for __go_construct_map.
17796 : :
17797 : : Expression*
17798 : 3534 : Map_construction_expression::do_flatten(Gogo* gogo, Named_object*,
17799 : : Statement_inserter* inserter)
17800 : : {
17801 : 3534 : if (!this->is_error_expression()
17802 : 3534 : && this->vals_ != NULL
17803 : 2672 : && !this->vals_->empty()
17804 : 6206 : && this->constructor_temp_ == NULL)
17805 : : {
17806 : 2638 : Map_type* mt = this->type_->map_type();
17807 : 2638 : Type* key_type = mt->key_type();
17808 : 2638 : Type* val_type = mt->val_type();
17809 : 2638 : this->element_type_ = Type::make_builtin_struct_type(2,
17810 : : "__key", key_type,
17811 : : "__val", val_type);
17812 : :
17813 : 2638 : Expression_list* value_pairs = new Expression_list();
17814 : 2638 : Location loc = this->location();
17815 : :
17816 : 2638 : size_t i = 0;
17817 : 2638 : for (Expression_list::const_iterator pv = this->vals_->begin();
17818 : 32491 : pv != this->vals_->end();
17819 : 29853 : ++pv, ++i)
17820 : : {
17821 : 29853 : Expression_list* key_value_pair = new Expression_list();
17822 : 29853 : Expression* key = *pv;
17823 : 59706 : if (key->is_error_expression() || key->type()->is_error_type())
17824 : : {
17825 : 0 : go_assert(saw_errors());
17826 : 0 : return Expression::make_error(loc);
17827 : : }
17828 : 29853 : if (key->type()->interface_type() != NULL
17829 : 148 : && !key->is_multi_eval_safe())
17830 : : {
17831 : 44 : Temporary_statement* temp =
17832 : 44 : Statement::make_temporary(NULL, key, loc);
17833 : 44 : inserter->insert(temp);
17834 : 44 : key = Expression::make_temporary_reference(temp, loc);
17835 : : }
17836 : 29853 : key = Expression::convert_for_assignment(gogo, key_type, key, loc);
17837 : :
17838 : 29853 : ++pv;
17839 : 29853 : Expression* val = *pv;
17840 : 59706 : if (val->is_error_expression() || val->type()->is_error_type())
17841 : : {
17842 : 0 : go_assert(saw_errors());
17843 : 0 : return Expression::make_error(loc);
17844 : : }
17845 : 29853 : if (val->type()->interface_type() != NULL
17846 : 501 : && !val->is_multi_eval_safe())
17847 : : {
17848 : 497 : Temporary_statement* temp =
17849 : 497 : Statement::make_temporary(NULL, val, loc);
17850 : 497 : inserter->insert(temp);
17851 : 497 : val = Expression::make_temporary_reference(temp, loc);
17852 : : }
17853 : 29853 : val = Expression::convert_for_assignment(gogo, val_type, val, loc);
17854 : :
17855 : 29853 : key_value_pair->push_back(key);
17856 : 29853 : key_value_pair->push_back(val);
17857 : 29853 : value_pairs->push_back(
17858 : 29853 : Expression::make_struct_composite_literal(this->element_type_,
17859 : : key_value_pair, loc));
17860 : : }
17861 : :
17862 : 2638 : Expression* element_count = Expression::make_integer_ul(i, NULL, loc);
17863 : 2638 : Array_type* ctor_type =
17864 : 2638 : Type::make_array_type(this->element_type_, element_count);
17865 : 2638 : ctor_type->set_is_array_incomparable();
17866 : 2638 : Expression* constructor =
17867 : : new Fixed_array_construction_expression(ctor_type, NULL,
17868 : 2638 : value_pairs, loc);
17869 : :
17870 : 5276 : this->constructor_temp_ =
17871 : 2638 : Statement::make_temporary(NULL, constructor, loc);
17872 : 2638 : constructor->issue_nil_check();
17873 : 2638 : this->constructor_temp_->set_is_address_taken();
17874 : 2638 : this->constructor_temp_->determine_types(gogo);
17875 : 2638 : inserter->insert(this->constructor_temp_);
17876 : : }
17877 : :
17878 : 3534 : return this;
17879 : : }
17880 : :
17881 : : // Copy.
17882 : :
17883 : : Expression*
17884 : 0 : Map_construction_expression::do_copy()
17885 : : {
17886 : 0 : return new Map_construction_expression(this->type_->copy_expressions(),
17887 : 0 : (this->vals_ == NULL
17888 : : ? NULL
17889 : 0 : : this->vals_->copy()),
17890 : 0 : this->location());
17891 : : }
17892 : :
17893 : : // Make implicit type conversions explicit.
17894 : :
17895 : : void
17896 : 3481 : Map_construction_expression::do_add_conversions()
17897 : : {
17898 : 3481 : if (this->vals_ == NULL || this->vals_->empty())
17899 : 3336 : return;
17900 : :
17901 : 2638 : Map_type* mt = this->type_->map_type();
17902 : 2638 : Type* kt = mt->key_type();
17903 : 2638 : Type* vt = mt->val_type();
17904 : 2638 : bool key_is_interface = (kt->interface_type() != NULL);
17905 : 2638 : bool val_is_interface = (vt->interface_type() != NULL);
17906 : 2638 : if (!key_is_interface && !val_is_interface)
17907 : : return;
17908 : :
17909 : 145 : Location loc = this->location();
17910 : 790 : for (Expression_list::iterator pv = this->vals_->begin();
17911 : 790 : pv != this->vals_->end();
17912 : 645 : ++pv)
17913 : : {
17914 : 793 : if (key_is_interface &&
17915 : 148 : !Type::are_identical(kt, (*pv)->type(), 0, NULL))
17916 : 44 : *pv = Expression::make_cast(kt, *pv, loc);
17917 : 645 : ++pv;
17918 : 1146 : if (val_is_interface &&
17919 : 501 : !Type::are_identical(vt, (*pv)->type(), 0, NULL))
17920 : 493 : *pv = Expression::make_cast(vt, *pv, loc);
17921 : : }
17922 : : }
17923 : :
17924 : : // Return the backend representation for constructing a map.
17925 : :
17926 : : Bexpression*
17927 : 3481 : Map_construction_expression::do_get_backend(Translate_context* context)
17928 : : {
17929 : 3481 : if (this->is_error_expression())
17930 : 0 : return context->backend()->error_expression();
17931 : 3481 : Location loc = this->location();
17932 : :
17933 : 3481 : size_t i = 0;
17934 : 3481 : Expression* ventries;
17935 : 3481 : if (this->vals_ == NULL || this->vals_->empty())
17936 : 843 : ventries = Expression::make_nil(loc);
17937 : : else
17938 : : {
17939 : 2638 : go_assert(this->constructor_temp_ != NULL);
17940 : 2638 : i = this->vals_->size() / 2;
17941 : :
17942 : 2638 : Expression* ctor_ref =
17943 : 2638 : Expression::make_temporary_reference(this->constructor_temp_, loc);
17944 : 2638 : ventries = Expression::make_unary(OPERATOR_AND, ctor_ref, loc);
17945 : : }
17946 : :
17947 : 3481 : Map_type* mt = this->type_->map_type();
17948 : 3481 : if (this->element_type_ == NULL)
17949 : 843 : this->element_type_ =
17950 : 843 : Type::make_builtin_struct_type(2,
17951 : : "__key", mt->key_type(),
17952 : : "__val", mt->val_type());
17953 : 3481 : Expression* descriptor = Expression::make_type_descriptor(mt, loc);
17954 : :
17955 : 3481 : Type* uintptr_t = Type::lookup_integer_type("uintptr");
17956 : 3481 : Expression* count = Expression::make_integer_ul(i, uintptr_t, loc);
17957 : :
17958 : 3481 : Expression* entry_size =
17959 : 3481 : Expression::make_type_info(this->element_type_, TYPE_INFO_SIZE);
17960 : :
17961 : 3481 : unsigned int field_index;
17962 : 3481 : const Struct_field* valfield =
17963 : 3481 : this->element_type_->find_local_field("__val", &field_index);
17964 : 3481 : Expression* val_offset =
17965 : 3481 : Expression::make_struct_field_offset(this->element_type_, valfield);
17966 : :
17967 : 3481 : Gogo* gogo = context->gogo();
17968 : 3481 : Expression* map_ctor =
17969 : 3481 : Runtime::make_call(gogo, Runtime::CONSTRUCT_MAP, loc, 5,
17970 : : descriptor, count, entry_size, val_offset, ventries);
17971 : 3481 : map_ctor->determine_type_no_context(gogo);
17972 : 3481 : return map_ctor->get_backend(context);
17973 : : }
17974 : :
17975 : : // Export an array construction.
17976 : :
17977 : : void
17978 : 0 : Map_construction_expression::do_export(Export_function_body* efb) const
17979 : : {
17980 : 0 : efb->write_c_string("$convert(");
17981 : 0 : efb->write_type(this->type_);
17982 : 0 : for (Expression_list::const_iterator pv = this->vals_->begin();
17983 : 0 : pv != this->vals_->end();
17984 : 0 : ++pv)
17985 : : {
17986 : 0 : efb->write_c_string(", ");
17987 : 0 : (*pv)->export_expression(efb);
17988 : : }
17989 : 0 : efb->write_c_string(")");
17990 : 0 : }
17991 : :
17992 : : // Dump ast representation for a map construction expression.
17993 : :
17994 : : void
17995 : 0 : Map_construction_expression::do_dump_expression(
17996 : : Ast_dump_context* ast_dump_context) const
17997 : : {
17998 : 0 : ast_dump_context->ostream() << "{" ;
17999 : 0 : ast_dump_context->dump_expression_list(this->vals_, true);
18000 : 0 : ast_dump_context->ostream() << "}";
18001 : 0 : }
18002 : :
18003 : : // A composite literal key. This is seen during parsing, but is not
18004 : : // resolved to a named_object in case this is a composite literal of
18005 : : // struct type.
18006 : :
18007 : : class Composite_literal_key_expression : public Parser_expression
18008 : : {
18009 : : public:
18010 : 115521 : Composite_literal_key_expression(const std::string& name, Location location)
18011 : 115521 : : Parser_expression(EXPRESSION_COMPOSITE_LITERAL_KEY, location),
18012 : 115521 : name_(name), expr_(NULL)
18013 : 115521 : { }
18014 : :
18015 : : const std::string&
18016 : 114982 : name() const
18017 : 114982 : { return this->name_; }
18018 : :
18019 : : protected:
18020 : : Type*
18021 : : do_type();
18022 : :
18023 : : void
18024 : : do_determine_type(Gogo*, const Type_context*);
18025 : :
18026 : : Expression*
18027 : : do_lower(Gogo*, Named_object*, Statement_inserter*);
18028 : :
18029 : : Expression*
18030 : 0 : do_copy()
18031 : : {
18032 : 0 : return new Composite_literal_key_expression(this->name_, this->location());
18033 : : }
18034 : :
18035 : : void
18036 : : do_dump_expression(Ast_dump_context*) const;
18037 : :
18038 : : private:
18039 : : // The name.
18040 : : std::string name_;
18041 : : // After we look up the name, a corresponding expression.
18042 : : Expression* expr_;
18043 : : };
18044 : :
18045 : : // Determine the type of a composite literal key. We will never get
18046 : : // here for keys in composite literals of struct types, because they
18047 : : // will be handled by Composite_literal_expression::do_determine_type.
18048 : : // So if we get here, this must be a regular name reference after all.
18049 : :
18050 : : void
18051 : 529 : Composite_literal_key_expression::do_determine_type(
18052 : : Gogo* gogo,
18053 : : const Type_context* context)
18054 : : {
18055 : 529 : if (this->expr_ != NULL)
18056 : : {
18057 : : // Already resolved.
18058 : : return;
18059 : : }
18060 : :
18061 : 529 : Named_object* no = gogo->lookup(this->name_, NULL);
18062 : 529 : if (no == NULL)
18063 : : {
18064 : : // Gogo::lookup doesn't look in the global namespace, and names
18065 : : // used in composite literal keys aren't seen by
18066 : : // Gogo::define_global_names, so we have to look in the global
18067 : : // namespace ourselves.
18068 : 9 : no = gogo->lookup_global(Gogo::unpack_hidden_name(this->name_).c_str());
18069 : 9 : if (no == NULL)
18070 : : {
18071 : 1 : go_error_at(this->location(), "reference to undefined name %qs",
18072 : 1 : Gogo::message_name(this->name_).c_str());
18073 : 1 : this->set_is_error();
18074 : 1 : return;
18075 : : }
18076 : : }
18077 : :
18078 : 528 : this->expr_ = Expression::make_unknown_reference(no, this->location());
18079 : 528 : this->expr_->determine_type(gogo, context);
18080 : : }
18081 : :
18082 : : Type*
18083 : 369 : Composite_literal_key_expression::do_type()
18084 : : {
18085 : 369 : if (this->is_error_expression())
18086 : 0 : return Type::make_error_type();
18087 : 369 : go_assert(this->expr_ != NULL);
18088 : 369 : return this->expr_->type();
18089 : : }
18090 : :
18091 : : Expression*
18092 : 529 : Composite_literal_key_expression::do_lower(Gogo*, Named_object*,
18093 : : Statement_inserter*)
18094 : : {
18095 : 529 : if (this->is_error_expression())
18096 : 1 : return Expression::make_error(this->location());
18097 : 528 : go_assert(this->expr_ != NULL);
18098 : : return this->expr_;
18099 : : }
18100 : :
18101 : : // Dump a composite literal key.
18102 : :
18103 : : void
18104 : 0 : Composite_literal_key_expression::do_dump_expression(
18105 : : Ast_dump_context* ast_dump_context) const
18106 : : {
18107 : 0 : ast_dump_context->ostream() << "_UnknownName_(" << this->name_ << ")";
18108 : 0 : }
18109 : :
18110 : : // Make a composite literal key.
18111 : :
18112 : : Expression*
18113 : 115521 : Expression::make_composite_literal_key(const std::string& name,
18114 : : Location location)
18115 : : {
18116 : 115521 : return new Composite_literal_key_expression(name, location);
18117 : : }
18118 : :
18119 : : // Class Composite_literal_expression.
18120 : :
18121 : : // Traversal.
18122 : :
18123 : : int
18124 : 1146569 : Composite_literal_expression::do_traverse(Traverse* traverse)
18125 : : {
18126 : 1146569 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
18127 : : return TRAVERSE_EXIT;
18128 : :
18129 : : // If this is a struct composite literal with keys, then the keys
18130 : : // are field names, not expressions. We don't want to traverse them
18131 : : // in that case. If we do, we can give an erroneous error "variable
18132 : : // initializer refers to itself." See bug482.go in the testsuite.
18133 : 1146569 : if (this->has_keys_ && this->vals_ != NULL)
18134 : : {
18135 : : // The type may not be resolvable at this point.
18136 : 108128 : Type* type = this->type_;
18137 : :
18138 : 158074 : for (int depth = 0; depth < this->depth_; ++depth)
18139 : : {
18140 : 49951 : type = type->deref();
18141 : 49951 : if (type->array_type() != NULL)
18142 : 96928 : type = type->array_type()->element_type();
18143 : 159689 : else if (type->map_type() != NULL)
18144 : : {
18145 : 1482 : if (this->key_path_[depth])
18146 : 12 : type = type->map_type()->key_type();
18147 : : else
18148 : 2952 : type = type->map_type()->val_type();
18149 : : }
18150 : : else
18151 : : {
18152 : : // This error will be reported during lowering.
18153 : : return TRAVERSE_CONTINUE;
18154 : : }
18155 : : }
18156 : 108123 : type = type->deref();
18157 : :
18158 : 239712 : while (true)
18159 : : {
18160 : 239712 : if (type->classification() == Type::TYPE_NAMED)
18161 : 86409 : type = type->named_type()->real_type();
18162 : 153303 : else if (type->classification() == Type::TYPE_FORWARD)
18163 : : {
18164 : 45180 : Type* t = type->forwarded();
18165 : 45180 : if (t == type)
18166 : : break;
18167 : : type = t;
18168 : : }
18169 : : else
18170 : : break;
18171 : : }
18172 : :
18173 : 108123 : if (type->classification() == Type::TYPE_STRUCT)
18174 : : {
18175 : 92452 : Expression_list::iterator p = this->vals_->begin();
18176 : 346938 : while (p != this->vals_->end())
18177 : : {
18178 : : // Skip key.
18179 : 254486 : ++p;
18180 : 254486 : go_assert(p != this->vals_->end());
18181 : 254486 : if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
18182 : : return TRAVERSE_EXIT;
18183 : 254486 : ++p;
18184 : : }
18185 : : return TRAVERSE_CONTINUE;
18186 : : }
18187 : : }
18188 : :
18189 : 1054112 : if (this->vals_ != NULL)
18190 : 988367 : return this->vals_->traverse(traverse);
18191 : :
18192 : : return TRAVERSE_CONTINUE;
18193 : : }
18194 : :
18195 : : void
18196 : 233460 : Composite_literal_expression::do_determine_type(Gogo* gogo,
18197 : : const Type_context*)
18198 : : {
18199 : : // Resolve the type if this composite literal is within another
18200 : : // composite literal and has omitted the type. The DEPTH_ field
18201 : : // tells us how deeply this one is embedded.
18202 : 233460 : Type* type = this->type_;
18203 : 412341 : for (int depth = 0; depth < this->depth_; ++depth)
18204 : : {
18205 : 178885 : type = type->deref();
18206 : 178885 : if (type->array_type() != NULL)
18207 : 349558 : type = type->array_type()->element_type();
18208 : 4106 : else if (type->map_type() != NULL)
18209 : : {
18210 : 4102 : if (this->key_path_[depth])
18211 : 70 : type = type->map_type()->key_type();
18212 : : else
18213 : 8134 : type = type->map_type()->val_type();
18214 : : }
18215 : : else
18216 : : {
18217 : 4 : if (!type->is_error())
18218 : 4 : this->report_error(_("may only omit types within composite "
18219 : : "literals of slice, array, or map type"));
18220 : : else
18221 : : {
18222 : 0 : go_assert(saw_errors());
18223 : 0 : this->set_is_error();
18224 : : }
18225 : 4 : return;
18226 : : }
18227 : : }
18228 : :
18229 : 233456 : this->type_ = type;
18230 : 233456 : this->depth_ = 0;
18231 : :
18232 : 233456 : type = type->deref();
18233 : :
18234 : 233456 : if (this->vals_ == NULL || this->vals_->empty())
18235 : : {
18236 : : // No value types to determine.
18237 : 17677 : if (type->array_type() != NULL
18238 : 4059 : && type->array_type()->length() != NULL
18239 : 577 : && type->array_type()->length()->is_nil_expression())
18240 : 2 : this->resolve_array_length(type);
18241 : 13618 : return;
18242 : : }
18243 : :
18244 : 390165 : if (type->struct_type() != NULL && this->has_keys_)
18245 : : {
18246 : : // Rewrite the value list by removing the struct field keys. We
18247 : : // do this now rather than during lowering because handling
18248 : : // struct keys is painful. We don't need to do this for
18249 : : // slice/array/map literals, because it's easy to determine
18250 : : // their types with or without the keys.
18251 : 45900 : if (!this->resolve_struct_keys(gogo, type))
18252 : : {
18253 : 19 : this->set_is_error();
18254 : 38 : delete this->vals_;
18255 : 19 : this->vals_ = NULL;
18256 : 19 : this->has_keys_ = false;
18257 : 19 : return;
18258 : : }
18259 : : }
18260 : :
18261 : 219819 : if (type->struct_type() != NULL)
18262 : : {
18263 : 340616 : const Struct_field_list* fields = type->struct_type()->fields();
18264 : 170308 : Expression_list::const_iterator pv = this->vals_->begin();
18265 : 170308 : for (Struct_field_list::const_iterator pf = fields->begin();
18266 : 747385 : pf != fields->end();
18267 : 577077 : ++pf, ++pv)
18268 : : {
18269 : 577080 : if (pv == this->vals_->end())
18270 : 233460 : return;
18271 : 577077 : if (*pv != NULL)
18272 : : {
18273 : 480394 : Type_context subcontext(pf->type(), false);
18274 : 480394 : (*pv)->determine_type(gogo, &subcontext);
18275 : : }
18276 : : }
18277 : : // Extra values are an error we will report in the check_types
18278 : : // pass; we still want to determine the type to avoid knockon
18279 : : // errors.
18280 : 170313 : for (; pv != this->vals_->end(); ++pv)
18281 : 8 : (*pv)->determine_type_no_context(gogo);
18282 : : }
18283 : 49511 : else if (type->array_type() != NULL)
18284 : : {
18285 : 46824 : Array_type* at = type->array_type();
18286 : 46824 : Type_context intcontext(Type::lookup_integer_type("int"), false);
18287 : 46824 : Type_context subcontext(at->element_type(), false);
18288 : 652101 : for (Expression_list::const_iterator pv = this->vals_->begin();
18289 : 652101 : pv != this->vals_->end();
18290 : 605277 : ++pv)
18291 : : {
18292 : 605277 : if (this->has_keys_)
18293 : : {
18294 : 110423 : if (*pv != NULL)
18295 : 110400 : (*pv)->determine_type(gogo, &intcontext);
18296 : 110423 : ++pv;
18297 : 110423 : if (pv == this->vals_->end())
18298 : : break;
18299 : : }
18300 : :
18301 : 605277 : if (*pv != NULL)
18302 : 605277 : (*pv)->determine_type(gogo, &subcontext);
18303 : : }
18304 : :
18305 : 46824 : if (at->length() != NULL && at->length()->is_nil_expression())
18306 : 867 : this->resolve_array_length(type);
18307 : : }
18308 : 2687 : else if (type->map_type() != NULL)
18309 : : {
18310 : 2685 : if (!this->has_keys_)
18311 : : {
18312 : 0 : this->report_error(_("map composite literal must have keys"));
18313 : 0 : return;
18314 : : }
18315 : :
18316 : 2685 : Map_type* mt = type->map_type();
18317 : 2685 : Type_context key_context(mt->key_type(), false);
18318 : 2685 : Type_context val_context(mt->val_type(), false);
18319 : 32763 : for (Expression_list::const_iterator pv = this->vals_->begin();
18320 : 32763 : pv != this->vals_->end();
18321 : 30078 : ++pv)
18322 : : {
18323 : 30078 : if (*pv != NULL)
18324 : 30076 : (*pv)->determine_type(gogo, &key_context);
18325 : 30078 : ++pv;
18326 : 30078 : if (*pv != NULL)
18327 : 30078 : (*pv)->determine_type(gogo, &val_context);
18328 : : }
18329 : : }
18330 : : else
18331 : : {
18332 : : // We'll report this as an error in the check_types pass.
18333 : : // Determine types to avoid knockon errors.
18334 : 6 : for (Expression_list::const_iterator pv = this->vals_->begin();
18335 : 6 : pv != this->vals_->end();
18336 : 4 : ++pv)
18337 : : {
18338 : 4 : if (*pv != NULL)
18339 : 4 : (*pv)->determine_type_no_context(gogo);
18340 : : }
18341 : : }
18342 : : }
18343 : :
18344 : : Type*
18345 : 257216 : Composite_literal_expression::do_type()
18346 : : {
18347 : 257216 : if (this->is_error_expression())
18348 : 38 : return Type::make_error_type();
18349 : 257178 : go_assert(this->depth_ == 0);
18350 : 257178 : return this->type_;
18351 : : }
18352 : :
18353 : : // Resolve the field keys of a struct composite literal.
18354 : :
18355 : : bool
18356 : 45900 : Composite_literal_expression::resolve_struct_keys(Gogo* gogo, Type* type)
18357 : : {
18358 : 45900 : Struct_type* st = type->struct_type();
18359 : 45900 : size_t field_count = st->field_count();
18360 : 45900 : std::vector<Expression*> vals(field_count);
18361 : 45900 : std::vector<unsigned long>* traverse_order = new(std::vector<unsigned long>);
18362 : 45900 : Expression_list::const_iterator p = this->vals_->begin();
18363 : 45900 : Expression* external_expr = NULL;
18364 : 45900 : const Named_object* external_no = NULL;
18365 : 171820 : while (p != this->vals_->end())
18366 : : {
18367 : 125938 : Expression* name_expr = *p;
18368 : :
18369 : 125938 : ++p;
18370 : 125938 : go_assert(p != this->vals_->end());
18371 : 125938 : Expression* val = *p;
18372 : :
18373 : 125938 : ++p;
18374 : :
18375 : 125938 : if (name_expr == NULL)
18376 : : {
18377 : 1 : go_error_at(val->location(),
18378 : : "mixture of field and value initializers");
18379 : 18 : return false;
18380 : : }
18381 : :
18382 : 125937 : bool bad_key = false;
18383 : 125937 : std::string name;
18384 : 125937 : const Named_object* no = NULL;
18385 : 125937 : switch (name_expr->classification())
18386 : : {
18387 : 114982 : case EXPRESSION_COMPOSITE_LITERAL_KEY:
18388 : 114982 : name =
18389 : 114982 : static_cast<Composite_literal_key_expression*>(name_expr)->name();
18390 : 114982 : break;
18391 : :
18392 : 5232 : case EXPRESSION_UNKNOWN_REFERENCE:
18393 : 5232 : name = name_expr->unknown_expression()->name();
18394 : 5232 : if (type->named_type() != NULL)
18395 : : {
18396 : : // If the named object found for this field name comes from a
18397 : : // different package than the struct it is a part of, do not count
18398 : : // this incorrect lookup as a usage of the object's package.
18399 : 5042 : no = name_expr->unknown_expression()->named_object();
18400 : 5042 : if (no->package() != NULL
18401 : 5419 : && (no->package()
18402 : 377 : != type->named_type()->named_object()->package()))
18403 : 39 : no->package()->forget_usage(name_expr);
18404 : : }
18405 : : break;
18406 : :
18407 : 111 : case EXPRESSION_CONST_REFERENCE:
18408 : 111 : no = static_cast<Const_expression*>(name_expr)->named_object();
18409 : 111 : break;
18410 : :
18411 : 1 : case EXPRESSION_TYPE:
18412 : 1 : {
18413 : 1 : Type* t = name_expr->type();
18414 : 1 : Named_type* nt = t->named_type();
18415 : 1 : if (nt == NULL)
18416 : : bad_key = true;
18417 : : else
18418 : 1 : no = nt->named_object();
18419 : : }
18420 : : break;
18421 : :
18422 : 5185 : case EXPRESSION_VAR_REFERENCE:
18423 : 5185 : no = name_expr->var_expression()->named_object();
18424 : 5185 : break;
18425 : :
18426 : 91 : case EXPRESSION_ENCLOSED_VAR_REFERENCE:
18427 : 91 : no = name_expr->enclosed_var_expression()->variable();
18428 : 91 : break;
18429 : :
18430 : 331 : case EXPRESSION_FUNC_REFERENCE:
18431 : 331 : no = name_expr->func_expression()->named_object();
18432 : 331 : break;
18433 : :
18434 : : default:
18435 : : bad_key = true;
18436 : : break;
18437 : : }
18438 : 120740 : if (bad_key)
18439 : : {
18440 : 4 : go_error_at(name_expr->location(), "expected struct field name");
18441 : 4 : return false;
18442 : : }
18443 : :
18444 : 125933 : if (no != NULL)
18445 : : {
18446 : 10761 : if (no->package() != NULL && external_expr == NULL)
18447 : : {
18448 : 10761 : external_expr = name_expr;
18449 : 10761 : external_no = no;
18450 : : }
18451 : :
18452 : 10761 : name = no->name();
18453 : :
18454 : : // A predefined name won't be packed. If it starts with a
18455 : : // lower case letter we need to check for that case, because
18456 : : // the field name will be packed. FIXME.
18457 : 10761 : if (!Gogo::is_hidden_name(name)
18458 : 4447 : && name[0] >= 'a'
18459 : 10761 : && name[0] <= 'z')
18460 : : {
18461 : 0 : Named_object* gno = gogo->lookup_global(name.c_str());
18462 : 0 : if (gno == no)
18463 : 0 : name = gogo->pack_hidden_name(name, false);
18464 : : }
18465 : : }
18466 : :
18467 : 125933 : unsigned int index;
18468 : 125933 : const Struct_field* sf = st->find_local_field(name, &index);
18469 : 125933 : if (sf == NULL)
18470 : : {
18471 : 35 : go_error_at(name_expr->location(), "unknown field %qs in %qs",
18472 : 12 : Gogo::message_name(name).c_str(),
18473 : 12 : (type->named_type() != NULL
18474 : 34 : ? type->named_type()->message_name().c_str()
18475 : : : "unnamed struct"));
18476 : 12 : return false;
18477 : : }
18478 : 125921 : if (vals[index] != NULL)
18479 : : {
18480 : 3 : go_error_at(name_expr->location(),
18481 : : "duplicate value for field %qs in %qs",
18482 : 1 : Gogo::message_name(name).c_str(),
18483 : 1 : (type->named_type() != NULL
18484 : 3 : ? type->named_type()->message_name().c_str()
18485 : : : "unnamed struct"));
18486 : 1 : return false;
18487 : : }
18488 : :
18489 : 125920 : vals[index] = val;
18490 : 125920 : traverse_order->push_back(static_cast<unsigned long>(index));
18491 : 125937 : }
18492 : :
18493 : 45882 : if (!this->all_are_names_)
18494 : : {
18495 : : // This is a weird case like bug462 in the testsuite.
18496 : 1 : if (external_expr == NULL)
18497 : 0 : go_error_at(this->location(), "unknown field in %qs literal",
18498 : 0 : (type->named_type() != NULL
18499 : 0 : ? type->named_type()->message_name().c_str()
18500 : : : "unnamed struct"));
18501 : : else
18502 : 3 : go_error_at(external_expr->location(), "unknown field %qs in %qs",
18503 : 1 : external_no->message_name().c_str(),
18504 : 1 : (type->named_type() != NULL
18505 : 3 : ? type->named_type()->message_name().c_str()
18506 : : : "unnamed struct"));
18507 : 1 : return false;
18508 : : }
18509 : :
18510 : 45881 : Expression_list* list = new Expression_list;
18511 : 45881 : list->reserve(field_count);
18512 : 267738 : for (size_t i = 0; i < field_count; ++i)
18513 : 221857 : list->push_back(vals[i]);
18514 : :
18515 : 45881 : this->vals_ = list;
18516 : 45881 : this->traverse_order_ = traverse_order;
18517 : 45881 : this->has_keys_ = false;
18518 : :
18519 : 45881 : return true;
18520 : 45900 : }
18521 : :
18522 : : // Handle [...]{...}
18523 : :
18524 : : void
18525 : 869 : Composite_literal_expression::resolve_array_length(Type* type)
18526 : : {
18527 : 869 : size_t size;
18528 : 869 : if (this->vals_ == NULL || this->vals_->empty())
18529 : : size = 0;
18530 : 867 : else if (!this->has_keys_)
18531 : 690 : size = this->vals_->size();
18532 : : else
18533 : : {
18534 : : unsigned long index = 0;
18535 : : size = 0;
18536 : 2588 : for (Expression_list::const_iterator pv = this->vals_->begin();
18537 : 2765 : pv != this->vals_->end();
18538 : 2588 : pv += 2)
18539 : : {
18540 : 2590 : Expression* index_expr = *pv;
18541 : 2590 : if (index_expr != NULL)
18542 : : {
18543 : 2583 : Numeric_constant nc;
18544 : 2583 : unsigned long iv;
18545 : 2583 : if (!index_expr->numeric_constant_value(&nc)
18546 : 2583 : || nc.to_unsigned_long(&iv) != Numeric_constant::NC_UL_VALID)
18547 : : {
18548 : : // We will report an error when lowering.
18549 : : break;
18550 : : }
18551 : 2581 : index = iv;
18552 : 2583 : }
18553 : :
18554 : 2588 : if (index >= size)
18555 : 2553 : size = index + 1;
18556 : :
18557 : 2588 : ++index;
18558 : : }
18559 : : }
18560 : :
18561 : 869 : Expression* elen = Expression::make_integer_ul(size, NULL, this->location());
18562 : 1738 : this->type_ = Type::make_array_type(type->array_type()->element_type(),
18563 : : elen);
18564 : 869 : }
18565 : :
18566 : : void
18567 : 226843 : Composite_literal_expression::do_check_types(Gogo* gogo)
18568 : : {
18569 : 226843 : if (this->is_error_expression() || this->type_->is_error())
18570 : : {
18571 : 28 : go_assert(saw_errors());
18572 : : return;
18573 : : }
18574 : 226815 : go_assert(this->depth_ == 0);
18575 : :
18576 : 226815 : Type* type = this->type_->deref();
18577 : 226815 : if (type->struct_type() != NULL)
18578 : : {
18579 : 173959 : go_assert(!this->has_keys_);
18580 : 173959 : if (!Struct_construction_expression::check_value_types(gogo, type,
18581 : : this->vals_,
18582 : : this->location()))
18583 : 12 : this->set_is_error();
18584 : : }
18585 : 52856 : else if (type->array_type() != NULL)
18586 : : {
18587 : 98714 : Type* element_type = type->array_type()->element_type();
18588 : 49357 : if (element_type->is_error())
18589 : : {
18590 : 1 : go_assert(saw_errors());
18591 : : return;
18592 : : }
18593 : 49356 : if (this->vals_ == NULL || this->vals_->empty())
18594 : : return;
18595 : : int i = 0;
18596 : : for (Expression_list::const_iterator pv = this->vals_->begin();
18597 : 641084 : pv != this->vals_->end();
18598 : 595670 : ++pv, ++i)
18599 : : {
18600 : 595670 : if (this->has_keys_)
18601 : : {
18602 : : // We check the key type in the lowering pass.
18603 : 110423 : ++pv;
18604 : 110423 : if (pv == this->vals_->end())
18605 : : break;
18606 : : }
18607 : 595670 : if (*pv != NULL
18608 : 595670 : && !Type::are_assignable(element_type, (*pv)->type(), NULL))
18609 : : {
18610 : 10 : go_error_at((*pv)->location(),
18611 : : ("incompatible type for element %d "
18612 : : "in composite literal"),
18613 : : i + 1);
18614 : 10 : this->set_is_error();
18615 : : }
18616 : : }
18617 : : }
18618 : 3499 : else if (type->map_type() != NULL)
18619 : : {
18620 : 3496 : if (this->vals_ == NULL || this->vals_->empty())
18621 : : return;
18622 : 2653 : if (!this->has_keys_)
18623 : : {
18624 : 0 : this->report_error(_("map composite literal must have keys"));
18625 : 0 : return;
18626 : : }
18627 : 2653 : int i = 0;
18628 : 2653 : Map_type* mt = type->map_type();
18629 : 2653 : Type* key_type = mt->key_type();
18630 : 2653 : Type* val_type = mt->val_type();
18631 : 2653 : for (Expression_list::const_iterator pv = this->vals_->begin();
18632 : 32543 : pv != this->vals_->end();
18633 : 29890 : ++pv, ++i)
18634 : : {
18635 : 29890 : if (*pv != NULL
18636 : 29890 : && !Type::are_assignable(key_type, (*pv)->type(), NULL))
18637 : : {
18638 : 1 : go_error_at((*pv)->location(),
18639 : : ("incompatible type for element %d key "
18640 : : "in map construction"),
18641 : : i + 1);
18642 : 1 : this->set_is_error();
18643 : : }
18644 : 29890 : ++pv;
18645 : 29890 : if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
18646 : : {
18647 : 0 : go_error_at((*pv)->location(),
18648 : : ("incompatible type for element %d value "
18649 : : "in map construction"),
18650 : : i + 1);
18651 : 0 : this->set_is_error();
18652 : : }
18653 : : }
18654 : : }
18655 : : else
18656 : : {
18657 : 3 : this->report_error(_("expected struct, slice, array, or map type "
18658 : : "for composite literal"));
18659 : : }
18660 : : }
18661 : :
18662 : : // Lower a generic composite literal into a specific version based on
18663 : : // the type.
18664 : :
18665 : : Expression*
18666 : 227356 : Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
18667 : : Statement_inserter* inserter)
18668 : : {
18669 : 227356 : if (this->is_error_expression() || this->type_->is_error())
18670 : 50 : return Expression::make_error(this->location());
18671 : 227306 : go_assert(this->depth_ == 0);
18672 : :
18673 : 227306 : Type* type = this->type_;
18674 : 227306 : Type *pt = type->points_to();
18675 : 227306 : bool is_pointer = false;
18676 : 227306 : if (pt != NULL)
18677 : : {
18678 : 2001 : is_pointer = true;
18679 : 2001 : type = pt;
18680 : : }
18681 : :
18682 : 227306 : Expression* ret;
18683 : 227306 : if (type->is_error())
18684 : 0 : return Expression::make_error(this->location());
18685 : 227306 : else if (type->struct_type() != NULL)
18686 : 174460 : ret = this->lower_struct(type);
18687 : 52846 : else if (type->array_type() != NULL)
18688 : 49351 : ret = this->lower_array(type);
18689 : 3495 : else if (type->map_type() != NULL)
18690 : 3495 : ret = this->lower_map(gogo, function, inserter, type);
18691 : : else
18692 : 0 : go_unreachable();
18693 : :
18694 : 227306 : if (is_pointer)
18695 : 2001 : ret = Expression::make_heap_expression(ret, this->location());
18696 : :
18697 : : return ret;
18698 : : }
18699 : :
18700 : : // Lower a struct composite literal.
18701 : :
18702 : : Expression*
18703 : 174460 : Composite_literal_expression::lower_struct(Type* type)
18704 : : {
18705 : 174460 : go_assert(!this->has_keys_);
18706 : 174460 : Struct_construction_expression* ret =
18707 : 174460 : new Struct_construction_expression(type, this->vals_, this->location());
18708 : 174460 : ret->set_traverse_order(this->traverse_order_);
18709 : 174460 : return ret;
18710 : : }
18711 : :
18712 : : // Index/value/traversal-order triple.
18713 : :
18714 : : struct IVT_triple {
18715 : : unsigned long index;
18716 : : unsigned long traversal_order;
18717 : : Expression* expr;
18718 : 1881 : IVT_triple(unsigned long i, unsigned long to, Expression *e)
18719 : 1881 : : index(i), traversal_order(to), expr(e) { }
18720 : 10509 : bool operator<(const IVT_triple& other) const
18721 : 10337 : { return this->index < other.index; }
18722 : : };
18723 : :
18724 : : // Lower an array composite literal.
18725 : :
18726 : : Expression*
18727 : 49351 : Composite_literal_expression::lower_array(Type* type)
18728 : : {
18729 : 49351 : Location location = this->location();
18730 : 49351 : if (this->vals_ == NULL || !this->has_keys_)
18731 : 48884 : return this->make_array(type, NULL, this->vals_);
18732 : :
18733 : 467 : std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
18734 : 467 : indexes->reserve(this->vals_->size());
18735 : 467 : bool indexes_out_of_order = false;
18736 : 467 : Expression_list* vals = new Expression_list();
18737 : 467 : vals->reserve(this->vals_->size());
18738 : 467 : unsigned long index = 0;
18739 : 467 : Expression_list::const_iterator p = this->vals_->begin();
18740 : 110874 : while (p != this->vals_->end())
18741 : : {
18742 : 110420 : Expression* index_expr = *p;
18743 : :
18744 : 110420 : ++p;
18745 : 110420 : go_assert(p != this->vals_->end());
18746 : 110420 : Expression* val = *p;
18747 : :
18748 : 110420 : ++p;
18749 : :
18750 : 110420 : if (index_expr == NULL)
18751 : : {
18752 : 22 : if (std::find(indexes->begin(), indexes->end(), index)
18753 : 22 : != indexes->end())
18754 : : {
18755 : 0 : go_error_at(val->location(),
18756 : : "duplicate value for index %lu", index);
18757 : 0 : return Expression::make_error(location);
18758 : : }
18759 : 22 : if (!indexes->empty())
18760 : 16 : indexes->push_back(index);
18761 : : }
18762 : : else
18763 : : {
18764 : 110398 : if (indexes->empty() && !vals->empty())
18765 : : {
18766 : 10 : for (size_t i = 0; i < vals->size(); ++i)
18767 : 6 : indexes->push_back(i);
18768 : : }
18769 : :
18770 : 110398 : Numeric_constant nc;
18771 : 110398 : if (!index_expr->numeric_constant_value(&nc))
18772 : : {
18773 : 4 : go_error_at(index_expr->location(),
18774 : : "index expression is not integer constant");
18775 : 4 : return Expression::make_error(location);
18776 : : }
18777 : :
18778 : 110394 : switch (nc.to_unsigned_long(&index))
18779 : : {
18780 : 110387 : case Numeric_constant::NC_UL_VALID:
18781 : 110387 : break;
18782 : 1 : case Numeric_constant::NC_UL_NOTINT:
18783 : 1 : go_error_at(index_expr->location(),
18784 : : "index expression is not integer constant");
18785 : 1 : return Expression::make_error(location);
18786 : 6 : case Numeric_constant::NC_UL_NEGATIVE:
18787 : 6 : go_error_at(index_expr->location(),
18788 : : "index expression is negative");
18789 : 6 : return Expression::make_error(location);
18790 : 0 : case Numeric_constant::NC_UL_BIG:
18791 : 0 : go_error_at(index_expr->location(), "index value overflow");
18792 : 0 : return Expression::make_error(location);
18793 : 0 : default:
18794 : 0 : go_unreachable();
18795 : : }
18796 : :
18797 : 110387 : Named_type* ntype = Type::lookup_integer_type("int");
18798 : 110387 : Integer_type* inttype = ntype->integer_type();
18799 : 110387 : if (sizeof(index) >= static_cast<size_t>(inttype->bits() / 8)
18800 : 110387 : && index >> (inttype->bits() - 1) != 0)
18801 : : {
18802 : 0 : go_error_at(index_expr->location(), "index value overflow");
18803 : 0 : return Expression::make_error(location);
18804 : : }
18805 : :
18806 : 110387 : if (std::find(indexes->begin(), indexes->end(), index)
18807 : 110387 : != indexes->end())
18808 : : {
18809 : 2 : go_error_at(index_expr->location(),
18810 : : "duplicate value for index %lu",
18811 : : index);
18812 : 2 : return Expression::make_error(location);
18813 : : }
18814 : :
18815 : 110385 : if (!indexes->empty() && index < indexes->back())
18816 : : indexes_out_of_order = true;
18817 : :
18818 : 110385 : indexes->push_back(index);
18819 : 110398 : }
18820 : :
18821 : 110407 : vals->push_back(val);
18822 : :
18823 : 110407 : ++index;
18824 : : }
18825 : :
18826 : 454 : if (indexes->empty())
18827 : : {
18828 : 0 : delete indexes;
18829 : 0 : indexes = NULL;
18830 : : }
18831 : :
18832 : 454 : std::vector<unsigned long>* traverse_order = NULL;
18833 : 454 : if (indexes_out_of_order)
18834 : : {
18835 : 62 : typedef std::vector<IVT_triple> V;
18836 : :
18837 : 62 : V v;
18838 : 62 : v.reserve(indexes->size());
18839 : 62 : std::vector<unsigned long>::const_iterator pi = indexes->begin();
18840 : 62 : unsigned long torder = 0;
18841 : 62 : for (Expression_list::const_iterator pe = vals->begin();
18842 : 1943 : pe != vals->end();
18843 : 1881 : ++pe, ++pi, ++torder)
18844 : 1881 : v.push_back(IVT_triple(*pi, torder, *pe));
18845 : :
18846 : 62 : std::sort(v.begin(), v.end());
18847 : :
18848 : 62 : delete indexes;
18849 : 62 : delete vals;
18850 : :
18851 : 62 : indexes = new std::vector<unsigned long>();
18852 : 62 : indexes->reserve(v.size());
18853 : 62 : vals = new Expression_list();
18854 : 62 : vals->reserve(v.size());
18855 : 62 : traverse_order = new std::vector<unsigned long>();
18856 : 62 : traverse_order->reserve(v.size());
18857 : :
18858 : 1943 : for (V::const_iterator pv = v.begin(); pv != v.end(); ++pv)
18859 : : {
18860 : 1881 : indexes->push_back(pv->index);
18861 : 1881 : vals->push_back(pv->expr);
18862 : 1881 : traverse_order->push_back(pv->traversal_order);
18863 : : }
18864 : 62 : }
18865 : :
18866 : 454 : Expression* ret = this->make_array(type, indexes, vals);
18867 : 454 : Array_construction_expression* ace = ret->array_literal();
18868 : 454 : if (ace != NULL && traverse_order != NULL)
18869 : 55 : ace->set_traverse_order(traverse_order);
18870 : : return ret;
18871 : : }
18872 : :
18873 : : // Actually build the array composite literal. This handles
18874 : : // [...]{...}.
18875 : :
18876 : : Expression*
18877 : 49338 : Composite_literal_expression::make_array(
18878 : : Type* type,
18879 : : const std::vector<unsigned long>* indexes,
18880 : : Expression_list* vals)
18881 : : {
18882 : 49338 : Location location = this->location();
18883 : 49338 : Array_type* at = type->array_type();
18884 : :
18885 : 49338 : if (at->length() != NULL
18886 : 18043 : && !at->length()->is_error_expression()
18887 : 67381 : && this->vals_ != NULL)
18888 : : {
18889 : 17491 : Numeric_constant nc;
18890 : 17491 : unsigned long val;
18891 : 17491 : if (at->length()->numeric_constant_value(&nc)
18892 : 17491 : && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID)
18893 : : {
18894 : 17491 : if (indexes == NULL)
18895 : : {
18896 : 17167 : if (this->vals_->size() > val)
18897 : : {
18898 : 1 : go_error_at(location,
18899 : : "too many elements in composite literal");
18900 : 1 : return Expression::make_error(location);
18901 : : }
18902 : : }
18903 : : else
18904 : : {
18905 : 324 : unsigned long max = indexes->back();
18906 : 324 : if (max >= val)
18907 : : {
18908 : 5 : go_error_at(location,
18909 : : ("some element keys in composite literal "
18910 : : "are out of range"));
18911 : 5 : return Expression::make_error(location);
18912 : : }
18913 : : }
18914 : : }
18915 : 17491 : }
18916 : :
18917 : 49332 : if (at->length() != NULL)
18918 : 18037 : return new Fixed_array_construction_expression(type, indexes, vals,
18919 : 18037 : location);
18920 : : else
18921 : 31295 : return new Slice_construction_expression(type, indexes, vals, location);
18922 : : }
18923 : :
18924 : : // Lower a map composite literal.
18925 : :
18926 : : Expression*
18927 : 3495 : Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
18928 : : Statement_inserter* inserter,
18929 : : Type* type)
18930 : : {
18931 : 3495 : Location location = this->location();
18932 : 3495 : Unordered_map(unsigned int, std::vector<Expression*>) st;
18933 : 3495 : Unordered_map(unsigned int, std::vector<Expression*>) nt;
18934 : 3495 : bool saw_false = false;
18935 : 3495 : bool saw_true = false;
18936 : 3495 : if (this->vals_ != NULL)
18937 : : {
18938 : 2652 : go_assert(this->has_keys_);
18939 : :
18940 : 32535 : for (Expression_list::iterator p = this->vals_->begin();
18941 : 32535 : p != this->vals_->end();
18942 : 29883 : p += 2)
18943 : : {
18944 : 29885 : if (*p == NULL)
18945 : : {
18946 : 1 : ++p;
18947 : 1 : go_error_at((*p)->location(),
18948 : : ("map composite literal must "
18949 : : "have keys for every value"));
18950 : 2 : return Expression::make_error(location);
18951 : : }
18952 : : // Make sure we have lowered the key; it may not have been
18953 : : // lowered in order to handle keys for struct composite
18954 : : // literals. Lower it now to get the right error message.
18955 : 29884 : if ((*p)->unknown_expression() != NULL)
18956 : : {
18957 : 0 : gogo->lower_expression(function, inserter, &*p);
18958 : 0 : go_assert((*p)->is_error_expression());
18959 : 0 : return Expression::make_error(location);
18960 : : }
18961 : : // Check if there are duplicate constant keys.
18962 : 29884 : if (!(*p)->is_constant())
18963 : 1169 : continue;
18964 : 28715 : std::string sval;
18965 : 28715 : Numeric_constant nval;
18966 : 28715 : bool bval;
18967 : 28715 : if ((*p)->string_constant_value(&sval)) // Check string keys.
18968 : : {
18969 : 25028 : unsigned int h = Gogo::hash_string(sval, 0);
18970 : : // Search the index h in the hash map.
18971 : 25028 : Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
18972 : 25028 : mit = st.find(h);
18973 : 25028 : if (mit == st.end())
18974 : : {
18975 : : // No duplicate since h is a new index.
18976 : : // Create a new vector indexed by h and add it to the hash map.
18977 : 25027 : std::vector<Expression*> l;
18978 : 25027 : l.push_back(*p);
18979 : 25027 : std::pair<unsigned int, std::vector<Expression*> > val(h, l);
18980 : 25027 : st.insert(val);
18981 : 25027 : }
18982 : : else
18983 : : {
18984 : : // Do further check since index h already exists.
18985 : 1 : for (std::vector<Expression*>::iterator lit =
18986 : 1 : mit->second.begin();
18987 : 1 : lit != mit->second.end();
18988 : 0 : lit++)
18989 : : {
18990 : 1 : std::string s;
18991 : 1 : bool ok = (*lit)->string_constant_value(&s);
18992 : 1 : go_assert(ok);
18993 : 1 : if (s == sval)
18994 : : {
18995 : 1 : go_error_at((*p)->location(), ("duplicate key "
18996 : : "in map literal"));
18997 : 1 : return Expression::make_error(location);
18998 : : }
18999 : 1 : }
19000 : : // Add this new string key to the vector indexed by h.
19001 : 0 : mit->second.push_back(*p);
19002 : : }
19003 : : }
19004 : 3687 : else if ((*p)->numeric_constant_value(&nval))
19005 : : {
19006 : : // Check numeric keys.
19007 : 3663 : unsigned int h = nval.hash(0);
19008 : 3663 : Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
19009 : 3663 : mit = nt.find(h);
19010 : 3663 : if (mit == nt.end())
19011 : : {
19012 : : // No duplicate since h is a new code.
19013 : : // Create a new vector indexed by h and add it to the hash map.
19014 : 3659 : std::vector<Expression*> l;
19015 : 3659 : l.push_back(*p);
19016 : 3659 : std::pair<unsigned int, std::vector<Expression*> > val(h, l);
19017 : 3659 : nt.insert(val);
19018 : 3659 : }
19019 : : else
19020 : : {
19021 : : // Do further check since h already exists.
19022 : 8 : for (std::vector<Expression*>::iterator lit =
19023 : 4 : mit->second.begin();
19024 : 8 : lit != mit->second.end();
19025 : 4 : lit++)
19026 : : {
19027 : 4 : Numeric_constant rval;
19028 : 4 : bool ok = (*lit)->numeric_constant_value(&rval);
19029 : 4 : go_assert(ok);
19030 : 4 : if (nval.equals(rval))
19031 : : {
19032 : 0 : go_error_at((*p)->location(),
19033 : : "duplicate key in map literal");
19034 : 0 : return Expression::make_error(location);
19035 : : }
19036 : 4 : }
19037 : : // Add this new numeric key to the vector indexed by h.
19038 : 4 : mit->second.push_back(*p);
19039 : : }
19040 : : }
19041 : 24 : else if ((*p)->boolean_constant_value(&bval))
19042 : : {
19043 : 17 : if ((bval && saw_true) || (!bval && saw_false))
19044 : : {
19045 : 0 : go_error_at((*p)->location(),
19046 : : "duplicate key in map literal");
19047 : 0 : return Expression::make_error(location);
19048 : : }
19049 : 17 : if (bval)
19050 : : saw_true = true;
19051 : : else
19052 : 7 : saw_false = true;
19053 : : }
19054 : 28715 : }
19055 : : }
19056 : :
19057 : 3493 : return new Map_construction_expression(type, this->vals_, location);
19058 : 3495 : }
19059 : :
19060 : : // Copy.
19061 : :
19062 : : Expression*
19063 : 3 : Composite_literal_expression::do_copy()
19064 : : {
19065 : 3 : Composite_literal_expression* ret =
19066 : 3 : new Composite_literal_expression(this->type_->copy_expressions(),
19067 : 3 : this->depth_, this->has_keys_,
19068 : 3 : (this->vals_ == NULL
19069 : : ? NULL
19070 : 0 : : this->vals_->copy()),
19071 : 3 : this->all_are_names_,
19072 : 3 : this->location());
19073 : 3 : ret->key_path_ = this->key_path_;
19074 : 3 : return ret;
19075 : : }
19076 : :
19077 : : // Dump ast representation for a composite literal expression.
19078 : :
19079 : : void
19080 : 0 : Composite_literal_expression::do_dump_expression(
19081 : : Ast_dump_context* ast_dump_context) const
19082 : : {
19083 : 0 : ast_dump_context->ostream() << "composite(";
19084 : 0 : ast_dump_context->dump_type(this->type_);
19085 : 0 : ast_dump_context->ostream() << ", {";
19086 : 0 : ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
19087 : 0 : ast_dump_context->ostream() << "})";
19088 : 0 : }
19089 : :
19090 : : // Make a composite literal expression.
19091 : :
19092 : : Expression*
19093 : 226854 : Expression::make_composite_literal(Type* type, int depth, bool has_keys,
19094 : : Expression_list* vals, bool all_are_names,
19095 : : Location location)
19096 : : {
19097 : 226854 : return new Composite_literal_expression(type, depth, has_keys, vals,
19098 : 226854 : all_are_names, location);
19099 : : }
19100 : :
19101 : : // Return whether this expression is a composite literal.
19102 : :
19103 : : bool
19104 : 4395624 : Expression::is_composite_literal() const
19105 : : {
19106 : 4395624 : switch (this->classification_)
19107 : : {
19108 : : case EXPRESSION_COMPOSITE_LITERAL:
19109 : : case EXPRESSION_STRUCT_CONSTRUCTION:
19110 : : case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
19111 : : case EXPRESSION_SLICE_CONSTRUCTION:
19112 : : case EXPRESSION_MAP_CONSTRUCTION:
19113 : : return true;
19114 : 3975412 : default:
19115 : 3975412 : return false;
19116 : : }
19117 : : }
19118 : :
19119 : : // Return whether this expression is a composite literal which is not
19120 : : // constant.
19121 : :
19122 : : bool
19123 : 1079 : Expression::is_nonconstant_composite_literal() const
19124 : : {
19125 : 1079 : switch (this->classification_)
19126 : : {
19127 : 0 : case EXPRESSION_STRUCT_CONSTRUCTION:
19128 : 0 : {
19129 : 0 : const Struct_construction_expression *psce =
19130 : : static_cast<const Struct_construction_expression*>(this);
19131 : 0 : return !psce->is_constant_struct();
19132 : : }
19133 : 0 : case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
19134 : 0 : {
19135 : 0 : const Fixed_array_construction_expression *pace =
19136 : : static_cast<const Fixed_array_construction_expression*>(this);
19137 : 0 : return !pace->is_constant_array();
19138 : : }
19139 : 0 : case EXPRESSION_SLICE_CONSTRUCTION:
19140 : 0 : {
19141 : 0 : const Slice_construction_expression *pace =
19142 : : static_cast<const Slice_construction_expression*>(this);
19143 : 0 : return !pace->is_constant_array();
19144 : : }
19145 : : case EXPRESSION_MAP_CONSTRUCTION:
19146 : : return true;
19147 : 1079 : default:
19148 : 1079 : return false;
19149 : : }
19150 : : }
19151 : :
19152 : : // Return true if this is a variable or temporary_variable.
19153 : :
19154 : : bool
19155 : 0 : Expression::is_variable() const
19156 : : {
19157 : 0 : switch (this->classification_)
19158 : : {
19159 : : case EXPRESSION_VAR_REFERENCE:
19160 : : case EXPRESSION_TEMPORARY_REFERENCE:
19161 : : case EXPRESSION_SET_AND_USE_TEMPORARY:
19162 : : case EXPRESSION_ENCLOSED_VAR_REFERENCE:
19163 : : return true;
19164 : 0 : default:
19165 : 0 : return false;
19166 : : }
19167 : : }
19168 : :
19169 : : // Return true if this is a reference to a local variable.
19170 : :
19171 : : bool
19172 : 0 : Expression::is_local_variable() const
19173 : : {
19174 : 0 : const Var_expression* ve = this->var_expression();
19175 : 0 : if (ve == NULL)
19176 : : return false;
19177 : 0 : const Named_object* no = ve->named_object();
19178 : 0 : return (no->is_result_variable()
19179 : 0 : || (no->is_variable() && !no->var_value()->is_global()));
19180 : : }
19181 : :
19182 : : // Return true if multiple evaluations are OK.
19183 : :
19184 : : bool
19185 : 2787532 : Expression::is_multi_eval_safe()
19186 : : {
19187 : 2787532 : switch (this->classification_)
19188 : : {
19189 : 1050137 : case EXPRESSION_VAR_REFERENCE:
19190 : 1050137 : {
19191 : : // A variable is a simple reference if not stored in the heap.
19192 : 1050137 : const Named_object* no = this->var_expression()->named_object();
19193 : 1050137 : if (no->is_variable())
19194 : 2085294 : return !no->var_value()->is_in_heap();
19195 : 7490 : else if (no->is_result_variable())
19196 : 7490 : return !no->result_var_value()->is_in_heap();
19197 : : else
19198 : 0 : go_unreachable();
19199 : : }
19200 : :
19201 : : case EXPRESSION_TEMPORARY_REFERENCE:
19202 : : return true;
19203 : :
19204 : 837383 : default:
19205 : 837383 : break;
19206 : : }
19207 : :
19208 : 837383 : if (!this->is_constant())
19209 : : return false;
19210 : :
19211 : : // Only numeric and boolean constants are really multi-evaluation
19212 : : // safe. We don't want multiple copies of string constants.
19213 : 425230 : Type* type = this->type();
19214 : 496611 : return type->is_numeric_type() || type->is_boolean_type();
19215 : : }
19216 : :
19217 : : const Named_object*
19218 : 347675 : Expression::named_constant() const
19219 : : {
19220 : 347675 : if (this->classification() != EXPRESSION_CONST_REFERENCE)
19221 : : return NULL;
19222 : 38074 : const Const_expression* ce = static_cast<const Const_expression*>(this);
19223 : 38074 : return ce->named_object();
19224 : : }
19225 : :
19226 : : // Class Type_guard_expression.
19227 : :
19228 : : // Traversal.
19229 : :
19230 : : int
19231 : 247595 : Type_guard_expression::do_traverse(Traverse* traverse)
19232 : : {
19233 : 247595 : if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
19234 : 247595 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
19235 : 4659 : return TRAVERSE_EXIT;
19236 : : return TRAVERSE_CONTINUE;
19237 : : }
19238 : :
19239 : : Expression*
19240 : 13894 : Type_guard_expression::do_flatten(Gogo*, Named_object*,
19241 : : Statement_inserter* inserter)
19242 : : {
19243 : 13894 : if (this->expr_->is_error_expression()
19244 : 13894 : || this->expr_->type()->is_error_type())
19245 : : {
19246 : 0 : go_assert(saw_errors());
19247 : 0 : return Expression::make_error(this->location());
19248 : : }
19249 : :
19250 : 13894 : if (!this->expr_->is_multi_eval_safe())
19251 : : {
19252 : 1608 : Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_,
19253 : : this->location());
19254 : 1608 : inserter->insert(temp);
19255 : 1608 : this->expr_ =
19256 : 1608 : Expression::make_temporary_reference(temp, this->location());
19257 : : }
19258 : 13894 : return this;
19259 : : }
19260 : :
19261 : : // Check types of a type guard expression. The expression must have
19262 : : // an interface type, but the actual type conversion is checked at run
19263 : : // time.
19264 : :
19265 : : void
19266 : 13803 : Type_guard_expression::do_check_types(Gogo*)
19267 : : {
19268 : 13803 : Type* expr_type = this->expr_->type();
19269 : 13803 : if (expr_type->interface_type() == NULL)
19270 : : {
19271 : 1 : if (!expr_type->is_error() && !this->type_->is_error())
19272 : 1 : this->report_error(_("type assertion only valid for interface types"));
19273 : 1 : this->set_is_error();
19274 : : }
19275 : 13802 : else if (this->type_->interface_type() == NULL)
19276 : : {
19277 : 12780 : std::string reason;
19278 : 25560 : if (!expr_type->interface_type()->implements_interface(this->type_,
19279 : : &reason))
19280 : : {
19281 : 3 : if (!this->type_->is_error())
19282 : : {
19283 : 3 : if (reason.empty())
19284 : 0 : this->report_error(_("impossible type assertion: "
19285 : : "type does not implement interface"));
19286 : : else
19287 : 3 : go_error_at(this->location(),
19288 : : ("impossible type assertion: "
19289 : : "type does not implement interface (%s)"),
19290 : : reason.c_str());
19291 : : }
19292 : 3 : this->set_is_error();
19293 : : }
19294 : 12780 : }
19295 : 13803 : }
19296 : :
19297 : : // Copy.
19298 : :
19299 : : Expression*
19300 : 0 : Type_guard_expression::do_copy()
19301 : : {
19302 : 0 : return new Type_guard_expression(this->expr_->copy(),
19303 : 0 : this->type_->copy_expressions(),
19304 : 0 : this->location());
19305 : : }
19306 : :
19307 : : // Return the backend representation for a type guard expression.
19308 : :
19309 : : Bexpression*
19310 : 13541 : Type_guard_expression::do_get_backend(Translate_context* context)
19311 : : {
19312 : 13541 : Expression* conversion;
19313 : 13541 : if (this->type_->interface_type() != NULL)
19314 : 1016 : conversion = Expression::convert_interface_to_interface(context->gogo(),
19315 : : this->type_,
19316 : : this->expr_,
19317 : : true,
19318 : : this->location());
19319 : : else
19320 : 12525 : conversion = Expression::convert_for_assignment(context->gogo(),
19321 : : this->type_,
19322 : : this->expr_,
19323 : : this->location());
19324 : :
19325 : 13541 : Gogo* gogo = context->gogo();
19326 : 13541 : Btype* bt = this->type_->get_backend(gogo);
19327 : 13541 : Bexpression* bexpr = conversion->get_backend(context);
19328 : 13541 : return gogo->backend()->convert_expression(bt, bexpr, this->location());
19329 : : }
19330 : :
19331 : : // Dump ast representation for a type guard expression.
19332 : :
19333 : : void
19334 : 0 : Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
19335 : : const
19336 : : {
19337 : 0 : this->expr_->dump_expression(ast_dump_context);
19338 : 0 : ast_dump_context->ostream() << ".";
19339 : 0 : ast_dump_context->dump_type(this->type_);
19340 : 0 : }
19341 : :
19342 : : // Make a type guard expression.
19343 : :
19344 : : Expression*
19345 : 20347 : Expression::make_type_guard(Expression* expr, Type* type,
19346 : : Location location)
19347 : : {
19348 : 20347 : return new Type_guard_expression(expr, type, location);
19349 : : }
19350 : :
19351 : : // Class Heap_expression.
19352 : :
19353 : : // Return the type of the expression stored on the heap.
19354 : :
19355 : : Type*
19356 : 693909 : Heap_expression::do_type()
19357 : 693909 : { return Type::make_pointer_type(this->expr_->type()); }
19358 : :
19359 : : // Return the backend representation for allocating an expression on the heap.
19360 : :
19361 : : Bexpression*
19362 : 204189 : Heap_expression::do_get_backend(Translate_context* context)
19363 : : {
19364 : 204189 : Type* etype = this->expr_->type();
19365 : 204189 : if (this->expr_->is_error_expression() || etype->is_error())
19366 : 5 : return context->backend()->error_expression();
19367 : :
19368 : 204184 : Location loc = this->location();
19369 : 204184 : Gogo* gogo = context->gogo();
19370 : 204184 : Btype* btype = this->type()->get_backend(gogo);
19371 : :
19372 : 204184 : Expression* alloc = Expression::make_allocation(etype, loc);
19373 : 204184 : if (this->allocate_on_stack_)
19374 : 19415 : alloc->allocation_expression()->set_allocate_on_stack();
19375 : 204184 : Bexpression* space = alloc->get_backend(context);
19376 : :
19377 : 204184 : Bstatement* decl;
19378 : 204184 : Named_object* fn = context->function();
19379 : 204184 : go_assert(fn != NULL);
19380 : 204184 : Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
19381 : 204184 : Bvariable* space_temp =
19382 : 204184 : gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
19383 : : space,
19384 : : Backend::variable_address_is_taken,
19385 : : loc, &decl);
19386 : 204184 : Btype* expr_btype = etype->get_backend(gogo);
19387 : :
19388 : 204184 : Bexpression* bexpr = this->expr_->get_backend(context);
19389 : :
19390 : : // If this assignment needs a write barrier, call typedmemmove. We
19391 : : // don't do this in the write barrier pass because in some cases
19392 : : // backend conversion can introduce new Heap_expression values.
19393 : 204184 : Bstatement* assn;
19394 : 204184 : if (!etype->has_pointer() || this->allocate_on_stack_)
19395 : : {
19396 : 74124 : space = gogo->backend()->var_expression(space_temp, loc);
19397 : 74124 : Bexpression* ref =
19398 : 74124 : gogo->backend()->indirect_expression(expr_btype, space, true, loc);
19399 : 74124 : assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc);
19400 : : }
19401 : : else
19402 : : {
19403 : 130060 : Bstatement* edecl;
19404 : 130060 : Bvariable* btemp =
19405 : 130060 : gogo->backend()->temporary_variable(fndecl, context->bblock(),
19406 : : expr_btype, bexpr,
19407 : : Backend::variable_address_is_taken,
19408 : : loc, &edecl);
19409 : 130060 : Bexpression* btempref = gogo->backend()->var_expression(btemp,
19410 : : loc);
19411 : 130060 : space = gogo->backend()->var_expression(space_temp, loc);
19412 : 130060 : Type* etype_ptr = Type::make_pointer_type(etype);
19413 : 130060 : Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
19414 : 130060 : Expression* erhs;
19415 : 130060 : Expression* call;
19416 : 130060 : if (etype->is_direct_iface_type())
19417 : : {
19418 : : // Single pointer.
19419 : 4672 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
19420 : 4672 : erhs = Expression::make_backend(btempref, etype, loc);
19421 : 4672 : erhs = Expression::unpack_direct_iface(erhs, loc);
19422 : 4672 : erhs = Expression::make_unsafe_cast(uintptr_type, erhs, loc);
19423 : 4672 : call = Runtime::make_call(gogo, Runtime::GCWRITEBARRIER, loc, 2,
19424 : : elhs, erhs);
19425 : : }
19426 : : else
19427 : : {
19428 : 125388 : Expression* td = Expression::make_type_descriptor(etype, loc);
19429 : 125388 : Bexpression* addr =
19430 : 125388 : gogo->backend()->address_expression(btempref, loc);
19431 : 125388 : erhs = Expression::make_backend(addr, etype_ptr, loc);
19432 : 125388 : call = Runtime::make_call(gogo, Runtime::TYPEDMEMMOVE, loc, 3,
19433 : : td, elhs, erhs);
19434 : : }
19435 : 130060 : Statement* cs = Statement::make_statement(call, false);
19436 : :
19437 : 130060 : space = gogo->backend()->var_expression(space_temp, loc);
19438 : 130060 : Bexpression* ref =
19439 : 130060 : gogo->backend()->indirect_expression(expr_btype, space, true, loc);
19440 : 130060 : Expression* eref = Expression::make_backend(ref, etype, loc);
19441 : 130060 : btempref = gogo->backend()->var_expression(btemp, loc);
19442 : 130060 : erhs = Expression::make_backend(btempref, etype, loc);
19443 : 130060 : Statement* as = Statement::make_assignment(eref, erhs, loc);
19444 : :
19445 : 130060 : as = gogo->check_write_barrier(context->block(), as, cs);
19446 : 130060 : Bstatement* s = as->get_backend(context);
19447 : :
19448 : 130060 : assn = gogo->backend()->compound_statement(edecl, s);
19449 : : }
19450 : 204184 : decl = gogo->backend()->compound_statement(decl, assn);
19451 : 204184 : space = gogo->backend()->var_expression(space_temp, loc);
19452 : 204184 : return gogo->backend()->compound_expression(decl, space, loc);
19453 : : }
19454 : :
19455 : : // Dump ast representation for a heap expression.
19456 : :
19457 : : void
19458 : 0 : Heap_expression::do_dump_expression(
19459 : : Ast_dump_context* ast_dump_context) const
19460 : : {
19461 : 0 : ast_dump_context->ostream() << "&(";
19462 : 0 : ast_dump_context->dump_expression(this->expr_);
19463 : 0 : ast_dump_context->ostream() << ")";
19464 : 0 : }
19465 : :
19466 : : // Allocate an expression on the heap.
19467 : :
19468 : : Expression*
19469 : 204263 : Expression::make_heap_expression(Expression* expr, Location location)
19470 : : {
19471 : 204263 : return new Heap_expression(expr, location);
19472 : : }
19473 : :
19474 : : // Class Receive_expression.
19475 : :
19476 : : // Return the type of a receive expression.
19477 : :
19478 : : Type*
19479 : 9704 : Receive_expression::do_type()
19480 : : {
19481 : 9704 : if (this->is_error_expression())
19482 : 2 : return Type::make_error_type();
19483 : 9702 : Channel_type* channel_type = this->channel_->type()->channel_type();
19484 : 9702 : if (channel_type == NULL)
19485 : : {
19486 : 0 : this->report_error(_("expected channel"));
19487 : 0 : return Type::make_error_type();
19488 : : }
19489 : 9702 : return channel_type->element_type();
19490 : : }
19491 : :
19492 : : // Check types for a receive expression.
19493 : :
19494 : : void
19495 : 1986 : Receive_expression::do_check_types(Gogo*)
19496 : : {
19497 : 1986 : Type* type = this->channel_->type();
19498 : 1986 : if (type->is_error())
19499 : : {
19500 : 0 : go_assert(saw_errors());
19501 : 0 : this->set_is_error();
19502 : 0 : return;
19503 : : }
19504 : 1986 : if (type->channel_type() == NULL)
19505 : : {
19506 : 1 : this->report_error(_("expected channel"));
19507 : 1 : return;
19508 : : }
19509 : 3970 : if (!type->channel_type()->may_receive())
19510 : : {
19511 : 1 : this->report_error(_("invalid receive on send-only channel"));
19512 : 1 : return;
19513 : : }
19514 : : }
19515 : :
19516 : : // Flattening for receive expressions creates a temporary variable to store
19517 : : // received data in for receives.
19518 : :
19519 : : Expression*
19520 : 2042 : Receive_expression::do_flatten(Gogo*, Named_object*,
19521 : : Statement_inserter* inserter)
19522 : : {
19523 : 2042 : Channel_type* channel_type = this->channel_->type()->channel_type();
19524 : 2042 : if (channel_type == NULL)
19525 : : {
19526 : 1 : go_assert(saw_errors());
19527 : 1 : return this;
19528 : : }
19529 : 2041 : else if (this->channel_->is_error_expression())
19530 : : {
19531 : 0 : go_assert(saw_errors());
19532 : 0 : return Expression::make_error(this->location());
19533 : : }
19534 : :
19535 : 2041 : Type* element_type = channel_type->element_type();
19536 : 2041 : if (this->temp_receiver_ == NULL)
19537 : : {
19538 : 2033 : this->temp_receiver_ = Statement::make_temporary(element_type, NULL,
19539 : : this->location());
19540 : 2033 : this->temp_receiver_->set_is_address_taken();
19541 : 2033 : inserter->insert(this->temp_receiver_);
19542 : : }
19543 : :
19544 : 2041 : return this;
19545 : : }
19546 : :
19547 : : // Get the backend representation for a receive expression.
19548 : :
19549 : : Bexpression*
19550 : 2021 : Receive_expression::do_get_backend(Translate_context* context)
19551 : : {
19552 : 2021 : Location loc = this->location();
19553 : :
19554 : 2021 : Channel_type* channel_type = this->channel_->type()->channel_type();
19555 : 2021 : if (channel_type == NULL)
19556 : : {
19557 : 0 : go_assert(this->channel_->type()->is_error());
19558 : 0 : return context->backend()->error_expression();
19559 : : }
19560 : :
19561 : 2021 : Gogo* gogo = context->gogo();
19562 : 2021 : Expression* recv_ref =
19563 : 2021 : Expression::make_temporary_reference(this->temp_receiver_, loc);
19564 : 2021 : Expression* recv_addr =
19565 : 2021 : Expression::make_temporary_reference(this->temp_receiver_, loc);
19566 : 2021 : recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc);
19567 : 2021 : Expression* recv = Runtime::make_call(gogo, Runtime::CHANRECV1, loc, 2,
19568 : : this->channel_, recv_addr);
19569 : 2021 : Expression* ret = Expression::make_compound(recv, recv_ref, loc);
19570 : 2021 : ret->determine_type_no_context(gogo);
19571 : 2021 : return ret->get_backend(context);
19572 : : }
19573 : :
19574 : : // Export a receive expression.
19575 : :
19576 : : void
19577 : 17 : Receive_expression::do_export(Export_function_body* efb) const
19578 : : {
19579 : 17 : efb->write_c_string("<-");
19580 : 17 : this->channel_->export_expression(efb);
19581 : 17 : }
19582 : :
19583 : : // Dump ast representation for a receive expression.
19584 : :
19585 : : void
19586 : 0 : Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
19587 : : {
19588 : 0 : ast_dump_context->ostream() << " <- " ;
19589 : 0 : ast_dump_context->dump_expression(channel_);
19590 : 0 : }
19591 : :
19592 : : // Import a receive expression.
19593 : :
19594 : : Expression*
19595 : 0 : Receive_expression::do_import(Import_expression* imp, Location loc)
19596 : : {
19597 : 0 : imp->require_c_string("<-");
19598 : 0 : Expression* expr = Expression::import_expression(imp, loc);
19599 : 0 : return Expression::make_receive(expr, loc);
19600 : : }
19601 : :
19602 : : // Make a receive expression.
19603 : :
19604 : : Receive_expression*
19605 : 4139 : Expression::make_receive(Expression* channel, Location location)
19606 : : {
19607 : 4139 : return new Receive_expression(channel, location);
19608 : : }
19609 : :
19610 : : // An expression which evaluates to a pointer to the type descriptor
19611 : : // of a type.
19612 : :
19613 : : class Type_descriptor_expression : public Expression
19614 : : {
19615 : : public:
19616 : 1914213 : Type_descriptor_expression(Type* type, Location location)
19617 : 1914213 : : Expression(EXPRESSION_TYPE_DESCRIPTOR, location),
19618 : 3828426 : type_(type)
19619 : : { }
19620 : :
19621 : : protected:
19622 : : int
19623 : : do_traverse(Traverse*);
19624 : :
19625 : : Type*
19626 : 2181384 : do_type()
19627 : 2181384 : { return Type::make_type_descriptor_ptr_type(); }
19628 : :
19629 : : bool
19630 : 1391284 : do_is_static_initializer() const
19631 : 1391284 : { return true; }
19632 : :
19633 : : void
19634 : 2066872 : do_determine_type(Gogo*, const Type_context*)
19635 : 2066872 : { }
19636 : :
19637 : : Expression*
19638 : 12525 : do_copy()
19639 : 12525 : { return this; }
19640 : :
19641 : : Bexpression*
19642 : 1327336 : do_get_backend(Translate_context* context)
19643 : : {
19644 : 1327336 : return this->type_->type_descriptor_pointer(context->gogo(),
19645 : 1327336 : this->location());
19646 : : }
19647 : :
19648 : : void
19649 : : do_dump_expression(Ast_dump_context*) const;
19650 : :
19651 : : private:
19652 : : // The type for which this is the descriptor.
19653 : : Type* type_;
19654 : : };
19655 : :
19656 : : int
19657 : 683098 : Type_descriptor_expression::do_traverse(Traverse* traverse)
19658 : : {
19659 : 683098 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
19660 : 0 : return TRAVERSE_EXIT;
19661 : : return TRAVERSE_CONTINUE;
19662 : : }
19663 : :
19664 : : // Dump ast representation for a type descriptor expression.
19665 : :
19666 : : void
19667 : 0 : Type_descriptor_expression::do_dump_expression(
19668 : : Ast_dump_context* ast_dump_context) const
19669 : : {
19670 : 0 : ast_dump_context->dump_type(this->type_);
19671 : 0 : }
19672 : :
19673 : : // Make a type descriptor expression.
19674 : :
19675 : : Expression*
19676 : 1914213 : Expression::make_type_descriptor(Type* type, Location location)
19677 : : {
19678 : 1914213 : return new Type_descriptor_expression(type, location);
19679 : : }
19680 : :
19681 : : // An expression which evaluates to a pointer to the Garbage Collection symbol
19682 : : // of a type.
19683 : :
19684 : : class GC_symbol_expression : public Expression
19685 : : {
19686 : : public:
19687 : 243627 : GC_symbol_expression(Type* type)
19688 : 243627 : : Expression(EXPRESSION_GC_SYMBOL, Linemap::predeclared_location()),
19689 : 243627 : type_(type)
19690 : 243627 : {}
19691 : :
19692 : : protected:
19693 : : Type*
19694 : 212593 : do_type()
19695 : 212593 : { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
19696 : :
19697 : : bool
19698 : 0 : do_is_static_initializer() const
19699 : 0 : { return true; }
19700 : :
19701 : : void
19702 : 278020 : do_determine_type(Gogo*, const Type_context*)
19703 : 278020 : { }
19704 : :
19705 : : Expression*
19706 : 0 : do_copy()
19707 : 0 : { return this; }
19708 : :
19709 : : Bexpression*
19710 : 212593 : do_get_backend(Translate_context* context)
19711 : 212593 : { return this->type_->gc_symbol_pointer(context->gogo()); }
19712 : :
19713 : : void
19714 : : do_dump_expression(Ast_dump_context*) const;
19715 : :
19716 : : private:
19717 : : // The type which this gc symbol describes.
19718 : : Type* type_;
19719 : : };
19720 : :
19721 : : // Dump ast representation for a gc symbol expression.
19722 : :
19723 : : void
19724 : 0 : GC_symbol_expression::do_dump_expression(
19725 : : Ast_dump_context* ast_dump_context) const
19726 : : {
19727 : 0 : ast_dump_context->ostream() << "gcdata(";
19728 : 0 : ast_dump_context->dump_type(this->type_);
19729 : 0 : ast_dump_context->ostream() << ")";
19730 : 0 : }
19731 : :
19732 : : // Make a gc symbol expression.
19733 : :
19734 : : Expression*
19735 : 243627 : Expression::make_gc_symbol(Type* type)
19736 : : {
19737 : 243627 : return new GC_symbol_expression(type);
19738 : : }
19739 : :
19740 : : // An expression that evaluates to a pointer to a symbol holding the
19741 : : // ptrmask data of a type.
19742 : :
19743 : : class Ptrmask_symbol_expression : public Expression
19744 : : {
19745 : : public:
19746 : 22047 : Ptrmask_symbol_expression(Type* type)
19747 : 22047 : : Expression(EXPRESSION_PTRMASK_SYMBOL, Linemap::predeclared_location()),
19748 : 22047 : type_(type)
19749 : 22047 : {}
19750 : :
19751 : : protected:
19752 : : Type*
19753 : 44094 : do_type()
19754 : 44094 : { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
19755 : :
19756 : : bool
19757 : 22047 : do_is_static_initializer() const
19758 : 22047 : { return true; }
19759 : :
19760 : : void
19761 : 22047 : do_determine_type(Gogo*, const Type_context*)
19762 : 22047 : { }
19763 : :
19764 : : Expression*
19765 : 0 : do_copy()
19766 : 0 : { return this; }
19767 : :
19768 : : Bexpression*
19769 : : do_get_backend(Translate_context*);
19770 : :
19771 : : void
19772 : : do_dump_expression(Ast_dump_context*) const;
19773 : :
19774 : : private:
19775 : : // The type that this ptrmask symbol describes.
19776 : : Type* type_;
19777 : : };
19778 : :
19779 : : // Return the ptrmask variable.
19780 : :
19781 : : Bexpression*
19782 : 22047 : Ptrmask_symbol_expression::do_get_backend(Translate_context* context)
19783 : : {
19784 : 22047 : Gogo* gogo = context->gogo();
19785 : :
19786 : : // If this type does not need a gcprog, then we can use the standard
19787 : : // GC symbol.
19788 : 22047 : int64_t ptrsize, ptrdata;
19789 : 22047 : if (!this->type_->needs_gcprog(gogo, &ptrsize, &ptrdata))
19790 : 22034 : return this->type_->gc_symbol_pointer(gogo);
19791 : :
19792 : : // Otherwise we have to build a ptrmask variable, and return a
19793 : : // pointer to it.
19794 : :
19795 : 13 : Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata);
19796 : 13 : Location bloc = Linemap::predeclared_location();
19797 : 13 : Bexpression* bref = gogo->backend()->var_expression(bvar, bloc);
19798 : 13 : Bexpression* baddr = gogo->backend()->address_expression(bref, bloc);
19799 : :
19800 : 13 : Type* uint8_type = Type::lookup_integer_type("uint8");
19801 : 13 : Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
19802 : 13 : Btype* ubtype = pointer_uint8_type->get_backend(gogo);
19803 : 13 : return gogo->backend()->convert_expression(ubtype, baddr, bloc);
19804 : : }
19805 : :
19806 : : // Dump AST for a ptrmask symbol expression.
19807 : :
19808 : : void
19809 : 0 : Ptrmask_symbol_expression::do_dump_expression(
19810 : : Ast_dump_context* ast_dump_context) const
19811 : : {
19812 : 0 : ast_dump_context->ostream() << "ptrmask(";
19813 : 0 : ast_dump_context->dump_type(this->type_);
19814 : 0 : ast_dump_context->ostream() << ")";
19815 : 0 : }
19816 : :
19817 : : // Make a ptrmask symbol expression.
19818 : :
19819 : : Expression*
19820 : 22047 : Expression::make_ptrmask_symbol(Type* type)
19821 : : {
19822 : 22047 : return new Ptrmask_symbol_expression(type);
19823 : : }
19824 : :
19825 : : // An expression which evaluates to some characteristic of a type.
19826 : : // This is only used to initialize fields of a type descriptor. Using
19827 : : // a new expression class is slightly inefficient but gives us a good
19828 : : // separation between the frontend and the middle-end with regard to
19829 : : // how types are laid out.
19830 : :
19831 : : class Type_info_expression : public Expression
19832 : : {
19833 : : public:
19834 : 1155310 : Type_info_expression(Type* type, Type_info type_info)
19835 : 1155310 : : Expression(EXPRESSION_TYPE_INFO, Linemap::predeclared_location()),
19836 : 1155310 : type_(type), type_info_(type_info)
19837 : 1155310 : { }
19838 : :
19839 : : protected:
19840 : : bool
19841 : 44094 : do_is_static_initializer() const
19842 : 44094 : { return true; }
19843 : :
19844 : : Type*
19845 : : do_type();
19846 : :
19847 : : void
19848 : 1433528 : do_determine_type(Gogo*, const Type_context*)
19849 : 1433528 : { }
19850 : :
19851 : : Expression*
19852 : 0 : do_copy()
19853 : 0 : { return this; }
19854 : :
19855 : : Bexpression*
19856 : : do_get_backend(Translate_context* context);
19857 : :
19858 : : void
19859 : : do_dump_expression(Ast_dump_context*) const;
19860 : :
19861 : : private:
19862 : : // The type for which we are getting information.
19863 : : Type* type_;
19864 : : // What information we want.
19865 : : Type_info type_info_;
19866 : : };
19867 : :
19868 : : // The type is chosen to match what the type descriptor struct
19869 : : // expects.
19870 : :
19871 : : Type*
19872 : 2101779 : Type_info_expression::do_type()
19873 : : {
19874 : 2101779 : switch (this->type_info_)
19875 : : {
19876 : 1118343 : case TYPE_INFO_SIZE:
19877 : 1118343 : case TYPE_INFO_BACKEND_PTRDATA:
19878 : 1118343 : case TYPE_INFO_DESCRIPTOR_PTRDATA:
19879 : 1118343 : return Type::lookup_integer_type("uintptr");
19880 : 983436 : case TYPE_INFO_ALIGNMENT:
19881 : 983436 : case TYPE_INFO_FIELD_ALIGNMENT:
19882 : 983436 : return Type::lookup_integer_type("uint8");
19883 : 0 : default:
19884 : 0 : go_unreachable();
19885 : : }
19886 : : }
19887 : :
19888 : : // Return the backend representation for type information.
19889 : :
19890 : : Bexpression*
19891 : 1011302 : Type_info_expression::do_get_backend(Translate_context* context)
19892 : : {
19893 : 1011302 : Gogo* gogo = context->gogo();
19894 : 1011302 : bool ok = true;
19895 : 1011302 : int64_t val;
19896 : 1011302 : switch (this->type_info_)
19897 : : {
19898 : 284944 : case TYPE_INFO_SIZE:
19899 : 284944 : ok = this->type_->backend_type_size(gogo, &val);
19900 : 284944 : break;
19901 : 245859 : case TYPE_INFO_ALIGNMENT:
19902 : 245859 : ok = this->type_->backend_type_align(gogo, &val);
19903 : 245859 : break;
19904 : 245859 : case TYPE_INFO_FIELD_ALIGNMENT:
19905 : 245859 : ok = this->type_->backend_type_field_align(gogo, &val);
19906 : 245859 : break;
19907 : 22047 : case TYPE_INFO_BACKEND_PTRDATA:
19908 : 22047 : ok = this->type_->backend_type_ptrdata(gogo, &val);
19909 : 22047 : break;
19910 : 212593 : case TYPE_INFO_DESCRIPTOR_PTRDATA:
19911 : 212593 : ok = this->type_->descriptor_ptrdata(gogo, &val);
19912 : 212593 : break;
19913 : 0 : default:
19914 : 0 : go_unreachable();
19915 : : }
19916 : 1011302 : if (!ok)
19917 : : {
19918 : 3 : go_assert(saw_errors());
19919 : 3 : return gogo->backend()->error_expression();
19920 : : }
19921 : 1011299 : Expression* e = Expression::make_integer_int64(val, this->type(),
19922 : : this->location());
19923 : 1011299 : return e->get_backend(context);
19924 : : }
19925 : :
19926 : : // Dump ast representation for a type info expression.
19927 : :
19928 : : void
19929 : 0 : Type_info_expression::do_dump_expression(
19930 : : Ast_dump_context* ast_dump_context) const
19931 : : {
19932 : 0 : ast_dump_context->ostream() << "typeinfo(";
19933 : 0 : ast_dump_context->dump_type(this->type_);
19934 : 0 : ast_dump_context->ostream() << ",";
19935 : 0 : ast_dump_context->ostream() <<
19936 : 0 : (this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment"
19937 : 0 : : this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
19938 : 0 : : this->type_info_ == TYPE_INFO_SIZE ? "size"
19939 : 0 : : this->type_info_ == TYPE_INFO_BACKEND_PTRDATA ? "backend_ptrdata"
19940 : 0 : : this->type_info_ == TYPE_INFO_DESCRIPTOR_PTRDATA ? "descriptor_ptrdata"
19941 : 0 : : "unknown");
19942 : 0 : ast_dump_context->ostream() << ")";
19943 : 0 : }
19944 : :
19945 : : // Make a type info expression.
19946 : :
19947 : : Expression*
19948 : 1155310 : Expression::make_type_info(Type* type, Type_info type_info)
19949 : : {
19950 : 1155310 : return new Type_info_expression(type, type_info);
19951 : : }
19952 : :
19953 : : // Slice_info_expression.
19954 : :
19955 : : // Return the type of the slice info.
19956 : :
19957 : : Type*
19958 : 1101756 : Slice_info_expression::do_type()
19959 : : {
19960 : 1101756 : switch (this->slice_info_)
19961 : : {
19962 : 367207 : case SLICE_INFO_VALUE_POINTER:
19963 : 734414 : return Type::make_pointer_type(
19964 : 734414 : this->slice_->type()->array_type()->element_type());
19965 : 734549 : case SLICE_INFO_LENGTH:
19966 : 734549 : case SLICE_INFO_CAPACITY:
19967 : 734549 : return Type::lookup_integer_type("int");
19968 : 0 : default:
19969 : 0 : go_unreachable();
19970 : : }
19971 : : }
19972 : :
19973 : : // Return the backend information for slice information.
19974 : :
19975 : : Bexpression*
19976 : 723602 : Slice_info_expression::do_get_backend(Translate_context* context)
19977 : : {
19978 : 723602 : Gogo* gogo = context->gogo();
19979 : 723602 : Bexpression* bslice = this->slice_->get_backend(context);
19980 : 723602 : switch (this->slice_info_)
19981 : : {
19982 : 723602 : case SLICE_INFO_VALUE_POINTER:
19983 : 723602 : case SLICE_INFO_LENGTH:
19984 : 723602 : case SLICE_INFO_CAPACITY:
19985 : 723602 : return gogo->backend()->struct_field_expression(bslice, this->slice_info_,
19986 : 723602 : this->location());
19987 : 0 : break;
19988 : 0 : default:
19989 : 0 : go_unreachable();
19990 : : }
19991 : : }
19992 : :
19993 : : // Dump ast representation for a type info expression.
19994 : :
19995 : : void
19996 : 0 : Slice_info_expression::do_dump_expression(
19997 : : Ast_dump_context* ast_dump_context) const
19998 : : {
19999 : 0 : ast_dump_context->ostream() << "sliceinfo(";
20000 : 0 : this->slice_->dump_expression(ast_dump_context);
20001 : 0 : ast_dump_context->ostream() << ",";
20002 : 0 : ast_dump_context->ostream() <<
20003 : 0 : (this->slice_info_ == SLICE_INFO_VALUE_POINTER ? "values"
20004 : 0 : : this->slice_info_ == SLICE_INFO_LENGTH ? "length"
20005 : 0 : : this->slice_info_ == SLICE_INFO_CAPACITY ? "capacity "
20006 : 0 : : "unknown");
20007 : 0 : ast_dump_context->ostream() << ")";
20008 : 0 : }
20009 : :
20010 : : // Make a slice info expression.
20011 : :
20012 : : Expression*
20013 : 692526 : Expression::make_slice_info(Expression* slice, Slice_info slice_info,
20014 : : Location location)
20015 : : {
20016 : 692526 : return new Slice_info_expression(slice, slice_info, location);
20017 : : }
20018 : :
20019 : : // Class Slice_value_expression.
20020 : :
20021 : : int
20022 : 126120 : Slice_value_expression::do_traverse(Traverse* traverse)
20023 : : {
20024 : 126120 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT
20025 : 126120 : || Expression::traverse(&this->valmem_, traverse) == TRAVERSE_EXIT
20026 : 126120 : || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT
20027 : 252240 : || Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
20028 : 0 : return TRAVERSE_EXIT;
20029 : : return TRAVERSE_CONTINUE;
20030 : : }
20031 : :
20032 : : // Determine type of a slice value.
20033 : :
20034 : : void
20035 : 31327 : Slice_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
20036 : : {
20037 : 31327 : this->valmem_->determine_type_no_context(gogo);
20038 : 31327 : this->len_->determine_type_no_context(gogo);
20039 : 31327 : this->cap_->determine_type_no_context(gogo);
20040 : 31327 : }
20041 : :
20042 : : Expression*
20043 : 0 : Slice_value_expression::do_copy()
20044 : : {
20045 : 0 : return new Slice_value_expression(this->type_->copy_expressions(),
20046 : 0 : this->valmem_->copy(),
20047 : 0 : this->len_->copy(), this->cap_->copy(),
20048 : 0 : this->location());
20049 : : }
20050 : :
20051 : : Bexpression*
20052 : 405065 : Slice_value_expression::do_get_backend(Translate_context* context)
20053 : : {
20054 : 405065 : std::vector<Bexpression*> vals(3);
20055 : 405065 : vals[0] = this->valmem_->get_backend(context);
20056 : 405065 : vals[1] = this->len_->get_backend(context);
20057 : 405065 : vals[2] = this->cap_->get_backend(context);
20058 : :
20059 : 405065 : Gogo* gogo = context->gogo();
20060 : 405065 : Btype* btype = this->type_->get_backend(gogo);
20061 : 405065 : return gogo->backend()->constructor_expression(btype, vals, this->location());
20062 : 405065 : }
20063 : :
20064 : : void
20065 : 0 : Slice_value_expression::do_dump_expression(
20066 : : Ast_dump_context* ast_dump_context) const
20067 : : {
20068 : 0 : ast_dump_context->ostream() << "slicevalue(";
20069 : 0 : ast_dump_context->ostream() << "values: ";
20070 : 0 : this->valmem_->dump_expression(ast_dump_context);
20071 : 0 : ast_dump_context->ostream() << ", length: ";
20072 : 0 : this->len_->dump_expression(ast_dump_context);
20073 : 0 : ast_dump_context->ostream() << ", capacity: ";
20074 : 0 : this->cap_->dump_expression(ast_dump_context);
20075 : 0 : ast_dump_context->ostream() << ")";
20076 : 0 : }
20077 : :
20078 : : Expression*
20079 : 405685 : Expression::make_slice_value(Type* at, Expression* valmem, Expression* len,
20080 : : Expression* cap, Location location)
20081 : : {
20082 : 405685 : go_assert(at->is_slice_type());
20083 : 792204 : go_assert(valmem->is_nil_expression()
20084 : : || (at->array_type()->element_type()
20085 : : == valmem->type()->points_to()));
20086 : 405685 : return new Slice_value_expression(at, valmem, len, cap, location);
20087 : : }
20088 : :
20089 : : // Look through the expression of a Slice_value_expression's valmem to
20090 : : // find an call to makeslice. If found, return the call expression and
20091 : : // the containing temporary statement (if any).
20092 : :
20093 : : std::pair<Call_expression*, Temporary_statement*>
20094 : 12132 : Expression::find_makeslice_call(Expression* expr)
20095 : : {
20096 : 12132 : Unsafe_type_conversion_expression* utce =
20097 : 12159 : expr->unsafe_conversion_expression();
20098 : 27 : if (utce != NULL)
20099 : 27 : expr = utce->expr();
20100 : :
20101 : 12132 : Slice_value_expression* sve = expr->slice_value_expression();
20102 : 12132 : if (sve == NULL)
20103 : 3529 : return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
20104 : 8603 : expr = sve->valmem();
20105 : :
20106 : 8603 : utce = expr->unsafe_conversion_expression();
20107 : 8594 : if (utce != NULL)
20108 : 8594 : expr = utce->expr();
20109 : :
20110 : 8603 : Temporary_reference_expression* tre = expr->temporary_reference_expression();
20111 : 2797 : Temporary_statement* ts = (tre != NULL ? tre->statement() : NULL);
20112 : 2797 : if (ts != NULL && ts->init() != NULL && !ts->assigned()
20113 : 5594 : && !ts->is_address_taken())
20114 : : expr = ts->init();
20115 : :
20116 : 8603 : Call_expression* call = expr->call_expression();
20117 : 8603 : if (call == NULL)
20118 : 27 : return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
20119 : :
20120 : 8576 : Func_expression* fe = call->fn()->func_expression();
20121 : 8576 : if (fe != NULL
20122 : 8576 : && fe->runtime_code() == Runtime::MAKESLICE)
20123 : 8456 : return std::make_pair(call, ts);
20124 : :
20125 : 120 : return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
20126 : : }
20127 : :
20128 : : // An expression that evaluates to some characteristic of a non-empty interface.
20129 : : // This is used to access the method table or underlying object of an interface.
20130 : :
20131 : : class Interface_info_expression : public Expression
20132 : : {
20133 : : public:
20134 : 210141 : Interface_info_expression(Expression* iface, Interface_info iface_info,
20135 : : Location location)
20136 : 210141 : : Expression(EXPRESSION_INTERFACE_INFO, location),
20137 : 420282 : iface_(iface), iface_info_(iface_info)
20138 : : { }
20139 : :
20140 : : protected:
20141 : : Type*
20142 : : do_type();
20143 : :
20144 : : void
20145 : 398772 : do_determine_type(Gogo*, const Type_context*)
20146 : 398772 : { }
20147 : :
20148 : : Expression*
20149 : 0 : do_copy()
20150 : : {
20151 : 0 : return new Interface_info_expression(this->iface_->copy(),
20152 : 0 : this->iface_info_, this->location());
20153 : : }
20154 : :
20155 : : Bexpression*
20156 : : do_get_backend(Translate_context* context);
20157 : :
20158 : : void
20159 : : do_dump_expression(Ast_dump_context*) const;
20160 : :
20161 : : void
20162 : 0 : do_issue_nil_check()
20163 : 0 : { this->iface_->issue_nil_check(); }
20164 : :
20165 : : private:
20166 : : // The interface for which we are getting information.
20167 : : Expression* iface_;
20168 : : // What information we want.
20169 : : Interface_info iface_info_;
20170 : : };
20171 : :
20172 : : // Return the type of the interface info.
20173 : :
20174 : : Type*
20175 : 1108952 : Interface_info_expression::do_type()
20176 : : {
20177 : 1108952 : switch (this->iface_info_)
20178 : : {
20179 : 867135 : case INTERFACE_INFO_METHODS:
20180 : 867135 : {
20181 : 867135 : typedef Unordered_map(Interface_type*, Type*) Hashtable;
20182 : 867135 : static Hashtable result_types;
20183 : :
20184 : 867135 : Interface_type* itype = this->iface_->type()->interface_type();
20185 : :
20186 : 867135 : Hashtable::const_iterator pr = result_types.find(itype);
20187 : 867135 : if (pr != result_types.end())
20188 : 859918 : return pr->second;
20189 : :
20190 : 7217 : Type* pdt = Type::make_type_descriptor_ptr_type();
20191 : 7217 : if (itype->is_empty())
20192 : : {
20193 : 811 : result_types[itype] = pdt;
20194 : 811 : return pdt;
20195 : : }
20196 : :
20197 : 6406 : Location loc = this->location();
20198 : 6406 : Struct_field_list* sfl = new Struct_field_list();
20199 : 6406 : sfl->push_back(
20200 : 12812 : Struct_field(Typed_identifier("__type_descriptor", pdt, loc)));
20201 : :
20202 : 6406 : for (Typed_identifier_list::const_iterator p = itype->methods()->begin();
20203 : 28162 : p != itype->methods()->end();
20204 : 21756 : ++p)
20205 : : {
20206 : 21756 : Function_type* ft = p->type()->function_type();
20207 : 21756 : go_assert(ft->receiver() == NULL);
20208 : :
20209 : 21756 : const Typed_identifier_list* params = ft->parameters();
20210 : 21756 : Typed_identifier_list* mparams = new Typed_identifier_list();
20211 : 21756 : if (params != NULL)
20212 : 7984 : mparams->reserve(params->size() + 1);
20213 : 21756 : Type* vt = Type::make_pointer_type(Type::make_void_type());
20214 : 21756 : mparams->push_back(Typed_identifier("", vt, ft->location()));
20215 : 21756 : if (params != NULL)
20216 : : {
20217 : 7984 : for (Typed_identifier_list::const_iterator pp = params->begin();
20218 : 18017 : pp != params->end();
20219 : 10033 : ++pp)
20220 : 10033 : mparams->push_back(*pp);
20221 : : }
20222 : :
20223 : 21756 : Typed_identifier_list* mresults = (ft->results() == NULL
20224 : 21756 : ? NULL
20225 : 19407 : : ft->results()->copy());
20226 : 21756 : Backend_function_type* mft =
20227 : 21756 : Type::make_backend_function_type(NULL, mparams, mresults,
20228 : : ft->location());
20229 : :
20230 : 21756 : std::string fname = Gogo::unpack_hidden_name(p->name());
20231 : 21756 : sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc)));
20232 : 21756 : }
20233 : :
20234 : 6406 : Struct_type* st = Type::make_struct_type(sfl, loc);
20235 : 6406 : st->set_is_struct_incomparable();
20236 : 6406 : Pointer_type *pt = Type::make_pointer_type(st);
20237 : 6406 : result_types[itype] = pt;
20238 : 6406 : return pt;
20239 : : }
20240 : 241817 : case INTERFACE_INFO_OBJECT:
20241 : 241817 : return Type::make_pointer_type(Type::make_void_type());
20242 : 0 : default:
20243 : 0 : go_unreachable();
20244 : : }
20245 : : }
20246 : :
20247 : : // Return the backend representation for interface information.
20248 : :
20249 : : Bexpression*
20250 : 281884 : Interface_info_expression::do_get_backend(Translate_context* context)
20251 : : {
20252 : 281884 : Gogo* gogo = context->gogo();
20253 : 281884 : Bexpression* biface = this->iface_->get_backend(context);
20254 : 281884 : switch (this->iface_info_)
20255 : : {
20256 : 281884 : case INTERFACE_INFO_METHODS:
20257 : 281884 : case INTERFACE_INFO_OBJECT:
20258 : 281884 : return gogo->backend()->struct_field_expression(biface, this->iface_info_,
20259 : 281884 : this->location());
20260 : 0 : break;
20261 : 0 : default:
20262 : 0 : go_unreachable();
20263 : : }
20264 : : }
20265 : :
20266 : : // Dump ast representation for an interface info expression.
20267 : :
20268 : : void
20269 : 0 : Interface_info_expression::do_dump_expression(
20270 : : Ast_dump_context* ast_dump_context) const
20271 : : {
20272 : 0 : bool is_empty = this->iface_->type()->interface_type()->is_empty();
20273 : 0 : ast_dump_context->ostream() << "interfaceinfo(";
20274 : 0 : this->iface_->dump_expression(ast_dump_context);
20275 : 0 : ast_dump_context->ostream() << ",";
20276 : 0 : ast_dump_context->ostream() <<
20277 : 0 : (this->iface_info_ == INTERFACE_INFO_METHODS && !is_empty ? "methods"
20278 : 0 : : this->iface_info_ == INTERFACE_INFO_TYPE_DESCRIPTOR ? "type_descriptor"
20279 : 0 : : this->iface_info_ == INTERFACE_INFO_OBJECT ? "object"
20280 : 0 : : "unknown");
20281 : 0 : ast_dump_context->ostream() << ")";
20282 : 0 : }
20283 : :
20284 : : // Make an interface info expression.
20285 : :
20286 : : Expression*
20287 : 210141 : Expression::make_interface_info(Expression* iface, Interface_info iface_info,
20288 : : Location location)
20289 : : {
20290 : 210141 : return new Interface_info_expression(iface, iface_info, location);
20291 : : }
20292 : :
20293 : : // An expression that represents an interface value. The first field is either
20294 : : // a type descriptor for an empty interface or a pointer to the interface method
20295 : : // table for a non-empty interface. The second field is always the object.
20296 : :
20297 : : class Interface_value_expression : public Expression
20298 : : {
20299 : : public:
20300 : 229082 : Interface_value_expression(Type* type, Expression* first_field,
20301 : : Expression* obj, Location location)
20302 : 229082 : : Expression(EXPRESSION_INTERFACE_VALUE, location),
20303 : 458164 : type_(type), first_field_(first_field), obj_(obj)
20304 : : { }
20305 : :
20306 : : protected:
20307 : : int
20308 : : do_traverse(Traverse*);
20309 : :
20310 : : Type*
20311 : 847 : do_type()
20312 : 847 : { return this->type_; }
20313 : :
20314 : : void
20315 : : do_determine_type(Gogo*, const Type_context*);
20316 : :
20317 : : Expression*
20318 : 0 : do_copy()
20319 : : {
20320 : 0 : return new Interface_value_expression(this->type_->copy_expressions(),
20321 : 0 : this->first_field_->copy(),
20322 : 0 : this->obj_->copy(), this->location());
20323 : : }
20324 : :
20325 : : Bexpression*
20326 : : do_get_backend(Translate_context* context);
20327 : :
20328 : : void
20329 : : do_dump_expression(Ast_dump_context*) const;
20330 : :
20331 : : private:
20332 : : // The type of the interface value.
20333 : : Type* type_;
20334 : : // The first field of the interface (either a type descriptor or a pointer
20335 : : // to the method table.
20336 : : Expression* first_field_;
20337 : : // The underlying object of the interface.
20338 : : Expression* obj_;
20339 : : };
20340 : :
20341 : : int
20342 : 0 : Interface_value_expression::do_traverse(Traverse* traverse)
20343 : : {
20344 : 0 : if (Expression::traverse(&this->first_field_, traverse) == TRAVERSE_EXIT
20345 : 0 : || Expression::traverse(&this->obj_, traverse) == TRAVERSE_EXIT)
20346 : 0 : return TRAVERSE_EXIT;
20347 : : return TRAVERSE_CONTINUE;
20348 : : }
20349 : :
20350 : : void
20351 : 281130 : Interface_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
20352 : : {
20353 : 281130 : this->first_field_->determine_type_no_context(gogo);
20354 : 281130 : this->obj_->determine_type_no_context(gogo);
20355 : 281130 : }
20356 : :
20357 : : Bexpression*
20358 : 229082 : Interface_value_expression::do_get_backend(Translate_context* context)
20359 : : {
20360 : 229082 : std::vector<Bexpression*> vals(2);
20361 : 229082 : vals[0] = this->first_field_->get_backend(context);
20362 : 229082 : vals[1] = this->obj_->get_backend(context);
20363 : :
20364 : 229082 : Gogo* gogo = context->gogo();
20365 : 229082 : Btype* btype = this->type_->get_backend(gogo);
20366 : 229082 : return gogo->backend()->constructor_expression(btype, vals, this->location());
20367 : 229082 : }
20368 : :
20369 : : void
20370 : 0 : Interface_value_expression::do_dump_expression(
20371 : : Ast_dump_context* ast_dump_context) const
20372 : : {
20373 : 0 : ast_dump_context->ostream() << "interfacevalue(";
20374 : 0 : ast_dump_context->ostream() <<
20375 : 0 : (this->type_->interface_type()->is_empty()
20376 : : ? "type_descriptor: "
20377 : 0 : : "methods: ");
20378 : 0 : this->first_field_->dump_expression(ast_dump_context);
20379 : 0 : ast_dump_context->ostream() << ", object: ";
20380 : 0 : this->obj_->dump_expression(ast_dump_context);
20381 : 0 : ast_dump_context->ostream() << ")";
20382 : 0 : }
20383 : :
20384 : : Expression*
20385 : 229082 : Expression::make_interface_value(Type* type, Expression* first_value,
20386 : : Expression* object, Location location)
20387 : : {
20388 : 229082 : return new Interface_value_expression(type, first_value, object, location);
20389 : : }
20390 : :
20391 : : // An interface method table for a pair of types: an interface type and a type
20392 : : // that implements that interface.
20393 : :
20394 : : class Interface_mtable_expression : public Expression
20395 : : {
20396 : : public:
20397 : 66004 : Interface_mtable_expression(Interface_type* itype, Type* type,
20398 : : bool is_pointer, Location location)
20399 : 66004 : : Expression(EXPRESSION_INTERFACE_MTABLE, location),
20400 : 66004 : itype_(itype), type_(type), is_pointer_(is_pointer),
20401 : 132008 : method_table_type_(NULL), bvar_(NULL)
20402 : : { }
20403 : :
20404 : : protected:
20405 : : int
20406 : : do_traverse(Traverse*);
20407 : :
20408 : : Type*
20409 : : do_type();
20410 : :
20411 : : bool
20412 : 0 : do_is_static_initializer() const
20413 : 0 : { return true; }
20414 : :
20415 : : void
20416 : 43409 : do_determine_type(Gogo*, const Type_context*)
20417 : 43409 : { }
20418 : :
20419 : : Expression*
20420 : 0 : do_copy()
20421 : : {
20422 : 0 : Interface_type* itype = this->itype_->copy_expressions()->interface_type();
20423 : 0 : return new Interface_mtable_expression(itype,
20424 : 0 : this->type_->copy_expressions(),
20425 : 0 : this->is_pointer_, this->location());
20426 : : }
20427 : :
20428 : : bool
20429 : 0 : do_is_addressable() const
20430 : 0 : { return true; }
20431 : :
20432 : : Bexpression*
20433 : : do_get_backend(Translate_context* context);
20434 : :
20435 : : void
20436 : : do_dump_expression(Ast_dump_context*) const;
20437 : :
20438 : : private:
20439 : : // The interface type for which the methods are defined.
20440 : : Interface_type* itype_;
20441 : : // The type to construct the interface method table for.
20442 : : Type* type_;
20443 : : // Whether this table contains the method set for the receiver type or the
20444 : : // pointer receiver type.
20445 : : bool is_pointer_;
20446 : : // The type of the method table.
20447 : : Type* method_table_type_;
20448 : : // The backend variable that refers to the interface method table.
20449 : : Bvariable* bvar_;
20450 : : };
20451 : :
20452 : : int
20453 : 0 : Interface_mtable_expression::do_traverse(Traverse* traverse)
20454 : : {
20455 : 0 : if (Type::traverse(this->itype_, traverse) == TRAVERSE_EXIT
20456 : 0 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
20457 : 0 : return TRAVERSE_EXIT;
20458 : : return TRAVERSE_CONTINUE;
20459 : : }
20460 : :
20461 : : Type*
20462 : 217370 : Interface_mtable_expression::do_type()
20463 : : {
20464 : 217370 : if (this->method_table_type_ != NULL)
20465 : : return this->method_table_type_;
20466 : :
20467 : 66004 : const Typed_identifier_list* interface_methods = this->itype_->methods();
20468 : 66004 : go_assert(!interface_methods->empty());
20469 : :
20470 : 66004 : Struct_field_list* sfl = new Struct_field_list;
20471 : 66004 : Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(),
20472 : 66004 : this->location());
20473 : 66004 : sfl->push_back(Struct_field(tid));
20474 : 66004 : Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
20475 : 66004 : for (Typed_identifier_list::const_iterator p = interface_methods->begin();
20476 : 510485 : p != interface_methods->end();
20477 : 444481 : ++p)
20478 : : {
20479 : : // We want C function pointers here, not func descriptors; model
20480 : : // using void* pointers.
20481 : 444481 : Typed_identifier method(p->name(), unsafe_ptr_type, p->location());
20482 : 444481 : sfl->push_back(Struct_field(method));
20483 : 444481 : }
20484 : 66004 : Struct_type* st = Type::make_struct_type(sfl, this->location());
20485 : 66004 : st->set_is_struct_incomparable();
20486 : 66004 : this->method_table_type_ = st;
20487 : 66004 : return this->method_table_type_;
20488 : 66004 : }
20489 : :
20490 : : Bexpression*
20491 : 182999 : Interface_mtable_expression::do_get_backend(Translate_context* context)
20492 : : {
20493 : 182999 : Gogo* gogo = context->gogo();
20494 : 182999 : Location loc = Linemap::predeclared_location();
20495 : 182999 : if (this->bvar_ != NULL)
20496 : 116995 : return gogo->backend()->var_expression(this->bvar_, this->location());
20497 : :
20498 : 66004 : const Typed_identifier_list* interface_methods = this->itype_->methods();
20499 : 66004 : go_assert(!interface_methods->empty());
20500 : :
20501 : 66004 : std::string mangled_name =
20502 : : gogo->interface_method_table_name(this->itype_, this->type_,
20503 : 66004 : this->is_pointer_);
20504 : :
20505 : : // Set is_public if we are converting a named type to an interface
20506 : : // type that is defined in the same package as the named type, and
20507 : : // the interface has hidden methods. In that case the interface
20508 : : // method table will be defined by the package that defines the
20509 : : // types.
20510 : 66004 : bool is_public = false;
20511 : 66004 : if (this->type_->named_type() != NULL
20512 : 66004 : && (this->type_->named_type()->named_object()->package()
20513 : 65903 : == this->itype_->package()))
20514 : : {
20515 : 259537 : for (Typed_identifier_list::const_iterator p = interface_methods->begin();
20516 : 259537 : p != interface_methods->end();
20517 : 217227 : ++p)
20518 : : {
20519 : 254987 : if (Gogo::is_hidden_name(p->name()))
20520 : : {
20521 : : is_public = true;
20522 : : break;
20523 : : }
20524 : : }
20525 : : }
20526 : :
20527 : 42310 : if (is_public
20528 : 42310 : && this->type_->named_type()->named_object()->package() != NULL)
20529 : : {
20530 : : // The interface conversion table is defined elsewhere.
20531 : 34371 : Btype* btype = this->type()->get_backend(gogo);
20532 : 68742 : this->bvar_ =
20533 : 34371 : gogo->backend()->immutable_struct_reference(mangled_name, "",
20534 : : btype, loc);
20535 : 34371 : return gogo->backend()->var_expression(this->bvar_, this->location());
20536 : : }
20537 : :
20538 : : // The first element is the type descriptor.
20539 : 31633 : Type* td_type;
20540 : 31633 : if (!this->is_pointer_)
20541 : 13998 : td_type = this->type_;
20542 : : else
20543 : 17635 : td_type = Type::make_pointer_type(this->type_);
20544 : :
20545 : 31633 : std::vector<Backend::Btyped_identifier> bstructfields;
20546 : :
20547 : : // Build an interface method table for a type: a type descriptor followed by a
20548 : : // list of function pointers, one for each interface method. This is used for
20549 : : // interfaces.
20550 : 31633 : Expression_list* svals = new Expression_list();
20551 : 31633 : Expression* tdescriptor = Expression::make_type_descriptor(td_type, loc);
20552 : 31633 : svals->push_back(tdescriptor);
20553 : :
20554 : 31633 : Btype* tdesc_btype = tdescriptor->type()->get_backend(gogo);
20555 : 31633 : Backend::Btyped_identifier btd("_type", tdesc_btype, loc);
20556 : 31633 : bstructfields.push_back(btd);
20557 : :
20558 : 31633 : Named_type* nt = this->type_->named_type();
20559 : 31633 : Struct_type* st = this->type_->struct_type();
20560 : 31633 : go_assert(nt != NULL || st != NULL);
20561 : :
20562 : 31633 : for (Typed_identifier_list::const_iterator p = interface_methods->begin();
20563 : 217683 : p != interface_methods->end();
20564 : 186050 : ++p)
20565 : : {
20566 : 186050 : bool is_ambiguous;
20567 : 186050 : Method* m;
20568 : 186050 : if (nt != NULL)
20569 : 185878 : m = nt->method_function(p->name(), &is_ambiguous);
20570 : : else
20571 : 172 : m = st->method_function(p->name(), &is_ambiguous);
20572 : 186050 : go_assert(m != NULL);
20573 : :
20574 : : // See the comment in Type::method_constructor.
20575 : 186050 : bool use_direct_iface_stub = false;
20576 : 186050 : if (m->is_value_method()
20577 : 22460 : && this->is_pointer_
20578 : 191919 : && this->type_->is_direct_iface_type())
20579 : : use_direct_iface_stub = true;
20580 : 186050 : if (!m->is_value_method()
20581 : 163590 : && this->is_pointer_
20582 : 273696 : && !this->type_->in_heap())
20583 : : use_direct_iface_stub = true;
20584 : 186050 : Named_object* no = (use_direct_iface_stub
20585 : 186050 : ? m->iface_stub_object()
20586 : 185876 : : m->named_object());
20587 : :
20588 : 186050 : go_assert(no->is_function() || no->is_function_declaration());
20589 : :
20590 : 186050 : Function_type* fcn_type = (no->is_function()
20591 : 186050 : ? no->func_value()->type()
20592 : 158248 : : no->func_declaration_value()->type());
20593 : 186050 : Btype* fcn_btype = fcn_type->get_backend_fntype(gogo);
20594 : 186050 : Backend::Btyped_identifier bmtype(p->name(), fcn_btype, loc);
20595 : 186050 : bstructfields.push_back(bmtype);
20596 : :
20597 : 186050 : svals->push_back(Expression::make_func_code_reference(no, loc));
20598 : 186050 : }
20599 : :
20600 : 31633 : Btype *btype = gogo->backend()->struct_type(bstructfields);
20601 : 31633 : std::vector<Bexpression*> ctor_bexprs;
20602 : 31633 : for (Expression_list::const_iterator pe = svals->begin();
20603 : 249316 : pe != svals->end();
20604 : 217683 : ++pe)
20605 : : {
20606 : 217683 : ctor_bexprs.push_back((*pe)->get_backend(context));
20607 : : }
20608 : 31633 : Bexpression* ctor =
20609 : 31633 : gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
20610 : :
20611 : 31633 : unsigned int flags = 0;
20612 : 31633 : if (!is_public)
20613 : 28244 : flags |= Backend::variable_is_hidden;
20614 : 31633 : this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", flags,
20615 : : btype, loc);
20616 : 31633 : gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, flags,
20617 : : btype, loc, ctor);
20618 : 31633 : return gogo->backend()->var_expression(this->bvar_, loc);
20619 : 97637 : }
20620 : :
20621 : : void
20622 : 0 : Interface_mtable_expression::do_dump_expression(
20623 : : Ast_dump_context* ast_dump_context) const
20624 : : {
20625 : 0 : ast_dump_context->ostream() << "__go_"
20626 : 0 : << (this->is_pointer_ ? "pimt__" : "imt_");
20627 : 0 : ast_dump_context->dump_type(this->itype_);
20628 : 0 : ast_dump_context->ostream() << "__";
20629 : 0 : ast_dump_context->dump_type(this->type_);
20630 : 0 : }
20631 : :
20632 : : Expression*
20633 : 66004 : Expression::make_interface_mtable_ref(Interface_type* itype, Type* type,
20634 : : bool is_pointer, Location location)
20635 : : {
20636 : 66004 : return new Interface_mtable_expression(itype, type, is_pointer, location);
20637 : : }
20638 : :
20639 : : // An expression which evaluates to the offset of a field within a
20640 : : // struct. This, like Type_info_expression, q.v., is only used to
20641 : : // initialize fields of a type descriptor.
20642 : :
20643 : : class Struct_field_offset_expression : public Expression
20644 : : {
20645 : : public:
20646 : 188496 : Struct_field_offset_expression(Struct_type* type, const Struct_field* field)
20647 : 188496 : : Expression(EXPRESSION_STRUCT_FIELD_OFFSET,
20648 : : Linemap::predeclared_location()),
20649 : 188496 : type_(type), field_(field)
20650 : 188496 : { }
20651 : :
20652 : : protected:
20653 : : bool
20654 : 235762 : do_is_static_initializer() const
20655 : 235762 : { return true; }
20656 : :
20657 : : Type*
20658 : 311121 : do_type()
20659 : 311121 : { return Type::lookup_integer_type("uintptr"); }
20660 : :
20661 : : void
20662 : 191977 : do_determine_type(Gogo*, const Type_context*)
20663 : 191977 : { }
20664 : :
20665 : : Expression*
20666 : 0 : do_copy()
20667 : 0 : { return this; }
20668 : :
20669 : : Bexpression*
20670 : : do_get_backend(Translate_context* context);
20671 : :
20672 : : void
20673 : : do_dump_expression(Ast_dump_context*) const;
20674 : :
20675 : : private:
20676 : : // The type of the struct.
20677 : : Struct_type* type_;
20678 : : // The field.
20679 : : const Struct_field* field_;
20680 : : };
20681 : :
20682 : : // Return the backend representation for a struct field offset.
20683 : :
20684 : : Bexpression*
20685 : 121783 : Struct_field_offset_expression::do_get_backend(Translate_context* context)
20686 : : {
20687 : 121783 : const Struct_field_list* fields = this->type_->fields();
20688 : 121783 : Struct_field_list::const_iterator p;
20689 : 121783 : unsigned i = 0;
20690 : 121783 : for (p = fields->begin();
20691 : 561093 : p != fields->end();
20692 : 439310 : ++p, ++i)
20693 : 561093 : if (&*p == this->field_)
20694 : : break;
20695 : 121783 : go_assert(&*p == this->field_);
20696 : :
20697 : 121783 : Gogo* gogo = context->gogo();
20698 : 121783 : Btype* btype = this->type_->get_backend(gogo);
20699 : :
20700 : 121783 : int64_t offset = gogo->backend()->type_field_offset(btype, i);
20701 : 121783 : Type* uptr_type = Type::lookup_integer_type("uintptr");
20702 : 121783 : Expression* ret =
20703 : 121783 : Expression::make_integer_int64(offset, uptr_type,
20704 : : Linemap::predeclared_location());
20705 : 121783 : return ret->get_backend(context);
20706 : : }
20707 : :
20708 : : // Dump ast representation for a struct field offset expression.
20709 : :
20710 : : void
20711 : 0 : Struct_field_offset_expression::do_dump_expression(
20712 : : Ast_dump_context* ast_dump_context) const
20713 : : {
20714 : 0 : ast_dump_context->ostream() << "unsafe.Offsetof(";
20715 : 0 : ast_dump_context->dump_type(this->type_);
20716 : 0 : ast_dump_context->ostream() << '.';
20717 : 0 : ast_dump_context->ostream() <<
20718 : 0 : Gogo::message_name(this->field_->field_name());
20719 : 0 : ast_dump_context->ostream() << ")";
20720 : 0 : }
20721 : :
20722 : : // Make an expression for a struct field offset.
20723 : :
20724 : : Expression*
20725 : 188496 : Expression::make_struct_field_offset(Struct_type* type,
20726 : : const Struct_field* field)
20727 : : {
20728 : 188496 : return new Struct_field_offset_expression(type, field);
20729 : : }
20730 : :
20731 : : // An expression which evaluates to the address of an unnamed label.
20732 : :
20733 : : class Label_addr_expression : public Expression
20734 : : {
20735 : : public:
20736 : 8840 : Label_addr_expression(Label* label, Location location)
20737 : 8840 : : Expression(EXPRESSION_LABEL_ADDR, location),
20738 : 0 : label_(label)
20739 : : { }
20740 : :
20741 : : protected:
20742 : : Type*
20743 : 61880 : do_type()
20744 : 61880 : { return Type::make_pointer_type(Type::make_void_type()); }
20745 : :
20746 : : void
20747 : 17680 : do_determine_type(Gogo*, const Type_context*)
20748 : 17680 : { }
20749 : :
20750 : : Expression*
20751 : 0 : do_copy()
20752 : 0 : { return new Label_addr_expression(this->label_, this->location()); }
20753 : :
20754 : : Bexpression*
20755 : 8840 : do_get_backend(Translate_context* context)
20756 : 8840 : { return this->label_->get_addr(context, this->location()); }
20757 : :
20758 : : void
20759 : 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
20760 : 0 : { ast_dump_context->ostream() << this->label_->name(); }
20761 : :
20762 : : private:
20763 : : // The label whose address we are taking.
20764 : : Label* label_;
20765 : : };
20766 : :
20767 : : // Make an expression for the address of an unnamed label.
20768 : :
20769 : : Expression*
20770 : 8840 : Expression::make_label_addr(Label* label, Location location)
20771 : : {
20772 : 8840 : return new Label_addr_expression(label, location);
20773 : : }
20774 : :
20775 : : // Class Conditional_expression.
20776 : :
20777 : : // Traversal.
20778 : :
20779 : : int
20780 : 217442 : Conditional_expression::do_traverse(Traverse* traverse)
20781 : : {
20782 : 217442 : if (Expression::traverse(&this->cond_, traverse) == TRAVERSE_EXIT
20783 : 206217 : || Expression::traverse(&this->then_, traverse) == TRAVERSE_EXIT
20784 : 423659 : || Expression::traverse(&this->else_, traverse) == TRAVERSE_EXIT)
20785 : 11225 : return TRAVERSE_EXIT;
20786 : : return TRAVERSE_CONTINUE;
20787 : : }
20788 : :
20789 : : // Return the type of the conditional expression.
20790 : :
20791 : : Type*
20792 : 548757 : Conditional_expression::do_type()
20793 : : {
20794 : 548757 : Type* result_type = Type::make_void_type();
20795 : 548757 : if (Type::are_identical(this->then_->type(), this->else_->type(),
20796 : : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
20797 : : NULL))
20798 : 201266 : result_type = this->then_->type();
20799 : 347491 : else if (this->then_->is_nil_expression()
20800 : 347491 : || this->else_->is_nil_expression())
20801 : 124904 : result_type = (!this->then_->is_nil_expression()
20802 : 124904 : ? this->then_->type()
20803 : 122984 : : this->else_->type());
20804 : 548757 : return result_type;
20805 : : }
20806 : :
20807 : : // Determine type for a conditional expression.
20808 : :
20809 : : void
20810 : 439882 : Conditional_expression::do_determine_type(Gogo* gogo,
20811 : : const Type_context* context)
20812 : : {
20813 : 439882 : this->cond_->determine_type_no_context(gogo);
20814 : 439882 : this->then_->determine_type(gogo, context);
20815 : 439882 : this->else_->determine_type(gogo, context);
20816 : 439882 : }
20817 : :
20818 : : // Get the backend representation of a conditional expression.
20819 : :
20820 : : Bexpression*
20821 : 380064 : Conditional_expression::do_get_backend(Translate_context* context)
20822 : : {
20823 : 380064 : Gogo* gogo = context->gogo();
20824 : 380064 : Btype* result_btype = this->type()->get_backend(gogo);
20825 : 380064 : Bexpression* cond = this->cond_->get_backend(context);
20826 : 380064 : Bexpression* then = this->then_->get_backend(context);
20827 : 380064 : Bexpression* belse = this->else_->get_backend(context);
20828 : 380064 : Bfunction* bfn = context->function()->func_value()->get_decl();
20829 : 380064 : return gogo->backend()->conditional_expression(bfn, result_btype, cond, then,
20830 : 380064 : belse, this->location());
20831 : : }
20832 : :
20833 : : // Dump ast representation of a conditional expression.
20834 : :
20835 : : void
20836 : 0 : Conditional_expression::do_dump_expression(
20837 : : Ast_dump_context* ast_dump_context) const
20838 : : {
20839 : 0 : ast_dump_context->ostream() << "(";
20840 : 0 : ast_dump_context->dump_expression(this->cond_);
20841 : 0 : ast_dump_context->ostream() << " ? ";
20842 : 0 : ast_dump_context->dump_expression(this->then_);
20843 : 0 : ast_dump_context->ostream() << " : ";
20844 : 0 : ast_dump_context->dump_expression(this->else_);
20845 : 0 : ast_dump_context->ostream() << ") ";
20846 : 0 : }
20847 : :
20848 : : // Make a conditional expression.
20849 : :
20850 : : Expression*
20851 : 381973 : Expression::make_conditional(Expression* cond, Expression* then,
20852 : : Expression* else_expr, Location location)
20853 : : {
20854 : 381973 : return new Conditional_expression(cond, then, else_expr, location);
20855 : : }
20856 : :
20857 : : // Class Compound_expression.
20858 : :
20859 : : // Traversal.
20860 : :
20861 : : int
20862 : 14468 : Compound_expression::do_traverse(Traverse* traverse)
20863 : : {
20864 : 14468 : if (Expression::traverse(&this->init_, traverse) == TRAVERSE_EXIT
20865 : 14468 : || Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT)
20866 : 0 : return TRAVERSE_EXIT;
20867 : : return TRAVERSE_CONTINUE;
20868 : : }
20869 : :
20870 : : // Return the type of the compound expression.
20871 : :
20872 : : Type*
20873 : 14131 : Compound_expression::do_type()
20874 : : {
20875 : 14131 : return this->expr_->type();
20876 : : }
20877 : :
20878 : : // Determine type for a compound expression.
20879 : :
20880 : : void
20881 : 103569 : Compound_expression::do_determine_type(Gogo* gogo, const Type_context* context)
20882 : : {
20883 : 103569 : this->init_->determine_type_no_context(gogo);
20884 : 103569 : this->expr_->determine_type(gogo, context);
20885 : 103569 : }
20886 : :
20887 : : // Get the backend representation of a compound expression.
20888 : :
20889 : : Bexpression*
20890 : 100032 : Compound_expression::do_get_backend(Translate_context* context)
20891 : : {
20892 : 100032 : Gogo* gogo = context->gogo();
20893 : 100032 : Bexpression* binit = this->init_->get_backend(context);
20894 : 100032 : Bfunction* bfunction = context->function()->func_value()->get_decl();
20895 : 100032 : Bstatement* init_stmt = gogo->backend()->expression_statement(bfunction,
20896 : : binit);
20897 : 100032 : Bexpression* bexpr = this->expr_->get_backend(context);
20898 : 100032 : return gogo->backend()->compound_expression(init_stmt, bexpr,
20899 : 100032 : this->location());
20900 : : }
20901 : :
20902 : : // Dump ast representation of a conditional expression.
20903 : :
20904 : : void
20905 : 0 : Compound_expression::do_dump_expression(
20906 : : Ast_dump_context* ast_dump_context) const
20907 : : {
20908 : 0 : ast_dump_context->ostream() << "(";
20909 : 0 : ast_dump_context->dump_expression(this->init_);
20910 : 0 : ast_dump_context->ostream() << ",";
20911 : 0 : ast_dump_context->dump_expression(this->expr_);
20912 : 0 : ast_dump_context->ostream() << ") ";
20913 : 0 : }
20914 : :
20915 : : // Make a compound expression.
20916 : :
20917 : : Expression*
20918 : 100033 : Expression::make_compound(Expression* init, Expression* expr, Location location)
20919 : : {
20920 : 100033 : return new Compound_expression(init, expr, location);
20921 : : }
20922 : :
20923 : : // Class Backend_expression.
20924 : :
20925 : : int
20926 : 0 : Backend_expression::do_traverse(Traverse*)
20927 : : {
20928 : 0 : return TRAVERSE_CONTINUE;
20929 : : }
20930 : :
20931 : : Expression*
20932 : 0 : Backend_expression::do_copy()
20933 : : {
20934 : 0 : return new Backend_expression(this->bexpr_, this->type_->copy_expressions(),
20935 : 0 : this->location());
20936 : : }
20937 : :
20938 : : void
20939 : 0 : Backend_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
20940 : : {
20941 : 0 : ast_dump_context->ostream() << "backend_expression<";
20942 : 0 : ast_dump_context->dump_type(this->type_);
20943 : 0 : ast_dump_context->ostream() << ">";
20944 : 0 : }
20945 : :
20946 : : Expression*
20947 : 769233 : Expression::make_backend(Bexpression* bexpr, Type* type, Location location)
20948 : : {
20949 : 769233 : return new Backend_expression(bexpr, type, location);
20950 : : }
20951 : :
20952 : : // Import an expression. This comes at the end in order to see the
20953 : : // various class definitions.
20954 : :
20955 : : Expression*
20956 : 1124009 : Expression::import_expression(Import_expression* imp, Location loc)
20957 : : {
20958 : 1124009 : Expression* expr = Expression::import_expression_without_suffix(imp, loc);
20959 : 1145930 : while (true)
20960 : : {
20961 : 1145930 : if (imp->match_c_string("("))
20962 : : {
20963 : 18194 : imp->advance(1);
20964 : 18194 : Expression_list* args = new Expression_list();
20965 : 18194 : bool is_varargs = false;
20966 : 26443 : while (!imp->match_c_string(")"))
20967 : : {
20968 : 23597 : Expression* arg = Expression::import_expression(imp, loc);
20969 : 23597 : if (arg->is_error_expression())
20970 : : return arg;
20971 : 23597 : args->push_back(arg);
20972 : 23597 : if (imp->match_c_string(")"))
20973 : : break;
20974 : 8571 : else if (imp->match_c_string("...)"))
20975 : : {
20976 : 322 : imp->advance(3);
20977 : 322 : is_varargs = true;
20978 : 322 : break;
20979 : : }
20980 : 8249 : imp->require_c_string(", ");
20981 : : }
20982 : 18194 : imp->require_c_string(")");
20983 : 18194 : expr = Expression::make_call(expr, args, is_varargs, loc);
20984 : 18194 : expr->call_expression()->set_varargs_are_lowered();
20985 : : }
20986 : 1127736 : else if (imp->match_c_string("["))
20987 : : {
20988 : 3727 : imp->advance(1);
20989 : 3727 : Expression* start = Expression::import_expression(imp, loc);
20990 : 3727 : Expression* end = NULL;
20991 : 3727 : Expression* cap = NULL;
20992 : 3727 : if (imp->match_c_string(":"))
20993 : : {
20994 : 2119 : imp->advance(1);
20995 : 2119 : int c = imp->peek_char();
20996 : 2119 : if (c == ':' || c == ']')
20997 : 898 : end = Expression::make_nil(loc);
20998 : : else
20999 : 1221 : end = Expression::import_expression(imp, loc);
21000 : 2119 : if (imp->match_c_string(":"))
21001 : : {
21002 : 0 : imp->advance(1);
21003 : 0 : cap = Expression::import_expression(imp, loc);
21004 : : }
21005 : : }
21006 : 3727 : imp->require_c_string("]");
21007 : 3727 : expr = Expression::make_index(expr, start, end, cap, loc);
21008 : : }
21009 : : else
21010 : : break;
21011 : : }
21012 : :
21013 : : return expr;
21014 : : }
21015 : :
21016 : : // Import an expression without considering a suffix (function
21017 : : // arguments, index operations, etc.).
21018 : :
21019 : : Expression*
21020 : 1124009 : Expression::import_expression_without_suffix(Import_expression* imp,
21021 : : Location loc)
21022 : : {
21023 : 1124009 : int c = imp->peek_char();
21024 : 1124009 : if (c == '+' || c == '-' || c == '!' || c == '^' || c == '&' || c == '*')
21025 : 9633 : return Unary_expression::do_import(imp, loc);
21026 : : else if (c == '(')
21027 : 22026 : return Binary_expression::do_import(imp, loc);
21028 : 1092350 : else if (imp->match_c_string("$true")
21029 : 1090980 : || imp->match_c_string("$false")
21030 : 2181841 : || (imp->version() < EXPORT_FORMAT_V3
21031 : 0 : && (imp->match_c_string("true")
21032 : 0 : || imp->match_c_string("false"))))
21033 : 2859 : return Boolean_expression::do_import(imp, loc);
21034 : 1089491 : else if (c == '"')
21035 : 31862 : return String_expression::do_import(imp, loc);
21036 : 1057629 : else if (c == '-' || (c >= '0' && c <= '9'))
21037 : : {
21038 : : // This handles integers, floats and complex constants.
21039 : 962656 : return Integer_expression::do_import(imp, loc);
21040 : : }
21041 : 94973 : else if (imp->match_c_string("<-"))
21042 : 0 : return Receive_expression::do_import(imp, loc);
21043 : 94973 : else if (imp->match_c_string("$nil")
21044 : 94973 : || (imp->version() < EXPORT_FORMAT_V3
21045 : 0 : && imp->match_c_string("nil")))
21046 : 621 : return Nil_expression::do_import(imp, loc);
21047 : 94352 : else if (imp->match_c_string("$convert")
21048 : 94352 : || (imp->version() < EXPORT_FORMAT_V3
21049 : 0 : && imp->match_c_string("convert")))
21050 : 18058 : return Type_conversion_expression::do_import(imp, loc);
21051 : :
21052 : 76294 : Import_function_body* ifb = imp->ifb();
21053 : 76294 : if (ifb == NULL)
21054 : : {
21055 : 0 : go_error_at(imp->location(), "import error: expected expression");
21056 : 0 : return Expression::make_error(loc);
21057 : : }
21058 : 76294 : if (ifb->saw_error())
21059 : 0 : return Expression::make_error(loc);
21060 : :
21061 : 76294 : if (ifb->match_c_string("$t"))
21062 : 3923 : return Temporary_reference_expression::do_import(ifb, loc);
21063 : :
21064 : 72371 : return Expression::import_identifier(ifb, loc);
21065 : : }
21066 : :
21067 : : // Import an identifier in an expression. This is a reference to a
21068 : : // variable or function.
21069 : :
21070 : : Expression*
21071 : 72371 : Expression::import_identifier(Import_function_body* ifb, Location loc)
21072 : : {
21073 : 72371 : std::string id;
21074 : 72371 : Package* pkg;
21075 : 72371 : bool is_exported;
21076 : 72371 : if (!Import::read_qualified_identifier(ifb, &id, &pkg, &is_exported))
21077 : : {
21078 : 0 : if (!ifb->saw_error())
21079 : 0 : go_error_at(ifb->location(),
21080 : : "import error for %qs: bad qualified identifier at %lu",
21081 : 0 : ifb->name().c_str(),
21082 : 0 : static_cast<unsigned long>(ifb->off()));
21083 : 0 : ifb->set_saw_error();
21084 : 0 : return Expression::make_error(loc);
21085 : : }
21086 : :
21087 : 72371 : Named_object* no = NULL;
21088 : 72371 : if (pkg == NULL && is_exported)
21089 : 63256 : no = ifb->block()->bindings()->lookup(id);
21090 : 63256 : if (no == NULL)
21091 : : {
21092 : 20060 : const Package* ipkg = pkg;
21093 : 20060 : if (ipkg == NULL)
21094 : 16186 : ipkg = ifb->function()->package();
21095 : 20060 : if (!is_exported)
21096 : 5631 : id = '.' + ipkg->pkgpath() + '.' + id;
21097 : 20060 : no = ipkg->bindings()->lookup(id);
21098 : : }
21099 : 20060 : if (no == NULL)
21100 : 6503 : no = ifb->gogo()->lookup_global(id.c_str());
21101 : :
21102 : 6503 : if (no == NULL)
21103 : : {
21104 : 0 : if (!ifb->saw_error())
21105 : 0 : go_error_at(ifb->location(),
21106 : : "import error for %qs: lookup of %qs failed",
21107 : 0 : ifb->name().c_str(), id.c_str());
21108 : 0 : ifb->set_saw_error();
21109 : 0 : return Expression::make_error(loc);
21110 : : }
21111 : :
21112 : 72371 : if (no->is_variable() || no->is_result_variable())
21113 : 54239 : return Expression::make_var_reference(no, loc);
21114 : 18132 : else if (no->is_function() || no->is_function_declaration())
21115 : 18132 : return Expression::make_func_reference(no, NULL, loc);
21116 : : else
21117 : : {
21118 : 0 : if (!ifb->saw_error())
21119 : 0 : go_error_at(ifb->location(),
21120 : : ("import error for %qs: "
21121 : : "unexpected type of identifier %qs (%d)"),
21122 : 0 : ifb->name().c_str(),
21123 : 0 : id.c_str(), no->classification());
21124 : 0 : ifb->set_saw_error();
21125 : 0 : return Expression::make_error(loc);
21126 : : }
21127 : 72371 : }
21128 : :
21129 : : // Class Expression_list.
21130 : :
21131 : : // Traverse the list.
21132 : :
21133 : : int
21134 : 22943284 : Expression_list::traverse(Traverse* traverse)
21135 : : {
21136 : 83403428 : for (Expression_list::iterator p = this->begin();
21137 : 83403428 : p != this->end();
21138 : 60460144 : ++p)
21139 : : {
21140 : 60664984 : if (*p != NULL)
21141 : : {
21142 : 60375981 : if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
21143 : 22943284 : return TRAVERSE_EXIT;
21144 : : }
21145 : : }
21146 : : return TRAVERSE_CONTINUE;
21147 : : }
21148 : :
21149 : : // Copy the list.
21150 : :
21151 : : Expression_list*
21152 : 11 : Expression_list::copy()
21153 : : {
21154 : 11 : Expression_list* ret = new Expression_list();
21155 : 22 : for (Expression_list::iterator p = this->begin();
21156 : 22 : p != this->end();
21157 : 11 : ++p)
21158 : : {
21159 : 11 : if (*p == NULL)
21160 : 0 : ret->push_back(NULL);
21161 : : else
21162 : 11 : ret->push_back((*p)->copy());
21163 : : }
21164 : 11 : return ret;
21165 : : }
21166 : :
21167 : : // Return whether an expression list has an error expression.
21168 : :
21169 : : bool
21170 : 0 : Expression_list::contains_error() const
21171 : : {
21172 : 0 : for (Expression_list::const_iterator p = this->begin();
21173 : 0 : p != this->end();
21174 : 0 : ++p)
21175 : 0 : if (*p != NULL && (*p)->is_error_expression())
21176 : 0 : return true;
21177 : : return false;
21178 : : }
21179 : :
21180 : : // Class Numeric_constant.
21181 : :
21182 : : // Destructor.
21183 : :
21184 : 41257781 : Numeric_constant::~Numeric_constant()
21185 : : {
21186 : 41257781 : this->clear();
21187 : 41257781 : }
21188 : :
21189 : : // Copy constructor.
21190 : :
21191 : 0 : Numeric_constant::Numeric_constant(const Numeric_constant& a)
21192 : 0 : : classification_(a.classification_), type_(a.type_)
21193 : : {
21194 : 0 : switch (a.classification_)
21195 : : {
21196 : : case NC_INVALID:
21197 : : break;
21198 : 0 : case NC_INT:
21199 : 0 : case NC_RUNE:
21200 : 0 : mpz_init_set(this->u_.int_val, a.u_.int_val);
21201 : 0 : break;
21202 : 0 : case NC_FLOAT:
21203 : 0 : mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
21204 : 0 : break;
21205 : 0 : case NC_COMPLEX:
21206 : 0 : mpc_init2(this->u_.complex_val, mpc_precision);
21207 : 0 : mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
21208 : 0 : break;
21209 : 0 : default:
21210 : 0 : go_unreachable();
21211 : : }
21212 : 0 : }
21213 : :
21214 : : // Assignment operator.
21215 : :
21216 : : Numeric_constant&
21217 : 1029 : Numeric_constant::operator=(const Numeric_constant& a)
21218 : : {
21219 : 1029 : this->clear();
21220 : 1029 : this->classification_ = a.classification_;
21221 : 1029 : this->type_ = a.type_;
21222 : 1029 : switch (a.classification_)
21223 : : {
21224 : : case NC_INVALID:
21225 : : break;
21226 : 868 : case NC_INT:
21227 : 868 : case NC_RUNE:
21228 : 868 : mpz_init_set(this->u_.int_val, a.u_.int_val);
21229 : 868 : break;
21230 : 161 : case NC_FLOAT:
21231 : 161 : mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
21232 : 161 : break;
21233 : 0 : case NC_COMPLEX:
21234 : 0 : mpc_init2(this->u_.complex_val, mpc_precision);
21235 : 0 : mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
21236 : 0 : break;
21237 : 0 : default:
21238 : 0 : go_unreachable();
21239 : : }
21240 : 1029 : return *this;
21241 : : }
21242 : :
21243 : : // Check equality with another numeric constant.
21244 : :
21245 : : bool
21246 : 32 : Numeric_constant::equals(const Numeric_constant& a) const
21247 : : {
21248 : 32 : if (this->classification_ != a.classification_)
21249 : : return false;
21250 : :
21251 : 32 : if (this->type_ != NULL && a.type_ != NULL
21252 : 64 : && !Type::are_identical(this->type_, a.type_,
21253 : : Type::COMPARE_ALIASES, NULL))
21254 : : return false;
21255 : :
21256 : 32 : switch (a.classification_)
21257 : : {
21258 : : case NC_INVALID:
21259 : : break;
21260 : 30 : case NC_INT:
21261 : 30 : case NC_RUNE:
21262 : 30 : return mpz_cmp(this->u_.int_val, a.u_.int_val) == 0;
21263 : 0 : case NC_FLOAT:
21264 : 0 : return mpfr_cmp(this->u_.float_val, a.u_.float_val) == 0;
21265 : 2 : case NC_COMPLEX:
21266 : 2 : return mpc_cmp(this->u_.complex_val, a.u_.complex_val) == 0;
21267 : 0 : default:
21268 : 0 : go_unreachable();
21269 : : }
21270 : : return false;
21271 : : }
21272 : :
21273 : : // Clear the contents.
21274 : :
21275 : : void
21276 : 76810781 : Numeric_constant::clear()
21277 : : {
21278 : 76810781 : switch (this->classification_)
21279 : : {
21280 : : case NC_INVALID:
21281 : : break;
21282 : 35429794 : case NC_INT:
21283 : 35429794 : case NC_RUNE:
21284 : 35429794 : mpz_clear(this->u_.int_val);
21285 : 35429794 : break;
21286 : 112146 : case NC_FLOAT:
21287 : 112146 : mpfr_clear(this->u_.float_val);
21288 : 112146 : break;
21289 : 10069 : case NC_COMPLEX:
21290 : 10069 : mpc_clear(this->u_.complex_val);
21291 : 10069 : break;
21292 : 0 : default:
21293 : 0 : go_unreachable();
21294 : : }
21295 : 76810781 : this->classification_ = NC_INVALID;
21296 : 76810781 : }
21297 : :
21298 : : // Set to an unsigned long value.
21299 : :
21300 : : void
21301 : 67214 : Numeric_constant::set_unsigned_long(Type* type, unsigned long val)
21302 : : {
21303 : 67214 : this->clear();
21304 : 67214 : this->classification_ = NC_INT;
21305 : 67214 : this->type_ = type;
21306 : 67214 : mpz_init_set_ui(this->u_.int_val, val);
21307 : 67214 : }
21308 : :
21309 : : // Set to an integer value.
21310 : :
21311 : : void
21312 : 35268456 : Numeric_constant::set_int(Type* type, const mpz_t val)
21313 : : {
21314 : 35268456 : this->clear();
21315 : 35268456 : this->classification_ = NC_INT;
21316 : 35268456 : this->type_ = type;
21317 : 35268456 : mpz_init_set(this->u_.int_val, val);
21318 : 35268456 : }
21319 : :
21320 : : // Set to a rune value.
21321 : :
21322 : : void
21323 : 93735 : Numeric_constant::set_rune(Type* type, const mpz_t val)
21324 : : {
21325 : 93735 : this->clear();
21326 : 93735 : this->classification_ = NC_RUNE;
21327 : 93735 : this->type_ = type;
21328 : 93735 : mpz_init_set(this->u_.int_val, val);
21329 : 93735 : }
21330 : :
21331 : : // Set to a floating point value.
21332 : :
21333 : : void
21334 : 112486 : Numeric_constant::set_float(Type* type, const mpfr_t val)
21335 : : {
21336 : 112486 : this->clear();
21337 : 112486 : this->classification_ = NC_FLOAT;
21338 : 112486 : this->type_ = type;
21339 : :
21340 : : // Numeric constants do not have negative zero values, so remove
21341 : : // them here. They also don't have infinity or NaN values, but we
21342 : : // should never see them here.
21343 : 112486 : int bits = 0;
21344 : 112486 : if (type != NULL
21345 : 79463 : && type->float_type() != NULL
21346 : 191949 : && !type->float_type()->is_abstract())
21347 : 118728 : bits = type->float_type()->bits();
21348 : 112486 : if (Numeric_constant::is_float_neg_zero(val, bits))
21349 : 29 : mpfr_init_set_ui(this->u_.float_val, 0, MPFR_RNDN);
21350 : : else
21351 : 112457 : mpfr_init_set(this->u_.float_val, val, MPFR_RNDN);
21352 : 112486 : }
21353 : :
21354 : : // Set to a complex value.
21355 : :
21356 : : void
21357 : 10080 : Numeric_constant::set_complex(Type* type, const mpc_t val)
21358 : : {
21359 : 10080 : this->clear();
21360 : 10080 : this->classification_ = NC_COMPLEX;
21361 : 10080 : this->type_ = type;
21362 : :
21363 : : // Avoid negative zero as in set_float.
21364 : 10080 : int bits = 0;
21365 : 10080 : if (type != NULL
21366 : 7143 : && type->complex_type() != NULL
21367 : 17223 : && !type->complex_type()->is_abstract())
21368 : 12102 : bits = type->complex_type()->bits() / 2;
21369 : :
21370 : 10080 : mpfr_t real;
21371 : 10080 : mpfr_init_set(real, mpc_realref(val), MPFR_RNDN);
21372 : 10080 : if (Numeric_constant::is_float_neg_zero(real, bits))
21373 : 3 : mpfr_set_ui(real, 0, MPFR_RNDN);
21374 : :
21375 : 10080 : mpfr_t imag;
21376 : 10080 : mpfr_init_set(imag, mpc_imagref(val), MPFR_RNDN);
21377 : 10080 : if (Numeric_constant::is_float_neg_zero(imag, bits))
21378 : 0 : mpfr_set_ui(imag, 0, MPFR_RNDN);
21379 : :
21380 : 10080 : mpc_init2(this->u_.complex_val, mpc_precision);
21381 : 10080 : mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
21382 : :
21383 : 10080 : mpfr_clear(real);
21384 : 10080 : mpfr_clear(imag);
21385 : 10080 : }
21386 : :
21387 : : // Return whether VAL, at a precision of BITS, is a negative zero.
21388 : : // BITS may be zero in which case it is ignored.
21389 : :
21390 : : bool
21391 : 132646 : Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits)
21392 : : {
21393 : 132646 : if (!mpfr_signbit(val))
21394 : : return false;
21395 : 21171 : if (mpfr_zero_p(val))
21396 : : return true;
21397 : 21141 : mpfr_exp_t min_exp;
21398 : 21141 : switch (bits)
21399 : : {
21400 : : case 0:
21401 : : return false;
21402 : : case 32:
21403 : : // In a denormalized float32 the exponent is -126, and there are
21404 : : // 24 bits of which at least the last must be 1, so the smallest
21405 : : // representable non-zero exponent is -126 - (24 - 1) == -149.
21406 : : min_exp = -149;
21407 : : break;
21408 : 11794 : case 64:
21409 : : // Minimum exponent is -1022, there are 53 bits.
21410 : 11794 : min_exp = -1074;
21411 : 11794 : break;
21412 : 0 : default:
21413 : 0 : go_unreachable();
21414 : : }
21415 : 12000 : return mpfr_get_exp(val) < min_exp;
21416 : : }
21417 : :
21418 : : // Get an int value.
21419 : :
21420 : : void
21421 : 76700 : Numeric_constant::get_int(mpz_t* val) const
21422 : : {
21423 : 76700 : go_assert(this->is_int());
21424 : 76700 : mpz_init_set(*val, this->u_.int_val);
21425 : 76700 : }
21426 : :
21427 : : // Get a rune value.
21428 : :
21429 : : void
21430 : 0 : Numeric_constant::get_rune(mpz_t* val) const
21431 : : {
21432 : 0 : go_assert(this->is_rune());
21433 : 0 : mpz_init_set(*val, this->u_.int_val);
21434 : 0 : }
21435 : :
21436 : : // Get a floating point value.
21437 : :
21438 : : void
21439 : 4051 : Numeric_constant::get_float(mpfr_t* val) const
21440 : : {
21441 : 4051 : go_assert(this->is_float());
21442 : 4051 : mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
21443 : 4051 : }
21444 : :
21445 : : // Get a complex value.
21446 : :
21447 : : void
21448 : 10 : Numeric_constant::get_complex(mpc_t* val) const
21449 : : {
21450 : 10 : go_assert(this->is_complex());
21451 : 10 : mpc_init2(*val, mpc_precision);
21452 : 10 : mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
21453 : 10 : }
21454 : :
21455 : : // Express value as unsigned long if possible.
21456 : :
21457 : : Numeric_constant::To_unsigned_long
21458 : 772327 : Numeric_constant::to_unsigned_long(unsigned long* val) const
21459 : : {
21460 : 772327 : switch (this->classification_)
21461 : : {
21462 : 772030 : case NC_INT:
21463 : 772030 : case NC_RUNE:
21464 : 772030 : return this->mpz_to_unsigned_long(this->u_.int_val, val);
21465 : 284 : case NC_FLOAT:
21466 : 284 : return this->mpfr_to_unsigned_long(this->u_.float_val, val);
21467 : 13 : case NC_COMPLEX:
21468 : 13 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21469 : : return NC_UL_NOTINT;
21470 : 12 : return this->mpfr_to_unsigned_long(mpc_realref(this->u_.complex_val),
21471 : 12 : val);
21472 : 0 : default:
21473 : 0 : go_unreachable();
21474 : : }
21475 : : }
21476 : :
21477 : : // Express integer value as unsigned long if possible.
21478 : :
21479 : : Numeric_constant::To_unsigned_long
21480 : 772324 : Numeric_constant::mpz_to_unsigned_long(const mpz_t ival,
21481 : : unsigned long *val) const
21482 : : {
21483 : 772324 : if (mpz_sgn(ival) < 0)
21484 : : return NC_UL_NEGATIVE;
21485 : 771897 : unsigned long ui = mpz_get_ui(ival);
21486 : 771897 : if (mpz_cmp_ui(ival, ui) != 0)
21487 : : return NC_UL_BIG;
21488 : 771886 : *val = ui;
21489 : 771886 : return NC_UL_VALID;
21490 : : }
21491 : :
21492 : : // Express floating point value as unsigned long if possible.
21493 : :
21494 : : Numeric_constant::To_unsigned_long
21495 : 296 : Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
21496 : : unsigned long *val) const
21497 : : {
21498 : 296 : if (!mpfr_integer_p(fval))
21499 : : return NC_UL_NOTINT;
21500 : 294 : mpz_t ival;
21501 : 294 : mpz_init(ival);
21502 : 294 : mpfr_get_z(ival, fval, MPFR_RNDN);
21503 : 294 : To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
21504 : 294 : mpz_clear(ival);
21505 : 294 : return ret;
21506 : : }
21507 : :
21508 : : // Express value as memory size if possible.
21509 : :
21510 : : bool
21511 : 194245 : Numeric_constant::to_memory_size(int64_t* val) const
21512 : : {
21513 : 194245 : switch (this->classification_)
21514 : : {
21515 : 194240 : case NC_INT:
21516 : 194240 : case NC_RUNE:
21517 : 194240 : return this->mpz_to_memory_size(this->u_.int_val, val);
21518 : 5 : case NC_FLOAT:
21519 : 5 : return this->mpfr_to_memory_size(this->u_.float_val, val);
21520 : 0 : case NC_COMPLEX:
21521 : 0 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21522 : : return false;
21523 : 0 : return this->mpfr_to_memory_size(mpc_realref(this->u_.complex_val), val);
21524 : 0 : default:
21525 : 0 : go_unreachable();
21526 : : }
21527 : : }
21528 : :
21529 : : // Express integer as memory size if possible.
21530 : :
21531 : : bool
21532 : 194245 : Numeric_constant::mpz_to_memory_size(const mpz_t ival, int64_t* val) const
21533 : : {
21534 : 194245 : if (mpz_sgn(ival) < 0)
21535 : : return false;
21536 : 194245 : if (mpz_fits_slong_p(ival))
21537 : : {
21538 : 194245 : *val = static_cast<int64_t>(mpz_get_si(ival));
21539 : 194245 : return true;
21540 : : }
21541 : :
21542 : : // Test >= 64, not > 64, because an int64_t can hold 63 bits of a
21543 : : // positive value.
21544 : 0 : if (mpz_sizeinbase(ival, 2) >= 64)
21545 : : return false;
21546 : :
21547 : 0 : mpz_t q, r;
21548 : 0 : mpz_init(q);
21549 : 0 : mpz_init(r);
21550 : 0 : mpz_tdiv_q_2exp(q, ival, 32);
21551 : 0 : mpz_tdiv_r_2exp(r, ival, 32);
21552 : 0 : go_assert(mpz_fits_ulong_p(q) && mpz_fits_ulong_p(r));
21553 : 0 : *val = ((static_cast<int64_t>(mpz_get_ui(q)) << 32)
21554 : 0 : + static_cast<int64_t>(mpz_get_ui(r)));
21555 : 0 : mpz_clear(r);
21556 : 0 : mpz_clear(q);
21557 : 0 : return true;
21558 : : }
21559 : :
21560 : : // Express floating point value as memory size if possible.
21561 : :
21562 : : bool
21563 : 5 : Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const
21564 : : {
21565 : 5 : if (!mpfr_integer_p(fval))
21566 : : return false;
21567 : 5 : mpz_t ival;
21568 : 5 : mpz_init(ival);
21569 : 5 : mpfr_get_z(ival, fval, MPFR_RNDN);
21570 : 5 : bool ret = this->mpz_to_memory_size(ival, val);
21571 : 5 : mpz_clear(ival);
21572 : 5 : return ret;
21573 : : }
21574 : :
21575 : : // Convert value to integer if possible.
21576 : :
21577 : : bool
21578 : 31437768 : Numeric_constant::to_int(mpz_t* val) const
21579 : : {
21580 : 31437768 : switch (this->classification_)
21581 : : {
21582 : 31433601 : case NC_INT:
21583 : 31433601 : case NC_RUNE:
21584 : 31433601 : mpz_init_set(*val, this->u_.int_val);
21585 : 31433601 : return true;
21586 : 4128 : case NC_FLOAT:
21587 : 4128 : if (!mpfr_integer_p(this->u_.float_val))
21588 : : return false;
21589 : 4128 : mpz_init(*val);
21590 : 4128 : mpfr_get_z(*val, this->u_.float_val, MPFR_RNDN);
21591 : 4128 : return true;
21592 : 39 : case NC_COMPLEX:
21593 : 39 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))
21594 : 39 : || !mpfr_integer_p(mpc_realref(this->u_.complex_val)))
21595 : 0 : return false;
21596 : 39 : mpz_init(*val);
21597 : 39 : mpfr_get_z(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21598 : 39 : return true;
21599 : 0 : default:
21600 : 0 : go_unreachable();
21601 : : }
21602 : : }
21603 : :
21604 : : // Convert value to floating point if possible.
21605 : :
21606 : : bool
21607 : 40198 : Numeric_constant::to_float(mpfr_t* val) const
21608 : : {
21609 : 40198 : switch (this->classification_)
21610 : : {
21611 : 19927 : case NC_INT:
21612 : 19927 : case NC_RUNE:
21613 : 19927 : mpfr_init_set_z(*val, this->u_.int_val, MPFR_RNDN);
21614 : 19927 : return true;
21615 : 20267 : case NC_FLOAT:
21616 : 20267 : mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
21617 : 20267 : return true;
21618 : 4 : case NC_COMPLEX:
21619 : 4 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21620 : : return false;
21621 : 4 : mpfr_init_set(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21622 : 4 : return true;
21623 : 0 : default:
21624 : 0 : go_unreachable();
21625 : : }
21626 : : }
21627 : :
21628 : : // Convert value to complex.
21629 : :
21630 : : bool
21631 : 5034 : Numeric_constant::to_complex(mpc_t* val) const
21632 : : {
21633 : 5034 : mpc_init2(*val, mpc_precision);
21634 : 5034 : switch (this->classification_)
21635 : : {
21636 : 801 : case NC_INT:
21637 : 801 : case NC_RUNE:
21638 : 801 : mpc_set_z(*val, this->u_.int_val, MPC_RNDNN);
21639 : 801 : return true;
21640 : 600 : case NC_FLOAT:
21641 : 600 : mpc_set_fr(*val, this->u_.float_val, MPC_RNDNN);
21642 : 600 : return true;
21643 : 3633 : case NC_COMPLEX:
21644 : 3633 : mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
21645 : 3633 : return true;
21646 : 0 : default:
21647 : 0 : go_unreachable();
21648 : : }
21649 : : }
21650 : :
21651 : : // Get the type.
21652 : :
21653 : : Type*
21654 : 6991426 : Numeric_constant::type() const
21655 : : {
21656 : 6991426 : if (this->type_ != NULL)
21657 : : return this->type_;
21658 : 28948 : switch (this->classification_)
21659 : : {
21660 : 28948 : case NC_INT:
21661 : 28948 : return Type::make_abstract_integer_type();
21662 : 0 : case NC_RUNE:
21663 : 0 : return Type::make_abstract_character_type();
21664 : 0 : case NC_FLOAT:
21665 : 0 : return Type::make_abstract_float_type();
21666 : 0 : case NC_COMPLEX:
21667 : 0 : return Type::make_abstract_complex_type();
21668 : 0 : default:
21669 : 0 : go_unreachable();
21670 : : }
21671 : : }
21672 : :
21673 : : // If the constant can be expressed in TYPE, then set the type of the
21674 : : // constant to TYPE and return true. Otherwise return false, and, if
21675 : : // ISSUE_ERROR is true, report an appropriate error message.
21676 : :
21677 : : bool
21678 : 4143819 : Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
21679 : : {
21680 : 4143819 : bool ret;
21681 : 4143819 : if (type == NULL || type->is_error())
21682 : : ret = true;
21683 : 4143819 : else if (type->integer_type() != NULL)
21684 : 8152620 : ret = this->check_int_type(type->integer_type(), issue_error, loc);
21685 : 67509 : else if (type->float_type() != NULL)
21686 : 121476 : ret = this->check_float_type(type->float_type(), issue_error, loc);
21687 : 6771 : else if (type->complex_type() != NULL)
21688 : 13542 : ret = this->check_complex_type(type->complex_type(), issue_error, loc);
21689 : : else
21690 : : {
21691 : 0 : ret = false;
21692 : 0 : if (issue_error)
21693 : 0 : go_assert(saw_errors());
21694 : : }
21695 : 4143819 : if (ret)
21696 : 4141957 : this->type_ = type;
21697 : 4143819 : return ret;
21698 : : }
21699 : :
21700 : : // Check whether the constant can be expressed in an integer type.
21701 : :
21702 : : bool
21703 : 4076310 : Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
21704 : : Location location)
21705 : : {
21706 : 4076310 : mpz_t val;
21707 : 4076310 : switch (this->classification_)
21708 : : {
21709 : 4070818 : case NC_INT:
21710 : 4070818 : case NC_RUNE:
21711 : 4070818 : mpz_init_set(val, this->u_.int_val);
21712 : 4070818 : break;
21713 : :
21714 : 5443 : case NC_FLOAT:
21715 : 5443 : if (!mpfr_integer_p(this->u_.float_val))
21716 : : {
21717 : 924 : if (issue_error)
21718 : : {
21719 : 489 : go_error_at(location,
21720 : : "floating-point constant truncated to integer");
21721 : 489 : this->set_invalid();
21722 : : }
21723 : 924 : return false;
21724 : : }
21725 : 4519 : mpz_init(val);
21726 : 4519 : mpfr_get_z(val, this->u_.float_val, MPFR_RNDN);
21727 : 4519 : break;
21728 : :
21729 : 49 : case NC_COMPLEX:
21730 : 49 : if (!mpfr_integer_p(mpc_realref(this->u_.complex_val))
21731 : 49 : || !mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21732 : : {
21733 : 11 : if (issue_error)
21734 : : {
21735 : 8 : go_error_at(location, "complex constant truncated to integer");
21736 : 8 : this->set_invalid();
21737 : : }
21738 : 11 : return false;
21739 : : }
21740 : 38 : mpz_init(val);
21741 : 38 : mpfr_get_z(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21742 : 38 : break;
21743 : :
21744 : 0 : default:
21745 : 0 : go_unreachable();
21746 : : }
21747 : :
21748 : 4075375 : bool ret;
21749 : 4075375 : if (type->is_abstract())
21750 : : ret = true;
21751 : : else
21752 : : {
21753 : 2250182 : int bits = mpz_sizeinbase(val, 2);
21754 : 2250182 : if (type->is_unsigned())
21755 : : {
21756 : : // For an unsigned type we can only accept a nonnegative
21757 : : // number, and we must be able to represents at least BITS.
21758 : 967174 : ret = mpz_sgn(val) >= 0 && bits <= type->bits();
21759 : : }
21760 : : else
21761 : : {
21762 : : // For a signed type we need an extra bit to indicate the
21763 : : // sign. We have to handle the most negative integer
21764 : : // specially.
21765 : 1283008 : ret = (bits + 1 <= type->bits()
21766 : 1283008 : || (bits <= type->bits()
21767 : 1756 : && mpz_sgn(val) < 0
21768 : 1752 : && (mpz_scan1(val, 0)
21769 : 1752 : == static_cast<unsigned long>(type->bits() - 1))
21770 : 1752 : && mpz_scan0(val, type->bits()) == ULONG_MAX));
21771 : : }
21772 : : }
21773 : :
21774 : 4075375 : if (!ret && issue_error)
21775 : : {
21776 : 484 : go_error_at(location, "integer constant overflow");
21777 : 484 : this->set_invalid();
21778 : : }
21779 : :
21780 : : return ret;
21781 : : }
21782 : :
21783 : : // Check whether the constant can be expressed in a floating point
21784 : : // type.
21785 : :
21786 : : bool
21787 : 60738 : Numeric_constant::check_float_type(Float_type* type, bool issue_error,
21788 : : Location location)
21789 : : {
21790 : 60738 : mpfr_t val;
21791 : 60738 : switch (this->classification_)
21792 : : {
21793 : 22177 : case NC_INT:
21794 : 22177 : case NC_RUNE:
21795 : 22177 : mpfr_init_set_z(val, this->u_.int_val, MPFR_RNDN);
21796 : 22177 : break;
21797 : :
21798 : 38554 : case NC_FLOAT:
21799 : 38554 : mpfr_init_set(val, this->u_.float_val, MPFR_RNDN);
21800 : 38554 : break;
21801 : :
21802 : 7 : case NC_COMPLEX:
21803 : 7 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21804 : : {
21805 : 2 : if (issue_error)
21806 : : {
21807 : 2 : this->set_invalid();
21808 : 2 : go_error_at(location,
21809 : : "complex constant truncated to floating-point");
21810 : : }
21811 : 2 : return false;
21812 : : }
21813 : 5 : mpfr_init_set(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21814 : 5 : break;
21815 : :
21816 : 0 : default:
21817 : 0 : go_unreachable();
21818 : : }
21819 : :
21820 : 60736 : bool ret;
21821 : 60736 : if (type->is_abstract())
21822 : : ret = true;
21823 : 43297 : else if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
21824 : : {
21825 : : // A NaN or Infinity always fits in the range of the type.
21826 : : ret = true;
21827 : : }
21828 : : else
21829 : : {
21830 : 39455 : mpfr_exp_t exp = mpfr_get_exp(val);
21831 : 39455 : mpfr_exp_t max_exp;
21832 : 39455 : switch (type->bits())
21833 : : {
21834 : : case 32:
21835 : : max_exp = 128;
21836 : : break;
21837 : 30431 : case 64:
21838 : 30431 : max_exp = 1024;
21839 : 30431 : break;
21840 : 0 : default:
21841 : 0 : go_unreachable();
21842 : : }
21843 : :
21844 : 39455 : ret = exp <= max_exp;
21845 : :
21846 : 39455 : if (ret)
21847 : : {
21848 : : // Round the constant to the desired type.
21849 : 39449 : mpfr_t t;
21850 : 39449 : mpfr_init(t);
21851 : 39449 : switch (type->bits())
21852 : : {
21853 : 9021 : case 32:
21854 : 9021 : mpfr_set_prec(t, 24);
21855 : 9021 : break;
21856 : 30428 : case 64:
21857 : 30428 : mpfr_set_prec(t, 53);
21858 : 30428 : break;
21859 : 0 : default:
21860 : 0 : go_unreachable();
21861 : : }
21862 : 39449 : mpfr_set(t, val, MPFR_RNDN);
21863 : 39449 : mpfr_set(val, t, MPFR_RNDN);
21864 : 39449 : mpfr_clear(t);
21865 : :
21866 : 39449 : this->set_float(type, val);
21867 : : }
21868 : : }
21869 : :
21870 : 60736 : mpfr_clear(val);
21871 : :
21872 : 60736 : if (!ret && issue_error)
21873 : : {
21874 : 6 : go_error_at(location, "floating-point constant overflow");
21875 : 6 : this->set_invalid();
21876 : : }
21877 : :
21878 : : return ret;
21879 : : }
21880 : :
21881 : : // Check whether the constant can be expressed in a complex type.
21882 : :
21883 : : bool
21884 : 6771 : Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
21885 : : Location location)
21886 : : {
21887 : 6771 : if (type->is_abstract())
21888 : : return true;
21889 : :
21890 : 1894 : mpfr_exp_t max_exp;
21891 : 1894 : switch (type->bits())
21892 : : {
21893 : : case 64:
21894 : : max_exp = 128;
21895 : : break;
21896 : 1542 : case 128:
21897 : 1542 : max_exp = 1024;
21898 : 1542 : break;
21899 : 0 : default:
21900 : 0 : go_unreachable();
21901 : : }
21902 : :
21903 : 1894 : mpc_t val;
21904 : 1894 : mpc_init2(val, mpc_precision);
21905 : 1894 : switch (this->classification_)
21906 : : {
21907 : 539 : case NC_INT:
21908 : 539 : case NC_RUNE:
21909 : 539 : mpc_set_z(val, this->u_.int_val, MPC_RNDNN);
21910 : 539 : break;
21911 : :
21912 : 100 : case NC_FLOAT:
21913 : 100 : mpc_set_fr(val, this->u_.float_val, MPC_RNDNN);
21914 : 100 : break;
21915 : :
21916 : 1255 : case NC_COMPLEX:
21917 : 1255 : mpc_set(val, this->u_.complex_val, MPC_RNDNN);
21918 : 1255 : break;
21919 : :
21920 : 0 : default:
21921 : 0 : go_unreachable();
21922 : : }
21923 : :
21924 : 1894 : bool ret = true;
21925 : 1894 : if (!mpfr_nan_p(mpc_realref(val))
21926 : 1894 : && !mpfr_inf_p(mpc_realref(val))
21927 : 1894 : && !mpfr_zero_p(mpc_realref(val))
21928 : 1212 : && mpfr_get_exp(mpc_realref(val)) > max_exp)
21929 : : {
21930 : 2 : if (issue_error)
21931 : : {
21932 : 2 : go_error_at(location, "complex real part overflow");
21933 : 2 : this->set_invalid();
21934 : : }
21935 : : ret = false;
21936 : : }
21937 : :
21938 : 1894 : if (!mpfr_nan_p(mpc_imagref(val))
21939 : 1894 : && !mpfr_inf_p(mpc_imagref(val))
21940 : 1894 : && !mpfr_zero_p(mpc_imagref(val))
21941 : 1032 : && mpfr_get_exp(mpc_imagref(val)) > max_exp)
21942 : : {
21943 : 0 : if (issue_error)
21944 : : {
21945 : 0 : go_error_at(location, "complex imaginary part overflow");
21946 : 0 : this->set_invalid();
21947 : : }
21948 : : ret = false;
21949 : : }
21950 : :
21951 : 1894 : if (ret)
21952 : : {
21953 : : // Round the constant to the desired type.
21954 : 1892 : mpc_t t;
21955 : 1892 : switch (type->bits())
21956 : : {
21957 : 351 : case 64:
21958 : 351 : mpc_init2(t, 24);
21959 : 351 : break;
21960 : 1541 : case 128:
21961 : 1541 : mpc_init2(t, 53);
21962 : 1541 : break;
21963 : 0 : default:
21964 : 0 : go_unreachable();
21965 : : }
21966 : 1892 : mpc_set(t, val, MPC_RNDNN);
21967 : 1892 : mpc_set(val, t, MPC_RNDNN);
21968 : 1892 : mpc_clear(t);
21969 : :
21970 : 1892 : this->set_complex(type, val);
21971 : : }
21972 : :
21973 : 1894 : mpc_clear(val);
21974 : :
21975 : 1894 : return ret;
21976 : : }
21977 : :
21978 : : // Return an Expression for this value.
21979 : :
21980 : : Expression*
21981 : 235319 : Numeric_constant::expression(Location loc) const
21982 : : {
21983 : 235319 : switch (this->classification_)
21984 : : {
21985 : 219139 : case NC_INT:
21986 : 219139 : return Expression::make_integer_z(&this->u_.int_val, this->type_, loc);
21987 : 4382 : case NC_RUNE:
21988 : 4382 : return Expression::make_character(&this->u_.int_val, this->type_, loc);
21989 : 9205 : case NC_FLOAT:
21990 : 9205 : return Expression::make_float(&this->u_.float_val, this->type_, loc);
21991 : 2593 : case NC_COMPLEX:
21992 : 2593 : return Expression::make_complex(&this->u_.complex_val, this->type_, loc);
21993 : 0 : case NC_INVALID:
21994 : 0 : go_assert(saw_errors());
21995 : 0 : return Expression::make_error(loc);
21996 : 0 : default:
21997 : 0 : go_unreachable();
21998 : : }
21999 : : }
22000 : :
22001 : : // Calculate a hash code with a given seed.
22002 : :
22003 : : unsigned int
22004 : 3663 : Numeric_constant::hash(unsigned int seed) const
22005 : : {
22006 : 3663 : unsigned long val;
22007 : 3663 : const unsigned int PRIME = 97;
22008 : 3663 : long e = 0;
22009 : 3663 : double f = 1.0;
22010 : 3663 : mpfr_t m;
22011 : :
22012 : 3663 : switch (this->classification_)
22013 : : {
22014 : : case NC_INVALID:
22015 : : return PRIME;
22016 : 3653 : case NC_INT:
22017 : 3653 : case NC_RUNE:
22018 : 3653 : val = mpz_get_ui(this->u_.int_val);
22019 : : break;
22020 : 4 : case NC_COMPLEX:
22021 : 4 : mpfr_init(m);
22022 : 4 : mpc_abs(m, this->u_.complex_val, MPFR_RNDN);
22023 : 4 : val = mpfr_get_ui(m, MPFR_RNDN);
22024 : 4 : mpfr_clear(m);
22025 : 4 : break;
22026 : 6 : case NC_FLOAT:
22027 : 6 : f = mpfr_get_d_2exp(&e, this->u_.float_val, MPFR_RNDN) * 4294967295.0;
22028 : 6 : val = static_cast<unsigned long>(e + static_cast<long>(f));
22029 : 6 : break;
22030 : 0 : default:
22031 : 0 : go_unreachable();
22032 : : }
22033 : :
22034 : 3663 : return (static_cast<unsigned int>(val) + seed) * PRIME;
22035 : : }
|