From patchwork Wed Jan 7 10:27:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 425987 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 2DB281400D5 for ; Wed, 7 Jan 2015 21:27:26 +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:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=HdOAHyY2UzeGz8gHDiGVvcK643Tqg6+37GP+BaWBiHXPhtN7Ul swuVP4xy0p18VwDGxpLZ8SNigCUue+QzooN+qYrffMOWHZeVH+UyTwG44WwoCew9 q44WiqGZRtFdfvW5WXhaqtyQ2eSm1tlho2kk0kGbi1uj+UwqKE3aZwOuI= 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:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=9m995LhgTwdPs9C6bheqOwHam5E=; b=Fe0D/5hiSL90ak0dAitv Z2y01zNmu2Cmuh7cMwaCzPgxFs8tiHmppwM+r2PiqPBgyXWYasJMDZmdY8hbAU0D ATS8VZl3WMPJERXxFymRoErgcno5E3j8f7z0/8yehhKUWYhaza1rBcG4BiEbf0K/ xaE4Ivqm3cQ0XM5ZZOa93YA= Received: (qmail 8462 invoked by alias); 7 Jan 2015 10:27:20 -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 8445 invoked by uid 89); 7 Jan 2015 10:27:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Wed, 07 Jan 2015 10:27:17 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id EFDDD116532; Wed, 7 Jan 2015 05:27:15 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id ZaOtL4bifSY0; Wed, 7 Jan 2015 05:27:15 -0500 (EST) Received: from kwai.gnat.com (kwai.gnat.com [205.232.38.4]) by rock.gnat.com (Postfix) with ESMTP id DF1D1116528; Wed, 7 Jan 2015 05:27:15 -0500 (EST) Received: by kwai.gnat.com (Postfix, from userid 4192) id DB51D91A7D; Wed, 7 Jan 2015 05:27:15 -0500 (EST) Date: Wed, 7 Jan 2015 05:27:15 -0500 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Bob Duff Subject: [Ada] Warn on suspicious Subprogram'Access Message-ID: <20150107102715.GA30373@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) This patch adds a warning on certain occurrences of Subprogram'Access that could cause an access-before-elaboration error. The following example should give a warning when compiled with the -gnatw.f switch: % gcc -c -gnatw.f -gnatwe elab_acc.adb elab_acc.ads:4:31: warning: Access attribute of "F" before body seen elab_acc.ads:4:31: warning: possible Program_Error on later references % package Elab_Acc is function F return Integer; type Funcy is access function return Integer; F_Ptr : constant Funcy := F'Access; -- Calls to F_Ptr.all before F's body can cause an -- access-before-elaboration error. end Elab_Acc; package body Elab_Acc is function F return Integer is begin return 123; end F; end Elab_Acc; Tested on x86_64-pc-linux-gnu, committed on trunk 2015-01-07 Bob Duff * sem_elab.adb (Check_Internal_Call_Continue): Give a warning for P'Access, where P is a subprogram in the same package as the P'Access, and the P'Access is evaluated at elaboration time, and occurs before the body of P. For example, "X : T := P'Access;" would allow a subsequent call to X.all to be an access-before-elaboration error; hence the warning. This warning is enabled by the -gnatw.f switch. * opt.ads (Warn_On_Elab_Access): New flag for warning switch. * warnsw.adb (Set_Dot_Warning_Switch): Set Warn_On_Elab_Access. * gnat_ugn.texi: Document the new warning. Index: gnat_ugn.texi =================================================================== --- gnat_ugn.texi (revision 219252) +++ gnat_ugn.texi (working copy) @@ -5048,6 +5048,23 @@ effect of warning on unreferenced entities other than subprogram formals. +@item -gnatw.f +@emph{Activate warnings on suspicious subprogram 'Access.} +@cindex @option{-gnatw.f} (@command{gcc}) +This switch causes a warning to be generated if @code{P'Access} occurs +in the same package where subprogram P is declared, and the +@code{P'Access} is evaluated at elaboration time, and occurs before +the body of P has been elaborated. For example, if we have +@code{X : T := P'Access;}, then if X.all is subsequently called before +the body of P is elaborated, it could cause +access-before-elaboration. The default is that these warnings are not +generated. + +@item -gnatw.F +@emph{Suppress warnings on suspicious subprogram 'Access.} +@cindex @option{-gnatw.F} (@command{gcc}) +This switch suppresses warnings for suspicious subprogram 'Access. + @item -gnatwg @emph{Activate warnings on unrecognized pragmas.} @cindex @option{-gnatwg} (@command{gcc}) Index: warnsw.adb =================================================================== --- warnsw.adb (revision 219191) +++ warnsw.adb (working copy) @@ -326,6 +326,12 @@ when 'e' => All_Warnings (True); + when 'f' => + Warn_On_Elab_Access := True; + + when 'F' => + Warn_On_Elab_Access := False; + when 'g' => Set_GNAT_Mode_Warnings; Index: sem_elab.adb =================================================================== --- sem_elab.adb (revision 219191) +++ sem_elab.adb (working copy) @@ -1990,10 +1990,21 @@ Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation; begin - -- If not function or procedure call or instantiation, then ignore - -- call (this happens in some error cases and rewriting cases). + -- For P'Access, we want to warn if the -gnatw.f switch is set, and the + -- node comes from source. - if not Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement) + if Nkind (N) = N_Attribute_Reference and then + (not Warn_On_Elab_Access or else not Comes_From_Source (N)) + then + return; + + -- If not function or procedure call, instantiation, or 'Access, then + -- ignore call (this happens in some error cases and rewriting cases). + + elsif not Nkind_In + (N, N_Function_Call, + N_Procedure_Call_Statement, + N_Attribute_Reference) and then not Inst_Case then return; @@ -2001,7 +2012,7 @@ -- Nothing to do if this is a call or instantiation that has already -- been found to be a sure ABE. - elsif ABE_Is_Certain (N) then + elsif Nkind (N) /= N_Attribute_Reference and then ABE_Is_Certain (N) then return; -- Nothing to do if errors already detected (avoid cascaded errors) @@ -2323,7 +2334,7 @@ -- Not that special case, warning and dynamic check is required -- If we have nothing in the call stack, then this is at the outer - -- level, and the ABE is bound to occur. + -- level, and the ABE is bound to occur, unless it's a 'Access. if Elab_Call.Last = 0 then Error_Msg_Warn := SPARK_Mode /= On; @@ -2331,13 +2342,19 @@ if Inst_Case then Error_Msg_NE ("cannot instantiate& before body seen<<", N, Orig_Ent); + elsif Nkind (N) /= N_Attribute_Reference then + Error_Msg_NE + ("cannot call& before body seen<<", N, Orig_Ent); else Error_Msg_NE - ("cannot call& before body seen<<", N, Orig_Ent); + ("Access attribute of & before body seen<<", N, Orig_Ent); + Error_Msg_N ("\possible Program_Error on later references<", N); end if; - Error_Msg_N ("\Program_Error [<<", N); - Insert_Elab_Check (N); + if Nkind (N) /= N_Attribute_Reference then + Error_Msg_N ("\Program_Error [<<", N); + Insert_Elab_Check (N); + end if; -- Call is not at outer level Index: opt.ads =================================================================== --- opt.ads (revision 219280) +++ opt.ads (working copy) @@ -1669,6 +1669,13 @@ -- Set to True to generate warnings for suspicious use of export or -- import pragmas. Modified by use of -gnatwx/X. + Warn_On_Elab_Access : Boolean := False; + -- GNAT + -- Set to True to generate warnings for P'Access in the case where + -- subprogram P is in the same package as the P'Access, and the P'Access is + -- evaluated at package elaboration time, and occurs before the body of P + -- has been elaborated. + Warn_On_Hiding : Boolean := False; -- GNAT -- Set to True to generate warnings if a declared entity hides another