https://github.com/bozicrHT updated https://github.com/llvm/llvm-project/pull/209856
From 1359a8294268cc2ff32f1656d0967daede96b07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radovan=20Bo=C5=BEi=C4=87?= <[email protected]> Date: Wed, 15 Jul 2026 13:44:08 +0200 Subject: [PATCH 1/2] [clang-tidy] Add optional time_t narrowing diagnostics Extend bugprone-narrowing-conversion with a new WarnOnTimeTNarrowingConversion option for detecting conversions from time_t values to integer types that cannot represent the full range of time_t. This is useful for Y2038-related audits, where truncating time_t into int, or other narrower integer types can silently lose information on platforms with 64-bit time_t. The new mode detects both implicit and explicit conversions involving time_t, including cases where time_t is hidden behind typedef chains, std::time_t, or used inside arithmetic expressions. It also covers explicit casts such as: uint32_t u32 = (uint32_t)time(nullptr); The option is disabled by default, so the existing behavior of bugprone-narrowing-conversion is unchanged unless the new option is enabled. Bool conversions are intentionally ignored and diagnostics are only emitted when destination integer type is not wide enough to preserve the full range of time_t. Add tests for implicit conversions, function arguments, explicit C-style casts, static_cast, functional casts, typedef aliases, std::time_t, macro-expanded casts, and time_t expressions. --- .../bugprone/NarrowingConversionsCheck.cpp | 122 ++++++++++++++++++ .../bugprone/NarrowingConversionsCheck.h | 10 ++ .../bugprone/narrowing-conversions-time-t.cpp | 78 +++++++++++ 3 files changed, 210 insertions(+) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp index 934b365a07cad..3310c9f77123d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp @@ -55,6 +55,7 @@ NarrowingConversionsCheck::NarrowingConversionsCheck(StringRef Name, WarnWithinTemplateInstantiation( Options.get("WarnWithinTemplateInstantiation", false)), WarnOnEquivalentBitWidth(Options.get("WarnOnEquivalentBitWidth", true)), + WarnOnTimeTNarrowingConversion(Options.get("WarnOnTimeTNarrowingConversion", false)), IgnoreConversionFromTypes(Options.get("IgnoreConversionFromTypes", "")), PedanticMode(Options.get("PedanticMode", false)) {} @@ -69,6 +70,7 @@ void NarrowingConversionsCheck::storeOptions( Options.store(Opts, "WarnWithinTemplateInstantiation", WarnWithinTemplateInstantiation); Options.store(Opts, "WarnOnEquivalentBitWidth", WarnOnEquivalentBitWidth); + Options.store(Opts, "WarnOnTimeTNarrowingConversion", WarnOnTimeTNarrowingConversion); Options.store(Opts, "IgnoreConversionFromTypes", IgnoreConversionFromTypes); Options.store(Opts, "PedanticMode", PedanticMode); } @@ -184,6 +186,24 @@ void NarrowingConversionsCheck::registerMatchers(MatchFinder *Finder) { unless(hasOperatorName("="))) .bind("binary_op"), this); + + // Explicit casts are checked only in the time_t narrowing mode, + // so the default behavior of this check remains unchanged. + if (WarnOnTimeTNarrowingConversion) { + Finder->addMatcher( + traverse( + TK_AsIs, + explicitCastExpr( + hasDestinationType(hasUnqualifiedDesugaredType(builtinType())), + hasSourceExpression( + expr(hasType(hasUnqualifiedDesugaredType(builtinType())))), + unless(hasSourceExpression(IsCeilFloorCallExpr)), + WarnWithinTemplateInstantiation + ? stmt() + : stmt(unless(isInTemplateInstantiation()))) + .bind("explicit_cast")), + this); + } } static const BuiltinType *getBuiltinType(const Expr &E) { @@ -238,6 +258,48 @@ struct IntegerRange { llvm::APSInt Upper; }; +bool hasTimeTTypedef(QualType QT) { + while (true) { + const auto *T = QT.getTypePtrOrNull(); + if (!T) + return false; + + if (const auto *TT = dyn_cast<TypedefType>(T)) { + const auto *TD = TT->getDecl(); + if (TD->getName() == "time_t" || TD->getName() == "__time_t") + return true; + } + + QualType NextInChain = QT->getLocallyUnqualifiedSingleStepDesugaredType(); + NextInChain = NextInChain.getNonReferenceType().getUnqualifiedType(); + if (NextInChain == QT) + break; + + QT = NextInChain; + } + + return false; +} + +bool exprMentionsTimeT(const Expr *E) { + + if (!E) + return false; + + E = E->IgnoreParenImpCasts(); + + if (hasTimeTTypedef(E->getType())) + return true; + + for (const Stmt *Child : E->children()) { + if (const auto *ChildExpr = dyn_cast_or_null<Expr>(Child)) + if (exprMentionsTimeT(ChildExpr)) + return true; + } + + return false; +} + } // namespace static IntegerRange createFromType(const ASTContext &Context, @@ -387,6 +449,54 @@ void NarrowingConversionsCheck::diagNarrowTypeOrConstant( diagNarrowType(SourceLoc, Lhs, Rhs); } +void NarrowingConversionsCheck::diagTimeTConversion(SourceLocation SourceLoc, + const Expr &Lhs, + const Expr &Rhs) { + diag(SourceLoc, + "conversion from %0 to %1 may not preserve the full range of time_t") + << getUnqualifiedType(Rhs) << getUnqualifiedType(Lhs); +} + +void NarrowingConversionsCheck::handleTimeTOnlyCast( + const ASTContext &Context, const CastExpr &Cast) { + const Expr &Lhs = Cast; + const Expr &Rhs = *Cast.getSubExprAsWritten(); + + if (Lhs.isInstantiationDependent() || Rhs.isInstantiationDependent()) + return; + + const SourceLocation SourceLoc = Cast.getExprLoc(); + handleTimeTConversion(Context, SourceLoc, Lhs, Rhs); +} + +void NarrowingConversionsCheck::handleTimeTConversion( + const ASTContext &Context, SourceLocation SourceLoc, + const Expr &Lhs, const Expr &Rhs) { + if (!WarnOnTimeTNarrowingConversion) + return; + + if (!exprMentionsTimeT(&Rhs)) + return; + + const BuiltinType *FromType = getBuiltinType(Rhs); + const BuiltinType *ToType = getBuiltinType(Lhs); + + if (!FromType || !ToType) + return; + + if (!ToType->isInteger() || !FromType->isInteger()) + return; + + // Usually not useful for Y2038. Keep bool conversions quiet. + if (ToType->getKind() == BuiltinType::Bool) + return; + + if (isWideEnoughToHold(Context, *FromType, *ToType)) + return; + + diagTimeTConversion(SourceLoc, Lhs, Rhs); +} + void NarrowingConversionsCheck::handleIntegralCast(const ASTContext &Context, SourceLocation SourceLoc, const Expr &Lhs, @@ -572,6 +682,10 @@ void NarrowingConversionsCheck::handleConditionalOperatorArgument( void NarrowingConversionsCheck::handleImplicitCast( const ASTContext &Context, const ImplicitCastExpr &Cast) { + if (WarnOnTimeTNarrowingConversion) { + handleTimeTOnlyCast(Context, Cast); + return; + } if (Cast.getExprLoc().isMacroID()) return; const Expr &Lhs = Cast; @@ -626,6 +740,12 @@ void NarrowingConversionsCheck::handleBinaryOperator(const ASTContext &Context, const Expr &Rhs = *Op.getRHS(); if (Lhs.isInstantiationDependent() || Rhs.isInstantiationDependent()) return; + + if (WarnOnTimeTNarrowingConversion) { + handleTimeTConversion(Context, Op.getExprLoc(), Lhs, Rhs); + return; + } + if (handleConditionalOperator(Context, Lhs, Rhs)) return; handleBinaryOperator(Context, Rhs.getBeginLoc(), Lhs, Rhs); @@ -636,6 +756,8 @@ void NarrowingConversionsCheck::check(const MatchFinder::MatchResult &Result) { handleBinaryOperator(*Result.Context, *Op); else if (const auto *Cast = Result.Nodes.getNodeAs<ImplicitCastExpr>("cast")) handleImplicitCast(*Result.Context, *Cast); + else if (const auto *ECast = Result.Nodes.getNodeAs<ExplicitCastExpr>("explicit_cast")) + handleTimeTOnlyCast(*Result.Context, *ECast); else llvm_unreachable("must be binary operator or cast expression"); } diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h index e506e5b0315db..035a82383a0a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h @@ -53,6 +53,9 @@ class NarrowingConversionsCheck : public ClangTidyCheck { SourceLocation SourceLoc, const Expr &Lhs, const Expr &Rhs); + void diagTimeTConversion(SourceLocation SourceLoc, const Expr &Lhs, + const Expr &Rhs); + void handleIntegralCast(const ASTContext &Context, SourceLocation SourceLoc, const Expr &Lhs, const Expr &Rhs); @@ -79,6 +82,10 @@ class NarrowingConversionsCheck : public ClangTidyCheck { void handleFloatingCast(const ASTContext &Context, SourceLocation SourceLoc, const Expr &Lhs, const Expr &Rhs); + void handleTimeTConversion(const ASTContext &Context, + SourceLocation SourceLoc, const Expr &Lhs, + const Expr &Rhs); + void handleBinaryOperator(const ASTContext &Context, SourceLocation SourceLoc, const Expr &Lhs, const Expr &Rhs); @@ -93,6 +100,8 @@ class NarrowingConversionsCheck : public ClangTidyCheck { void handleBinaryOperator(const ASTContext &Context, const BinaryOperator &Op); + void handleTimeTOnlyCast(const ASTContext &Context, const CastExpr &Cast); + bool isWarningInhibitedByEquivalentSize(const ASTContext &Context, const BuiltinType &FromType, const BuiltinType &ToType) const; @@ -102,6 +111,7 @@ class NarrowingConversionsCheck : public ClangTidyCheck { const bool WarnOnFloatingPointNarrowingConversion; const bool WarnWithinTemplateInstantiation; const bool WarnOnEquivalentBitWidth; + const bool WarnOnTimeTNarrowingConversion; const StringRef IgnoreConversionFromTypes; const bool PedanticMode; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp new file mode 100644 index 0000000000000..de2880e6d83b6 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp @@ -0,0 +1,78 @@ +// RUN: %check_clang_tidy -check-suffix=DEFAULT %s \ +// RUN: bugprone-narrowing-conversions %t -- \ +// RUN: -config='{CheckOptions: {bugprone-narrowing-conversions.WarnOnTimeTNarrowingConversion: true}}' + +typedef long time_t; +typedef time_t mytime; +typedef mytime opaque_time; + +namespace std { + using ::time_t; +} + +using int32_t = int; +using uint32_t = unsigned int; +using int64_t = long; +using uint64_t = unsigned long; + +time_t time(time_t *); + +void takes_int(int); +int returns_int(float f) { + return f; +} + +void ignore(int i, long l, double d) { + short s1 = i; + short s2 = (short)i; + int i1 = l, i2 = (int)l; + float f = d; + takes_int(l); +} + +void implicit(time_t t) { + + int32_t i32 = t; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:19: warning: conversion from 'time_t' (aka 'long') to 'int32_t' (aka 'int') may not preserve the full range of time_t + + uint32_t u32 = t; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:20: warning: conversion from 'time_t' (aka 'long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t + + takes_int(t); + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:15: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + + bool b = t; +} + +void explicit_test(time_t t) { + int i = (int)t; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + + int32_t i32 = (int32_t)t; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:19: warning: conversion from 'time_t' (aka 'long') to 'int32_t' (aka 'int') may not preserve the full range of time_t + + short s = (short)t; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:15: warning: conversion from 'time_t' (aka 'long') to 'short' may not preserve the full range of time_t + + int c = static_cast<int>(t); + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + + int j = int(t); + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t +} + +void misc(std::time_t t, int offset) { + int i = t; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'std::time_t' (aka 'long') to 'int' may not preserve the full range of time_t + + opaque_time op = time(nullptr); + uint32_t u32 = (uint32_t)op; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:20: warning: conversion from 'opaque_time' (aka 'long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t + + int oper = t + offset; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:16: warning: conversion from 'std::time_t' (aka 'long') to 'int' may not preserve the full range of time_t + +#define TO_UINT32(arg) ((uint32_t)(arg)) + uint32_t trunc = TO_UINT32(t); + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:22: warning: conversion from 'std::time_t' (aka 'long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t +} From de689515cb5cdb69c1b47389bafd84122442f2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radovan=20Bo=C5=BEi=C4=87?= <[email protected]> Date: Thu, 23 Jul 2026 08:47:37 +0200 Subject: [PATCH 2/2] Fix formatting and test on Windows --- .../bugprone/NarrowingConversionsCheck.cpp | 20 ++++++++------ .../bugprone/narrowing-conversions-time-t.cpp | 26 +++++++++---------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp index 3310c9f77123d..a89d3581f9133 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp @@ -55,7 +55,8 @@ NarrowingConversionsCheck::NarrowingConversionsCheck(StringRef Name, WarnWithinTemplateInstantiation( Options.get("WarnWithinTemplateInstantiation", false)), WarnOnEquivalentBitWidth(Options.get("WarnOnEquivalentBitWidth", true)), - WarnOnTimeTNarrowingConversion(Options.get("WarnOnTimeTNarrowingConversion", false)), + WarnOnTimeTNarrowingConversion( + Options.get("WarnOnTimeTNarrowingConversion", false)), IgnoreConversionFromTypes(Options.get("IgnoreConversionFromTypes", "")), PedanticMode(Options.get("PedanticMode", false)) {} @@ -70,7 +71,8 @@ void NarrowingConversionsCheck::storeOptions( Options.store(Opts, "WarnWithinTemplateInstantiation", WarnWithinTemplateInstantiation); Options.store(Opts, "WarnOnEquivalentBitWidth", WarnOnEquivalentBitWidth); - Options.store(Opts, "WarnOnTimeTNarrowingConversion", WarnOnTimeTNarrowingConversion); + Options.store(Opts, "WarnOnTimeTNarrowingConversion", + WarnOnTimeTNarrowingConversion); Options.store(Opts, "IgnoreConversionFromTypes", IgnoreConversionFromTypes); Options.store(Opts, "PedanticMode", PedanticMode); } @@ -457,8 +459,8 @@ void NarrowingConversionsCheck::diagTimeTConversion(SourceLocation SourceLoc, << getUnqualifiedType(Rhs) << getUnqualifiedType(Lhs); } -void NarrowingConversionsCheck::handleTimeTOnlyCast( - const ASTContext &Context, const CastExpr &Cast) { +void NarrowingConversionsCheck::handleTimeTOnlyCast(const ASTContext &Context, + const CastExpr &Cast) { const Expr &Lhs = Cast; const Expr &Rhs = *Cast.getSubExprAsWritten(); @@ -469,9 +471,10 @@ void NarrowingConversionsCheck::handleTimeTOnlyCast( handleTimeTConversion(Context, SourceLoc, Lhs, Rhs); } -void NarrowingConversionsCheck::handleTimeTConversion( - const ASTContext &Context, SourceLocation SourceLoc, - const Expr &Lhs, const Expr &Rhs) { +void NarrowingConversionsCheck::handleTimeTConversion(const ASTContext &Context, + SourceLocation SourceLoc, + const Expr &Lhs, + const Expr &Rhs) { if (!WarnOnTimeTNarrowingConversion) return; @@ -756,7 +759,8 @@ void NarrowingConversionsCheck::check(const MatchFinder::MatchResult &Result) { handleBinaryOperator(*Result.Context, *Op); else if (const auto *Cast = Result.Nodes.getNodeAs<ImplicitCastExpr>("cast")) handleImplicitCast(*Result.Context, *Cast); - else if (const auto *ECast = Result.Nodes.getNodeAs<ExplicitCastExpr>("explicit_cast")) + else if (const auto *ECast = + Result.Nodes.getNodeAs<ExplicitCastExpr>("explicit_cast")) handleTimeTOnlyCast(*Result.Context, *ECast); else llvm_unreachable("must be binary operator or cast expression"); diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp index de2880e6d83b6..d0374ba9b88d3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions-time-t.cpp @@ -2,7 +2,7 @@ // RUN: bugprone-narrowing-conversions %t -- \ // RUN: -config='{CheckOptions: {bugprone-narrowing-conversions.WarnOnTimeTNarrowingConversion: true}}' -typedef long time_t; +typedef long long time_t; typedef time_t mytime; typedef mytime opaque_time; @@ -33,46 +33,46 @@ void ignore(int i, long l, double d) { void implicit(time_t t) { int32_t i32 = t; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:19: warning: conversion from 'time_t' (aka 'long') to 'int32_t' (aka 'int') may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:19: warning: conversion from 'time_t' (aka 'long long') to 'int32_t' (aka 'int') may not preserve the full range of time_t uint32_t u32 = t; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:20: warning: conversion from 'time_t' (aka 'long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:20: warning: conversion from 'time_t' (aka 'long long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t takes_int(t); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:15: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:15: warning: conversion from 'time_t' (aka 'long long') to 'int' may not preserve the full range of time_t bool b = t; } void explicit_test(time_t t) { int i = (int)t; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long long') to 'int' may not preserve the full range of time_t int32_t i32 = (int32_t)t; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:19: warning: conversion from 'time_t' (aka 'long') to 'int32_t' (aka 'int') may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:19: warning: conversion from 'time_t' (aka 'long long') to 'int32_t' (aka 'int') may not preserve the full range of time_t short s = (short)t; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:15: warning: conversion from 'time_t' (aka 'long') to 'short' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:15: warning: conversion from 'time_t' (aka 'long long') to 'short' may not preserve the full range of time_t int c = static_cast<int>(t); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long long') to 'int' may not preserve the full range of time_t int j = int(t); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long') to 'int' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'time_t' (aka 'long long') to 'int' may not preserve the full range of time_t } void misc(std::time_t t, int offset) { int i = t; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'std::time_t' (aka 'long') to 'int' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:13: warning: conversion from 'std::time_t' (aka 'long long') to 'int' may not preserve the full range of time_t opaque_time op = time(nullptr); uint32_t u32 = (uint32_t)op; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:20: warning: conversion from 'opaque_time' (aka 'long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:20: warning: conversion from 'opaque_time' (aka 'long long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t int oper = t + offset; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:16: warning: conversion from 'std::time_t' (aka 'long') to 'int' may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:16: warning: conversion from 'std::time_t' (aka 'long long') to 'int' may not preserve the full range of time_t #define TO_UINT32(arg) ((uint32_t)(arg)) uint32_t trunc = TO_UINT32(t); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:22: warning: conversion from 'std::time_t' (aka 'long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:22: warning: conversion from 'std::time_t' (aka 'long long') to 'uint32_t' (aka 'unsigned int') may not preserve the full range of time_t } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
