Bug 85081 - [7 Regression] Sanitizer error with references in vectorized/parallel for-loop
Summary: [7 Regression] Sanitizer error with references in vectorized/parallel for-loop
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: sanitizer (show other bugs)
Version: 8.0.1
: P3 normal
Target Milestone: 7.4
Assignee: Martin Liška
URL:
Keywords: openmp, wrong-code
Depends on:
Blocks:
 
Reported: 2018-03-26 16:44 UTC by Volker Reichelt
Modified: 2018-04-24 15:23 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.4.0, 7.3.1, 8.0.1
Known to fail:
Last reconfirmed: 2018-03-27 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Volker Reichelt 2018-03-26 16:44:34 UTC
The following valid code snippet compiled with
"-fopenmp-simd -fsanitize=address"
is aborted by the sanitizer at runtime since GCC 7.1.0:

====================================================
inline const int& max(const int& a, const int& b)
{
  return a < b ? b : a;
}

int main()
{
  #pragma omp simd
//   #pragma omp parallel for
  for ( int i = 0; i < 20; ++i )
  {
    const int j = max(i, 1);
  }

  return 0;
}
====================================================

==25412==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffe6a4ecac0 at pc 0x00000040090a bp 0x7ffe6a4eca80 sp 0x7ffe6a4eca78
WRITE of size 4 at 0x7ffe6a4ecac0 thread T0
    #0 0x400909 in main (a.out+0x400909)
    #1 0x7f88f7f84724 in __libc_start_main (/lib64/libc.so.6+0x20724)
    #2 0x400748 in _start (a.out+0x400748)

Address 0x7ffe6a4ecac0 is located in stack of thread T0 at offset 32 in frame
    #0 0x400805 in main (a.out+0x400805)

  This frame has 2 object(s):
    [32, 36) '<unknown>' <== Memory access at offset 32 is inside this variable
    [96, 100) 'i'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope (a.out+0x400909) in main
Shadow bytes around the buggy address:
  0x10004d495900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d495910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d495920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d495930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d495940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10004d495950: 00 00 00 00 f1 f1 f1 f1[f8]f2 f2 f2 f2 f2 f2 f2
  0x10004d495960: 04 f2 f2 f2 f3 f3 f3 f3 00 00 00 00 00 00 00 00
  0x10004d495970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d495980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d495990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004d4959a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==25412==ABORTING

The address-sanitizer also complains with "#pragma omp parallel for"
and "-fopenmp".
The problem persists if I change the return value of "max" to "int",
but disappears if I change the arguments to plain "int".

I don't know whether this is a sanitizer or OpenMP (or even a C++ frontend) issue.
Comment 1 Jakub Jelinek 2018-03-27 18:14:54 UTC
Martin, this is because of:
  /* When within an OMP context, do not emit ASAN_MARK internal fns.  */
  if (gimplify_omp_ctxp)
    return;
in asan_poison_variable.  Not really sure why exactly it has been added, but if we can't emit the ASAN_UNPOISON, we can't emit the corresponding ASAN_POISON either.

So something like:
--- gcc/gimplify.c.jj	2018-03-16 13:43:14.831910333 +0100
+++ gcc/gimplify.c	2018-03-27 20:11:27.680195380 +0200
@@ -1689,7 +1689,8 @@ gimplify_decl_expr (tree *stmt_p, gimple
 	  && !TREE_STATIC (decl)
 	  && !DECL_HAS_VALUE_EXPR_P (decl)
 	  && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
-	  && dbg_cnt (asan_use_after_scope))
+	  && dbg_cnt (asan_use_after_scope)
+	  && !gimplify_omp_ctxp)
 	{
 	  asan_poisoned_variables->add (decl);
 	  asan_poison_variable (decl, false, seq_p);
@@ -6614,7 +6615,8 @@ gimplify_target_expr (tree *expr_p, gimp
 	    }
 	  if (asan_poisoned_variables
 	      && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
-	      && dbg_cnt (asan_use_after_scope))
+	      && dbg_cnt (asan_use_after_scope)
+	      && !gimplify_omp_ctxp)
 	    {
 	      tree asan_cleanup = build_asan_poison_call_expr (temp);
 	      if (asan_cleanup)

fixes it from me, but not really sure about the reasons why the above check is in there.  Martin?
Comment 2 Martin Liška 2018-03-27 18:49:47 UTC
I'll take a look tomorrow.
Comment 3 Martin Liška 2018-03-28 14:46:10 UTC
Author: marxin
Date: Wed Mar 28 14:45:21 2018
New Revision: 258924

URL: https://gcc.gnu.org/viewcvs?rev=258924&root=gcc&view=rev
Log:
Fix wrong use-after-scope sanitization for omp variable (PR sanitizer/85081).

2018-03-28  Jakub Jelinek  <jakub@redhat.com>
	    Martin Liska  <mliska@suse.cz>

	PR sanitizer/85081
	* gimplify.c (asan_poison_variable): Don't do the check for
	gimplify_omp_ctxp here.
	(gimplify_decl_expr): Do it here.
	(gimplify_target_expr): Likewise.
2018-03-28  Jakub Jelinek  <jakub@redhat.com>
	    Martin Liska  <mliska@suse.cz>

	PR sanitizer/85081
	* g++.dg/asan/pr85081.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/asan/pr85081.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimplify.c
    trunk/gcc/testsuite/ChangeLog
Comment 4 Martin Liška 2018-03-28 14:46:59 UTC
Fixed on trunk.
Comment 5 Martin Liška 2018-04-24 15:18:20 UTC
Author: marxin
Date: Tue Apr 24 15:17:48 2018
New Revision: 259599

URL: https://gcc.gnu.org/viewcvs?rev=259599&root=gcc&view=rev
Log:
Backport r258924

2018-04-24  Martin Liska  <mliska@suse.cz>

	Backport from mainline
	2018-03-28  Jakub Jelinek  <jakub@redhat.com>
		    Martin Liska  <mliska@suse.cz>

	PR sanitizer/85081
	* gimplify.c (asan_poison_variable): Don't do the check for
	gimplify_omp_ctxp here.
	(gimplify_decl_expr): Do it here.
	(gimplify_target_expr): Likewise.
2018-04-24  Martin Liska  <mliska@suse.cz>

	Backport from mainline
	2018-03-28  Jakub Jelinek  <jakub@redhat.com>
		    Martin Liska  <mliska@suse.cz>

	PR sanitizer/85081
	* g++.dg/asan/pr85081.C: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/asan/pr85081.C
Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/gimplify.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
Comment 6 Martin Liška 2018-04-24 15:23:06 UTC
Fixed on GCC 7 branch.