[PATCH] sanitizer: do not ICE for pointer cmp/sub
Martin Liška
mliska@suse.cz
Thu Dec 10 08:31:33 GMT 2020
Hello.
In C FE we have troubles to instrument top-level pointer comparison
(and subtraction):
/home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/asan/pr98204.c:5:1: internal compiler error: in pointer_diff, at c/c-typeck.c:3954
5 | static long i=((char*)&(v.c)-(char*)&v);
| ^~~~~~
and
gcc /home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/asan/pr98204.c -c -fsanitize=address,pointer-compare
/home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/asan/pr98204.c:6:16: error: initializer element is not constant
6 | static long i2=((char*)&(v.c)<(char*)&v);
| ^
The patch fixes that by not instrumenting that when current_function_decl
is NULL_TREE.
On the contrary, C++ is fine with that and does the emission in ctor:
$ + /home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/asan/pr98204.c -c -fsanitize=address,pointer-compare,pointer-subtract -fdump-tree-gimple=/dev/stdout
...
void __static_initialization_and_destruction_0 (int __initialize_p, int __priority)
{
if (__initialize_p == 1) goto <D.2830>; else goto <D.2831>;
<D.2830>:
__builtin___asan_before_dynamic_init ("/home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/asan/pr98204.c");
if (__priority == 65535) goto <D.2832>; else goto <D.2833>;
<D.2832>:
__builtin___sanitizer_ptr_sub (&v.c, &v);
i = 0;
__builtin___sanitizer_ptr_cmp (&v.c, &v);
Are we able to do something similar for C FE, or are we fine with the suggested patch?
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed?
Thanks,
Martin
gcc/c/ChangeLog:
PR sanitizer/98204
* c-typeck.c (pointer_diff): Do not emit a top-level
sanitization.
(build_binary_op): Likewise.
gcc/testsuite/ChangeLog:
PR sanitizer/98204
* c-c++-common/asan/pr98204.c: New test.
---
gcc/c/c-typeck.c | 6 +++---
gcc/testsuite/c-c++-common/asan/pr98204.c | 6 ++++++
2 files changed, 9 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/asan/pr98204.c
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 138af073925..7d58e8de342 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3949,10 +3949,9 @@ pointer_diff (location_t loc, tree op0, tree op1, tree *instrument_expr)
pedwarn (loc, OPT_Wpointer_arith,
"pointer to a function used in subtraction");
- if (sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
+ if (current_function_decl != NULL_TREE
+ && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
{
- gcc_assert (current_function_decl != NULL_TREE);
-
op0 = save_expr (op0);
op1 = save_expr (op1);
@@ -12324,6 +12323,7 @@ build_binary_op (location_t location, enum tree_code code,
}
if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
+ && current_function_decl != NULL_TREE
&& sanitize_flags_p (SANITIZE_POINTER_COMPARE))
{
op0 = save_expr (op0);
diff --git a/gcc/testsuite/c-c++-common/asan/pr98204.c b/gcc/testsuite/c-c++-common/asan/pr98204.c
new file mode 100644
index 00000000000..7532646d712
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr98204.c
@@ -0,0 +1,6 @@
+/* PR sanitizer/98204 */
+/* { dg-options "-fsanitize=address,pointer-subtract,pointer-compare" } */
+
+struct{int c;}v;
+static long i=((char*)&(v.c)-(char*)&v);
+static long i2=((char*)&(v.c)<(char*)&v);
--
2.29.2
More information about the Gcc-patches
mailing list