From b776e2a0b03e93c45deb92f36a391d457ae5b43f Mon Sep 17 00:00:00 2001 From: Lucile Nihlen Date: Fri, 30 Jun 2023 19:48:40 +0000 Subject: [PATCH] [clang] detect integer overflow through temporary values Fixes #63629. Differential Revision: https://reviews.llvm.org/D154253 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaChecking.cpp | 2 ++ clang/test/SemaCXX/integer-overflow.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4a9a030..bea609c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -561,6 +561,8 @@ Bug Fixes in This Version when an immediate invocation appears as a part of an expression that produces temporaries. (`#60709 `_). +- Fixed a missed integer overflow warning with temporary values. + (`#63629 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ffda87a..09ce790 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -15212,6 +15212,8 @@ void Sema::CheckForIntOverflow (Expr *E) { Exprs.append(Message->arg_begin(), Message->arg_end()); else if (auto Construct = dyn_cast(E)) Exprs.append(Construct->arg_begin(), Construct->arg_end()); + else if (auto Temporary = dyn_cast(E)) + Exprs.push_back(Temporary->getSubExpr()); else if (auto Array = dyn_cast(E)) Exprs.push_back(Array->getIdx()); else if (auto Compound = dyn_cast(E)) diff --git a/clang/test/SemaCXX/integer-overflow.cpp b/clang/test/SemaCXX/integer-overflow.cpp index 870fbeb..0e8ad05 100644 --- a/clang/test/SemaCXX/integer-overflow.cpp +++ b/clang/test/SemaCXX/integer-overflow.cpp @@ -214,3 +214,32 @@ void f() { int a = -(1<<31); // expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} } } + +#if __cplusplus >= 201103L +namespace GH63629 { +typedef long long int64_t; + +template +class u_ptr { + T *ptr; +public: + u_ptr(const u_ptr&) = delete; + u_ptr &operator=(const u_ptr&) = delete; + u_ptr(u_ptr &&other) : ptr(other.ptr) { other.ptr = 0; } + u_ptr(T *ptr) : ptr(ptr) { } + ~u_ptr() { delete ptr; } +}; + +u_ptr Wrap(int64_t x) { + return nullptr; +} + +int64_t Pass(int64_t x) { return x; } + +int m() { + int64_t x = Pass(30 * 24 * 60 * 59 * 1000); // expected-warning {{overflow in expression; result is -1746167296 with type 'int'}} + auto r = Wrap(Pass(30 * 24 * 60 * 59 * 1000)); // expected-warning {{overflow in expression; result is -1746167296 with type 'int'}} + return 0; +} +} +#endif -- 2.7.4