diff mbox

Backports to 6.x

Message ID 20160916094036.GI7282@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Sept. 16, 2016, 9:40 a.m. UTC
Hi!

I've backported a bunch of patches to 6.x, after bootstrapping/regtesting
them on x86_64-linux and i686-linux:

	Jakub
2016-09-16  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-09-05  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/77396
	* asan/asan_globals.cc: Cherry-pick upstream r280657.

	* g++.dg/asan/pr77396-2.C: New test.

	2016-09-02  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/77396
	* g++.dg/asan/pr77396.C: New test.
2016-09-16  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-09-06  Jakub Jelinek  <jakub@redhat.com>

	PR target/69255
	* config/i386/i386.c (ix86_expand_builtin): For builtin with
	unsupported or unknown ISA, use expand_call.

	* gcc.target/i386/pr69255-1.c: New test.
	* gcc.target/i386/pr69255-2.c: New test.
	* gcc.target/i386/pr69255-3.c: New test.

--- gcc/config/i386/i386.c	(revision 240013)
+++ gcc/config/i386/i386.c	(revision 240014)
@@ -36107,7 +36107,7 @@ ix86_expand_builtin (tree exp, rtx targe
 	  error ("%qE needs isa option %s", fndecl, opts);
 	  free (opts);
 	}
-      return const0_rtx;
+      return expand_call (exp, target, ignore);
     }
 
   switch (fcode)
--- gcc/testsuite/gcc.target/i386/pr69255-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr69255-1.c	(revision 240014)
@@ -0,0 +1,17 @@
+/* PR target/69255 */
+/* { dg-do compile } */
+/* { dg-options "-msse4 -mno-avx" } */
+
+#pragma GCC target "avx512vl"
+#pragma GCC target "no-avx512vl"
+__attribute__ ((__vector_size__ (32))) long long a;
+__attribute__ ((__vector_size__ (16))) int b;
+
+void
+foo (const long long *p)
+{
+  a = __builtin_ia32_gather3siv4di (a, p, b, 1, 1);	/* { dg-error "needs isa option -m32 -mavx512vl" } */
+}
+
+/* { dg-warning "AVX vector return without AVX enabled changes the ABI" "" { target *-*-* } 13 } */
+/* { dg-warning "AVX vector argument without AVX enabled changes the ABI" "" { target *-*-* } 13 } */
--- gcc/testsuite/gcc.target/i386/pr69255-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr69255-2.c	(revision 240014)
@@ -0,0 +1,17 @@
+/* PR target/69255 */
+/* { dg-do compile } */
+/* { dg-options "-msse4 -mno-avx" } */
+
+#pragma GCC target "avx512vl"
+#pragma GCC target ""
+__attribute__ ((__vector_size__ (32))) long long a;
+__attribute__ ((__vector_size__ (16))) int b;
+
+void
+foo (const long long *p)
+{
+  __builtin_ia32_gather3siv4di (a, p, b, 1, 1);		/* { dg-error "needs isa option -m32 -mavx512vl" } */
+}
+
+/* { dg-warning "AVX vector return without AVX enabled changes the ABI" "" { target *-*-* } 13 } */
+/* { dg-warning "AVX vector argument without AVX enabled changes the ABI" "" { target *-*-* } 13 } */
--- gcc/testsuite/gcc.target/i386/pr69255-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr69255-3.c	(revision 240014)
@@ -0,0 +1,17 @@
+/* PR target/69255 */
+/* { dg-do compile } */
+/* { dg-options "-msse4 -mno-avx" } */
+
+#pragma GCC target "avx512vl"
+#pragma GCC target ""
+__attribute__ ((__vector_size__ (32))) long long a;
+__attribute__ ((__vector_size__ (16))) int b;
+
+void
+foo (const long long *p, __attribute__ ((__vector_size__ (32))) long long *q)
+{
+  *q = __builtin_ia32_gather3siv4di (a, p, b, 1, 1);	/* { dg-error "needs isa option -m32 -mavx512vl" } */
+}
+
+/* { dg-warning "AVX vector return without AVX enabled changes the ABI" "" { target *-*-* } 13 } */
+/* { dg-warning "AVX vector argument without AVX enabled changes the ABI" "" { target *-*-* } 13 } */
2016-09-16  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-09-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/77516
	* omp-low.c (lower_rec_simd_input_clauses): Use max_vf for non-positive
	OMP_CLAUSE_SAFELEN_EXPR.

	* gfortran.dg/gomp/pr77516.f90: New test.

--- gcc/omp-low.c	(revision 240036)
+++ gcc/omp-low.c	(revision 240037)
@@ -4302,7 +4302,9 @@ lower_rec_simd_input_clauses (tree new_v
 	{
 	  tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
 				    OMP_CLAUSE_SAFELEN);
-	  if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
+	  if (c
+	      && (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST
+		  || tree_int_cst_sgn (OMP_CLAUSE_SAFELEN_EXPR (c)) != 1))
 	    max_vf = 1;
 	  else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
 					  max_vf) == -1)
--- gcc/testsuite/gfortran.dg/gomp/pr77516.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/gomp/pr77516.f90	(revision 240037)
@@ -0,0 +1,12 @@
+! PR fortran/77516
+! { dg-do compile }
+
+program pr77516
+   integer :: i, x
+   x = 0
+!$omp simd safelen(0) reduction(+:x)
+   do i = 1, 8
+      x = x + 1
+   end do
+   print *, x
+end
2016-09-16  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-09-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/77500
	* trans-openmp.c (gfc_trans_omp_atomic): For atomic write or
	swap, don't try to look through GFC_ISYM_CONVERSION.  In other cases,
	check that value.function.isym is non-NULL before dereferencing it.

	* gfortran.dg/gomp/pr77500.f90: New test.

--- gcc/fortran/trans-openmp.c	(revision 240037)
+++ gcc/fortran/trans-openmp.c	(revision 240038)
@@ -2818,7 +2818,11 @@ gfc_trans_omp_atomic (gfc_code *code)
   gfc_start_block (&block);
 
   expr2 = code->expr2;
-  if (expr2->expr_type == EXPR_FUNCTION
+  if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
+       != GFC_OMP_ATOMIC_WRITE)
+      && (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP) == 0
+      && expr2->expr_type == EXPR_FUNCTION
+      && expr2->value.function.isym
       && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
     expr2 = expr2->value.function.actual->expr;
 
@@ -2857,6 +2861,7 @@ gfc_trans_omp_atomic (gfc_code *code)
 	  var = code->expr1->symtree->n.sym;
 	  expr2 = code->expr2;
 	  if (expr2->expr_type == EXPR_FUNCTION
+	      && expr2->value.function.isym
 	      && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
 	    expr2 = expr2->value.function.actual->expr;
 	}
@@ -2914,6 +2919,7 @@ gfc_trans_omp_atomic (gfc_code *code)
 	}
       e = expr2->value.op.op1;
       if (e->expr_type == EXPR_FUNCTION
+	  && e->value.function.isym
 	  && e->value.function.isym->id == GFC_ISYM_CONVERSION)
 	e = e->value.function.actual->expr;
       if (e->expr_type == EXPR_VARIABLE
@@ -2927,6 +2933,7 @@ gfc_trans_omp_atomic (gfc_code *code)
 	{
 	  e = expr2->value.op.op2;
 	  if (e->expr_type == EXPR_FUNCTION
+	      && e->value.function.isym
 	      && e->value.function.isym->id == GFC_ISYM_CONVERSION)
 	    e = e->value.function.actual->expr;
 	  gcc_assert (e->expr_type == EXPR_VARIABLE
@@ -3041,6 +3048,7 @@ gfc_trans_omp_atomic (gfc_code *code)
 	  code = code->next;
 	  expr2 = code->expr2;
 	  if (expr2->expr_type == EXPR_FUNCTION
+	      && expr2->value.function.isym
 	      && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
 	    expr2 = expr2->value.function.actual->expr;
 
--- gcc/testsuite/gfortran.dg/gomp/pr77500.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/gomp/pr77500.f90	(revision 240038)
@@ -0,0 +1,9 @@
+! PR fortran/77500
+! { dg-do compile }
+
+program pr77500
+   real :: x
+!$omp atomic write
+   x = f()
+!$omp end atomic
+end
2016-09-16  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-09-13  Jakub Jelinek  <jakub@redhat.com>

	PR c++/77553
	* constexpr.c (cxx_fold_pointer_plus_expression): New function.
	(cxx_eval_binary_expression): Use it for POINTER_PLUS_EXPR.
	(cxx_eval_pointer_plus_expression): Remove.
	(cxx_eval_constant_expression) <case POINTER_PLUS_EXPR>: Don't
	call cxx_eval_pointer_plus_expression.

	* g++.dg/cpp1y/constexpr-77553.C: New test.

--- gcc/cp/constexpr.c	(revision 240118)
+++ gcc/cp/constexpr.c	(revision 240119)
@@ -1745,6 +1745,63 @@ cxx_eval_unary_expression (const constex
   return r;
 }
 
+/* Helper function for cxx_eval_binary_expression.  Try to optimize
+   original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
+   generic folding should be used.  */
+
+static tree
+cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
+				  tree lhs, tree rhs, bool *non_constant_p,
+				  bool *overflow_p)
+{
+  STRIP_NOPS (lhs);
+  if (TREE_CODE (lhs) != ADDR_EXPR)
+    return NULL_TREE;
+
+  lhs = TREE_OPERAND (lhs, 0);
+
+  /* &A[i] p+ j => &A[i + j] */
+  if (TREE_CODE (lhs) == ARRAY_REF
+      && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
+      && TREE_CODE (rhs) == INTEGER_CST
+      && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
+      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
+    {
+      tree orig_type = TREE_TYPE (t);
+      location_t loc = EXPR_LOCATION (t);
+      tree type = TREE_TYPE (lhs);
+
+      t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
+      tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
+      nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
+					    overflow_p);
+      if (*non_constant_p)
+	return NULL_TREE;
+      /* Don't fold an out-of-bound access.  */
+      if (!tree_int_cst_le (t, nelts))
+	return NULL_TREE;
+      rhs = cp_fold_convert (ssizetype, rhs);
+      /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
+	 constexpr int A[1]; ... (char *)&A[0] + 1 */
+      if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
+					   rhs, TYPE_SIZE_UNIT (type))))
+	return NULL_TREE;
+      /* Make sure to treat the second operand of POINTER_PLUS_EXPR
+	 as signed.  */
+      rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
+			     TYPE_SIZE_UNIT (type));
+      t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
+      t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
+		      t, NULL_TREE, NULL_TREE);
+      t = cp_build_addr_expr (t, tf_warning_or_error);
+      t = cp_fold_convert (orig_type, t);
+      return cxx_eval_constant_expression (ctx, t, /*lval*/false,
+					   non_constant_p, overflow_p);
+    }
+
+  return NULL_TREE;
+}
+
 /* Subroutine of cxx_eval_constant_expression.
    Like cxx_eval_unary_expression, except for binary expressions.  */
 
@@ -1790,6 +1847,9 @@ cxx_eval_binary_expression (const conste
       else if (TREE_CODE (rhs) == PTRMEM_CST)
 	rhs = cplus_expand_constant (rhs);
     }
+  else if (code == POINTER_PLUS_EXPR)
+    r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
+					  overflow_p);
 
   if (r == NULL_TREE)
     r = fold_binary_loc (loc, code, type, lhs, rhs);
@@ -3448,65 +3508,6 @@ cxx_eval_switch_expr (const constexpr_ct
   return NULL_TREE;
 }
 
-/* Subroutine of cxx_eval_constant_expression.
-   Attempt to reduce a POINTER_PLUS_EXPR expression T.  */
-
-static tree
-cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
-				  bool lval, bool *non_constant_p,
-				  bool *overflow_p)
-{
-  tree orig_type = TREE_TYPE (t);
-  tree op00 = TREE_OPERAND (t, 0);
-  tree op01 = TREE_OPERAND (t, 1);
-  location_t loc = EXPR_LOCATION (t);
-
-  op00 = cxx_eval_constant_expression (ctx, op00, lval,
-				       non_constant_p, overflow_p);
-
-  STRIP_NOPS (op00);
-  if (TREE_CODE (op00) != ADDR_EXPR)
-    return NULL_TREE;
-
-  op01 = cxx_eval_constant_expression (ctx, op01, lval,
-				       non_constant_p, overflow_p);
-  op00 = TREE_OPERAND (op00, 0);
-
-  /* &A[i] p+ j => &A[i + j] */
-  if (TREE_CODE (op00) == ARRAY_REF
-      && TREE_CODE (TREE_OPERAND (op00, 1)) == INTEGER_CST
-      && TREE_CODE (op01) == INTEGER_CST
-      && TYPE_SIZE_UNIT (TREE_TYPE (op00))
-      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (op00))) == INTEGER_CST)
-    {
-      tree type = TREE_TYPE (op00);
-      t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (op00, 1));
-      tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (op00, 0)));
-      /* Don't fold an out-of-bound access.  */
-      if (!tree_int_cst_le (t, nelts))
-	return NULL_TREE;
-      op01 = cp_fold_convert (ssizetype, op01);
-      /* Don't fold if op01 can't be divided exactly by TYPE_SIZE_UNIT.
-	 constexpr int A[1]; ... (char *)&A[0] + 1 */
-      if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
-					   op01, TYPE_SIZE_UNIT (type))))
-	return NULL_TREE;
-      /* Make sure to treat the second operand of POINTER_PLUS_EXPR
-	 as signed.  */
-      op01 = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, op01,
-			      TYPE_SIZE_UNIT (type));
-      t = size_binop_loc (loc, PLUS_EXPR, op01, t);
-      t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (op00, 0),
-		      t, NULL_TREE, NULL_TREE);
-      t = cp_build_addr_expr (t, tf_warning_or_error);
-      t = cp_fold_convert (orig_type, t);
-      return cxx_eval_constant_expression (ctx, t, lval, non_constant_p,
-					   overflow_p);
-    }
-
-  return NULL_TREE;
-}
-
 /* Attempt to reduce the expression T to a constant value.
    On failure, issue diagnostic and return error_mark_node.  */
 /* FIXME unify with c_fully_fold */
@@ -3824,12 +3825,6 @@ cxx_eval_constant_expression (const cons
       break;
 
     case POINTER_PLUS_EXPR:
-      r = cxx_eval_pointer_plus_expression (ctx, t, lval, non_constant_p,
-					    overflow_p);
-      if (r)
-	break;
-      /* else fall through */
-
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
--- gcc/testsuite/g++.dg/cpp1y/constexpr-77553.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-77553.C	(revision 240119)
@@ -0,0 +1,29 @@
+// PR c++/77553
+// { dg-do compile { target c++14 } }
+
+constexpr void
+bar (int *x)
+{
+  int i = 0;
+  x[i++] = 1;
+  x[3] = i;
+}
+
+constexpr int
+foo ()
+{
+  int a[] = { 0, 0, 0, 0 };
+  bar (a);
+
+  return a[0] + 8 * a[1] + 64 * a[2] + 512 * a[3];
+}
+
+constexpr int b = foo ();
+
+int
+main ()
+{
+  static_assert (b == 513, "");
+  if (foo () != 513)
+    __builtin_abort ();
+}
2016-09-16  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-09-14  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/68260
	* tsan.c: Include target.h.
	(enum tsan_atomic_action): Add bool_clear and bool_test_and_set.
	(BOOL_CLEAR, BOOL_TEST_AND_SET): Define.
	(tsan_atomic_table): Add BUILT_IN_ATOMIC_CLEAR and
	BUILT_IN_ATOMIC_TEST_AND_SET entries.
	(instrument_builtin_call): Handle bool_clear and bool_test_and_set.

	* c-c++-common/tsan/pr68260.c: New test.

--- gcc/tsan.c	(revision 240128)
+++ gcc/tsan.c	(revision 240129)
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.
 #include "tsan.h"
 #include "asan.h"
 #include "builtins.h"
+#include "target.h"
 
 /* Number of instrumented memory accesses in the current function.  */
 
@@ -240,7 +241,8 @@ instrument_expr (gimple_stmt_iterator gs
 enum tsan_atomic_action
 {
   check_last, add_seq_cst, add_acquire, weak_cas, strong_cas,
-  bool_cas, val_cas, lock_release, fetch_op, fetch_op_seq_cst
+  bool_cas, val_cas, lock_release, fetch_op, fetch_op_seq_cst,
+  bool_clear, bool_test_and_set
 };
 
 /* Table how to map sync/atomic builtins to their corresponding
@@ -274,6 +276,10 @@ static const struct tsan_map_atomic
   TRANSFORM (fcode, tsan_fcode, fetch_op, code)
 #define FETCH_OPS(fcode, tsan_fcode, code) \
   TRANSFORM (fcode, tsan_fcode, fetch_op_seq_cst, code)
+#define BOOL_CLEAR(fcode, tsan_fcode) \
+  TRANSFORM (fcode, tsan_fcode, bool_clear, ERROR_MARK)
+#define BOOL_TEST_AND_SET(fcode, tsan_fcode) \
+  TRANSFORM (fcode, tsan_fcode, bool_test_and_set, ERROR_MARK)
 
   CHECK_LAST (ATOMIC_LOAD_1, TSAN_ATOMIC8_LOAD),
   CHECK_LAST (ATOMIC_LOAD_2, TSAN_ATOMIC16_LOAD),
@@ -463,7 +469,11 @@ static const struct tsan_map_atomic
   LOCK_RELEASE (SYNC_LOCK_RELEASE_2, TSAN_ATOMIC16_STORE),
   LOCK_RELEASE (SYNC_LOCK_RELEASE_4, TSAN_ATOMIC32_STORE),
   LOCK_RELEASE (SYNC_LOCK_RELEASE_8, TSAN_ATOMIC64_STORE),
-  LOCK_RELEASE (SYNC_LOCK_RELEASE_16, TSAN_ATOMIC128_STORE)
+  LOCK_RELEASE (SYNC_LOCK_RELEASE_16, TSAN_ATOMIC128_STORE),
+
+  BOOL_CLEAR (ATOMIC_CLEAR, TSAN_ATOMIC8_STORE),
+
+  BOOL_TEST_AND_SET (ATOMIC_TEST_AND_SET, TSAN_ATOMIC8_EXCHANGE)
 };
 
 /* Instrument an atomic builtin.  */
@@ -615,6 +625,57 @@ instrument_builtin_call (gimple_stmt_ite
 				build_int_cst (NULL_TREE,
 					       MEMMODEL_RELEASE));
 	    return;
+	  case bool_clear:
+	  case bool_test_and_set:
+	    if (BOOL_TYPE_SIZE != 8)
+	      {
+		decl = NULL_TREE;
+		for (j = 1; j < 5; j++)
+		  if (BOOL_TYPE_SIZE == (8 << j))
+		    {
+		      enum built_in_function tsan_fcode
+			= (enum built_in_function)
+			  (tsan_atomic_table[i].tsan_fcode + j);
+		      decl = builtin_decl_implicit (tsan_fcode);
+		      break;
+		    }
+		if (decl == NULL_TREE)
+		  return;
+	      }
+	    last_arg = gimple_call_arg (stmt, num - 1);
+	    if (!tree_fits_uhwi_p (last_arg)
+		|| memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
+	      return;
+	    t = TYPE_ARG_TYPES (TREE_TYPE (decl));
+	    t = TREE_VALUE (TREE_CHAIN (t));
+	    if (tsan_atomic_table[i].action == bool_clear)
+	      {
+		update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0),
+				    build_int_cst (t, 0), last_arg);
+		return;
+	      }
+	    t = build_int_cst (t, targetm.atomic_test_and_set_trueval);
+	    update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0),
+				t, last_arg);
+	    stmt = gsi_stmt (*gsi);
+	    lhs = gimple_call_lhs (stmt);
+	    if (lhs == NULL_TREE)
+	      return;
+	    if (targetm.atomic_test_and_set_trueval != 1
+		|| !useless_type_conversion_p (TREE_TYPE (lhs),
+					       TREE_TYPE (t)))
+	      {
+		tree new_lhs = make_ssa_name (TREE_TYPE (t));
+		gimple_call_set_lhs (stmt, new_lhs);
+		if (targetm.atomic_test_and_set_trueval != 1)
+		  g = gimple_build_assign (lhs, NE_EXPR, new_lhs,
+					   build_int_cst (TREE_TYPE (t), 0));
+		else
+		  g = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
+		gsi_insert_after (gsi, g, GSI_NEW_STMT);
+		update_stmt (stmt);
+	      }
+	    return;
 	  default:
 	    continue;
 	  }
--- gcc/testsuite/c-c++-common/tsan/pr68260.c	(revision 0)
+++ gcc/testsuite/c-c++-common/tsan/pr68260.c	(revision 240129)
@@ -0,0 +1,28 @@
+/* PR sanitizer/68260 */
+
+#include <pthread.h>
+#include <stdbool.h>
+
+bool lock;
+int counter;
+
+void *
+tf (void *arg)
+{
+  (void) arg;
+  while (__atomic_test_and_set (&lock, __ATOMIC_ACQUIRE))
+    ;
+  ++counter;
+  __atomic_clear (&lock, __ATOMIC_RELEASE);
+  return (void *) 0;
+}
+
+int
+main ()
+{
+  pthread_t thr;
+  pthread_create (&thr, 0, tf, 0);
+  tf ((void *) 0);
+  pthread_join (thr, 0);
+  return 0;
+}
2016-09-16  Jakub Jelinek  <jakub@redhat.com>
	    Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/77594
	* internal-fn.c (expand_arith_overflow) <case MINUS_EXPR>: Don't fall
	through into expand_addsub_overflow after expand_neg_overflow.

	* gcc.target/i386/pr77594.c: New test.

--- gcc/internal-fn.c	(revision 240172)
+++ gcc/internal-fn.c	(revision 240173)
@@ -1833,7 +1833,10 @@ expand_arith_overflow (enum tree_code co
 	    {
 	    case MINUS_EXPR:
 	      if (integer_zerop (arg0) && !unsr_p)
-		expand_neg_overflow (loc, lhs, arg1, false);
+		{
+		  expand_neg_overflow (loc, lhs, arg1, false);
+		  return;
+		}
 	      /* FALLTHRU */
 	    case PLUS_EXPR:
 	      expand_addsub_overflow (loc, code, lhs, arg0, arg1,
--- gcc/testsuite/gcc.target/i386/pr77594.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr77594.c	(revision 240173)
@@ -0,0 +1,11 @@
+/* PR middle-end/77594 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+int
+foo (int a, int *b)
+{
+  return __builtin_sub_overflow (0, a, b);
+}
+
+/* { dg-final { scan-assembler-times "\tjn?o\t" 1 } } */
diff mbox

Patch

--- libsanitizer/asan/asan_globals.cc	(revision 239997)
+++ libsanitizer/asan/asan_globals.cc	(revision 239998)
@@ -248,10 +248,10 @@  void __asan_unregister_globals(__asan_gl
 // initializer can only touch global variables in the same TU.
 void __asan_before_dynamic_init(const char *module_name) {
   if (!flags()->check_initialization_order ||
-      !CanPoisonMemory())
+      !CanPoisonMemory() ||
+      !dynamic_init_globals)
     return;
   bool strict_init_order = flags()->strict_init_order;
-  CHECK(dynamic_init_globals);
   CHECK(module_name);
   CHECK(asan_inited);
   BlockingMutexLock lock(&mu_for_globals);
@@ -274,7 +274,8 @@  void __asan_before_dynamic_init(const ch
 // TU are poisoned.  It simply unpoisons all dynamically initialized globals.
 void __asan_after_dynamic_init() {
   if (!flags()->check_initialization_order ||
-      !CanPoisonMemory())
+      !CanPoisonMemory() ||
+      !dynamic_init_globals)
     return;
   CHECK(asan_inited);
   BlockingMutexLock lock(&mu_for_globals);
--- gcc/testsuite/g++.dg/asan/pr77396.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/pr77396.C	(revision 239961)
@@ -0,0 +1,12 @@ 
+// PR sanitizer/77396
+// { dg-do run }
+// { dg-set-target-env-var ASAN_OPTIONS "check_initialization_order=true" }
+
+static int a = 0; 
+static int b = a; 
+
+int
+main ()
+{
+  return 0;
+}
--- gcc/testsuite/g++.dg/asan/pr77396-2.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/pr77396-2.C	(revision 239998)
@@ -0,0 +1,12 @@ 
+// PR sanitizer/77396
+// { dg-do run }
+// { dg-set-target-env-var ASAN_OPTIONS "check_initialization_order=true" }
+
+struct S { S () { asm volatile ("" : : : "memory"); } };
+static S c;
+
+int
+main ()
+{
+  return 0;
+}