From patchwork Mon Aug 19 08:39:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 1149109 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-507222-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="BDX3m83P"; 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 46BnSK1wjsz9s3Z for ; Mon, 19 Aug 2019 18:40:33 +1000 (AEST) 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=ZoBuFqADlNdzuL5GIBTJ9F2CA4S9cdUDJ4SLw/mp6VLmuBlI4R Q0mGPIQLjJ2683UVLbOw3MZVSYLLJIma6huPEbP8hjhH8IAvf5ak3IAyEFHhs6tp 8vPJJupqj9raOnsp/7zhsDRE40tSbNOXU0PiFFmLuFuRDQVUnLX3rDhhc= 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=Kf5lxk4IEvqXsDO23Hp7vG/BAKs=; b=BDX3m83PVu3YggarSsin 2IwADd77v04tNvP1ZbziaszX7v23LmQl3tPgunVAbN3rnqDXxN9FLiZyiNjfIbOw 0TzGzgdjr4rOOVuF6M/b0M+8vlt9pDncMEX0OX3vZ1luUzgqNZprdPw7tt2W9XX/ TNM+XZO8me1r9t1/nIldB1k= Received: (qmail 115572 invoked by alias); 19 Aug 2019 08:39:07 -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 115497 invoked by uid 89); 19 Aug 2019 08:39:06 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-13.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Copy 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 ESMTP; Mon, 19 Aug 2019 08:39:04 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 26BB95604F; Mon, 19 Aug 2019 04:39:01 -0400 (EDT) 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 1P4e13GIiLmc; Mon, 19 Aug 2019 04:39:01 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [205.232.38.10]) by rock.gnat.com (Postfix) with ESMTP id 147C411619A; Mon, 19 Aug 2019 04:39:01 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id 1370E6AB; Mon, 19 Aug 2019 04:39:01 -0400 (EDT) Date: Mon, 19 Aug 2019 04:39:01 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Cc: Gary Dismukes Subject: [Ada] Improve warnings about "too few elements" and "too many elements" Message-ID: <20190819083900.GA33449@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes When warning about length-check failures detected at compile time that are flagged with "too few elements" or "too many elements", the compiler now gives an additional message indicating the number of elements expected by the context versus how many are present in the conflicting expression (such as an aggregate that has too few or too many components). The test below reports the following warnings when compiled with this command: $ gcc -c -gnatj78 length_warnings.adb length_warnings.adb:6:09: warning: too few elements for subtype of "Boolean_Array" defined at line 5, expected 10 elements; found 9 elements, "Constraint_Error" will be raised at run time length_warnings.adb:10:09: warning: too few elements for subtype of "Boolean_Array" defined at line 9, expected 2 elements; found 1 element, "Constraint_Error" will be raised at run time length_warnings.adb:14:09: warning: too many elements for subtype of "Boolean_Array" defined at line 13, expected 10 elements; found 11 elements, "Constraint_Error" will be raised at run time length_warnings.adb:18:09: warning: too many elements for subtype of "Boolean_Array" defined at line 17, expected 0 elements; found 1 element, "Constraint_Error" will be raised at run time length_warnings.adb:22:09: warning: too many elements for subtype of "Boolean_Array" defined at line 21, expected 1 element; found 2 elements, "Constraint_Error" will be raised at run time procedure Length_Check_Warnings is type Boolean_Array is array (Natural range <>) of Boolean; Bits_A : Boolean_Array (1 .. 10) := (True, True, True, True, True, True, True, True, True); -- Too few elements Bits_B : Boolean_Array (1 .. 2) := (1 => False); -- Too few elements Bits_C : Boolean_Array (1 .. 10) := (True, True, True, True, True, True, True, True, True, True, True); -- Too many elements Bits_D : Boolean_Array (1 .. 0) := (1 => True); -- Too many elements Bits_E : Boolean_Array (1 .. 1) := (True, False); -- Too many elements begin null; end Length_Check_Warnings; Tested on x86_64-pc-linux-gnu, committed on trunk 2019-08-19 Gary Dismukes gcc/ada/ * checks.adb (Length_Mismatch_Info_Message): New function in Selected_Length_Checks to return a message indicating the element counts for the mismatched lengths for a failed compile-time length check. (Plural_Or_Singular_Ending): Support function in Length_Mismatch_Info_Message to return either "" or "s", for concatenating to the end of words. (Selected_Length_Checks): Pass the result of Length_Mismatch_Info_Message as an extra warning message to Compile_Time_Constraint_Error to indicate the mismatched lengths for a failed compile-time length check. * sem_util.ads (Compile_Time_Constraint_Error): Add an optional message formal (Extra_Msg), defaulted to the empty string. * sem_util.adb (Compile_Time_Constraint_Error): Output an extra message following the main warning message (when Extra_Msg is not the empty string). --- gcc/ada/checks.adb +++ gcc/ada/checks.adb @@ -9542,6 +9542,12 @@ package body Checks is -- Returns expression to compute: -- Typ'Length /= Expr'Length + function Length_Mismatch_Info_Message + (Left_Element_Count : Uint; + Right_Element_Count : Uint) return String; + -- Returns a message indicating how many elements were expected + -- (Left_Element_Count) and how many were found (Right_Element_Count). + --------------- -- Add_Check -- --------------- @@ -9729,6 +9735,36 @@ package body Checks is Right_Opnd => Get_N_Length (Expr, Indx)); end Length_N_Cond; + ---------------------------------- + -- Length_Mismatch_Info_Message -- + ---------------------------------- + + function Length_Mismatch_Info_Message + (Left_Element_Count : Uint; + Right_Element_Count : Uint) return String + is + + function Plural_Vs_Singular_Ending (Count : Uint) return String; + -- Returns an empty string if Count is 1; otherwise returns "s" + + function Plural_Vs_Singular_Ending (Count : Uint) return String is + begin + if Count = 1 then + return ""; + else + return "s"; + end if; + end Plural_Vs_Singular_Ending; + + begin + return "expected " & UI_Image (Left_Element_Count) + & " element" + & Plural_Vs_Singular_Ending (Left_Element_Count) + & "; found " & UI_Image (Right_Element_Count) + & " element" + & Plural_Vs_Singular_Ending (Right_Element_Count); + end Length_Mismatch_Info_Message; + ----------------- -- Same_Bounds -- ----------------- @@ -9923,12 +9959,16 @@ package body Checks is if L_Length > R_Length then Add_Check (Compile_Time_Constraint_Error - (Wnode, "too few elements for}??", T_Typ)); + (Wnode, "too few elements for}??", T_Typ, + Extra_Msg => Length_Mismatch_Info_Message + (L_Length, R_Length))); elsif L_Length < R_Length then Add_Check (Compile_Time_Constraint_Error - (Wnode, "too many elements for}??", T_Typ)); + (Wnode, "too many elements for}??", T_Typ, + Extra_Msg => Length_Mismatch_Info_Message + (L_Length, R_Length))); end if; -- The comparison for an individual index subtype --- gcc/ada/sem_util.adb +++ gcc/ada/sem_util.adb @@ -5358,11 +5358,12 @@ package body Sem_Util is ----------------------------------- function Compile_Time_Constraint_Error - (N : Node_Id; - Msg : String; - Ent : Entity_Id := Empty; - Loc : Source_Ptr := No_Location; - Warn : Boolean := False) return Node_Id + (N : Node_Id; + Msg : String; + Ent : Entity_Id := Empty; + Loc : Source_Ptr := No_Location; + Warn : Boolean := False; + Extra_Msg : String := "") return Node_Id is Msgc : String (1 .. Msg'Length + 3); -- Copy of message, with room for possible ?? or << and ! at end @@ -5456,6 +5457,12 @@ package body Sem_Util is Error_Msg_NEL (Msgc (1 .. Msgl), N, Etype (N), Eloc); end if; + -- Emit any extra message as a continuation + + if Extra_Msg /= "" then + Error_Msg_N ('\' & Extra_Msg, N); + end if; + if Wmsg then -- Check whether the context is an Init_Proc --- gcc/ada/sem_util.ads +++ gcc/ada/sem_util.ads @@ -465,16 +465,20 @@ package Sem_Util is -- the type itself. function Compile_Time_Constraint_Error - (N : Node_Id; - Msg : String; - Ent : Entity_Id := Empty; - Loc : Source_Ptr := No_Location; - Warn : Boolean := False) return Node_Id; + (N : Node_Id; + Msg : String; + Ent : Entity_Id := Empty; + Loc : Source_Ptr := No_Location; + Warn : Boolean := False; + Extra_Msg : String := "") return Node_Id; -- This is similar to Apply_Compile_Time_Constraint_Error in that it -- generates a warning (or error) message in the same manner, but it does -- not replace any nodes. For convenience, the function always returns its -- first argument. The message is a warning if the message ends with ?, or -- we are operating in Ada 83 mode, or the Warn parameter is set to True. + -- If Extra_Msg is not a null string, then it's associated with N and + -- emitted immediately after the main message (and before output of any + -- message indicating that Constraint_Error will be raised). procedure Conditional_Delay (New_Ent, Old_Ent : Entity_Id); -- Sets the Has_Delayed_Freeze flag of New_Ent if the Delayed_Freeze flag