From patchwork Tue Dec 6 18:45:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 86899 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp2167385qgi; Tue, 6 Dec 2016 10:45:47 -0800 (PST) X-Received: by 10.99.167.15 with SMTP id d15mr113955920pgf.167.1481049947608; Tue, 06 Dec 2016 10:45:47 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id g17si20448725pgh.51.2016.12.06.10.45.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Dec 2016 10:45:47 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-443628-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-443628-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-443628-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=dITGmBo+cAt/lXzjk iVwutEni43Ce+tnwn4vnEBs8sAJbp0DGy75AOPyYquQ1xVx5nEAgtgE72uA0mlAl /LIV7nYuAm24pfBJ+Vo0XkqmVOumvkZmpc3OILVhlVe2yW52V7Uk972g6MZZWRIZ j/sZ37Ta2kt00ymMqVCGc5fGig= 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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=F2Z0pSSYv2r6ELl1fGUV97j dFw8=; b=Bn0ARiQlOjo2KoCpgkBRXLiHwWf8fofXJeC50T0h3jlepqgr++p0BtA avpjTziz4aVOx37dM4zLa4POQcLCevw9srW7N0tNrA5TtdUzKMHWLzUPEgoEV1SL uBAfPHlneb/EpVKrM/VM3b0dyjqhdUdWxtBBUY6J3QVw2ScpunG0= Received: (qmail 75231 invoked by alias); 6 Dec 2016 18:45:28 -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 75209 invoked by uid 89); 6 Dec 2016 18:45:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=preceded, H*MI:sk:CADfx-V, H*MI:sk:8UpOQLQ, D*inria.fr X-Spam-User: qpsmtpd, 2 recipients 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 ESMTP; Tue, 06 Dec 2016 18:45:16 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (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 7357C19CF46; Tue, 6 Dec 2016 18:45:10 +0000 (UTC) Received: from localhost (ovpn-116-110.ams2.redhat.com [10.36.116.110]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uB6Ij8ai006341; Tue, 6 Dec 2016 13:45:09 -0500 Date: Tue, 6 Dec 2016 18:45:08 +0000 From: Jonathan Wakely To: Felipe Magno de Almeida Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: Fix compilation errors with libstdc++v3 for AVR target and allow --enable-libstdcxx Message-ID: <20161206184508.GQ6326@redhat.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.7.1 (2016-10-04) On 16/09/16 02:53 -0300, Felipe Magno de Almeida wrote: >On Fri, Sep 16, 2016 at 2:42 AM, Marc Glisse wrote: >> On Thu, 15 Sep 2016, Felipe Magno de Almeida wrote: >> >> + || sizeof(uint32_t) == sizeof(void*) >> + || sizeof(uint16_t) == sizeof(void*), >> >> Indentation is off? >> >>> Call _M_extract_* functions family through temporary int objects >> >> >> Would it make sense to use a template type instead of int for this >> parameter? Or possibly have a typedef that defaults to int (what POSIX >> requires). The hard case would be a libc that uses bitfields for the fields >> of struct tm (that could save some space), but I don't think anyone does >> that. > >I've tried both approaches. Templates were causing problems of not >defined instantations because they were being used as ints too >in other _M_extract functions through a tmp integer. And typedef's >caused the same problem of having to use a tmp value of the right >type but for example _M_extract_wday_or_month could not have the >same type (in AVR they do) and I'd have to use a temporary anyway >then. > >This was the least intrusive way. Did you consider something like this? This should have no overhead for the targets with standard conforming struct tm, and only uses a temporary variable and additional assignments for AVR. It's ugly though. diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index 1a4f9a0..30cc57f 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -626,6 +626,29 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 time_get<_CharT, _InIter>::do_date_order() const { return time_base::no_order; } + template + struct _Tm_member + { + explicit + _Tm_member(_Tp& __mem) : _M_mem(__mem) { _M_tmp = __mem; } + ~_Tm_member() { _M_mem = _M_tmp; } + operator int&() { return _M_mem; } + _Tp& _M_mem; + int _M_tmp; + }; + + template<> + struct _Tm_member + { + explicit + _Tm_member(int& __mem) : _M_mem(__mem) { } + operator int&() { return _M_mem; } + int& _M_mem; + }; + +#define _GLIBCXX_TM_MEM(_M) \ + static_cast(_Tm_member<__decltype(__tm->tm_##_M)>(__tm->tm_##_M)) + // Expand a strftime format string and parse it. E.g., do_get_date() may // pass %m/%d/%Y => extracted characters. template @@ -659,29 +682,29 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // Abbreviated weekday name [tm_wday] const char_type* __days1[7]; __tp._M_days_abbreviated(__days1); - __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, - 7, __io, __tmperr); + __beg = _M_extract_name(__beg, __end, _GLIBCXX_TM_MEM(wday), + __days1, 7, __io, __tmperr); break; case 'A': // Weekday name [tm_wday]. const char_type* __days2[7]; __tp._M_days(__days2); - __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, - 7, __io, __tmperr); + __beg = _M_extract_name(__beg, __end, _GLIBCXX_TM_MEM(wday), + __days2, 7, __io, __tmperr); break; case 'h': case 'b': // Abbreviated month name [tm_mon] const char_type* __months1[12]; __tp._M_months_abbreviated(__months1); - __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __beg = _M_extract_name(__beg, __end, _GLIBCXX_TM_MEM(mon), __months1, 12, __io, __tmperr); break; case 'B': // Month name [tm_mon]. const char_type* __months2[12]; __tp._M_months(__months2); - __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __beg = _M_extract_name(__beg, __end, _GLIBCXX_TM_MEM(mon), __months2, 12, __io, __tmperr); break; case 'c': @@ -693,18 +716,20 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 break; case 'd': // Day [01, 31]. [tm_mday] - __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, - __io, __tmperr); + __beg = _M_extract_num(__beg, __end, _GLIBCXX_TM_MEM(mday), + 1, 31, 2, __io, __tmperr); break; case 'e': // Day [1, 31], with single digits preceded by // space. [tm_mday] if (__ctype.is(ctype_base::space, *__beg)) - __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, - 1, __io, __tmperr); + __beg = _M_extract_num(++__beg, __end, + _GLIBCXX_TM_MEM(mday), + 1, 9, 1, __io, __tmperr); else - __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, - 2, __io, __tmperr); + __beg = _M_extract_num(__beg, __end, + _GLIBCXX_TM_MEM(mday), + 10, 31, 2, __io, __tmperr); break; case 'D': // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] @@ -715,13 +740,13 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 break; case 'H': // Hour [00, 23]. [tm_hour] - __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, - __io, __tmperr); + __beg = _M_extract_num(__beg, __end, _GLIBCXX_TM_MEM(hour), + 0, 23, 2, __io, __tmperr); break; case 'I': // Hour [01, 12]. [tm_hour] - __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, - __io, __tmperr); + __beg = _M_extract_num(__beg, __end, _GLIBCXX_TM_MEM(hour), + 1, 12, 2, __io, __tmperr); break; case 'm': // Month [01, 12]. [tm_mon] @@ -732,8 +757,8 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 break; case 'M': // Minute [00, 59]. [tm_min] - __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, - __io, __tmperr); + __beg = _M_extract_num(__beg, __end, _GLIBCXX_TM_MEM(min), + 0, 59, 2, __io, __tmperr); break; case 'n': if (__ctype.narrow(*__beg, 0) == '\n') @@ -752,11 +777,12 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // Seconds. [tm_sec] // [00, 60] in C99 (one leap-second), [00, 61] in C89. #if _GLIBCXX_USE_C99 - __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, + static const int __max_secs = 60; #else - __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, + static const int __max_secs = 61; #endif - __io, __tmperr); + __beg = _M_extract_num(__beg, __end, _GLIBCXX_TM_MEM(sec), + 0, __max_secs, 2, __io, __tmperr); break; case 't': if (__ctype.narrow(*__beg, 0) == '\t') @@ -842,6 +868,8 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 return __beg; } +#undef _GLIBCXX_TM_MEM + template _InIter time_get<_CharT, _InIter>::