From patchwork Fri Nov 8 23:12:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 1192307 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-512863-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yJ5Nx6sC"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=verizon.net header.i=@verizon.net header.b="LDUR59CR"; 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 478wzm5zd2z9sP4 for ; Sat, 9 Nov 2019 10:13:08 +1100 (AEDT) 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:reply-to:subject:message-id:date:mime-version:content-type :references; q=dns; s=default; b=Hg/SrLVtlBtgIl7+nyF3SBZwJBYIog3 RWH8ZLbAQb/o4kA8xu3wyRCqpf5nYoBrMz/VeaE2wBxM8m3OSbmoiznHuU+jFlwO vRTpveRTXWY++2eaaXvjWaer/i3VDHTqTwhi/b2q3Mf89PLWz+IymuKB9m4Wq29F GfjkLs9llnjQ= 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:reply-to:subject:message-id:date:mime-version:content-type :references; s=default; bh=1GOtu9TCoGNzV3zt0+s+BD76K6s=; b=yJ5Nx 6sCC2Ewlc6Fy/1Lg8Bi6hWq8lHPvf53LBokh86W6BxqjeA2TdY7vhe+mQAPwjzlB TvUfmPke7b87vOi+gssbiC0Xi95CvM7oZe7ncUlp7DGAovdkkvZfw0pbujrKrrjg cx7BvF1btQh9LTrxvtaEKGzEsFsYMXWjRtO+fo= Received: (qmail 112442 invoked by alias); 8 Nov 2019 23:12:53 -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 112425 invoked by uid 89); 8 Nov 2019 23:12:53 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=H*r:sk:sonic.g, H*RU:sk:sonic31, HX-HELO:sk:sonic31, HX-Spam-Relays-External:sk:sonic31 X-HELO: sonic313-9.consmr.mail.ne1.yahoo.com Received: from sonic313-9.consmr.mail.ne1.yahoo.com (HELO sonic313-9.consmr.mail.ne1.yahoo.com) (66.163.185.32) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 08 Nov 2019 23:12:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=verizon.net; s=a2048; t=1573254767; bh=cQwN5cAHDSONVHNIzCfsAb84diRYuoHTzO5VpC4hHto=; h=To:From:Subject:Date:References:From:Subject; b=LDUR59CRhgrBCe/yciDmP0FgnN1WdJWntJhUBsE1BCJIElQkxtkX0LvNxXimrK1D4Ru3MzWZQuhUHHWUrADtIC69F68kob8U/QZQvQW/q3+940bVqHyZp7QblAxwemy817lMiu74x7bLU0FqtJpb3ZFNy4eNUy1X03LeCGTesMmsBZqZ6377mOoXDGzES+xv9CLsVTJYk7/3qdFwFlcHuO3d1kKfgzslypp6KjcNApvINE40/+Hx3JAvArMvZO9+soeylMXaNyxd69PFjrmJ5yeGKabEE+MiHmVbN3jXDj8MpBQ7vOWS1V7iJa37odv3/ZUQE/0ZBk+AJ2fepbOLzg== Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Fri, 8 Nov 2019 23:12:47 +0000 Received: by smtp420.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID a7c49af605f080fbbf55733b36c553af; Fri, 08 Nov 2019 23:12:43 +0000 (UTC) To: Jonathan Wakely , "libstdc++@gcc.gnu.org" , gcc-patches X-Patchwork-Original-From: "Ed Smith-Rowland via gcc-patches" From: "Li, Pan2 via Gcc-patches" Reply-To: Ed Smith-Rowland <3dw4rd@verizon.net> Subject: [RFC, libstdc++] Implement C++20 P1208R6 - source_location. Message-ID: <71d6be45-bf71-2df4-4838-9bf092c234be@verizon.net> Date: Fri, 8 Nov 2019 18:12:42 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 References: <71d6be45-bf71-2df4-4838-9bf092c234be.ref@verizon.net> As an experiment, I took a shot at implementing source_location for C++20.?? This was mostly done in experimental but I wanted to try adding column information.?? (The experimental version just returned 0).?? I added __builtin_COLUMN in analogy to __builtin_LINE.?? The std version is also consteval so you get different results in some cases wrt experimental. You can diff the two 1.cc test cases in libstdc++ to see for yourself. As Jonathan mentioned on IRC, we probably want a single builtin and we want to coordinate the name with clang (__builtin_source_location?).?? But this "works" and it might make useful fodder for the next round. Ed gcc/ChangeLog 2019-11-08 Ed Smith-Rowland <3dw4rd@verizon.net> Implement C++20 P1208R6 - source_location. Implement column with a __builtin_COLUMN for both std and experimental. The std current() is consteval. * builtins.c (fold_builtin_COLUMN): New function. (fold_builtin_0): Use it. * builtins.def: Add __builtin_COLUMN. * doc/extend.texi: Doc __builtin_COLUMN. * testsuite/c-c++-common/builtin_location.c: __builtin_COLUMN() tests. * testsuite/c-c++-common/cpp/has-builtin-2.c: __builtin_COLUMN test. libstdc++-v3/ChangeLog 2019-11-08 Ed Smith-Rowland <3dw4rd@verizon.net> Implement C++20 P1208R6 - source_location. Implement column with a __builtin_COLUMN for both std and experimental. The std current() is consteval. * include/experimental/source_location: Call __builtin_COLUMN * include/std/source_location: New header. * include/std/version: Add * testsuite/20_util/source_location/1.cc: New test. * libstdc++-v3/testsuite/experimental/source_location/1.cc: Test column. Index: gcc/builtins.c =================================================================== --- gcc/builtins.c (revision 277745) +++ gcc/builtins.c (working copy) @@ -9500,6 +9500,14 @@ return build_int_cst (type, LOCATION_LINE (loc)); } +/* Fold a call to __builtin_COLUMN to an integer constant. */ + +static inline tree +fold_builtin_COLUMN (location_t loc, tree type) +{ + return build_int_cst (type, LOCATION_COLUMN (loc)); +} + /* Fold a call to built-in function FNDECL with 0 arguments. This function returns NULL_TREE if no simplification was possible. */ @@ -9519,6 +9527,9 @@ case BUILT_IN_LINE: return fold_builtin_LINE (loc, type); + case BUILT_IN_COLUMN: + return fold_builtin_COLUMN (loc, type); + CASE_FLT_FN (BUILT_IN_INF): CASE_FLT_FN_FLOATN_NX (BUILT_IN_INF): case BUILT_IN_INFD32: Index: gcc/builtins.def =================================================================== --- gcc/builtins.def (revision 277745) +++ gcc/builtins.def (working copy) @@ -1048,6 +1048,7 @@ DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_COLUMN, "COLUMN", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST) /* Synchronization Primitives. */ #include "sync-builtins.def" Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 277745) +++ gcc/doc/extend.texi (working copy) @@ -13154,6 +13154,13 @@ of the call to @var{F}. @end deftypefn +@deftypefn {Built-in Function} int __builtin_COLUMN () +This function returns a constant integer expression that evaluates to +the column number of the invocation of the built-in. When used as a C++ +default argument for a function @var{F}, it returns the line number +of the call to @var{F}. +@end deftypefn + @deftypefn {Built-in Function} {const char *} __builtin_FUNCTION () This function is the equivalent of the @code{__FUNCTION__} symbol and returns an address constant pointing to the name of the function Index: libstdc++-v3/include/experimental/source_location =================================================================== --- libstdc++-v3/include/experimental/source_location (revision 277745) +++ libstdc++-v3/include/experimental/source_location (working copy) @@ -52,7 +52,7 @@ current(const char* __file = __builtin_FILE(), const char* __func = __builtin_FUNCTION(), int __line = __builtin_LINE(), - int __col = 0) noexcept + int __col = __builtin_COLUMN()) noexcept { source_location __loc; __loc._M_file = __file; Index: libstdc++-v3/include/std/source_location =================================================================== --- libstdc++-v3/include/std/source_location (nonexistent) +++ libstdc++-v3/include/std/source_location (working copy) @@ -0,0 +1,95 @@ +// -*- C++ -*- + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file include/source_location + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_SOURCE_LOCATION +#define _GLIBCXX_SOURCE_LOCATION 1 + +#include + +namespace std { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +#define __cpp_lib_source_location 201907L + + struct source_location + { +#ifndef _GLIBCXX_USE_C99_STDINT_TR1 + private: + using uint_least32_t = unsigned; + public: +#endif + + // source_location creation + + static consteval source_location + current(const char* __file = __builtin_FILE(), + const char* __func = __builtin_FUNCTION(), + int __line = __builtin_LINE(), + int __col = __builtin_COLUMN()) noexcept + { + source_location __loc; + __loc._M_file = __file; + __loc._M_func = __func; + __loc._M_line = __line; + __loc._M_col = __col; + return __loc; + } + + constexpr source_location() noexcept + : _M_file("unknown"), _M_func(_M_file), _M_line(0), _M_col(0) + { } + + // source_location field access + + constexpr uint_least32_t + line() const noexcept + { return this->_M_line; } + + constexpr uint_least32_t + column() const noexcept + { return this->_M_col; } + + constexpr const char* + file_name() const noexcept + { return this->_M_file; } + + constexpr const char* + function_name() const noexcept + { return this->_M_func; } + + private: + const char* _M_file; + const char* _M_func; + uint_least32_t _M_line; + uint_least32_t _M_col; + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // _GLIBCXX_SOURCE_LOCATION Index: libstdc++-v3/include/std/version =================================================================== --- libstdc++-v3/include/std/version (revision 277745) +++ libstdc++-v3/include/std/version (working copy) @@ -173,6 +173,7 @@ #define __cpp_lib_math_constants 201907L #define __cpp_lib_span 201902L #define __cpp_lib_to_array 201907L +#define __cpp_lib_source_location 201907L #endif // C++2a #endif // C++17 #endif // C++14 Index: libstdc++-v3/testsuite/20_util/source_location/1.cc =================================================================== --- libstdc++-v3/testsuite/20_util/source_location/1.cc (nonexistent) +++ libstdc++-v3/testsuite/20_util/source_location/1.cc (working copy) @@ -0,0 +1,118 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++2a } } +// { dg-require-cstdint "" } +#include +#include +#include +#include +#include +using std::source_location; +using std::string_view; + +void +test01() +{ + constexpr source_location loc = source_location::current(); + static_assert( loc.line() == 31 ); + static_assert( loc.column() == 60 ); + static_assert( loc.file_name() == __FILE__ ); + static_assert( loc.function_name() == __FUNCTION__ ); +} + +struct S { + string_view func; + source_location loc = source_location::current(); + + S(source_location loc = source_location::current()) + : func(__FUNCTION__), loc(loc) // Values of loc will be from call-site. + {} + + S(int) + : func(__FUNCTION__) // Values of loc should be at the NSDMI above. + {} +}; + +void test02() +{ + S s0; + VERIFY( s0.loc.line() == 42 ); + VERIFY( s0.loc.column() == 52 ); + VERIFY( s0.loc.file_name() == __FILE__ ); + VERIFY( s0.loc.function_name() == "" ); // Not inside ctor. + + S s1(1); + VERIFY( s1.loc.line() == 40 ); + VERIFY( s1.loc.file_name() == __FILE__ ); + VERIFY( s1.loc.function_name() == "" ); // No function, class member. +} + +source_location f(source_location a = source_location::current()) { + return a; +} + +source_location g(string_view& func) { + source_location a = source_location::current(); + func = __FUNCTION__; + return a; +} + +void test03() +{ + auto loc = f(); // f's first argument corresponds to the definition above + VERIFY( loc.line() == 65 ); + VERIFY( loc.column() == 64 ); + VERIFY( loc.file_name() == __FILE__ ); + VERIFY( loc.function_name() == "" ); + + source_location c = source_location::current(); + loc = f(c); // f's first argument gets the same values as c, above + VERIFY( loc.line() == 83 ); + VERIFY( loc.column() == 48 ); + VERIFY( loc.file_name() == __FILE__ ); + VERIFY( loc.function_name() == __FUNCTION__ ); + + string_view func; + loc = g(func); + VERIFY( loc.line() == 70 ); + VERIFY( loc.column() == 48 ); + VERIFY( loc.file_name() == __FILE__ ); + VERIFY( loc.function_name() == func ); +} + +void +test04() +{ + using std::is_same_v; + using std::uint_least32_t; + auto loc = source_location::current(); + static_assert(is_same_v); + static_assert(is_same_v); + static_assert(is_same_v); + static_assert(is_same_v); + static_assert(is_same_v); +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); +} Index: libstdc++-v3/testsuite/experimental/source_location/1.cc =================================================================== --- libstdc++-v3/testsuite/experimental/source_location/1.cc (revision 277745) +++ libstdc++-v3/testsuite/experimental/source_location/1.cc (working copy) @@ -30,7 +30,7 @@ { constexpr source_location loc = source_location::current(); static_assert( loc.line() == 31 ); - // static_assert( loc.column() == 35 ); + static_assert( loc.column() == 60 ); VERIFY( loc.file_name() == __FILE__ ); VERIFY( loc.function_name() == string_view(__FUNCTION__) ); } @@ -52,7 +52,7 @@ { S s0; VERIFY( s0.loc.line() == 53 ); - // static_assert( s0.loc.column() == 7 ); + VERIFY( s0.loc.column() == 5 ); VERIFY( s0.loc.file_name() == __FILE__ ); VERIFY( s0.loc.function_name() == string_view(__FUNCTION__) ); @@ -76,7 +76,7 @@ { auto loc = f(); // f's first argument corresponds to this line of code VERIFY( loc.line() == 77 ); - // static_assert( loc.column() == 16 ); + VERIFY( loc.column() == 16 ); VERIFY( loc.file_name() == __FILE__ ); VERIFY( loc.function_name() == string_view(__FUNCTION__) ); @@ -83,7 +83,7 @@ source_location c = source_location::current(); loc = f(c); // f's first argument gets the same values as c, above VERIFY( loc.line() == 83 ); - // static_assert( loc.column() == 23 ); + VERIFY( loc.column() == 48 ); VERIFY( loc.file_name() == __FILE__ ); VERIFY( loc.function_name() == string_view(__FUNCTION__) ); @@ -90,7 +90,7 @@ string_view func; loc = g(func); VERIFY( loc.line() == 70 ); - // static_assert( loc.column() == 23 ); + VERIFY( loc.column() == 48 ); VERIFY( loc.file_name() == __FILE__ ); VERIFY( loc.function_name() == func ); } Index: gcc/testsuite/c-c++-common/builtin_location.c =================================================================== --- gcc/testsuite/c-c++-common/builtin_location.c (revision 277745) +++ gcc/testsuite/c-c++-common/builtin_location.c (working copy) @@ -55,3 +55,11 @@ struct S { unsigned bitfield: __builtin_LINE (); } s; Assert (__builtin_constant_p (__builtin_LINE ())); + +/* Verify that __builtin_COLUMN () yields an integer constant expression. */ +#line 23 +int aC [__builtin_COLUMN ()][__builtin_COLUMN ()]; +enum FC { f0 = __builtin_LINE () }; +struct SC { unsigned bitfield: __builtin_COLUMN (); } s; + +Assert (__builtin_constant_p (__builtin_COLUMN ())); Index: gcc/testsuite/c-c++-common/cpp/has-builtin-2.c =================================================================== --- gcc/testsuite/c-c++-common/cpp/has-builtin-2.c (revision 277745) +++ gcc/testsuite/c-c++-common/cpp/has-builtin-2.c (working copy) @@ -64,6 +64,10 @@ # error "__has_builtin (__builtin_LINE) failed" #endif +#if !__has_builtin (__builtin_COLUMN) +# error "__has_builtin (__builtin_COLUMN) failed" +#endif + #if !__has_builtin (__builtin_object_size) # error "__has_builtin (__builtin_object_size) failed" #endif