From patchwork Tue Jun 22 08:14:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 56410 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]) by ozlabs.org (Postfix) with SMTP id 2D62CB6EDD for ; Tue, 22 Jun 2010 18:14:57 +1000 (EST) Received: (qmail 13682 invoked by alias); 22 Jun 2010 08:14:52 -0000 Received: (qmail 13669 invoked by uid 22791); 22 Jun 2010 08:14:50 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 22 Jun 2010 08:14:46 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 8377ACB025E; Tue, 22 Jun 2010 10:14:47 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FX0pu6DBltT6; Tue, 22 Jun 2010 10:14:47 +0200 (CEST) Received: from saumur.act-europe.fr (saumur.act-europe.fr [10.10.0.183]) by mel.act-europe.fr (Postfix) with ESMTP id 668EBCB024F; Tue, 22 Jun 2010 10:14:47 +0200 (CEST) Received: by saumur.act-europe.fr (Postfix, from userid 525) id 5C1F3D9B31; Tue, 22 Jun 2010 10:14:47 +0200 (CEST) Date: Tue, 22 Jun 2010 10:14:47 +0200 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Ed Schonberg Subject: [Ada] Resolution of references to predefined operators Message-ID: <20100622081447.GA9698@adacore.com> Mime-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.9i X-IsSubscribed: yes 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 A reference of the form P."+" is analyzed by verifying that there is a numeric type defined in P, and then treating both unary and binary operators as possible interpretation of the node. Subsequent analysis usually is sufficient to disambiguate the reference. In some complex overloading cases, the wrong operator may remain as a possible interpretation leading to spurious errors or crashes. This patch uses the fact that if the context is known to be a call, it is possible to discard one of the interpretations without any further type analysis, thus simplifying subsequent resolution. The following must compile quietly: procedure Crash_Op_Resolution is package Scop is type T1 is new Integer; function F return T1; procedure P1 (X : T1); type T2 is new Integer; function F return T2; procedure P2 (X : T2); end Scop; package body Scop is procedure P (X : T1) is begin null; end; procedure P1 (X : T1) is begin null; end; function F return T1 is begin return 0; end; procedure P (X : T2) is begin null; end; procedure P2 (X : T2) is begin null; end; function F return T2 is begin return 0; end; end Scop; begin Scop.P2 (Scop."+" (Scop.F, Scop.F)); end; Tested on x86_64-pc-linux-gnu, committed on trunk 2010-06-22 Ed Schonberg * sem_ch8.adb (Add_Implicit_Operator): If the context of the expanded name is a call, use the number of actuals to determine whether this is a binary or unary operator, rather than relying on later information to resolve the overload. Index: sem_ch8.adb =================================================================== --- sem_ch8.adb (revision 161073) +++ sem_ch8.adb (working copy) @@ -6029,12 +6029,43 @@ package body Sem_Ch8 is Change_Selected_Component_To_Expanded_Name (N); end if; - Add_One_Interp (N, Predef_Op, T); + -- If the context is an unanalyzed function call, determine whether + -- a binary or unary interpretation is required. - -- For operators with unary and binary interpretations, add both + if Nkind (Parent (N)) = N_Indexed_Component then + declare + Is_Binary_Call : constant Boolean + := Present (Next (First (Expressions (Parent (N))))); + Is_Binary_Op : constant Boolean + := First_Entity (Predef_Op) /= Last_Entity (Predef_Op); + Predef_Op2 : constant Entity_Id := Homonym (Predef_Op); + + begin + if Is_Binary_Call then + if Is_Binary_Op then + Add_One_Interp (N, Predef_Op, T); + else + Add_One_Interp (N, Predef_Op2, T); + end if; - if Present (Homonym (Predef_Op)) then - Add_One_Interp (N, Homonym (Predef_Op), T); + else + if not Is_Binary_Op then + Add_One_Interp (N, Predef_Op, T); + else + Add_One_Interp (N, Predef_Op2, T); + end if; + end if; + end; + + else + Add_One_Interp (N, Predef_Op, T); + + -- For operators with unary and binary interpretations, if + -- context is not a call, add both + + if Present (Homonym (Predef_Op)) then + Add_One_Interp (N, Homonym (Predef_Op), T); + end if; end if; -- The node is a reference to a predefined operator, and