From patchwork Tue Apr 5 16:22:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 606559 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 3qfYzy08n1z9t5m for ; Wed, 6 Apr 2016 02:22:52 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Zq6I+i4k; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:cc:message-id:date:mime-version:content-type; q= dns; s=default; b=FJunwBkxWNjTeZFyUgWH7+IZCTYGq9C/HReZILKbuUmeT5 2ARFF9g75Zf+IWKgcy+AbA7oHQnBsGVhU+fcUdiBZW39tfibYqmlgE2S6JoD+Tu+ tvtWfHS/evlYVntiK3CEnP6o1F+F4ABNurz/P44ssX4nV27pGq34wENNKxFkA= 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:to :from:subject:cc:message-id:date:mime-version:content-type; s= default; bh=8WWwayZ9zKAtWbs3NRrKzM2e460=; b=Zq6I+i4kxi4yqf+OEmTu Yogp9w+QBcDk+zY4ICwLbr30oHTofxwbfM3YZWAXk7oSqw3qESlAsihNW7qNb7XV Y4xrWaE0sSuTkM7bAMG3IZ7242H+aoEG1nPVJvToD4PvhyxdeUL/QSGGqI9mH6nl mOimBRn2FaIpIuP10KpoU1o= Received: (qmail 51902 invoked by alias); 5 Apr 2016 16:22:45 -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 51886 invoked by uid 89); 5 Apr 2016 16:22:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Accept, macro.c, macroc, UD:macro.c 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, 05 Apr 2016 16:22:41 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D0B6B804E0; Tue, 5 Apr 2016 16:22:39 +0000 (UTC) Received: from bigtime.twiddle.net (ovpn-113-227.phx2.redhat.com [10.3.113.227]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u35GMcAl004514; Tue, 5 Apr 2016 12:22:39 -0400 To: gcc-patches@gcc.gnu.org From: Richard Henderson Subject: [PATCH, cpp] Fix pr61817 and 69391 Cc: David Malcolm , "Joseph S. Myers" Message-ID: <5703E64D.3090503@redhat.com> Date: Tue, 5 Apr 2016 09:22:37 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.1 MIME-Version: 1.0 X-IsSubscribed: yes These two related PRs are all about remembering where a macro is expanded. Worse, we've got two competing goals -- the real location of the expansion, for __LINE__, and the virtual location of the expansion, for diagnostics. There seems to be no way to unify the two competing goals. If we simply "fix" the first, we break the second. Therefore, I resort to passing down both locations. Ok? r~ * internal.h (_cpp_builtin_macro_text): Update decl. * macro.c (_cpp_builtin_macro_text): Accept location for __LINE__. (builtin_macro): Accept a second location for __LINE__. (enter_macro_context): Compute both virtual and real expansion locations for the macro. * gcc.dg/pr61817.c: New test. * gcc.dg/pr69391-1.c: New test. * gcc.dg/pr69391-2.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr61817.c b/gcc/testsuite/gcc.dg/pr61817.c new file mode 100644 index 0000000..4230485 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr61817.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -ftrack-macro-expansion=0" } */ + +#define A(x) _Static_assert(x, #x) +#define F(x, y, z) a = __LINE__, b = x ## y, c = z + +enum { +#line 10 + F + ( + __LI, + NE__, + __LINE__ + ) +}; + +A(a == 15); +A(b == 15); +A(c == 15); diff --git a/gcc/testsuite/gcc.dg/pr69391-1.c b/gcc/testsuite/gcc.dg/pr69391-1.c new file mode 100644 index 0000000..15e49dc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69391-1.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftrack-macro-expansion=0" } */ +#define STR_I(X) #X +#define STR(X) STR_I(X) +#define LINE STR(__LINE__) STR(__LINE__) +int main() +{ + const char *s = LINE; + if (s[0] != '8' || s[1] != '8') + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr69391-2.c b/gcc/testsuite/gcc.dg/pr69391-2.c new file mode 100644 index 0000000..7d2faae --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69391-2.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftrack-macro-expansion=1" } */ +#define STR_I(X) #X +#define STR(X) STR_I(X) +#define LINE STR(__LINE__) STR(__LINE__) +int main() +{ + const char *s = LINE; + if (s[0] != '8' || s[1] != '8') + __builtin_abort (); + return 0; +} diff --git a/libcpp/internal.h b/libcpp/internal.h index bafd480..9ce8707 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -626,7 +626,8 @@ extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *, extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *, unsigned int); extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, - cpp_hashnode *); + cpp_hashnode *, + source_location = 0); extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *, const cpp_token *, unsigned int); diff --git a/libcpp/macro.c b/libcpp/macro.c index 759fbe7..c251553 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -93,7 +93,8 @@ struct macro_arg_saved_data { static int enter_macro_context (cpp_reader *, cpp_hashnode *, const cpp_token *, source_location); -static int builtin_macro (cpp_reader *, cpp_hashnode *, source_location); +static int builtin_macro (cpp_reader *, cpp_hashnode *, + source_location, source_location); static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, const cpp_token **, unsigned int); static void push_extended_tokens_context (cpp_reader *, cpp_hashnode *, @@ -229,7 +230,8 @@ static const char * const monthnames[] = /* Helper function for builtin_macro. Returns the text generated by a builtin macro. */ const uchar * -_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) +_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, + source_location loc) { const uchar *result = NULL; linenum_type number = 1; @@ -319,11 +321,14 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) case BT_SPECLINE: /* If __LINE__ is embedded in a macro, it must expand to the line of the macro's invocation, not its definition. - Otherwise things like assert() will not work properly. */ - number = linemap_get_expansion_line (pfile->line_table, - CPP_OPTION (pfile, traditional) - ? pfile->line_table->highest_line - : pfile->cur_token[-1].src_loc); + Otherwise things like assert() will not work properly. + See WG14 N1911, WG21 N4220 sec 6.5, and PR 61861. */ + if (CPP_OPTION (pfile, traditional)) + loc = pfile->line_table->highest_line; + else + loc = linemap_resolve_location (pfile->line_table, loc, + LRK_MACRO_EXPANSION_POINT, NULL); + number = linemap_get_expansion_line (pfile->line_table, loc); break; /* __STDC__ has the value 1 under normal circumstances. @@ -417,7 +422,8 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) return the token to the caller. LOC is the location of the expansion point of the macro. */ static int -builtin_macro (cpp_reader *pfile, cpp_hashnode *node, source_location loc) +builtin_macro (cpp_reader *pfile, cpp_hashnode *node, + source_location loc, source_location expand_loc) { const uchar *buf; size_t len; @@ -433,7 +439,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node, source_location loc) return _cpp_do__Pragma (pfile, loc); } - buf = _cpp_builtin_macro_text (pfile, node); + buf = _cpp_builtin_macro_text (pfile, node, expand_loc); len = ustrlen (buf); nbuf = (char *) alloca (len + 1); memcpy (nbuf, buf, len); @@ -456,8 +462,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node, source_location loc) source_location *virt_locs = NULL; _cpp_buff *token_buf = tokens_buff_new (pfile, 1, &virt_locs); const line_map_macro * map = - linemap_enter_macro (pfile->line_table, node, - token->src_loc, 1); + linemap_enter_macro (pfile->line_table, node, loc, 1); tokens_buff_add_token (token_buf, virt_locs, token, pfile->line_table->builtin_location, pfile->line_table->builtin_location, @@ -1231,22 +1236,29 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, pfile->about_to_expand_macro_p = false; /* Handle built-in macros and the _Pragma operator. */ { - source_location loc; + source_location loc, expand_loc; + if (/* The top-level macro invocation that triggered the expansion we are looking at is with a standard macro ...*/ !(pfile->top_most_macro_node->flags & NODE_BUILTIN) /* ... and it's a function-like macro invocation. */ && pfile->top_most_macro_node->value.macro->fun_like) - /* Then the location of the end of the macro invocation is the - location of the closing parenthesis. */ - loc = pfile->cur_token[-1].src_loc; + { + /* Then the location of the end of the macro invocation is the + location of the closing parenthesis. */ + loc = pfile->cur_token[-1].src_loc; + expand_loc = loc; + } else - /* Otherwise, the location of the end of the macro invocation is - the location of the expansion point of that top-level macro - invocation. */ - loc = location; + { + /* Otherwise, the location of the end of the macro invocation is + the location of the expansion point of that top-level macro + invocation. */ + loc = location; + expand_loc = pfile->invocation_location; + } - return builtin_macro (pfile, node, loc); + return builtin_macro (pfile, node, loc, expand_loc); } }