aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr T <oleksandr.tarasiuk@outlook.com>2024-06-17 20:29:28 +0300
committerGitHub <noreply@github.com>2024-06-17 19:29:28 +0200
commit2ebe4794b1bdb3519d5dda7ef39f32d868dfa9b0 (patch)
tree0ea51852685aa3a2b5526942915320c1fef3bcec
parenta1994ae6247ddd0374c7eb3a5d421925117833ab (diff)
downloadllvm-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.rst2
-rw-r--r--clang/lib/AST/ExprConstant.cpp7
-rw-r--r--clang/test/Sema/integral-to-ptr.c3
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}}