From patchwork Sat Dec 2 00:38:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 843845 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-468384-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="j2zjI96Q"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ypXMQ3L7qz9sMN for ; Sat, 2 Dec 2017 11:39:12 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=hq2zdjniYgWVGjbRmzo02/c+s2qR7HTLGcbMZLmR2Hj5GN GxwPZBsfJlv8bKYB/X/CkPi8NsJWVTl36BhoMQEd4vWmPSnD0NJ73/sTdDygy2rS 2ss1ccwiveTPfn4CFm5nqmsEc1uIrZycpcRMvrvpuP4MZIfUi5cR96eIDYpsY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=BRG/8/ayX4Wm+d0vPihHtJWjxbM=; b=j2zjI96QiJBgA1//X986 JSAnTPgnIKqM0dq8voUEMarm3ES30bl75NAl/CkutmbTa73rmUdZ6Y2uWjItE7cb POVaMbivx4HzPRjGfe/VaKZz6YDTRmZGJPMlhweiGuHNePHkI9BAD2W+7SveKFEb 9BS/Kd4pELtzIb7WJlK0Uic= Received: (qmail 77786 invoked by alias); 2 Dec 2017 00:39:04 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 77774 invoked by uid 89); 2 Dec 2017 00:39:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=4868 X-HELO: mail-wm0-f52.google.com Received: from mail-wm0-f52.google.com (HELO mail-wm0-f52.google.com) (74.125.82.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 02 Dec 2017 00:39:00 +0000 Received: by mail-wm0-f52.google.com with SMTP id t8so6275371wmc.3 for ; Fri, 01 Dec 2017 16:39:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=6BIVuKo01FcEfhatQCyy2UYM48yiDqFLdTGdvDmta7k=; b=Cn4XFYbld8tB3etUNQULIN3rrjph2GWHKqvZMCgMuyflJLuggbNUONCvrur6yZFhTd n8rJ18VEcmqB++h643jSLezy5rETPx7BzahPxOqJsvStoq8SEFaXUR6dQNmCX5L0tggp 85Pu866aNWGDBFn7bsNHuhoUrhlj1y4eFRZ79M8aKN+hTsy3o2edcRJWWU+pITrktw2S 8bPM+Ne8Bph0mKZ0wbOyXhi2pi4QPdIQQ2pca4m8ghaGAJcwyQNfZQUqxnH8nRMeRvJo Lst6WTK/krozj/iPwhEHFEZ7gzaRLpAUTsnQQ2MqF2pgfCuPSOZXg7+aoBXc3HXA8mYP sg0Q== X-Gm-Message-State: AJaThX4n3e54fq4+UPJaP/mmWz+W8PxBo6logC5qOBRpqOoxK2MUhAoo T0UcaufOQT6hUqmbh9iBJ+Ie2YAJJV686IIbtZ+ncI5h X-Google-Smtp-Source: AGs4zMYUw/4MNDuQuoJuZVsi5bsukJ89zdkp3utxHkkkd7MQPs9zH2OXUM32+hLa8YYJ5IjPQbS5BjVbCIaiUVDHTms= X-Received: by 10.80.150.70 with SMTP id y64mr9583586eda.223.1512175138442; Fri, 01 Dec 2017 16:38:58 -0800 (PST) MIME-Version: 1.0 Received: by 10.80.179.221 with HTTP; Fri, 1 Dec 2017 16:38:57 -0800 (PST) From: Ian Lance Taylor Date: Fri, 1 Dec 2017 16:38:57 -0800 Message-ID: Subject: Go patch committed: Avoid middle-end control flow warnings To: gcc-patches , "gofrontend-dev@googlegroups.com" The GCC middle-end has started emitting "control reaches end of non-void function" warnings. This are not too useful for Go, which implements its own error for this in the frontend. Avoid the middle-end warnings for Go by 1) marking the builtin function panic and the compiler-generated function __go_runtime_error as not returning and 2) adding a default case to the switch used for select statements that simply calls __builtin_unreachable. This fixes https://golang.org/issue/22767. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian 2017-12-01 Ian Lance Taylor * go-gcc.cc (Gcc_backend::Gcc_backend): Define __builtin_unreachable. (Gcc_backend::function): Add does_not_return parameter. Index: gcc/go/go-gcc.cc =================================================================== --- gcc/go/go-gcc.cc (revision 255340) +++ gcc/go/go-gcc.cc (working copy) @@ -486,7 +486,8 @@ class Gcc_backend : public Backend Bfunction* function(Btype* fntype, const std::string& name, const std::string& asm_name, bool is_visible, bool is_declaration, bool is_inlinable, - bool disable_split_stack, bool in_unique_section, Location); + bool disable_split_stack, bool does_not_return, + bool in_unique_section, Location); Bstatement* function_defer_statement(Bfunction* function, Bexpression* undefer, @@ -760,6 +761,12 @@ Gcc_backend::Gcc_backend() const_ptr_type_node, NULL_TREE), false, false); + + // The compiler uses __builtin_unreachable for cases that can not + // occur. + this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL, + build_function_type(void_type_node, void_list_node), + true, true); } // Get an unnamed integer type. @@ -3012,8 +3019,8 @@ Bfunction* Gcc_backend::function(Btype* fntype, const std::string& name, const std::string& asm_name, bool is_visible, bool is_declaration, bool is_inlinable, - bool disable_split_stack, bool in_unique_section, - Location location) + bool disable_split_stack, bool does_not_return, + bool in_unique_section, Location location) { tree functype = fntype->get_tree(); if (functype != error_mark_node) @@ -3049,6 +3056,8 @@ Gcc_backend::function(Btype* fntype, con tree attr = get_identifier ("no_split_stack"); DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); } + if (does_not_return) + TREE_THIS_VOLATILE(decl) = 1; if (in_unique_section) resolve_unique_section(decl, 0, 1); Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 255340) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -8cd42a3e9e0e618bb09e67be73f7d2f2477a0faa +1949a203fca0c8bde6f2690ebc36427c5e3953c7 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/backend.h =================================================================== --- gcc/go/gofrontend/backend.h (revision 255340) +++ gcc/go/gofrontend/backend.h (working copy) @@ -711,12 +711,15 @@ class Backend // IS_INLINABLE is true if the function can be inlined. // DISABLE_SPLIT_STACK is true if this function may not split the stack; this // is used for the implementation of recover. + // DOES_NOT_RETURN is true for a function that does not return; this is used + // for the implementation of panic. // IN_UNIQUE_SECTION is true if this function should be put into a unique // location if possible; this is used for field tracking. virtual Bfunction* function(Btype* fntype, const std::string& name, const std::string& asm_name, bool is_visible, bool is_declaration, bool is_inlinable, - bool disable_split_stack, bool in_unique_section, Location) = 0; + bool disable_split_stack, bool does_not_return, + bool in_unique_section, Location) = 0; // Create a statement that runs all deferred calls for FUNCTION. This should // be a statement that looks like this in C++: Index: gcc/go/gofrontend/gogo.cc =================================================================== --- gcc/go/gofrontend/gogo.cc (revision 255340) +++ gcc/go/gofrontend/gogo.cc (working copy) @@ -711,7 +711,7 @@ Gogo::init_imports(std::vectorbackend()->function(fntype, user_name, init_name, true, true, true, false, - false, unknown_loc); + false, false, unknown_loc); Bexpression* pfunc_code = this->backend()->function_code_expression(pfunc, unknown_loc); Bexpression* pfunc_call = @@ -5435,8 +5435,8 @@ Function::get_or_make_decl(Gogo* gogo, N this->fndecl_ = gogo->backend()->function(functype, no->get_id(gogo), asm_name, is_visible, false, is_inlinable, - disable_split_stack, in_unique_section, - this->location()); + disable_split_stack, false, + in_unique_section, this->location()); } return this->fndecl_; } @@ -5448,6 +5448,8 @@ Function_declaration::get_or_make_decl(G { if (this->fndecl_ == NULL) { + bool does_not_return = false; + // Let Go code use an asm declaration to pick up a builtin // function. if (!this->asm_name_.empty()) @@ -5459,6 +5461,10 @@ Function_declaration::get_or_make_decl(G this->fndecl_ = builtin_decl; return this->fndecl_; } + + if (this->asm_name_ == "runtime.gopanic" + || this->asm_name_ == "__go_runtime_error") + does_not_return = true; } std::string asm_name; @@ -5475,8 +5481,8 @@ Function_declaration::get_or_make_decl(G Btype* functype = this->fntype_->get_backend_fntype(gogo); this->fndecl_ = gogo->backend()->function(functype, no->get_id(gogo), asm_name, - true, true, true, false, false, - this->location()); + true, true, true, false, does_not_return, + false, this->location()); } return this->fndecl_; Index: gcc/go/gofrontend/runtime.def =================================================================== --- gcc/go/gofrontend/runtime.def (revision 255340) +++ gcc/go/gofrontend/runtime.def (working copy) @@ -363,6 +363,9 @@ DEF_GO_RUNTIME(PRINTNL, "runtime.printnl DEF_GO_RUNTIME(FIELDTRACK, "__go_fieldtrack", P1(POINTER), R0()) +// Unreachable code. +DEF_GO_RUNTIME(UNREACHABLE, "__builtin_unreachable", P0(), R0()) + // Remove helper macros. #undef ABFT6 #undef ABFT2 Index: gcc/go/gofrontend/statements.cc =================================================================== --- gcc/go/gofrontend/statements.cc (revision 255340) +++ gcc/go/gofrontend/statements.cc (working copy) @@ -4866,8 +4866,8 @@ Select_clauses::get_backend(Translate_co Location location) { size_t count = this->clauses_.size(); - std::vector > cases(count); - std::vector clauses(count); + std::vector > cases(count + 1); + std::vector clauses(count + 1); Type* int_type = Type::lookup_integer_type("int"); @@ -4905,10 +4905,15 @@ Select_clauses::get_backend(Translate_co return context->backend()->expression_statement(bfunction, bcall); } + Bfunction* bfunction = context->function()->func_value()->get_decl(); + + Expression* crash = Runtime::make_call(Runtime::UNREACHABLE, location, 0); + Bexpression* bcrash = crash->get_backend(context); + clauses[count] = context->backend()->expression_statement(bfunction, bcrash); + std::vector statements; statements.reserve(2); - Bfunction* bfunction = context->function()->func_value()->get_decl(); Bstatement* switch_stmt = context->backend()->switch_statement(bfunction, bcall, cases,