aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-04-02 19:28:20 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2025-04-02 19:28:20 +0200
commit29bc904cb827615ed9f36bc3742ccc4ac77515ec (patch)
tree7fa87245cc2b21e87f6012a8b0e9850578de03f9 /gcc
parentaca8155c09001f269a20d6df438fa0e749dd5388 (diff)
downloadgcc-29bc904cb827615ed9f36bc3742ccc4ac77515ec.zip
gcc-29bc904cb827615ed9f36bc3742ccc4ac77515ec.tar.gz
gcc-29bc904cb827615ed9f36bc3742ccc4ac77515ec.tar.bz2
c: Fix ICEs with -fsanitize=pointer-{subtract,compare} [PR119582]
The following testcase ICEs because c_fully_fold isn't performed on the arguments of __sanitizer_ptr_{sub,cmp} builtins and so e.g. C_MAYBE_CONST_EXPR can leak into the gimplifier where it ICEs. 2025-04-02 Jakub Jelinek <jakub@redhat.com> PR c/119582 * c-typeck.cc (pointer_diff, build_binary_op): Call c_fully_fold on __sanitizer_ptr_sub or __sanitizer_ptr_cmp arguments. * gcc.dg/asan/pr119582.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/c-typeck.cc8
-rw-r--r--gcc/testsuite/gcc.dg/asan/pr119582.c23
2 files changed, 27 insertions, 4 deletions
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index aaf8e54..19e79b5 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -4824,8 +4824,8 @@ pointer_diff (location_t loc, tree op0, tree op1, tree *instrument_expr)
if (current_function_decl != NULL_TREE
&& sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
{
- op0 = save_expr (op0);
- op1 = save_expr (op1);
+ op0 = save_expr (c_fully_fold (op0, false, NULL));
+ op1 = save_expr (c_fully_fold (op1, false, NULL));
tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
*instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
@@ -14455,8 +14455,8 @@ build_binary_op (location_t location, enum tree_code code,
&& current_function_decl != NULL_TREE
&& sanitize_flags_p (SANITIZE_POINTER_COMPARE))
{
- op0 = save_expr (op0);
- op1 = save_expr (op1);
+ op0 = save_expr (c_fully_fold (op0, false, NULL));
+ op1 = save_expr (c_fully_fold (op1, false, NULL));
tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
diff --git a/gcc/testsuite/gcc.dg/asan/pr119582.c b/gcc/testsuite/gcc.dg/asan/pr119582.c
new file mode 100644
index 0000000..f33cb51
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr119582.c
@@ -0,0 +1,23 @@
+/* PR c/119582 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsanitize=address,pointer-subtract,pointer-compare" } */
+
+const char v;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+char a;
+const ptrdiff_t p = &a + 1 - &a;
+const int q = (&a + 1) != &a;
+
+ptrdiff_t
+foo (void)
+{
+ char b;
+ return &b + (v != '\n') - &b;
+}
+
+int
+bar (void)
+{
+ char b;
+ return (&b + (v != '\n')) != &b;
+}