From patchwork Fri Jan 27 18:52:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Diego Novillo X-Patchwork-Id: 138275 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 97F2DB6F9D for ; Sat, 28 Jan 2012 05:52:57 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1328295177; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Received:Received:To:Subject:Message-Id:Date: From:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=p4jgMRY yQZX0l++kf9np517XTNg=; b=rqIz+cNihMjshNCsu3K0wWuKsDhDO9/X1r1Ptx7 bwtAfh9wmAiLTLvu+FtU7SrXKjRvpLaiteaJ7k/NBAnuuELeThw2sdTBoWfj+dko T/Ss7YtJTvA9kXKhN8CP+/+I+7iwSNCDqKulMtCd3vmReB/OQ43q5qd2l3V4Nywf GRMc= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Received:Received:To:Subject:Message-Id:Date:From:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=sfLmUhz/nZGPU3XmvRJpzarL1vZ8/spkyqxnommvGFYxjSmiFkTvzMS0/AEaxy lfk5jVdkka3ZFZ7MAnZLTkRNsD6WyawPMoDV0P1gilUDKN3d6sAC4pDF3nIsyo9i +Q9G37YZcURBan054mxeV6y4IRrZIzZ9nfURoKytwNN/s=; Received: (qmail 19523 invoked by alias); 27 Jan 2012 18:52:54 -0000 Received: (qmail 19513 invoked by uid 22791); 27 Jan 2012 18:52:52 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_LOW, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-ee0-f73.google.com (HELO mail-ee0-f73.google.com) (74.125.83.73) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 27 Jan 2012 18:52:39 +0000 Received: by eekb57 with SMTP id b57so107415eek.2 for ; Fri, 27 Jan 2012 10:52:38 -0800 (PST) Received: by 10.14.4.212 with SMTP id 60mr445068eej.5.1327690358137; Fri, 27 Jan 2012 10:52:38 -0800 (PST) Received: by 10.14.4.212 with SMTP id 60mr445054eej.5.1327690358006; Fri, 27 Jan 2012 10:52:38 -0800 (PST) Received: from hpza10.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id g43si5760282eea.0.2012.01.27.10.52.37 (version=TLSv1/SSLv3 cipher=AES128-SHA); Fri, 27 Jan 2012 10:52:38 -0800 (PST) Received: from tobiano.tor.corp.google.com (tobiano.tor.corp.google.com [172.29.41.6]) by hpza10.eem.corp.google.com (Postfix) with ESMTP id 9E720200059; Fri, 27 Jan 2012 10:52:37 -0800 (PST) Received: by tobiano.tor.corp.google.com (Postfix, from userid 54752) id 99FD0AE1D7; Fri, 27 Jan 2012 13:52:36 -0500 (EST) To: reply@codereview.appspotmail.com, crowl@google.com, gcc-patches@gcc.gnu.org Subject: [pph] Fix ICE with circular #includes (issue5588046) Message-Id: <20120127185236.99FD0AE1D7@tobiano.tor.corp.google.com> Date: Fri, 27 Jan 2012 13:52:36 -0500 (EST) From: dnovillo@google.com (Diego Novillo) 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 When generating PPH images, circular #includes cannot be handled using the usual double-guard inclusion in the pre-processor. This happens because we generate PPH images in separate compilations. So, even with properly double-guarded headers, each header will include the other in its image: 1.h #ifndef _1_H #define _1_H #include "2.h" #endif 2.h #ifndef _2_H #define _2_H #include "1.h" #endif When compiling 1.h, we will try open 2.pph, which in turn includes 1.h, which is being generated. To avoid this situation, we simply force the inclusion of 1.h to proceed as a text inclusion. When adding a test for this, I ran into trouble with the testing harness. The test would fail depending on which PPH images were already present in the build directory. So, I modified pph.exp to remove all the PPH images before starting the main test loop. I think this will not work in a remote test setting, but I will deal with that later. 2012-01-27 Diego Novillo cp/ChangeLog.pph * pph-core.c (pph_stream_open): If STREAM exists and its mode is different than the mode in which it was originally opened, return NULL. testsuite/ChangeLog.pph * g++.dg/pph/pph.exp: Remove PPH images before running the tests. * g++.dg/pph/x1circular.h: New. * g++.dg/pph/x2circular.h: New. * g++.dg/pph/x3circular.cc: New. --- This patch is available for review at http://codereview.appspot.com/5588046 diff --git a/gcc/cp/pph-core.c b/gcc/cp/pph-core.c index f252720..5f6c27f 100644 --- a/gcc/cp/pph-core.c +++ b/gcc/cp/pph-core.c @@ -1117,7 +1117,9 @@ pph_stream_unregister (pph_stream *stream) /* Create a new PPH stream to be stored on the file called NAME. - MODE is passed to fopen directly. */ + MODE is passed to fopen directly. If NAME could not be opened, + return NULL to indicate to the caller that it should process NAME + as a regular text header. */ pph_stream * pph_stream_open (const char *name, const char *mode) @@ -1130,6 +1132,15 @@ pph_stream_open (const char *name, const char *mode) stream = pph_stream_registry_lookup (name); if (stream) { + /* In a circular #include scenario, we will eventually try to + read from the same PPH image that we are generating. To + avoid that problem, detect circularity and return NULL to + force the caller to process NAME as a regular text header. */ + if (stream->write_p && strchr (mode, 'r') != NULL) + return NULL; + + /* Otherwise, assert that we have read (or are reading) STREAM + and return it. */ gcc_assert (stream->in_memory_p); return stream; } diff --git a/gcc/testsuite/g++.dg/pph/pph.exp b/gcc/testsuite/g++.dg/pph/pph.exp index a632365..7df3596 100644 --- a/gcc/testsuite/g++.dg/pph/pph.exp +++ b/gcc/testsuite/g++.dg/pph/pph.exp @@ -41,6 +41,14 @@ exec echo "string.h string.pph" >> pph.map set mapflag -fpph-map=pph.map +# Remove all existing PPH images to prevent stale state issues. +verbose "Removing existing PPH images" 0 +set pph_file_list "[glob -nocomplain *.pph]" +foreach pph_file $pph_file_list { + remote_file build delete $pph_file +} + +verbose "Running PPH tests" 0 foreach scenario $scenarios { set old_dg_do_what_default "${dg-do-what-default}" diff --git a/gcc/testsuite/g++.dg/pph/x1circular.h b/gcc/testsuite/g++.dg/pph/x1circular.h new file mode 100644 index 0000000..5b9f744 --- /dev/null +++ b/gcc/testsuite/g++.dg/pph/x1circular.h @@ -0,0 +1,8 @@ +#ifndef X1_CIRCULAR_H +#define X1_CIRCULAR_H +/* We are purposely generating a circular #include chain. Neither + header will be able to open the other one as their images are + being generated. */ +#include "x2circular.h" // { dg-warning "cannot open PPH file x2circular.pph.*" } +int foo(int, int); +#endif diff --git a/gcc/testsuite/g++.dg/pph/x2circular.h b/gcc/testsuite/g++.dg/pph/x2circular.h new file mode 100644 index 0000000..d276f28 --- /dev/null +++ b/gcc/testsuite/g++.dg/pph/x2circular.h @@ -0,0 +1,7 @@ +#ifndef X2_CIRCULAR_H +#define X2_CIRCULAR_H +int bar(int, int); + +#include "x1circular.h" + +#endif diff --git a/gcc/testsuite/g++.dg/pph/x3circular.cc b/gcc/testsuite/g++.dg/pph/x3circular.cc new file mode 100644 index 0000000..410cba5 --- /dev/null +++ b/gcc/testsuite/g++.dg/pph/x3circular.cc @@ -0,0 +1,21 @@ +// { dg-do run } +#include "x2circular.h" + +extern "C" { void abort(void); } + +int bar(int x, int y) +{ + return x - y; +} + +int foo(int x, int y) +{ + return bar (x, y) + x + y; +} + +int main(void) +{ + if (foo (0, 0) != 0) + abort (); + return 0; +}