From patchwork Fri Nov 6 16:58:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1395743 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=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=iUtIrJbX; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CSRRV71Tkz9sVM for ; Sat, 7 Nov 2020 03:58:29 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 14FCB3851C03; Fri, 6 Nov 2020 16:58:27 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf31.google.com (mail-qv1-xf31.google.com [IPv6:2607:f8b0:4864:20::f31]) by sourceware.org (Postfix) with ESMTPS id CEAF13857801 for ; Fri, 6 Nov 2020 16:58:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CEAF13857801 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qv1-xf31.google.com with SMTP id dj6so746729qvb.3 for ; Fri, 06 Nov 2020 08:58:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=+CNOsWNufmjHpOwASy+Z0nspvl5Lt/JN2+S8O2qYu0Y=; b=iUtIrJbXHX3f+PQ1pt1o+1lgM6Y4D3RYhyfkTET0oS+p99ZdI/DcDLDHpWtZ566xy6 MZzaOda8btf7ILVzpFGSW1kKUnrvMEGbIuilCS2uNhqI3RKMB1VIXSzBEhdjsIWOrJ9Z pSHd/5t+T7YIcNY1uj6CybgtYjIhw6rytGBULJp7wwja2i9v08fIRYtYPSpD8bxiQ0Wn U9CY5oaYv7o3Y2MZhzW0LNYwstFPBIhjd+dmfRhbIo/g4dWOLC/QmGSZNjHny9JKGWfL GwTXNvnUcj+EVj9awts44ZHsLbOdk9S5o2ClaHAyWgftGCCFv4tHOnNzwB5amqIliP1P ZFtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=+CNOsWNufmjHpOwASy+Z0nspvl5Lt/JN2+S8O2qYu0Y=; b=XGhllR8TpY+ENhekJVJsrIuq3EpgP2U3fFyoCHEGbMq1H9GoNguXt/Bv9CjxyrtvNZ bE6N1LFxD91P2Uk58U+hyHK24JonoV1w0n86mhOHxg/ZDJ2ILg3Nikm9ZwMuOPvvrX/p QGzBknXWzLSFRb8D6iPUKmyH960kwXWgom6/0idtcZg6V2MWCUoEdSi2QMXZT/J02eGg 9F5H4OaTjVsfyi/ONsMEwARATEmkFgo8wuxJw5ghggIWJJdIKCTbZbhByO6YuCbJFeut IAaP4uAiQ4q2AmGwrDZMb51G7P7zXN+lkQBmqmCcN6kpoW0xLzAIowOJtIWMn3m0bNLd OI1Q== X-Gm-Message-State: AOAM532T3aK4NJp3f3cIUqwludctieSx63kqKIIOPi1EhAts7d8NnqCr ZTiDlaiHwZloTZ1uzZrqBbI= X-Google-Smtp-Source: ABdhPJzFh46xvJNvYggA3g/wdgcL5KJoW6sWtDAO9VC41AAXZUEbEInxeAvbtm2uuo4C2JLK3VQg4Q== X-Received: by 2002:a05:6214:10c4:: with SMTP id r4mr2386520qvs.62.1604681904028; Fri, 06 Nov 2020 08:58:24 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:858f:cc6c:e2a0:8b92? ([2620:10d:c091:480::1:f5b0]) by smtp.googlemail.com with ESMTPSA id s23sm964993qke.11.2020.11.06.08.58.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 06 Nov 2020 08:58:23 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: libcpp: Provide date routine Message-ID: Date: Fri, 6 Nov 2020 11:58:22 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Joseph pointed me at cb_get_source_date_epoch, which allows repeatable builds and solves a FIXME I had on the modules branch. Unfortunately it's used exclusively to generate __DATE__ and __TIME__ values, which fallback to using a time(2) call. It'd be nicer if the preprocessor made whatever time value it determined available to the rest of the compiler. So this patch adds a new cpp_get_date function, which abstracts the call to the get_source_date_epoch hook, or uses time directly. The value is cached. Thus the timestamp I end up putting on CMI files matches __DATE__ and __TIME__ expansions. That seems worthwhile. libcpp/ * include/libcpp.h (enum class CPP_time_kind): New. (cpp_get_date): Declare. * internal.h (struct cpp_reader): Replace source_date_epoch with time_stamp and time_stamp_kind. * init.c (cpp_create_reader): Initialize them. * macro.c (_cpp_builtin_macro_text): Use cpp_get_date. (cpp_get_date): Broken out from _cpp_builtin_macro_text and genericized. pushing to trunk nathan diff --git i/libcpp/include/cpplib.h w/libcpp/include/cpplib.h index 8e398863cf6..c4d7cc520d1 100644 --- i/libcpp/include/cpplib.h +++ w/libcpp/include/cpplib.h @@ -1040,6 +1040,15 @@ inline location_t cpp_macro_definition_location (cpp_hashnode *node) { return node->value.macro->line; } +/* Return an idempotent time stamp (possibly from SOURCE_DATE_EPOCH). */ +enum class CPP_time_kind +{ + FIXED = -1, /* Fixed time via source epoch. */ + DYNAMIC = -2, /* Dynamic via time(2). */ + UNKNOWN = -3 /* Wibbly wobbly, timey wimey. */ +}; +extern CPP_time_kind cpp_get_date (cpp_reader *, time_t *); + extern void _cpp_backup_tokens (cpp_reader *, unsigned int); extern const cpp_token *cpp_peek_token (cpp_reader *, int); diff --git i/libcpp/init.c w/libcpp/init.c index 6c52f50de39..dcf1d4be587 100644 --- i/libcpp/init.c +++ w/libcpp/init.c @@ -273,8 +273,9 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, /* Do not force token locations by default. */ pfile->forced_token_location = 0; - /* Initialize source_date_epoch to -2 (not yet set). */ - pfile->source_date_epoch = (time_t) -2; + /* Note the timestamp is unset. */ + pfile->time_stamp = time_t (-1); + pfile->time_stamp_kind = 0; /* The expression parser stack. */ _cpp_expand_op_stack (pfile); diff --git i/libcpp/internal.h w/libcpp/internal.h index 4759961a33a..d7780e49d27 100644 --- i/libcpp/internal.h +++ w/libcpp/internal.h @@ -512,10 +512,9 @@ struct cpp_reader const unsigned char *date; const unsigned char *time; - /* Externally set timestamp to replace current date and time useful for - reproducibility. It should be initialized to -2 (not yet set) and - set to -1 to disable it or to a non-negative value to enable it. */ - time_t source_date_epoch; + /* Time stamp, set idempotently lazily. */ + time_t time_stamp; + int time_stamp_kind; /* Or errno. */ /* A token forcing paste avoidance, and one demarking macro arguments. */ cpp_token avoid_paste; diff --git i/libcpp/macro.c w/libcpp/macro.c index e304f67c2e0..e2cb89e4c43 100644 --- i/libcpp/macro.c +++ w/libcpp/macro.c @@ -606,29 +606,21 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, at init time, because time() and localtime() are very slow on some systems. */ time_t tt; - struct tm *tb = NULL; + auto kind = cpp_get_date (pfile, &tt); - /* Set a reproducible timestamp for __DATE__ and __TIME__ macro - if SOURCE_DATE_EPOCH is defined. */ - if (pfile->source_date_epoch == (time_t) -2 - && pfile->cb.get_source_date_epoch != NULL) - pfile->source_date_epoch = pfile->cb.get_source_date_epoch (pfile); - - if (pfile->source_date_epoch >= (time_t) 0) - tb = gmtime (&pfile->source_date_epoch); - else + if (kind == CPP_time_kind::UNKNOWN) { - /* (time_t) -1 is a legitimate value for "number of seconds - since the Epoch", so we have to do a little dance to - distinguish that from a genuine error. */ - errno = 0; - tt = time (NULL); - if (tt != (time_t)-1 || errno == 0) - tb = localtime (&tt); + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine date and time"); + + pfile->date = UC"\"??? ?? ????\""; + pfile->time = UC"\"??:??:??\""; } - - if (tb) + else { + struct tm *tb = (kind == CPP_time_kind::FIXED + ? gmtime : localtime) (&tt); + pfile->date = _cpp_unaligned_alloc (pfile, sizeof ("\"Oct 11 1347\"")); sprintf ((char *) pfile->date, "\"%s %2d %4d\"", @@ -640,14 +632,6 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", tb->tm_hour, tb->tm_min, tb->tm_sec); } - else - { - cpp_errno (pfile, CPP_DL_WARNING, - "could not determine date and time"); - - pfile->date = UC"\"??? ?? ????\""; - pfile->time = UC"\"??:??:??\""; - } } if (node->value.builtin == BT_DATE) @@ -688,6 +672,51 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, return result; } +/* Get an idempotent date. Either the cached value, the value from + source epoch, or failing that, the value from time(2). Use this + during compilation so that every time stamp is the same. */ +CPP_time_kind +cpp_get_date (cpp_reader *pfile, time_t *result) +{ + if (!pfile->time_stamp_kind) + { + int kind = 0; + if (pfile->cb.get_source_date_epoch) + { + /* Try reading the fixed epoch. */ + pfile->time_stamp = pfile->cb.get_source_date_epoch (pfile); + if (pfile->time_stamp != time_t (-1)) + kind = int (CPP_time_kind::FIXED); + } + + if (!kind) + { + /* Pedantically time_t (-1) is a legitimate value for + "number of seconds since the Epoch". It is a silly + time. */ + errno = 0; + pfile->time_stamp = time (nullptr); + /* Annoyingly a library could legally set errno and return a + valid time! Bad library! */ + if (pfile->time_stamp == time_t (-1) && errno) + kind = errno; + else + kind = int (CPP_time_kind::DYNAMIC); + } + + pfile->time_stamp_kind = kind; + } + + *result = pfile->time_stamp; + if (pfile->time_stamp_kind >= 0) + { + errno = pfile->time_stamp_kind; + return CPP_time_kind::UNKNOWN; + } + + return CPP_time_kind (pfile->time_stamp_kind); +} + /* Convert builtin macros like __FILE__ to a token and push it on the context stack. Also handles _Pragma, for which a new token may not be created. Returns 1 if it generates a new token context, 0 to