This patch to the Go frontend edits various error messages to avoid -Wformat-diag warnings.
GCC recently introduced -Wformat-diag to scrutinize GCC error messages. It reports a number of warnings about gofrontend code, such as: ../../trunk/gcc/go/gofrontend/import.cc: In member function ‘Type* Import::type_for_index(int, const string&, size_t, bool*)’: ../../trunk/gcc/go/gofrontend/import.cc:1129:48: warning: unquoted operator ‘>=’ in format [-Wformat-diag] 1129 | "error in %s at %lu: bad type index %d >= %d", | ^~ ../../trunk/gcc/go/gofrontend/ast-dump.cc: In member function ‘void Ast_dump_context::dump(Gogo*, const char*)’: ../../trunk/gcc/go/gofrontend/ast-dump.cc:203:25: warning: unquoted option name ‘-fgo-dump-ast’ in format [-Wformat-diag] 203 | "cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str()); | ^~~~~~~~~~~~~ ../../trunk/gcc/go/gofrontend/expressions.cc: In static member function ‘static Bexpression* Func_expression::get_code_pointer(Gogo*, Named_object*, Location)’: ../../trunk/gcc/go/gofrontend/expressions.cc:1350:29: warning: misspelled term ‘builtin function’ in format; use ‘built-in function’ instead [-Wformat-diag] 1350 | "invalid use of special builtin function %qs; must be called", | ^~~~~~~~~~~~~~~~ ../../trunk/gcc/go/gofrontend/gogo.cc: In member function ‘void Gogo::add_linkname(const string&, bool, const string&, Location)’: ../../trunk/gcc/go/gofrontend/gogo.cc:2527:4: warning: unquoted sequence of 2 consecutive punctuation characters ‘//’ in format [-Wformat-diag] 2527 | ("%s is not a function; " | ~^~~~~~~~~~~~~~~~~~~~~~~~ 2528 | "//go:linkname is only supported for functions"), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This patch edits error messages to avoid these warnings. I don't think they are all improvements, but some are, and none seem significantly worse. This required changing one Go test to accept quote characters we were not previously generating. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian 2019-06-23 Ian Lance Taylor <i...@golang.org> * go.test/test/blank1.go: Update for diagnostic message changes.
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 272607) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -6bb63a21434b3360dbe7e4bd34889734f361d434 +1232eef628227ef855c5fa6d94b31778b2e74a85 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/ast-dump.cc =================================================================== --- gcc/go/gofrontend/ast-dump.cc (revision 272577) +++ gcc/go/gofrontend/ast-dump.cc (working copy) @@ -200,7 +200,8 @@ Ast_dump_context::dump(Gogo* gogo, const if (out.fail()) { go_error_at(Linemap::unknown_location(), - "cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str()); + "cannot open %s:%m; %<-fgo-dump-ast%> ignored", + dumpname.c_str()); return; } Index: gcc/go/gofrontend/expressions.cc =================================================================== --- gcc/go/gofrontend/expressions.cc (revision 272607) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -1347,7 +1347,8 @@ Func_expression::get_code_pointer(Gogo* if (fntype->is_builtin()) { go_error_at(loc, - "invalid use of special builtin function %qs; must be called", + ("invalid use of special built-in function %qs; " + "must be called"), no->message_name().c_str()); return gogo->backend()->error_expression(); } @@ -1386,7 +1387,7 @@ Func_expression::do_get_backend(Translat if (no->func_declaration_value()->type()->is_builtin()) { go_error_at(this->location(), - ("invalid use of special builtin function %qs; " + ("invalid use of special built-in function %qs; " "must be called"), no->message_name().c_str()); return gogo->backend()->error_expression(); @@ -8425,7 +8426,7 @@ Builtin_call_expression::lower_make(Stat if (!type->in_heap()) go_error_at(first_arg->location(), - "can't make slice of go:notinheap type"); + "cannot make slice of go:notinheap type"); bool is_slice = false; bool is_map = false; @@ -9804,7 +9805,7 @@ Builtin_call_expression::do_check_types( { if (this->code_ == BUILTIN_PRINT) go_warning_at(this->location(), 0, - "no arguments for builtin function %<%s%>", + "no arguments for built-in function %<%s%>", (this->code_ == BUILTIN_PRINT ? "print" : "println")); @@ -9946,7 +9947,7 @@ Builtin_call_expression::do_check_types( Type* element_type = slice_type->array_type()->element_type(); if (!element_type->in_heap()) go_error_at(args->front()->location(), - "can't append to slice of go:notinheap type"); + "cannot append to slice of go:notinheap type"); if (this->is_varargs()) { if (!args->back()->type()->is_slice_type() @@ -14452,7 +14453,7 @@ void Allocation_expression::do_check_types(Gogo*) { if (!this->type_->in_heap()) - go_error_at(this->location(), "can't heap allocate go:notinheap type"); + go_error_at(this->location(), "cannot heap allocate go:notinheap type"); } // Make a copy of an allocation expression. @@ -19025,7 +19026,7 @@ Numeric_constant::check_int_type(Integer if (issue_error) { go_error_at(location, - "floating point constant truncated to integer"); + "floating-point constant truncated to integer"); this->set_invalid(); } return false; @@ -19113,7 +19114,8 @@ Numeric_constant::check_float_type(Float if (issue_error) { this->set_invalid(); - go_error_at(location, "complex constant truncated to float"); + go_error_at(location, + "complex constant truncated to floating-point"); } return false; } @@ -19178,7 +19180,7 @@ Numeric_constant::check_float_type(Float if (!ret && issue_error) { - go_error_at(location, "floating point constant overflow"); + go_error_at(location, "floating-point constant overflow"); this->set_invalid(); } Index: gcc/go/gofrontend/go.cc =================================================================== --- gcc/go/gofrontend/go.cc (revision 272577) +++ gcc/go/gofrontend/go.cc (working copy) @@ -92,7 +92,7 @@ go_parse_input_files(const char** filena p != linknames->end(); ++p) go_error_at(p->second.loc, - ("//go:linkname only allowed in Go files that " + ("%<//go:linkname%> only allowed in Go files that " "import \"unsafe\"")); } all_linknames.insert(linknames->begin(), linknames->end()); Index: gcc/go/gofrontend/gogo.cc =================================================================== --- gcc/go/gofrontend/gogo.cc (revision 272577) +++ gcc/go/gofrontend/gogo.cc (working copy) @@ -552,7 +552,7 @@ Gogo::import_package(const std::string& if (package->pkgpath() == this->pkgpath()) go_error_at(location, ("imported package uses same package path as package " - "being compiled (see -fgo-pkgpath option)")); + "being compiled (see %<-fgo-pkgpath%> option)")); this->imports_.insert(std::make_pair(filename, package)); } @@ -2525,7 +2525,7 @@ Gogo::add_linkname(const std::string& go else go_error_at(loc, ("%s is not a function; " - "//go:linkname is only supported for functions"), + "%<//go:linkname%> is only supported for functions"), go_name.c_str()); } @@ -3693,7 +3693,7 @@ Check_types_traverse::variable(Named_obj if (fntype->is_builtin()) { go_error_at(init->location(), - "invalid use of special builtin function %qs; " + "invalid use of special built-in function %qs; " "must be called", no->message_name().c_str()); } @@ -8161,7 +8161,7 @@ Type_declaration::define_methods(Named_t ++p) go_error_at((*p)->location(), ("invalid receiver type " - "(receiver must be a named type")); + "(receiver must be a named type)")); return; } } Index: gcc/go/gofrontend/import-archive.cc =================================================================== --- gcc/go/gofrontend/import-archive.cc (revision 272577) +++ gcc/go/gofrontend/import-archive.cc (working copy) @@ -420,7 +420,7 @@ Archive_file::read_big_archive_header(of char* buf = new char[sizeof(hdr.ar_size) + 1]; memcpy(buf, hdr.ar_size, sizeof(hdr.ar_size)); go_error_at(this->location_, - ("%s: malformed ar_size in entry header at %ld" + ("%s: malformed size in entry header at %ld" " (expected decimal, got %s)"), this->filename_.c_str(), static_cast<long>(off), buf); delete[] buf; @@ -434,7 +434,7 @@ Archive_file::read_big_archive_header(of char* buf = new char[sizeof(hdr.ar_namlen) + 1]; memcpy(buf, hdr.ar_namlen, sizeof(hdr.ar_namlen)); go_error_at(this->location_, - ("%s: malformed ar_namlen in entry header at %ld" + ("%s: malformed name length in entry header at %ld" " (expected decimal, got %s)"), this->filename_.c_str(), static_cast<long>(off), buf); delete[] buf; @@ -460,7 +460,7 @@ Archive_file::read_big_archive_header(of char* buf = new char[sizeof(hdr.ar_nxtmem) + 1]; memcpy(buf, hdr.ar_nxtmem, sizeof(hdr.ar_nxtmem)); go_error_at(this->location_, - ("%s: malformed ar_nxtmem in entry header at %ld" + ("%s: malformed next member offset in entry header at %ld" " (expected decimal, got %s)"), this->filename_.c_str(), static_cast<long>(off), buf); delete[] buf; @@ -655,7 +655,7 @@ Archive_file::get_file_and_offset(off_t int nfd = open(filename.c_str(), O_RDONLY | O_BINARY); if (nfd < 0) { - go_error_at(this->location_, "%s: can't open nested archive %s", + go_error_at(this->location_, "%s: cannot open nested archive %s", this->filename_.c_str(), filename.c_str()); return false; } Index: gcc/go/gofrontend/import.cc =================================================================== --- gcc/go/gofrontend/import.cc (revision 272577) +++ gcc/go/gofrontend/import.cc (working copy) @@ -925,7 +925,7 @@ Import::read_type() { if (!stream->saw_error()) go_error_at(this->location_, - "error in import data at %d: expected %< %> or %<>%>'", + "error in import data at %d: expected %< %> or %<>%>", stream->pos()); stream->set_saw_error(); stream->advance(1); @@ -1126,7 +1126,7 @@ Import::type_for_index(int index, const if (static_cast<size_t>(index) >= this->type_offsets_.size()) { go_error_at(this->location_, - "error in %s at %lu: bad type index %d >= %d", + "error in %s at %lu: bad type index %d, max %d", input_name.c_str(), static_cast<unsigned long>(input_offset), index, static_cast<int>(this->type_offsets_.size())); Index: gcc/go/gofrontend/lex.cc =================================================================== --- gcc/go/gofrontend/lex.cc (revision 272577) +++ gcc/go/gofrontend/lex.cc (working copy) @@ -1863,7 +1863,7 @@ Lex::skip_cpp_comment() } } if (go_name.empty() || ext_name.empty()) - go_error_at(loc, "usage: //go:linkname localname linkname"); + go_error_at(loc, "usage: %<//go:linkname%> localname linkname"); else { if (this->linknames_ == NULL) Index: gcc/go/gofrontend/parse.cc =================================================================== --- gcc/go/gofrontend/parse.cc (revision 272577) +++ gcc/go/gofrontend/parse.cc (working copy) @@ -1359,7 +1359,7 @@ Parse::decl(void (Parse::*pfn)(void*, un { if (pragmas != 0) go_warning_at(this->location(), 0, - "ignoring magic //go:... comment before group"); + "ignoring magic %<//go:...%> comment before group"); if (!this->advance_token()->is_op(OPERATOR_RPAREN)) { this->list(pfn, varg, true); @@ -1605,7 +1605,7 @@ Parse::type_spec(void*, unsigned int pra } if (pragmas != 0) go_warning_at(location, 0, - "ignoring magic //go:... comment before type"); + "ignoring magic %<//go:...%> comment before type"); } else { @@ -1633,7 +1633,7 @@ Parse::var_spec(void*, unsigned int prag { if (pragmas != 0) go_warning_at(this->location(), 0, - "ignoring magic //go:... comment before var"); + "ignoring magic %<//go:...%> comment before var"); // Get the variable names. Typed_identifier_list til; @@ -2383,7 +2383,7 @@ Parse::function_decl(unsigned int pragma if (pragma_check[i].decl_ok) continue; go_warning_at(location, 0, - ("ignoring magic //go:%s comment " + ("ignoring magic %<//go:%s%> comment " "before declaration"), pragma_check[i].name); } @@ -2392,7 +2392,7 @@ Parse::function_decl(unsigned int pragma if (pragma_check[i].func_ok) continue; go_warning_at(location, 0, - ("ignoring magic //go:%s comment " + ("ignoring magic %<//go:%s%> comment " "before function definition"), pragma_check[i].name); } @@ -2401,7 +2401,7 @@ Parse::function_decl(unsigned int pragma if (pragma_check[i].method_ok) continue; go_warning_at(location, 0, - ("ignoring magic //go:%s comment " + ("ignoring magic %<//go:%s%> comment " "before method definition"), pragma_check[i].name); } @@ -2602,7 +2602,7 @@ Parse::operand(bool may_be_sink, bool* i return Expression::make_sink(location); else { - go_error_at(location, "cannot use _ as value"); + go_error_at(location, "cannot use %<_%> as value"); return Expression::make_error(location); } case Named_object::NAMED_OBJECT_FUNC: @@ -4178,7 +4178,7 @@ Parse::tuple_assignment(Expression_list* if ((*pe)->is_error_expression()) return; if (op != OPERATOR_EQ && (*pe)->is_sink_expression()) - go_error_at((*pe)->location(), "cannot use _ as value"); + go_error_at((*pe)->location(), "cannot use %<_%> as value"); } for (Expression_list::const_iterator pe = vals->begin(); pe != vals->end(); @@ -5721,7 +5721,7 @@ Parse::package_clause() name = token->identifier(); if (name == "_") { - go_error_at(this->location(), "invalid package name _"); + go_error_at(this->location(), "invalid package name %<_%>"); name = Gogo::erroneous_name(); } this->advance_token(); @@ -5752,7 +5752,7 @@ Parse::import_spec(void*, unsigned int p { if (pragmas != 0) go_warning_at(this->location(), 0, - "ignoring magic //go:... comment before import"); + "ignoring magic %<//go:...%> comment before import"); const Token* token = this->peek_token(); Location location = token->location(); @@ -5876,7 +5876,7 @@ Parse::verify_not_sink(Expression* expr) { if (expr->is_sink_expression()) { - go_error_at(expr->location(), "cannot use _ as value"); + go_error_at(expr->location(), "cannot use %<_%> as value"); expr = Expression::make_error(expr->location()); } Index: gcc/go/gofrontend/statements.cc =================================================================== --- gcc/go/gofrontend/statements.cc (revision 272607) +++ gcc/go/gofrontend/statements.cc (working copy) @@ -2168,7 +2168,7 @@ Block_statement::do_import(Import_functi { if (!ifb->saw_error()) go_error_at(ifb->location(), - "import error: no newline after { at %lu", + "import error: no newline after %<{%> at %lu", static_cast<unsigned long>(ifb->off())); ifb->set_saw_error(); return NULL; Index: gcc/testsuite/go.test/test/blank1.go =================================================================== --- gcc/testsuite/go.test/test/blank1.go (revision 272577) +++ gcc/testsuite/go.test/test/blank1.go (working copy) @@ -7,7 +7,7 @@ // Test that incorrect uses of the blank identifer are caught. // Does not compile. -package _ // ERROR "invalid package name _" +package _ // ERROR "invalid package name" var t struct { _ int @@ -18,8 +18,8 @@ type T struct { } func main() { - _() // ERROR "cannot use _ as value" - x := _+1 // ERROR "cannot use _ as value" + _() // ERROR "cannot use .* as value" + x := _+1 // ERROR "cannot use .* as value" _ = x _ = t._ // ERROR "cannot refer to blank field|invalid use of"