diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
commit | b9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch) | |
tree | ed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/go | |
parent | 1957047ed1c94bf17cf993a2b1866965f493ba87 (diff) | |
parent | 56638b9b1853666f575928f8baf17f70e4ed3517 (diff) | |
download | gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2 |
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517
Author: GCC Administrator <gccadmin@gcc.gnu.org>
Date: Wed Jun 17 00:16:36 2020 +0000
Daily bump.
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 179 | ||||
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/export.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 193 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 22 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/lex.cc | 12 | ||||
-rw-r--r-- | gcc/go/gofrontend/names.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 25 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.h | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 26 |
12 files changed, 287 insertions, 191 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index fc73347..5be05e9 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,12 @@ +2020-04-15 Ian Lance Taylor <iant@golang.org> + + PR go/94607 + * go-gcc.cc (class Gcc_backend): Define builtin_const, + builtin_noreturn, builtin_novops. + (Gcc_backend::define_builtin): Change const_p and noreturn_p + parameters to a single flags parameter. Change all callers. + (Gcc_backend::Gcc_backend): Pass novops for prefetch. + 2020-01-01 Jakub Jelinek <jakub@redhat.com> Update copyright years. diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 0960894..fd96481 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -541,9 +541,13 @@ class Gcc_backend : public Backend convert_tree(tree, tree, Location); private: + static const int builtin_const = 1 << 0; + static const int builtin_noreturn = 1 << 1; + static const int builtin_novops = 1 << 2; + void define_builtin(built_in_function bcode, const char* name, const char* libname, - tree fntype, bool const_p, bool noreturn_p); + tree fntype, int flags); // A mapping of the GCC built-ins exposed to GCCGo. std::map<std::string, Bfunction*> builtin_functions_; @@ -566,26 +570,22 @@ Gcc_backend::Gcc_backend() tree t = this->integer_type(true, BITS_PER_UNIT)->get_tree(); tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1", - NULL, build_function_type_list(t, p, t, NULL_TREE), - false, false); + NULL, build_function_type_list(t, p, t, NULL_TREE), 0); t = this->integer_type(true, BITS_PER_UNIT * 2)->get_tree(); p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2", - NULL, build_function_type_list(t, p, t, NULL_TREE), - false, false); + NULL, build_function_type_list(t, p, t, NULL_TREE), 0); t = this->integer_type(true, BITS_PER_UNIT * 4)->get_tree(); p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4", - NULL, build_function_type_list(t, p, t, NULL_TREE), - false, false); + NULL, build_function_type_list(t, p, t, NULL_TREE), 0); t = this->integer_type(true, BITS_PER_UNIT * 8)->get_tree(); p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8", - NULL, build_function_type_list(t, p, t, NULL_TREE), - false, false); + NULL, build_function_type_list(t, p, t, NULL_TREE), 0); // We use __builtin_expect for magic import functions. this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL, @@ -593,7 +593,7 @@ Gcc_backend::Gcc_backend() long_integer_type_node, long_integer_type_node, NULL_TREE), - true, false); + builtin_const); // We use __builtin_memcmp for struct comparisons. this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp", @@ -602,7 +602,7 @@ Gcc_backend::Gcc_backend() const_ptr_type_node, size_type_node, NULL_TREE), - false, false); + 0); // We use __builtin_memmove for copying data. this->define_builtin(BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove", @@ -611,7 +611,7 @@ Gcc_backend::Gcc_backend() const_ptr_type_node, size_type_node, NULL_TREE), - false, false); + 0); // We use __builtin_memset for zeroing data. this->define_builtin(BUILT_IN_MEMSET, "__builtin_memset", "memset", @@ -620,54 +620,54 @@ Gcc_backend::Gcc_backend() integer_type_node, size_type_node, NULL_TREE), - false, false); + 0); // Used by runtime/internal/sys and math/bits. this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz", build_function_type_list(integer_type_node, unsigned_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll", build_function_type_list(integer_type_node, long_long_unsigned_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_CLZ, "__builtin_clz", "clz", build_function_type_list(integer_type_node, unsigned_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll", build_function_type_list(integer_type_node, long_long_unsigned_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount", build_function_type_list(integer_type_node, unsigned_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_POPCOUNTLL, "__builtin_popcountll", "popcountll", build_function_type_list(integer_type_node, long_long_unsigned_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16", build_function_type_list(uint16_type_node, uint16_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32", build_function_type_list(uint32_type_node, uint32_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64", build_function_type_list(uint64_type_node, uint64_type_node, NULL_TREE), - true, false); + builtin_const); // We provide some functions for the math library. tree math_function_type = build_function_type_list(double_type_node, @@ -684,104 +684,104 @@ Gcc_backend::Gcc_backend() build_function_type_list(long_double_type_node, long_double_type_node, long_double_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2", - math_function_type_two, true, false); + math_function_type_two, builtin_const); this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l", - math_function_type_long_two, true, false); + math_function_type_long_two, builtin_const); this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod", - math_function_type_two, true, false); + math_function_type_two, builtin_const); this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl", - math_function_type_long_two, true, false); + math_function_type_long_two, builtin_const); this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp", build_function_type_list(double_type_node, double_type_node, integer_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl", build_function_type_list(long_double_type_node, long_double_type_node, integer_type_node, NULL_TREE), - true, false); + builtin_const); this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc", - math_function_type, true, false); + math_function_type, builtin_const); this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl", - math_function_type_long, true, false); + math_function_type_long, builtin_const); // We use __builtin_return_address in the thunk we build for // functions which call recover, and for runtime.getcallerpc. t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE); this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address", - NULL, t, false, false); + NULL, t, 0); // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp. t = build_function_type_list(ptr_type_node, NULL_TREE); this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa", - NULL, t, false, false); + NULL, t, 0); // The runtime calls __builtin_extract_return_addr when recording // the address to which a function returns. @@ -790,26 +790,26 @@ Gcc_backend::Gcc_backend() build_function_type_list(ptr_type_node, ptr_type_node, NULL_TREE), - false, false); + 0); // The compiler uses __builtin_trap for some exception handling // cases. this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL, build_function_type(void_type_node, void_list_node), - false, true); + builtin_noreturn); // The runtime uses __builtin_prefetch. this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL, build_varargs_function_type_list(void_type_node, const_ptr_type_node, NULL_TREE), - false, false); + builtin_novops); // The compiler uses __builtin_unreachable for cases that cannot // occur. this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL, build_function_type(void_type_node, void_list_node), - true, true); + builtin_const | builtin_noreturn); // We provide some atomic functions. t = build_function_type_list(uint32_type_node, @@ -817,14 +817,14 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL, - t, false, false); + t, 0); t = build_function_type_list(uint64_type_node, ptr_type_node, integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL, - t, false, false); + t, 0); t = build_function_type_list(void_type_node, ptr_type_node, @@ -832,7 +832,7 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL, - t, false, false); + t, 0); t = build_function_type_list(void_type_node, ptr_type_node, @@ -840,7 +840,7 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL, - t, false, false); + t, 0); t = build_function_type_list(uint32_type_node, ptr_type_node, @@ -848,7 +848,7 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL, - t, false, false); + t, 0); t = build_function_type_list(uint64_type_node, ptr_type_node, @@ -856,7 +856,7 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL, - t, false, false); + t, 0); t = build_function_type_list(boolean_type_node, ptr_type_node, @@ -868,7 +868,7 @@ Gcc_backend::Gcc_backend() NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4, "__atomic_compare_exchange_4", NULL, - t, false, false); + t, 0); t = build_function_type_list(boolean_type_node, ptr_type_node, @@ -880,7 +880,7 @@ Gcc_backend::Gcc_backend() NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8, "__atomic_compare_exchange_8", NULL, - t, false, false); + t, 0); t = build_function_type_list(uint32_type_node, ptr_type_node, @@ -888,7 +888,7 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4", NULL, - t, false, false); + t, 0); t = build_function_type_list(uint64_type_node, ptr_type_node, @@ -896,7 +896,7 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", NULL, - t, false, false); + t, 0); t = build_function_type_list(unsigned_char_type_node, ptr_type_node, @@ -904,9 +904,9 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", NULL, - t, false, false); + t, 0); this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", NULL, - t, false, false); + t, 0); t = build_function_type_list(unsigned_char_type_node, ptr_type_node, @@ -914,9 +914,9 @@ Gcc_backend::Gcc_backend() integer_type_node, NULL_TREE); this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL, - t, false, false); + t, 0); this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL, - t, false, false); + t, 0); } // Get an unnamed integer type. @@ -3482,25 +3482,28 @@ Gcc_backend::write_export_data(const char* bytes, unsigned int size) void Gcc_backend::define_builtin(built_in_function bcode, const char* name, - const char* libname, tree fntype, bool const_p, - bool noreturn_p) + const char* libname, tree fntype, int flags) { tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL, libname, NULL_TREE); - if (const_p) + if ((flags & builtin_const) != 0) TREE_READONLY(decl) = 1; - if (noreturn_p) + if ((flags & builtin_noreturn) != 0) TREE_THIS_VOLATILE(decl) = 1; + if ((flags & builtin_novops) != 0) + DECL_IS_NOVOPS(decl) = 1; set_builtin_decl(bcode, decl, true); this->builtin_functions_[name] = this->make_function(decl); if (libname != NULL) { decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL, NULL, NULL_TREE); - if (const_p) + if ((flags & builtin_const) != 0) TREE_READONLY(decl) = 1; - if (noreturn_p) + if ((flags & builtin_noreturn) != 0) TREE_THIS_VOLATILE(decl) = 1; + if ((flags & builtin_novops) != 0) + DECL_IS_NOVOPS(decl) = 1; this->builtin_functions_[libname] = this->make_function(decl); } } diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d993dc8..fa37648 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -e0790a756e9ba77e2d3d6ef5d0abbb11dd71211b +d4dade353648eae4a1eaa1acd3e4ce1f7180a913 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index b27d2fa..277aa74 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -1231,7 +1231,7 @@ Export::write_name(const std::string& name) if (name.empty()) this->write_c_string("?"); else - this->write_string(Gogo::message_name(name)); + this->write_string(Gogo::unpack_hidden_name(name)); } // Write an integer value to the export stream. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index af09138..deac874 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1761,8 +1761,6 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int) real = no->unknown_value()->real_named_object(); if (real == NULL) { - if (this->is_composite_literal_key_) - return this; if (!this->no_error_message_) go_error_at(location, "reference to undefined name %qs", this->named_object_->message_name().c_str()); @@ -1776,8 +1774,6 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int) case Named_object::NAMED_OBJECT_TYPE: return Expression::make_type(real->type_value(), location); case Named_object::NAMED_OBJECT_TYPE_DECLARATION: - if (this->is_composite_literal_key_) - return this; if (!this->no_error_message_) go_error_at(location, "reference to undefined type %qs", real->message_name().c_str()); @@ -1789,8 +1785,6 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int) case Named_object::NAMED_OBJECT_FUNC_DECLARATION: return Expression::make_func_reference(real, NULL, location); case Named_object::NAMED_OBJECT_PACKAGE: - if (this->is_composite_literal_key_) - return this; if (!this->no_error_message_) go_error_at(location, "unexpected reference to package"); return Expression::make_error(location); @@ -2586,11 +2580,11 @@ Integer_expression::do_import(Import_expression* imp, Location loc) return Expression::make_error(loc); } if (pos == std::string::npos) - mpfr_set_ui(real, 0, GMP_RNDN); + mpfr_set_ui(real, 0, MPFR_RNDN); else { std::string real_str = num.substr(0, pos); - if (mpfr_init_set_str(real, real_str.c_str(), 10, GMP_RNDN) != 0) + if (mpfr_init_set_str(real, real_str.c_str(), 10, MPFR_RNDN) != 0) { go_error_at(imp->location(), "bad number in import data: %qs", real_str.c_str()); @@ -2605,7 +2599,7 @@ Integer_expression::do_import(Import_expression* imp, Location loc) imag_str = num.substr(pos); imag_str = imag_str.substr(0, imag_str.size() - 1); mpfr_t imag; - if (mpfr_init_set_str(imag, imag_str.c_str(), 10, GMP_RNDN) != 0) + if (mpfr_init_set_str(imag, imag_str.c_str(), 10, MPFR_RNDN) != 0) { go_error_at(imp->location(), "bad number in import data: %qs", imag_str.c_str()); @@ -2645,7 +2639,7 @@ Integer_expression::do_import(Import_expression* imp, Location loc) else { mpfr_t val; - if (mpfr_init_set_str(val, num.c_str(), 10, GMP_RNDN) != 0) + if (mpfr_init_set_str(val, num.c_str(), 10, MPFR_RNDN) != 0) { go_error_at(imp->location(), "bad number in import data: %qs", num.c_str()); @@ -2759,7 +2753,7 @@ class Float_expression : public Expression : Expression(EXPRESSION_FLOAT, location), type_(type) { - mpfr_init_set(this->val_, *val, GMP_RNDN); + mpfr_init_set(this->val_, *val, MPFR_RNDN); } // Write VAL to export data. @@ -2929,8 +2923,8 @@ Float_expression::do_get_backend(Translate_context* context) void Float_expression::export_float(String_dump *exp, const mpfr_t val) { - mp_exp_t exponent; - char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN); + mpfr_exp_t exponent; + char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, MPFR_RNDN); if (*s == '-') exp->write_c_string("-"); exp->write_c_string("0."); @@ -4787,7 +4781,7 @@ Unary_expression::eval_constant(Operator op, const Numeric_constant* unc, unc->get_float(&uval); mpfr_t val; mpfr_init(val); - mpfr_neg(val, uval, GMP_RNDN); + mpfr_neg(val, uval, MPFR_RNDN); nc->set_float(unc->type(), val); mpfr_clear(uval); mpfr_clear(val); @@ -5619,8 +5613,8 @@ Binary_expression::compare_float(const Numeric_constant* left_nc, if (!type->is_abstract() && type->float_type() != NULL) { int bits = type->float_type()->bits(); - mpfr_prec_round(left_val, bits, GMP_RNDN); - mpfr_prec_round(right_val, bits, GMP_RNDN); + mpfr_prec_round(left_val, bits, MPFR_RNDN); + mpfr_prec_round(right_val, bits, MPFR_RNDN); } *cmp = mpfr_cmp(left_val, right_val); @@ -5655,10 +5649,10 @@ Binary_expression::compare_complex(const Numeric_constant* left_nc, if (!type->is_abstract() && type->complex_type() != NULL) { int bits = type->complex_type()->bits(); - mpfr_prec_round(mpc_realref(left_val), bits / 2, GMP_RNDN); - mpfr_prec_round(mpc_imagref(left_val), bits / 2, GMP_RNDN); - mpfr_prec_round(mpc_realref(right_val), bits / 2, GMP_RNDN); - mpfr_prec_round(mpc_imagref(right_val), bits / 2, GMP_RNDN); + mpfr_prec_round(mpc_realref(left_val), bits / 2, MPFR_RNDN); + mpfr_prec_round(mpc_imagref(left_val), bits / 2, MPFR_RNDN); + mpfr_prec_round(mpc_realref(right_val), bits / 2, MPFR_RNDN); + mpfr_prec_round(mpc_imagref(right_val), bits / 2, MPFR_RNDN); } *cmp = mpc_cmp(left_val, right_val) != 0; @@ -5905,10 +5899,10 @@ Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc, switch (op) { case OPERATOR_PLUS: - mpfr_add(val, left_val, right_val, GMP_RNDN); + mpfr_add(val, left_val, right_val, MPFR_RNDN); break; case OPERATOR_MINUS: - mpfr_sub(val, left_val, right_val, GMP_RNDN); + mpfr_sub(val, left_val, right_val, MPFR_RNDN); break; case OPERATOR_OR: case OPERATOR_XOR: @@ -5917,20 +5911,20 @@ Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc, case OPERATOR_MOD: case OPERATOR_LSHIFT: case OPERATOR_RSHIFT: - mpfr_set_ui(val, 0, GMP_RNDN); + mpfr_set_ui(val, 0, MPFR_RNDN); ret = false; break; case OPERATOR_MULT: - mpfr_mul(val, left_val, right_val, GMP_RNDN); + mpfr_mul(val, left_val, right_val, MPFR_RNDN); break; case OPERATOR_DIV: if (!mpfr_zero_p(right_val)) - mpfr_div(val, left_val, right_val, GMP_RNDN); + mpfr_div(val, left_val, right_val, MPFR_RNDN); else { go_error_at(location, "division by zero"); nc->set_invalid(); - mpfr_set_ui(val, 0, GMP_RNDN); + mpfr_set_ui(val, 0, MPFR_RNDN); } break; default: @@ -15992,6 +15986,85 @@ Map_construction_expression::do_dump_expression( ast_dump_context->ostream() << "}"; } +// A composite literal key. This is seen during parsing, but is not +// resolved to a named_object in case this is a composite literal of +// struct type. + +class Composite_literal_key_expression : public Parser_expression +{ + public: + Composite_literal_key_expression(const std::string& name, Location location) + : Parser_expression(EXPRESSION_COMPOSITE_LITERAL_KEY, location), + name_(name) + { } + + const std::string& + name() const + { return this->name_; } + + protected: + Expression* + do_lower(Gogo*, Named_object*, Statement_inserter*, int); + + Expression* + do_copy() + { + return new Composite_literal_key_expression(this->name_, this->location()); + } + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The name. + std::string name_; +}; + +// Lower a composite literal key. We will never get here for keys in +// composite literals of struct types, because that is prevented by +// Composite_literal_expression::do_traverse. So if we do get here, +// this must be a regular name reference after all. + +Expression* +Composite_literal_key_expression::do_lower(Gogo* gogo, Named_object*, + Statement_inserter*, int) +{ + Named_object* no = gogo->lookup(this->name_, NULL); + if (no == NULL) + { + // Gogo::lookup doesn't look in the global namespace, and names + // used in composite literal keys aren't seen by + // Gogo::define_global_names, so we have to look in the global + // namespace ourselves. + no = gogo->lookup_global(Gogo::unpack_hidden_name(this->name_).c_str()); + if (no == NULL) + { + go_error_at(this->location(), "reference to undefined name %qs", + Gogo::message_name(this->name_).c_str()); + return Expression::make_error(this->location()); + } + } + return Expression::make_unknown_reference(no, this->location()); +} + +// Dump a composite literal key. + +void +Composite_literal_key_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "_UnknownName_(" << this->name_ << ")"; +} + +// Make a composite literal key. + +Expression* +Expression::make_composite_literal_key(const std::string& name, + Location location) +{ + return new Composite_literal_key_expression(name, location); +} + // Class Composite_literal_expression. // Traversal. @@ -16013,6 +16086,7 @@ Composite_literal_expression::do_traverse(Traverse* traverse) for (int depth = 0; depth < this->depth_; ++depth) { + type = type->deref(); if (type->array_type() != NULL) type = type->array_type()->element_type(); else if (type->map_type() != NULL) @@ -16028,6 +16102,7 @@ Composite_literal_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } } + type = type->deref(); while (true) { @@ -16186,6 +16261,11 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) const Named_object* no = NULL; switch (name_expr->classification()) { + case EXPRESSION_COMPOSITE_LITERAL_KEY: + name = + static_cast<Composite_literal_key_expression*>(name_expr)->name(); + break; + case EXPRESSION_UNKNOWN_REFERENCE: name = name_expr->unknown_expression()->name(); if (type->named_type() != NULL) @@ -16593,7 +16673,6 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function, // literals. Lower it now to get the right error message. if ((*p)->unknown_expression() != NULL) { - (*p)->unknown_expression()->clear_is_composite_literal_key(); gogo->lower_expression(function, inserter, &*p); go_assert((*p)->is_error_expression()); return Expression::make_error(location); @@ -18797,7 +18876,7 @@ Numeric_constant::Numeric_constant(const Numeric_constant& a) mpz_init_set(this->u_.int_val, a.u_.int_val); break; case NC_FLOAT: - mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN); + mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN); break; case NC_COMPLEX: mpc_init2(this->u_.complex_val, mpc_precision); @@ -18825,7 +18904,7 @@ Numeric_constant::operator=(const Numeric_constant& a) mpz_init_set(this->u_.int_val, a.u_.int_val); break; case NC_FLOAT: - mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN); + mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN); break; case NC_COMPLEX: mpc_init2(this->u_.complex_val, mpc_precision); @@ -18943,9 +19022,9 @@ Numeric_constant::set_float(Type* type, const mpfr_t val) && !type->float_type()->is_abstract()) bits = type->float_type()->bits(); if (Numeric_constant::is_float_neg_zero(val, bits)) - mpfr_init_set_ui(this->u_.float_val, 0, GMP_RNDN); + mpfr_init_set_ui(this->u_.float_val, 0, MPFR_RNDN); else - mpfr_init_set(this->u_.float_val, val, GMP_RNDN); + mpfr_init_set(this->u_.float_val, val, MPFR_RNDN); } // Set to a complex value. @@ -18965,14 +19044,14 @@ Numeric_constant::set_complex(Type* type, const mpc_t val) bits = type->complex_type()->bits() / 2; mpfr_t real; - mpfr_init_set(real, mpc_realref(val), GMP_RNDN); + mpfr_init_set(real, mpc_realref(val), MPFR_RNDN); if (Numeric_constant::is_float_neg_zero(real, bits)) - mpfr_set_ui(real, 0, GMP_RNDN); + mpfr_set_ui(real, 0, MPFR_RNDN); mpfr_t imag; - mpfr_init_set(imag, mpc_imagref(val), GMP_RNDN); + mpfr_init_set(imag, mpc_imagref(val), MPFR_RNDN); if (Numeric_constant::is_float_neg_zero(imag, bits)) - mpfr_set_ui(imag, 0, GMP_RNDN); + mpfr_set_ui(imag, 0, MPFR_RNDN); mpc_init2(this->u_.complex_val, mpc_precision); mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN); @@ -18991,7 +19070,7 @@ Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits) return false; if (mpfr_zero_p(val)) return true; - mp_exp_t min_exp; + mpfr_exp_t min_exp; switch (bits) { case 0: @@ -19036,7 +19115,7 @@ void Numeric_constant::get_float(mpfr_t* val) const { go_assert(this->is_float()); - mpfr_init_set(*val, this->u_.float_val, GMP_RNDN); + mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN); } // Get a complex value. @@ -19096,7 +19175,7 @@ Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval, return NC_UL_NOTINT; mpz_t ival; mpz_init(ival); - mpfr_get_z(ival, fval, GMP_RNDN); + mpfr_get_z(ival, fval, MPFR_RNDN); To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val); mpz_clear(ival); return ret; @@ -19163,7 +19242,7 @@ Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const return false; mpz_t ival; mpz_init(ival); - mpfr_get_z(ival, fval, GMP_RNDN); + mpfr_get_z(ival, fval, MPFR_RNDN); bool ret = this->mpz_to_memory_size(ival, val); mpz_clear(ival); return ret; @@ -19184,14 +19263,14 @@ Numeric_constant::to_int(mpz_t* val) const if (!mpfr_integer_p(this->u_.float_val)) return false; mpz_init(*val); - mpfr_get_z(*val, this->u_.float_val, GMP_RNDN); + mpfr_get_z(*val, this->u_.float_val, MPFR_RNDN); return true; case NC_COMPLEX: if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)) || !mpfr_integer_p(mpc_realref(this->u_.complex_val))) return false; mpz_init(*val); - mpfr_get_z(*val, mpc_realref(this->u_.complex_val), GMP_RNDN); + mpfr_get_z(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN); return true; default: go_unreachable(); @@ -19207,15 +19286,15 @@ Numeric_constant::to_float(mpfr_t* val) const { case NC_INT: case NC_RUNE: - mpfr_init_set_z(*val, this->u_.int_val, GMP_RNDN); + mpfr_init_set_z(*val, this->u_.int_val, MPFR_RNDN); return true; case NC_FLOAT: - mpfr_init_set(*val, this->u_.float_val, GMP_RNDN); + mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN); return true; case NC_COMPLEX: if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))) return false; - mpfr_init_set(*val, mpc_realref(this->u_.complex_val), GMP_RNDN); + mpfr_init_set(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN); return true; default: go_unreachable(); @@ -19320,7 +19399,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error, return false; } mpz_init(val); - mpfr_get_z(val, this->u_.float_val, GMP_RNDN); + mpfr_get_z(val, this->u_.float_val, MPFR_RNDN); break; case NC_COMPLEX: @@ -19335,7 +19414,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error, return false; } mpz_init(val); - mpfr_get_z(val, mpc_realref(this->u_.complex_val), GMP_RNDN); + mpfr_get_z(val, mpc_realref(this->u_.complex_val), MPFR_RNDN); break; default: @@ -19389,11 +19468,11 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error, { case NC_INT: case NC_RUNE: - mpfr_init_set_z(val, this->u_.int_val, GMP_RNDN); + mpfr_init_set_z(val, this->u_.int_val, MPFR_RNDN); break; case NC_FLOAT: - mpfr_init_set(val, this->u_.float_val, GMP_RNDN); + mpfr_init_set(val, this->u_.float_val, MPFR_RNDN); break; case NC_COMPLEX: @@ -19407,7 +19486,7 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error, } return false; } - mpfr_init_set(val, mpc_realref(this->u_.complex_val), GMP_RNDN); + mpfr_init_set(val, mpc_realref(this->u_.complex_val), MPFR_RNDN); break; default: @@ -19424,8 +19503,8 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error, } else { - mp_exp_t exp = mpfr_get_exp(val); - mp_exp_t max_exp; + mpfr_exp_t exp = mpfr_get_exp(val); + mpfr_exp_t max_exp; switch (type->bits()) { case 32: @@ -19456,8 +19535,8 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error, default: go_unreachable(); } - mpfr_set(t, val, GMP_RNDN); - mpfr_set(val, t, GMP_RNDN); + mpfr_set(t, val, MPFR_RNDN); + mpfr_set(val, t, MPFR_RNDN); mpfr_clear(t); this->set_float(type, val); @@ -19484,7 +19563,7 @@ Numeric_constant::check_complex_type(Complex_type* type, bool issue_error, if (type->is_abstract()) return true; - mp_exp_t max_exp; + mpfr_exp_t max_exp; switch (type->bits()) { case 64: @@ -19616,12 +19695,12 @@ Numeric_constant::hash(unsigned int seed) const break; case NC_COMPLEX: mpfr_init(m); - mpc_abs(m, this->u_.complex_val, GMP_RNDN); - val = mpfr_get_ui(m, GMP_RNDN); + mpc_abs(m, this->u_.complex_val, MPFR_RNDN); + val = mpfr_get_ui(m, MPFR_RNDN); mpfr_clear(m); break; case NC_FLOAT: - f = mpfr_get_d_2exp(&e, this->u_.float_val, GMP_RNDN) * 4294967295.0; + f = mpfr_get_d_2exp(&e, this->u_.float_val, MPFR_RNDN) * 4294967295.0; val = static_cast<unsigned long>(e + static_cast<long>(f)); break; default: diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index a0370e1..a4f892ac 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -127,6 +127,7 @@ class Expression EXPRESSION_SLICE_CONSTRUCTION, EXPRESSION_MAP_CONSTRUCTION, EXPRESSION_COMPOSITE_LITERAL, + EXPRESSION_COMPOSITE_LITERAL_KEY, EXPRESSION_HEAP, EXPRESSION_RECEIVE, EXPRESSION_TYPE_DESCRIPTOR, @@ -384,6 +385,10 @@ class Expression make_composite_literal(Type*, int depth, bool has_keys, Expression_list*, bool all_are_names, Location); + // Make a composite literal key. + static Expression* + make_composite_literal_key(const std::string& name, Location); + // Make a struct composite literal. static Expression* make_struct_composite_literal(Type*, Expression_list*, Location); @@ -2881,8 +2886,7 @@ class Unknown_expression : public Parser_expression public: Unknown_expression(Named_object* named_object, Location location) : Parser_expression(EXPRESSION_UNKNOWN_REFERENCE, location), - named_object_(named_object), no_error_message_(false), - is_composite_literal_key_(false) + named_object_(named_object), no_error_message_(false) { } // The associated named object. @@ -2901,18 +2905,6 @@ class Unknown_expression : public Parser_expression set_no_error_message() { this->no_error_message_ = true; } - // Note that this expression is being used as the key in a composite - // literal, so it may be OK if it is not resolved. - void - set_is_composite_literal_key() - { this->is_composite_literal_key_ = true; } - - // Note that this expression should no longer be treated as a - // composite literal key. - void - clear_is_composite_literal_key() - { this->is_composite_literal_key_ = false; } - protected: Expression* do_lower(Gogo*, Named_object*, Statement_inserter*, int); @@ -2930,8 +2922,6 @@ class Unknown_expression : public Parser_expression // True if we should not give errors if this is undefined. This is // used if there was a parse failure. bool no_error_message_; - // True if this is the key in a composite literal. - bool is_composite_literal_key_; }; // An index expression. This is lowered to an array index, a string diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 7d83119..2fb8a3a 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -958,7 +958,7 @@ class Gogo // Return the name of the type descriptor list symbol of a package. std::string - type_descriptor_list_symbol(std::string); + type_descriptor_list_symbol(const std::string&); // Return the name of the list of all type descriptor lists. std::string @@ -1073,7 +1073,7 @@ class Gogo Specific_type_function(Type* atype, Named_type* aname, int64_t asize, Specific_type_function_kind akind, - const std::string afnname, + const std::string& afnname, Function_type* afntype) : type(atype), name(aname), size(asize), kind(akind), fnname(afnname), fntype(afntype) diff --git a/gcc/go/gofrontend/lex.cc b/gcc/go/gofrontend/lex.cc index f023613..156a90c 100644 --- a/gcc/go/gofrontend/lex.cc +++ b/gcc/go/gofrontend/lex.cc @@ -198,7 +198,7 @@ Token::Token(const Token& tok) break; case TOKEN_FLOAT: case TOKEN_IMAGINARY: - mpfr_init_set(this->u_.float_value, tok.u_.float_value, GMP_RNDN); + mpfr_init_set(this->u_.float_value, tok.u_.float_value, MPFR_RNDN); break; default: go_unreachable(); @@ -238,7 +238,7 @@ Token::operator=(const Token& tok) break; case TOKEN_FLOAT: case TOKEN_IMAGINARY: - mpfr_init_set(this->u_.float_value, tok.u_.float_value, GMP_RNDN); + mpfr_init_set(this->u_.float_value, tok.u_.float_value, MPFR_RNDN); break; default: go_unreachable(); @@ -278,11 +278,11 @@ Token::print(FILE* file) const break; case TOKEN_FLOAT: fprintf(file, "float "); - mpfr_out_str(file, 10, 0, this->u_.float_value, GMP_RNDN); + mpfr_out_str(file, 10, 0, this->u_.float_value, MPFR_RNDN); break; case TOKEN_IMAGINARY: fprintf(file, "imaginary "); - mpfr_out_str(file, 10, 0, this->u_.float_value, GMP_RNDN); + mpfr_out_str(file, 10, 0, this->u_.float_value, MPFR_RNDN); break; case TOKEN_OPERATOR: fprintf(file, "operator "); @@ -1213,7 +1213,7 @@ Lex::gather_number() else { mpfr_t ival; - mpfr_init_set_z(ival, val, GMP_RNDN); + mpfr_init_set_z(ival, val, MPFR_RNDN); mpz_clear(val); Token ret = Token::make_imaginary_token(ival, location); mpfr_clear(ival); @@ -1310,7 +1310,7 @@ Lex::gather_number() } mpfr_t val; - int r = mpfr_init_set_str(val, num.c_str(), base, GMP_RNDN); + int r = mpfr_init_set_str(val, num.c_str(), base, MPFR_RNDN); go_assert(r == 0); bool is_imaginary = *p == 'i'; diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc index f4ad1815..a721a36 100644 --- a/gcc/go/gofrontend/names.cc +++ b/gcc/go/gofrontend/names.cc @@ -1024,7 +1024,7 @@ Gogo::type_descriptor_name(const Type* type, Named_type* nt) // Return the name of the type descriptor list symbol of a package. std::string -Gogo::type_descriptor_list_symbol(std::string pkgpath) +Gogo::type_descriptor_list_symbol(const std::string& pkgpath) { return pkgpath + "..types"; } diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index e50af61..ef59415 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -2200,7 +2200,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name, p != til.end(); ++p) exprs->push_back(this->id_to_expression(p->name(), p->location(), - true)); + true, false)); Expression_list* more_exprs = this->expression_list(NULL, true, may_be_composite_lit); @@ -2651,7 +2651,7 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized) case Token::TOKEN_IMAGINARY: { mpfr_t zero; - mpfr_init_set_ui(zero, 0, GMP_RNDN); + mpfr_init_set_ui(zero, 0, MPFR_RNDN); mpc_t val; mpc_init2(val, mpc_precision); mpc_set_fr_fr(val, zero, *token->imaginary_value(), MPC_RNDNN); @@ -2820,7 +2820,7 @@ Parse::composite_lit(Type* type, int depth, Location location) Gogo* gogo = this->gogo_; val = this->id_to_expression(gogo->pack_hidden_name(identifier, is_exported), - id_location, false); + id_location, false, true); is_name = true; } else @@ -2877,9 +2877,6 @@ Parse::composite_lit(Type* type, int depth, Location location) } has_keys = true; - if (val->unknown_expression() != NULL) - val->unknown_expression()->set_is_composite_literal_key(); - vals->push_back(val); if (!token->is_op(OPERATOR_LCURLY)) @@ -3345,12 +3342,22 @@ Parse::call(Expression* func) Expression* Parse::id_to_expression(const std::string& name, Location location, - bool is_lhs) + bool is_lhs, bool is_composite_literal_key) { Named_object* in_function; Named_object* named_object = this->gogo_->lookup(name, &in_function); if (named_object == NULL) - named_object = this->gogo_->add_unknown_name(name, location); + { + if (is_composite_literal_key) + { + // This is a composite literal key, which means that it + // could just be a struct field name, so avoid confusiong by + // not adding it to the bindings. We'll look up the name + // later during the lowering phase if necessary. + return Expression::make_composite_literal_key(name, location); + } + named_object = this->gogo_->add_unknown_name(name, location); + } if (in_function != NULL && in_function != this->gogo_->current_function() @@ -5167,7 +5174,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val, *val = this->id_to_expression(gogo->pack_hidden_name(recv_var, is_rv_exported), - recv_var_loc, true); + recv_var_loc, true, false); saw_comma = true; } else diff --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h index f309ee0..4a5a4b8 100644 --- a/gcc/go/gofrontend/parse.h +++ b/gcc/go/gofrontend/parse.h @@ -231,7 +231,7 @@ class Parse bool* is_type_switch, bool* is_parenthesized); Type* reassociate_chan_direction(Channel_type*, Location); Expression* qualified_expr(Expression*, Location); - Expression* id_to_expression(const std::string&, Location, bool); + Expression* id_to_expression(const std::string&, Location, bool, bool); void statement(Label*); bool statement_may_start_here(); void labeled_stmt(const std::string&, Location); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 27d53df..d6cd326 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -8943,8 +8943,12 @@ Interface_type::finalize_methods() continue; } + const Typed_identifier_list* imethods = it->parse_methods_; + if (imethods == NULL) + continue; + Named_type* nt = t->named_type(); - if (nt != NULL && it->parse_methods_ != NULL) + if (nt != NULL) { std::vector<Named_type*>::const_iterator q; for (q = seen.begin(); q != seen.end(); ++q) @@ -8960,22 +8964,26 @@ Interface_type::finalize_methods() seen.push_back(nt); } - const Typed_identifier_list* imethods = it->parse_methods_; - if (imethods == NULL) - continue; for (Typed_identifier_list::const_iterator q = imethods->begin(); q != imethods->end(); ++q) { if (q->name().empty()) inherit.push_back(*q); - else if (this->find_method(q->name()) == NULL) - this->all_methods_->push_back(Typed_identifier(q->name(), - q->type(), tl)); else - go_error_at(tl, "inherited method %qs is ambiguous", - Gogo::message_name(q->name()).c_str()); + { + const Typed_identifier* oldm = this->find_method(q->name()); + if (oldm == NULL) + this->all_methods_->push_back(Typed_identifier(q->name(), + q->type(), tl)); + else if (!Type::are_identical(q->type(), oldm->type(), + Type::COMPARE_TAGS, NULL)) + go_error_at(tl, "duplicate method %qs", + Gogo::message_name(q->name()).c_str()); + } } + + seen.pop_back(); } if (!this->all_methods_->empty()) |