[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-04-29 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

Jeffrey A. Law  changed:

   What|Removed |Added

 CC||law at redhat dot com
   Priority|P3  |P2

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-18 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

--- Comment #12 from Jakub Jelinek  ---
Though, admittedly fixing that:
 T *EltPtr = 
-if (I <= EltPtr && EltPtr < this->EndX)
+if ((std::uintptr_t) I <= (std::uintptr_t) EltPtr && (std::uintptr_t)
EltPtr < (std::uintptr_t) this->EndX)
   ++EltPtr;

 *I = ::std::move(*EltPtr);
doesn't make the warning go away.
We have:
  int D.48534;
...
   [local count: 885408257]:
  # EltPtr_49 = PHI <(27), (28),   [(void *) +
4B](29)>
  _50 = MEM[(type &)EltPtr_49];
  *I_42 = _50;
before phiprop and phiprop changes that into:
   [local count: 442704129]:
  _33 = MEM[(type &)];
  goto ; [100.00%]
...
   [local count: 221352064]:
  _34 = MEM[(type &)];
  goto ; [100.00%]

   [local count: 221352064]:
  _48 = MEM[(type &) + 4];

   [local count: 885408257]:
  # EltPtr_49 = PHI <  [(void *) + 4B](29), (38),
(39)>
  # _50 = PHI <_48(29), _33(38), _34(39)>
  *I_42 = _50;
where the _48 load is clearly UB, but with -fsanitize=address the compiler
can't prove that it is unreachable, or with the adjusted testcase either.
So we are back to the dozens of other PRs of this kind, late warnings warning
on UB in dead code and the question what the users actually want, whether a
(false positive) warning, or no warning, or whether the compiler should replace
the UB code with __builtin_unreachable and let the code be further simplified,
or replace it with __builtin_trap.

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-18 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

--- Comment #11 from Jakub Jelinek  ---
Regarding the original testcase, small tweak results in the same warning even
without sanitization:
#include "pr91146.h"

class A
{
public:
  virtual void f () = 0;
};

template 
void foo (T &);

class B : public A
{
public:
  void f () override
  {
small_vector v;
auto i = v.begin ();
foo (i);
v.insert (i, 1); 
foo (v);
  }
};

int main ()
{
  B b;
  b.f ();
  return 0;
}

Here we just make sure the method isn't optimized away completely and that the
optimizer doesn't know v.insert is called with v.begin () iterator.
And the problem is that the llvm small vector implementation does:
iterator insert(iterator I, T &) {
...
T *EltPtr = 
if (I <= EltPtr && EltPtr < this->EndX)
  ++EltPtr;

*I = ::std::move(*EltPtr);
return I;
  }

*++EltPtr on an int (not array) is obviously UB, but the condition should guard
that this doesn't happen.  Except that there is UB already in the condition
that guards this, because non-equality pointer comparisons are valid only if
both pointers point into the same object or one past the end of it, or both are
NULL.
That isn't the case here, as I points into the payload of the v variable and so
does this->endX, while EltPtr points to a temporary holding 1.
So, I'd say this is LLVM bug.

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-18 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

Jakub Jelinek  changed:

   What|Removed |Added

 CC||marxin at gcc dot gnu.org

--- Comment #10 from Jakub Jelinek  ---
The #c9 patch passed bootstrap, but regresses:
FAIL: g++.dg/asan/use-after-scope-types-1.C   -O1  execution test
FAIL: g++.dg/asan/use-after-scope-types-1.C   -O2  execution test
FAIL: g++.dg/asan/use-after-scope-types-1.C   -O3 -g  execution test
FAIL: g++.dg/asan/use-after-scope-types-1.C   -Os  execution test
FAIL: g++.dg/asan/use-after-scope-types-1.C   -O2 -flto -fno-use-linker-plugin
-flto-partition=none  execution test
FAIL: g++.dg/asan/use-after-scope-types-1.C   -O2 -flto -fuse-linker-plugin
-fno-fat-lto-objects  execution test
FAIL: g++.dg/asan/use-after-scope-types-2.C   -O1  execution test
FAIL: g++.dg/asan/use-after-scope-types-2.C   -O2  execution test
FAIL: g++.dg/asan/use-after-scope-types-2.C   -O3 -g  execution test
FAIL: g++.dg/asan/use-after-scope-types-2.C   -Os  execution test
FAIL: g++.dg/asan/use-after-scope-types-2.C   -O2 -flto -fno-use-linker-plugin
-flto-partition=none  execution test
FAIL: g++.dg/asan/use-after-scope-types-2.C   -O2 -flto -fuse-linker-plugin
-fno-fat-lto-objects  execution test
FAIL: g++.dg/asan/use-after-scope-types-3.C   -O1  execution test
FAIL: g++.dg/asan/use-after-scope-types-3.C   -O2  execution test
FAIL: g++.dg/asan/use-after-scope-types-3.C   -O3 -g  execution test
FAIL: g++.dg/asan/use-after-scope-types-3.C   -Os  execution test
FAIL: g++.dg/asan/use-after-scope-types-3.C   -O2 -flto -fno-use-linker-plugin
-flto-partition=none  execution test
FAIL: g++.dg/asan/use-after-scope-types-3.C   -O2 -flto -fuse-linker-plugin
-fno-fat-lto-objects  execution test
FAIL: g++.dg/asan/use-after-scope-types-5.C   -O1  execution test
FAIL: g++.dg/asan/use-after-scope-types-5.C   -O2  execution test
FAIL: g++.dg/asan/use-after-scope-types-5.C   -O3 -g  execution test
FAIL: g++.dg/asan/use-after-scope-types-5.C   -Os  execution test
FAIL: g++.dg/asan/use-after-scope-types-5.C   -O2 -flto -fno-use-linker-plugin
-flto-partition=none  execution test
FAIL: g++.dg/asan/use-after-scope-types-5.C   -O2 -flto -fuse-linker-plugin
-fno-fat-lto-objects  execution test

The thing is that those tests do those use after scope accesses but don't
really have anything afterwards that would allow optimizing those accesses
away.  With the previous behavior of ASAN_MARK ifns such barriers were in those
ifns.
So, the big question is, what do we want.
For -O0 -fsanitize=address both the unpatched and patched versions work
similarly, and for -O1 -fsanitize=address and higher,
do we want the sanitizer to detect just those after scope uses that would
remain after optimization even in non-instrumented code?  Then we want the
patch.  Or do we want to detect more after scope uses, even at the expense of
some false positive warnings?
If I try clang++ -O{0,1} -fsanitize=address on the use-after-scope-types-1.C
testcase, then it detects the violation (patched g++ with already -O1
-fsanitize=address doesn't), but clang++ -O{2,3} -fsanitize=address doesn't
detect it (while unpatched g++ -O{2,3} -fsanitize=address does).

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-17 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

--- Comment #9 from Jakub Jelinek  ---
Seems even with that patch
3677  if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p))
in tree-ssa-sccvn.c thinks the
  .ASAN_MARK (UNPOISON, , 4);
call may clobber
MEM[(struct small_vector_template_common *)].D.48455.BeginX
With the following completely untested patch we optimize like withouf
-fsanitize=address and don't warn.
--- gcc/internal-fn.def.jj  2020-01-18 13:47:09.517357706 +0100
+++ gcc/internal-fn.def 2020-03-17 16:32:41.210800195 +0100
@@ -309,7 +309,7 @@ DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_
 DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
-DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, "..W.")
 DEF_INTERNAL_FN (ASAN_POISON, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
 DEF_INTERNAL_FN (ASAN_POISON_USE, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
 DEF_INTERNAL_FN (ADD_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
--- gcc/tree-ssa-alias.c.jj 2020-03-03 11:04:46.367821907 +0100
+++ gcc/tree-ssa-alias.c2020-03-17 17:40:22.295385869 +0100
@@ -3032,6 +3032,14 @@ call_may_clobber_ref_p_1 (gcall *call, a
default:
  /* Fallthru to general call handling.  */;
   }
+  else if (gimple_call_internal_p (call)
+  && gimple_call_internal_fn (call) == IFN_ASAN_MARK)
+{
+  ao_ref dref;
+  tree size = gimple_call_arg (call, 2);
+  ao_ref_init_from_ptr_and_size (, gimple_call_arg (call, 1), size);
+  return refs_may_alias_p_1 (, ref, false);
+}

   /* Check if base is a global static variable that is not written
  by the function.  */

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-17 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

--- Comment #8 from Jakub Jelinek  ---
Created attachment 48050
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48050=edit
pr91146.ii.xz

Preprocessed source.  -O2 -fsanitize=address -Wall

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-17 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

--- Comment #7 from Jakub Jelinek  ---
Ah, should have been:
--- gcc/internal-fn.def.jj  2020-01-18 13:47:09.517357706 +0100
+++ gcc/internal-fn.def 2020-03-17 16:04:08.092861394 +0100
@@ -309,7 +309,7 @@ DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_
 DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
-DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, "..W.")
 DEF_INTERNAL_FN (ASAN_POISON, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
 DEF_INTERNAL_FN (ASAN_POISON_USE, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
 DEF_INTERNAL_FN (ADD_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
the ifn has 3 arguments and the pointer is the middle one.
Anyway, even with this sccvn isn't able to see through it.

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-17 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek  ---
The testcase isn't very good, because it is optimized to nothing without the
sanitization.
But using
  __attribute__((used)) void f () override
  {
small_vector v;
v.insert (v.begin (), 1);
__asm volatile ("" : : "r" () : "memory");
  }
prevents that.
With that, the dumps look comparable until fre3.
Initially, I thought the issue is that ASAN_MARK ifn isn't said to affect just
the pointed memory (and directly only).  In reality it affects something
different (the shadow memory corresponding to that memory), but perhaps it
would work.  Unfortunately:
--- gcc/internal-fn.def.jj  2020-01-18 13:47:09.517357706 +0100
+++ gcc/internal-fn.def 2020-03-17 16:04:08.092861394 +0100
@@ -309,7 +309,7 @@ DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_
 DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
-DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, ".W.")
 DEF_INTERNAL_FN (ASAN_POISON, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
 DEF_INTERNAL_FN (ASAN_POISON_USE, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
 DEF_INTERNAL_FN (ADD_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
doesn't fix it.
So, at the start of f without asan we have:
  v ={v} {CLOBBER};
  MEM[(struct  &)] ={v} {CLOBBER};
  MEM[(struct small_vector_base *)] ={v} {CLOBBER};
  MEM[(struct small_vector_base *)].BeginX = [(struct
small_vector_template_common *)].FirstEl;
  MEM[(struct small_vector_base *)].EndX = [(struct
small_vector_template_common *)].FirstEl;
  MEM[(struct small_vector_base *)].CapacityX =   [(void *) +
104B];
  D.48526 = 1;
  _17 = MEM[(struct small_vector_template_common *)].D.48095.EndX;
  if ([(struct small_vector_template_common *)].FirstEl == _17)
where small_vector_template_common is derived from small_vector_base and thus
MEM[(struct small_vector_template_common *)].D.48095 and MEM[(struct
small_vector_base *)] is the same thing.
Now, with asan we have:
  .ASAN_MARK (UNPOISON, , 104);
  v ={v} {CLOBBER};
  MEM[(struct  &)] ={v} {CLOBBER};
  MEM[(struct small_vector_base *)] ={v} {CLOBBER};
  MEM[(struct small_vector_base *)].BeginX = [(struct
small_vector_template_common *)].FirstEl;
  MEM[(struct small_vector_base *)].EndX = [(struct
small_vector_template_common *)].FirstEl;
  MEM[(struct small_vector_base *)].CapacityX =   [(void *) +
104B];
  .ASAN_MARK (UNPOISON, , 4);
  D.48886 = 1;
  _10 = MEM[(struct small_vector_template_common *)].D.48455.BeginX;
  _20 = MEM[(struct small_vector_template_common *)].D.48455.EndX;
  if (_10 == _20)
The only difference other than .ASAN_MARK calls is that in the asan case _10
hasn't been propagated into the comparison.
Anyway, fre3 seems to be able to value number the _17 load to  [(struct
small_vector_template_common *)].FirstEl and thus optimize the comparison
into true, while with the .ASAN_MARK calls it doesn't.

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.3 |9.4

--- Comment #5 from Jakub Jelinek  ---
GCC 9.3.0 has been released, adjusting target milestone.

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-02-07 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|--- |9.3

[Bug middle-end/91146] [9/10 Regression] -Werror=array-bounds if compile with -fsanitize=address

2020-01-23 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146

Martin Liška  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2020-01-23
 CC||marxin at gcc dot gnu.org
  Known to work||8.3.0
Summary|-Werror=array-bounds if |[9/10 Regression]
   |compile with|-Werror=array-bounds if
   |-fsanitize=address  |compile with
   ||-fsanitize=address
 Ever confirmed|0   |1
  Known to fail||10.0, 9.2.0

--- Comment #4 from Martin Liška  ---
Just for the record, it started with
r9-1948-gd893b683f40884cd00b5beb392566ecc7b67f721.