diff options
author | Oleksandr T <oleksandr.tarasiuk@outlook.com> | 2024-06-17 20:29:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-17 19:29:28 +0200 |
commit | 2ebe4794b1bdb3519d5dda7ef39f32d868dfa9b0 (patch) | |
tree | 0ea51852685aa3a2b5526942915320c1fef3bcec | |
parent | a1994ae6247ddd0374c7eb3a5d421925117833ab (diff) | |
download | llvm-2ebe4794b1bdb3519d5dda7ef39f32d868dfa9b0.zip llvm-2ebe4794b1bdb3519d5dda7ef39f32d868dfa9b0.tar.gz llvm-2ebe4794b1bdb3519d5dda7ef39f32d868dfa9b0.tar.bz2 |
[Clang] Disallow non-lvalue values in constant expressions to prevent invalid pointer offset computation (#95479)
Fixes #95366
-rw-r--r-- | clang/docs/ReleaseNotes.rst | 2 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 7 | ||||
-rw-r--r-- | clang/test/Sema/integral-to-ptr.c | 3 |
3 files changed, 12 insertions, 0 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 69aea6c..2bf20bc 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -859,6 +859,8 @@ Bug Fixes to C++ Support (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). - Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849) +- Fixed a failed assertion when attempting to convert an integer representing the difference + between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index bf9c9ba..3a6c8b4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9325,6 +9325,13 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { Result.IsNullPtr = false; return true; } else { + // In rare instances, the value isn't an lvalue. + // For example, when the value is the difference between the addresses of + // two labels. We reject that as a constant expression because we can't + // compute a valid offset to convert into a pointer. + if (!Value.isLValue()) + return false; + // Cast is of an lvalue, no need to change value. Result.setFrom(Info.Ctx, Value); return true; diff --git a/clang/test/Sema/integral-to-ptr.c b/clang/test/Sema/integral-to-ptr.c new file mode 100644 index 0000000..b8ab4cb --- /dev/null +++ b/clang/test/Sema/integral-to-ptr.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11 + +int x(void) { e: b: ; return &&e - &&b < x; } // expected-warning {{ordered comparison between pointer and integer}} |