From patchwork Tue Jul 15 13:32:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 369994 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 BD76C14009B for ; Tue, 15 Jul 2014 23:32:41 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type; q=dns; s=default; b=ENzuIcNtvTLxyfDM F7I35hs/krl2sFvSgZV8HPOFiopdBLCZ49Vy41wCOshNmqKWtr9eXJoLqvN4/dM+ YixoxJO1mY+HLRlY6CN7c7Hn1FiUs+AWzyeGA4t4cC+bpn79jhyO2Qt+mEaYOsvk RswSWQE2gCGdA0noz4gihX4jb8c= 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:from :to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type; s=default; bh=wKPlQmPlQmD13h6YV60ytl 3h5Ls=; b=A4D9/fKv9MvcfP3jYEVVAbNVqIMSXJVL5vWEdtRjo26Tpm/HIykGSK XGKVwAU3xpTevtbolq49h45dnN/l2Ev2oDcESZtR2eifspCMjgTrHYML2MxC+fPZ 429magJ6Y4UsqpCn0GZ1pD9xBBAfChQQ72Rp5pGu525yDOTf5ULHc= Received: (qmail 24256 invoked by alias); 15 Jul 2014 13:32:34 -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 24243 invoked by uid 89); 15 Jul 2014 13:32:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.8 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 15 Jul 2014 13:32:30 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s6FDWSbC021083 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jul 2014 09:32:28 -0400 Received: from localhost (ovpn-116-30.ams2.redhat.com [10.36.116.30]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s6FDWQN0002463 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 15 Jul 2014 09:32:27 -0400 Received: by localhost (Postfix, from userid 1001) id 72BC4FFE; Tue, 15 Jul 2014 15:32:20 +0200 (CEST) From: Dodji Seketeli To: Jason Merrill Cc: Nicholas Ormrod , GCC Patches Subject: [PATCH 2/2] PR preprocessor/60723 - missing system-ness marks for macro tokens References: <87d2du4xsu.fsf@redhat.com> <53ADD6C2.9030200@redhat.com> <877g3uo6cq.fsf@redhat.com> <871tu1fhjh.fsf@redhat.com> <53B9991D.7090401@redhat.com> <871ttt8l8l.fsf@redhat.com> <53BEE945.6080905@redhat.com> <86iomyvkai.fsf@redhat.com> X-URL: http://www.redhat.com Date: Tue, 15 Jul 2014 15:32:20 +0200 In-Reply-To: <86iomyvkai.fsf@redhat.com> (Dodji Seketeli's message of "Tue, 15 Jul 2014 15:11:33 +0200") Message-ID: <868unuvjbv.fsf_-_@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Hello, When a system macro is expanded in a non-system file during out-of-line preprocessing, it can happen that the preprocessor forgets to emit line markers to express the system-ness status of tokens that come after the expansion of the macro. That can lead to situations where the entire non-system file can be considered as being a system file and thus have its warnings be discarded during the compilation of the resulting preprocessed file. My understanding is that this is due to the preprocessor not systematically detecting (and reporting) the change in system-ness of tokens. And this is what this patch does. Each time the system-ness of a given token is different from the previous token that was emitted by the preprocessor, it emits a line marker for the sole purpose of marking the new system-ness of the subsequent tokens to come. The patch also avoids emitting either adjacent line change markers or line markers in case of tokens originating from built-in macro expansion. Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. gcc/c-family/ChangeLog: * c-ppoutput.c (struct print::prev_was_system_token): New data member. (init_pp_output): Initialize it. (maybe_print_line_1, maybe_print_line, print_line_1, print_line) (do_line_change): Return a flag saying if a line marker was emitted or not. (scan_translation_unit): Detect if the system-ness of the token we are about to emit is different from the one of the previously emitted token. If so, emit a line marker. Avoid emitting useless adjacent line markers. Avoid emitting line markers for tokens originating from the expansion of built-in macros. (scan_translation_unit_directives_only): Adjust. gcc/testsuite/ChangeLog: * gcc.dg/cpp/syshdr{4,5}.{c,h}: New test files. Signed-off-by: Dodji Seketeli git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212194 138bc75d-0d04-0410-961f-82ee72b054a4 Signed-off-by: Dodji Seketeli --- gcc/c-family/c-ppoutput.c | 81 +++++++++++++++++++++++++++----------- gcc/testsuite/gcc.dg/cpp/syshdr4.c | 24 +++++++++++ gcc/testsuite/gcc.dg/cpp/syshdr4.h | 8 ++++ gcc/testsuite/gcc.dg/cpp/syshdr5.c | 14 +++++++ gcc/testsuite/gcc.dg/cpp/syshdr5.h | 6 +++ 5 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/syshdr4.c create mode 100644 gcc/testsuite/gcc.dg/cpp/syshdr4.h create mode 100644 gcc/testsuite/gcc.dg/cpp/syshdr5.c create mode 100644 gcc/testsuite/gcc.dg/cpp/syshdr5.h diff --git a/gcc/c-family/c-ppoutput.c b/gcc/c-family/c-ppoutput.c index f3b5fa4..0292d16 100644 --- a/gcc/c-family/c-ppoutput.c +++ b/gcc/c-family/c-ppoutput.c @@ -36,6 +36,8 @@ static struct unsigned char printed; /* Nonzero if something output at line. */ bool first_time; /* pp_file_change hasn't been called yet. */ const char *src_file; /* Current source file. */ + bool prev_was_system_token; /* True if the previous token was a + system token.*/ } print; /* Defined and undefined macros being queued for output with -dU at @@ -58,11 +60,11 @@ static void account_for_newlines (const unsigned char *, size_t); static int dump_macro (cpp_reader *, cpp_hashnode *, void *); static void dump_queued_macros (cpp_reader *); -static void print_line_1 (source_location, const char*, FILE *); -static void print_line (source_location, const char *); -static void maybe_print_line_1 (source_location, FILE *); -static void maybe_print_line (source_location); -static void do_line_change (cpp_reader *, const cpp_token *, +static bool print_line_1 (source_location, const char*, FILE *); +static bool print_line (source_location, const char *); +static bool maybe_print_line_1 (source_location, FILE *); +static bool maybe_print_line (source_location); +static bool do_line_change (cpp_reader *, const cpp_token *, source_location, int); /* Callback routines for the parser. Most of these are active only @@ -156,6 +158,7 @@ init_pp_output (FILE *out_stream) print.outf = out_stream; print.first_time = 1; print.src_file = ""; + print.prev_was_system_token = false; } /* Writes out the preprocessed file, handling spacing and paste @@ -168,6 +171,7 @@ scan_translation_unit (cpp_reader *pfile) = cpp_get_options (parse_in)->lang != CLK_ASM && !flag_no_line_commands; bool in_pragma = false; + bool line_marker_emitted = false; print.source = NULL; for (;;) @@ -200,7 +204,7 @@ scan_translation_unit (cpp_reader *pfile) && do_line_adjustments && !in_pragma) { - do_line_change (pfile, token, loc, false); + line_marker_emitted = do_line_change (pfile, token, loc, false); putc (' ', print.outf); } else if (print.source->flags & PREV_WHITE @@ -216,7 +220,7 @@ scan_translation_unit (cpp_reader *pfile) if (src_line != print.src_line && do_line_adjustments && !in_pragma) - do_line_change (pfile, token, loc, false); + line_marker_emitted = do_line_change (pfile, token, loc, false); putc (' ', print.outf); } @@ -228,7 +232,7 @@ scan_translation_unit (cpp_reader *pfile) const char *space; const char *name; - maybe_print_line (token->src_loc); + line_marker_emitted = maybe_print_line (token->src_loc); fputs ("#pragma ", print.outf); c_pp_lookup_pragma (token->val.pragma, &space, &name); if (space) @@ -248,7 +252,21 @@ scan_translation_unit (cpp_reader *pfile) if (cpp_get_options (parse_in)->debug) linemap_dump_location (line_table, token->src_loc, print.outf); + + if (do_line_adjustments + && !in_pragma + && !line_marker_emitted + && print.prev_was_system_token != !!in_system_header_at(loc) + && !is_location_from_builtin_token (loc)) + /* The system-ness of this token is different from the one + of the previous token. Let's emit a line change to + mark the new system-ness before we emit the token. */ + { + do_line_change (pfile, token, loc, false); + print.prev_was_system_token = !!in_system_header_at(loc); + } cpp_output_token (token, print.outf); + line_marker_emitted = false; } /* CPP_COMMENT tokens and raw-string literal tokens can @@ -275,7 +293,7 @@ scan_translation_unit_directives_only (cpp_reader *pfile) struct _cpp_dir_only_callbacks cb; cb.print_lines = print_lines_directives_only; - cb.maybe_print_line = maybe_print_line; + cb.maybe_print_line = (void (*) (source_location)) maybe_print_line; _cpp_preprocess_dir_only (pfile, &cb); } @@ -306,11 +324,13 @@ scan_translation_unit_trad (cpp_reader *pfile) /* If the token read on logical line LINE needs to be output on a different line to the current one, output the required newlines or - a line marker, and return 1. Otherwise return 0. */ + a line marker. If a line marker was emitted, return TRUE otherwise + return FALSE. */ -static void +static bool maybe_print_line_1 (source_location src_loc, FILE *stream) { + bool emitted_line_marker = false; int src_line = LOCATION_LINE (src_loc); const char *src_file = LOCATION_FILE (src_loc); @@ -334,29 +354,34 @@ maybe_print_line_1 (source_location src_loc, FILE *stream) } } else - print_line_1 (src_loc, "", stream); + emitted_line_marker = print_line_1 (src_loc, "", stream); + return emitted_line_marker; } /* If the token read on logical line LINE needs to be output on a different line to the current one, output the required newlines or - a line marker, and return 1. Otherwise return 0. */ + a line marker. If a line marker was emitted, return TRUE otherwise + return FALSE. */ -static void +static bool maybe_print_line (source_location src_loc) { if (cpp_get_options (parse_in)->debug) linemap_dump_location (line_table, src_loc, print.outf); - maybe_print_line_1 (src_loc, print.outf); + return maybe_print_line_1 (src_loc, print.outf); } /* Output a line marker for logical line LINE. Special flags are "1" - or "2" indicating entering or leaving a file. */ + or "2" indicating entering or leaving a file. If the line marker + was effectively emitted, return TRUE otherwise return FALSE. */ -static void +static bool print_line_1 (source_location src_loc, const char *special_flags, FILE *stream) { + bool emitted_line_marker = false; + /* End any previous line of text. */ if (print.printed) putc ('\n', stream); @@ -391,33 +416,39 @@ print_line_1 (source_location src_loc, const char *special_flags, FILE *stream) fputs (" 3", stream); putc ('\n', stream); + emitted_line_marker = true; } + + return emitted_line_marker; } /* Output a line marker for logical line LINE. Special flags are "1" - or "2" indicating entering or leaving a file. */ + or "2" indicating entering or leaving a file. Return TRUE if a + line marker was effectively emitted, FALSE otherwise. */ -static void +static bool print_line (source_location src_loc, const char *special_flags) { if (cpp_get_options (parse_in)->debug) linemap_dump_location (line_table, src_loc, print.outf); - print_line_1 (src_loc, special_flags, print.outf); + return print_line_1 (src_loc, special_flags, print.outf); } -/* Helper function for cb_line_change and scan_translation_unit. */ -static void +/* Helper function for cb_line_change and scan_translation_unit. + Return TRUE if a line marker is emitted, FALSE otherwise. */ +static bool do_line_change (cpp_reader *pfile, const cpp_token *token, source_location src_loc, int parsing_args) { + bool emitted_line_marker = false; if (define_queue || undef_queue) dump_queued_macros (pfile); if (token->type == CPP_EOF || parsing_args) - return; + return false; - maybe_print_line (src_loc); + emitted_line_marker = maybe_print_line (src_loc); print.prev = 0; print.source = 0; @@ -434,6 +465,8 @@ do_line_change (cpp_reader *pfile, const cpp_token *token, while (-- spaces >= 0) putc (' ', print.outf); } + + return emitted_line_marker; } /* Called when a line of output is started. TOKEN is the first token diff --git a/gcc/testsuite/gcc.dg/cpp/syshdr4.c b/gcc/testsuite/gcc.dg/cpp/syshdr4.c new file mode 100644 index 0000000..fe001d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/syshdr4.c @@ -0,0 +1,24 @@ +/* Contributed by Nicholas Ormrod */ +/* Origin: PR preprocessor/60723 */ + +/* This tests that multi-line macro callsites, which are defined + in system headers and whose expansion contains a builtin followed + by a non-builtin token, do not generate a line directive that + mark the current file as being a system file, when performing + non-integrated preprocessing. */ +/* System files suppress div-by-zero warnings, so the presence of + such indicates the lack of the bug. + + { dg-do compile } + { dg-options -no-integrated-cpp } */ + +#include "syshdr4.h" +FOO( +) + +int +foo() +{ + return 1 / 0; /* { dg-warning "div-by-zero" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/cpp/syshdr4.h b/gcc/testsuite/gcc.dg/cpp/syshdr4.h new file mode 100644 index 0000000..c464f6e --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/syshdr4.h @@ -0,0 +1,8 @@ +/* Contributed by Nicholas Ormrod + Origin: PR preprocessor/60723. + + This file is to be included by the syshdr4.c file. */ + +#pragma GCC system_header + +#define FOO() int line = __LINE__ ; diff --git a/gcc/testsuite/gcc.dg/cpp/syshdr5.c b/gcc/testsuite/gcc.dg/cpp/syshdr5.c new file mode 100644 index 0000000..42c6263 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/syshdr5.c @@ -0,0 +1,14 @@ +/* Origin: PR preprocessor/60723 + + { dg-do compile } + { dg-options -no-integrated-cpp } */ + +#include "syshdr5.h" + +int +main() +{ + FOO(1/0 /* { dg-warning "division by zero" } */ + ); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/cpp/syshdr5.h b/gcc/testsuite/gcc.dg/cpp/syshdr5.h new file mode 100644 index 0000000..300d6c3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/syshdr5.h @@ -0,0 +1,6 @@ +/* Origin: PR preprocessor/60723 + + This header file is to be included by the syshdr5.c file. */ + +#pragma GCC system_header +#define FOO(A)do {int line = __LINE__ ; A;} while(0)