Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-06-19 Thread Marek Polacek
On Mon, Jun 16, 2014 at 01:23:04PM +0200, Jakub Jelinek wrote:
 On Mon, Jun 16, 2014 at 12:39:07PM +0200, Marek Polacek wrote:
  Jason/Joseph, could you please look at the C++/C FE parts?
 
 As mentioned on IRC, you need to differentiate between taking address
 and not taking address.
 
 struct S { int a; int b; } s[4], *t;
 int *a, *b, *c;
 void *d;
 int e[4][4];
 
 void
 foo ()
 {
   t = s[4];  // Should be fine
   a = s[4].a; // Error
   b = s[4].b; // Error
   d = e[4];  // Should be fine
   c = e[4][0]; // Error
 }
 
 So, supposedly when e.g. in cp_genericize_r, for ADDR_EXPR ARRAY_REF
 allow off-by-one, for all other ARRAY_REFs (e.g. those not appearing
 inside of ADDR_EXPR, or not directly inside of ADDR_EXPR, e.g. with
 COMPONENT_REF or another ARRAY_REF in between) disallow off-by-one.

Should be fixed in this new patch.  Another change is in handling
flexible array member-like arrays, what I had in last patch was wrong.
I use the non-strict mode by default, which means flexible array
member-like arrays are not instrumented.   We could have e.g.
-fsanitize=bounds-strict option that would instrument even those.
(Regular FMAs are never instrumented.)

I moved the code that instruments array to c_genericize (works for
both C and C++).  Also I fixed an ICE (we shouldn't instrument
initializers of TREE_STATIC, otherwise internal calls from FE
survive up to expansion).

Oh, I see I forgot to update docs, I'll write something up in
another iteration.

Regtested/bootstrapped on x86_64-linux.  How does this look?

2014-06-19  Marek Polacek  pola...@redhat.com

* asan.c (pass_sanopt::execute): Handle IFN_UBSAN_BOUNDS.
* flag-types.h (enum sanitize_code): Add SANITIZE_BOUNDS and or it
into SANITIZE_UNDEFINED.
* gimplify.c (gimplify_call_expr): Add gimplification of internal
functions created in the FEs.
* internal-fn.c: Move internal-fn.h after tree.h.
(expand_UBSAN_BOUNDS): New function.
* internal-fn.def (UBSAN_BOUNDS): New internal function.
* internal-fn.h: Don't define internal functions here.
* opts.c (common_handle_option): Add -fsanitize=bounds.
* sanitizer.def (BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS,
BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT): Add.
* tree-core.h: Define internal functions here.
(struct tree_base): Add ifn field.
* tree-pretty-print.c (print_call_name): Handle functions without
CALL_EXPR_FN.
* tree.c (get_callee_fndecl): Likewise.
(build_call_expr_internal_loc): New function.
* tree.def (CALL_EXPR): Update description.
* tree.h (CALL_EXPR_IFN): Define.
(build_call_expr_internal_loc): Declare.
* ubsan.c (get_ubsan_type_info_for_type): Return 0 for non-arithmetic
types.
(ubsan_type_descriptor): Change bool parameter to enum
ubsan_print_style.  Adjust the code.  Add handling of
UBSAN_PRINT_ARRAY.
(ubsan_expand_bounds_btn): New function.
(ubsan_expand_null_ifn): Adjust ubsan_type_descriptor call.
(ubsan_build_overflow_builtin): Likewise.
(instrument_bool_enum_load): Likewise.
(ubsan_instrument_float_cast): Likewise.
* ubsan.h (enum ubsan_print_style): New enum.
(ubsan_expand_bounds_btn): Declare.
(ubsan_type_descriptor): Adjust declaration.  Use a default parameter.
c-family/
* c-gimplify.c: Include c-ubsan.h and pointer-set.h.
(ubsan_walk_array_refs_r): New function.
(c_genericize): Instrument array bounds.
* c-ubsan.c: Include internal-fn.h.
(ubsan_instrument_division): Mark instrumented arrays as having
side effects.  Adjust ubsan_type_descriptor call.
(ubsan_instrument_shift): Likewise.
(ubsan_instrument_vla): Adjust ubsan_type_descriptor call.
(ubsan_instrument_bounds): New function.
(ubsan_array_ref_instrumented_p): New function.
(ubsan_maybe_instrument_array_ref): New function.
* c-ubsan.h (ubsan_instrument_bounds): Declare.
(ubsan_array_ref_instrumented_p): Declare.
(ubsan_maybe_instrument_array_ref): Declare.
testsuite/
* c-c++-common/ubsan/bounds-1.c: New test.
* c-c++-common/ubsan/bounds-2.c: New test.
* c-c++-common/ubsan/bounds-3.c: New test.
* c-c++-common/ubsan/bounds-4.c: New test.
* c-c++-common/ubsan/bounds-5.c: New test.
* c-c++-common/ubsan/bounds-6.c: New test.

diff --git gcc/asan.c gcc/asan.c
index 281a795..5f5dcaa 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2761,6 +2761,9 @@ pass_sanopt::execute (function *fun)
  case IFN_UBSAN_NULL:
ubsan_expand_null_ifn (gsi);
break;
+ case IFN_UBSAN_BOUNDS:
+   ubsan_expand_bounds_btn (gsi);
+   break;
  default:
break;
  }
@@ -2771,6 +2774,10 @@ pass_sanopt::execute (function *fun

Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-06-19 Thread Marek Polacek
On Thu, Jun 19, 2014 at 04:56:53PM +0200, Marek Polacek wrote:
 Regtested/bootstrapped on x86_64-linux.  How does this look?

Now even bootstrap-ubsan passed, with 92258 runtime errors:
index 1 out of bounds for type 'rtunion [1]' - heh.

Marek


Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-06-20 Thread Marek Polacek
On Thu, Jun 19, 2014 at 07:19:31PM +0200, Jakub Jelinek wrote:
  + case IFN_UBSAN_BOUNDS:
  +   ubsan_expand_bounds_btn (gsi);
  +   break;
default:
 
 Why *_btn instead of *_ifn ?

Remnant from when I was using __builtin.ubsan instead of the internal
call.  Fixed.
 
  +static tree
  +ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
  +{
  +  struct pointer_set_t *pset = (struct pointer_set_t *) data;
  +
  +  if (TREE_CODE (*tp) == BIND_EXPR)
  +{
 
 I think it would be worth adding here a comment why do you handle BIND_EXPR
 here, that it doesn't walk the vars, but only their initializers etc. and
 thus in order to prevent walking DECL_INITIAL of TREE_STATIC decls
 we have to duplicate this part of walk_tree.

Done.

  +  for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN 
  (decl))
  +   {
  + if (TREE_STATIC (decl))
  +   {
  + *walk_subtrees = 0;
  + continue;
  +   }
  + walk_tree (DECL_INITIAL (decl), ubsan_walk_array_refs_r, NULL, pset);
  + walk_tree (DECL_SIZE (decl), ubsan_walk_array_refs_r, NULL, pset);
  + walk_tree (DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, NULL, 
  pset);
 
 Shouldn't that use pset, pset); or data, pset); ?
 Also, too long lines (at least the last one, first one likely too).

Oops, fixed.
 
  +  tree bound = TYPE_MAX_VALUE (domain);
  +  if (ignore_off_by_one)
  +bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
  +build_int_cst (TREE_TYPE (bound), 1));
  +
  +  /* Detect flexible array members and suchlike.  */
  +  tree base = get_base_address (array);
  +  if (base  TREE_CODE (base) == INDIRECT_REF)
 
 I'd check also == MEM_REF here, while the FEs often use INDIRECT_REFs,
 there are already spots where it creates MEM_REFs.

Fixed.

  +void
  +ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
  +{
  +  if (!ubsan_array_ref_instrumented_p (*expr_p)
  +   current_function_decl != 0
 
 Please use != NULL_TREE.

Ok.
 
  +   !lookup_attribute (no_sanitize_undefined,
  +   DECL_ATTRIBUTES (current_function_decl)))
  +{
  +  tree t = copy_node (*expr_p);
  +  tree op0 = TREE_OPERAND (t, 0);
  +  tree op1 = TREE_OPERAND (t, 1);
 
 Please don't call copy_node until you know you want to instrument it.
 I.e.
   tree op0 = TREE_OPERAND (*expr_p, 0);
   tree op1 = TREE_OPERAND (*expr_p, 1);
  +  tree e = ubsan_instrument_bounds (EXPR_LOCATION (t), op0, op1,
 
 s/t/*expr_p/ above.
 
  +   ignore_off_by_one);
  +  if (e != NULL_TREE)
  +   {
 
 and only here add:
 tree t = copy_node (*expr_p);
  + TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
  +   e, op1);
  + *expr_p = t;
  +   }
  +}
  +}

Fixed as well.

  --- gcc/tree-pretty-print.c
  +++ gcc/tree-pretty-print.c
  @@ -3218,6 +3218,13 @@ print_call_name (pretty_printer *buffer, tree node, 
  int flags)
   {
 tree op0 = node;
   
  +  if (node == NULL_TREE)
  +{
  +  /* TODO Print builtin name.  */
  +  pp_string (buffer, internal function call);
 
 Use internal_fn_name function?

Uh, not sure how I missed that.  I print the internal function before calling
print_call_name, since that gets NULL node - and we can't determine
CALL_EXPR_IFN.

I added some docs as well, as promised.

2014-06-20  Marek Polacek  pola...@redhat.com

* asan.c (pass_sanopt::execute): Handle IFN_UBSAN_BOUNDS.
* flag-types.h (enum sanitize_code): Add SANITIZE_BOUNDS and or it
into SANITIZE_UNDEFINED.
* doc/invoke.texi: Describe -fsanitize=bounds.
* gimplify.c (gimplify_call_expr): Add gimplification of internal
functions created in the FEs.
* internal-fn.c: Move internal-fn.h after tree.h.
(expand_UBSAN_BOUNDS): New function.
* internal-fn.def (UBSAN_BOUNDS): New internal function.
* internal-fn.h: Don't define internal functions here.
* opts.c (common_handle_option): Add -fsanitize=bounds.
* sanitizer.def (BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS,
BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT): Add.
* tree-core.h: Define internal functions here.
(struct tree_base): Add ifn field.
* tree-pretty-print.c: Include internal-fn.h.
(dump_generic_node): Handle functions without CALL_EXPR_FN.
* tree.c (get_callee_fndecl): Likewise.
(build_call_expr_internal_loc): New function.
* tree.def (CALL_EXPR): Update description.
* tree.h (CALL_EXPR_IFN): Define.
(build_call_expr_internal_loc): Declare.
* ubsan.c (get_ubsan_type_info_for_type): Return 0 for non-arithmetic
types.
(ubsan_type_descriptor): Change bool parameter to enum
ubsan_print_style.  Adjust the code.  Add handling of
UBSAN_PRINT_ARRAY

Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-06-20 Thread Marek Polacek
On Fri, Jun 20, 2014 at 10:57:47AM +0200, Jakub Jelinek wrote:
 On Fri, Jun 20, 2014 at 10:43:04AM +0200, Marek Polacek wrote:
  +
  +/* Internal function code.  */
  +ENUM_BITFIELD(internal_fn) ifn : 5;
 
 Any reason for the  : 5 here?  I mean, the union also contains
 unsigned int, so it doesn't hurt if you use full 32 bits for it there,
 and it should be faster and you won't run into problems when we'll have
 more than 32 internal functions.

The sole reason was that all other ENUM_BITFIELDs have it - on the
other hand, they're not in a union and here the bit-field is
pointless.  I'll drop it.
 
 Otherwise the patch looks good to me, but please wait for comments
 from Joseph and/or Jason.

Thanks for all your help!

The following is the same patch with only  : 5 dropped.

2014-06-20  Marek Polacek  pola...@redhat.com

* asan.c (pass_sanopt::execute): Handle IFN_UBSAN_BOUNDS.
* flag-types.h (enum sanitize_code): Add SANITIZE_BOUNDS and or it
into SANITIZE_UNDEFINED.
* doc/invoke.texi: Describe -fsanitize=bounds.
* gimplify.c (gimplify_call_expr): Add gimplification of internal
functions created in the FEs.
* internal-fn.c: Move internal-fn.h after tree.h.
(expand_UBSAN_BOUNDS): New function.
* internal-fn.def (UBSAN_BOUNDS): New internal function.
* internal-fn.h: Don't define internal functions here.
* opts.c (common_handle_option): Add -fsanitize=bounds.
* sanitizer.def (BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS,
BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT): Add.
* tree-core.h: Define internal functions here.
(struct tree_base): Add ifn field.
* tree-pretty-print.c: Include internal-fn.h.
(dump_generic_node): Handle functions without CALL_EXPR_FN.
* tree.c (get_callee_fndecl): Likewise.
(build_call_expr_internal_loc): New function.
* tree.def (CALL_EXPR): Update description.
* tree.h (CALL_EXPR_IFN): Define.
(build_call_expr_internal_loc): Declare.
* ubsan.c (get_ubsan_type_info_for_type): Return 0 for non-arithmetic
types.
(ubsan_type_descriptor): Change bool parameter to enum
ubsan_print_style.  Adjust the code.  Add handling of
UBSAN_PRINT_ARRAY.
(ubsan_expand_bounds_ifn): New function.
(ubsan_expand_null_ifn): Adjust ubsan_type_descriptor call.
(ubsan_build_overflow_builtin): Likewise.
(instrument_bool_enum_load): Likewise.
(ubsan_instrument_float_cast): Likewise.
* ubsan.h (enum ubsan_print_style): New enum.
(ubsan_expand_bounds_ifn): Declare.
(ubsan_type_descriptor): Adjust declaration.  Use a default parameter.
c-family/
* c-gimplify.c: Include c-ubsan.h and pointer-set.h.
(ubsan_walk_array_refs_r): New function.
(c_genericize): Instrument array bounds.
* c-ubsan.c: Include internal-fn.h.
(ubsan_instrument_division): Mark instrumented arrays as having
side effects.  Adjust ubsan_type_descriptor call.
(ubsan_instrument_shift): Likewise.
(ubsan_instrument_vla): Adjust ubsan_type_descriptor call.
(ubsan_instrument_bounds): New function.
(ubsan_array_ref_instrumented_p): New function.
(ubsan_maybe_instrument_array_ref): New function.
* c-ubsan.h (ubsan_instrument_bounds): Declare.
(ubsan_array_ref_instrumented_p): Declare.
(ubsan_maybe_instrument_array_ref): Declare.
testsuite/
* c-c++-common/ubsan/bounds-1.c: New test.
* c-c++-common/ubsan/bounds-2.c: New test.
* c-c++-common/ubsan/bounds-3.c: New test.
* c-c++-common/ubsan/bounds-4.c: New test.
* c-c++-common/ubsan/bounds-5.c: New test.
* c-c++-common/ubsan/bounds-6.c: New test.

diff --git gcc/asan.c gcc/asan.c
index 281a795..b7c76cf 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2761,6 +2761,9 @@ pass_sanopt::execute (function *fun)
  case IFN_UBSAN_NULL:
ubsan_expand_null_ifn (gsi);
break;
+ case IFN_UBSAN_BOUNDS:
+   ubsan_expand_bounds_ifn (gsi);
+   break;
  default:
break;
  }
@@ -2771,6 +2774,10 @@ pass_sanopt::execute (function *fun)
  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
  fprintf (dump_file, \n);
}
+
+ /* ubsan_expand_bounds_ifn might move us to the end of the BB.  */
+ if (gsi_end_p (gsi))
+   break;
}
 }
   return 0;
diff --git gcc/c-family/c-gimplify.c gcc/c-family/c-gimplify.c
index 737be4d..c797d99 100644
--- gcc/c-family/c-gimplify.c
+++ gcc/c-family/c-gimplify.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3.  If not see
 #include c-pretty-print.h
 #include cgraph.h
 #include cilk.h
+#include c-ubsan.h
+#include pointer-set.h
 
 /*  The gimplification pass converts the language-dependent

Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-06-20 Thread Marek Polacek
On Fri, Jun 20, 2014 at 11:39:23AM +0200, Jakub Jelinek wrote:
 On Fri, Jun 20, 2014 at 11:34:26AM +0200, Marek Polacek wrote:
  On Fri, Jun 20, 2014 at 10:57:47AM +0200, Jakub Jelinek wrote:
   On Fri, Jun 20, 2014 at 10:43:04AM +0200, Marek Polacek wrote:
+
+/* Internal function code.  */
+ENUM_BITFIELD(internal_fn) ifn : 5;
   
   Any reason for the  : 5 here?  I mean, the union also contains
   unsigned int, so it doesn't hurt if you use full 32 bits for it there,
   and it should be faster and you won't run into problems when we'll have
   more than 32 internal functions.
  
  The sole reason was that all other ENUM_BITFIELDs have it - on the
  other hand, they're not in a union and here the bit-field is
  pointless.  I'll drop it.
 
 Well, no point to use ENUM_BITFIELD either, just use
 enum internal_fn ifn;

Works as well.

2014-06-20  Marek Polacek  pola...@redhat.com

* asan.c (pass_sanopt::execute): Handle IFN_UBSAN_BOUNDS.
* flag-types.h (enum sanitize_code): Add SANITIZE_BOUNDS and or it
into SANITIZE_UNDEFINED.
* doc/invoke.texi: Describe -fsanitize=bounds.
* gimplify.c (gimplify_call_expr): Add gimplification of internal
functions created in the FEs.
* internal-fn.c: Move internal-fn.h after tree.h.
(expand_UBSAN_BOUNDS): New function.
* internal-fn.def (UBSAN_BOUNDS): New internal function.
* internal-fn.h: Don't define internal functions here.
* opts.c (common_handle_option): Add -fsanitize=bounds.
* sanitizer.def (BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS,
BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT): Add.
* tree-core.h: Define internal functions here.
(struct tree_base): Add ifn field.
* tree-pretty-print.c: Include internal-fn.h.
(dump_generic_node): Handle functions without CALL_EXPR_FN.
* tree.c (get_callee_fndecl): Likewise.
(build_call_expr_internal_loc): New function.
* tree.def (CALL_EXPR): Update description.
* tree.h (CALL_EXPR_IFN): Define.
(build_call_expr_internal_loc): Declare.
* ubsan.c (get_ubsan_type_info_for_type): Return 0 for non-arithmetic
types.
(ubsan_type_descriptor): Change bool parameter to enum
ubsan_print_style.  Adjust the code.  Add handling of
UBSAN_PRINT_ARRAY.
(ubsan_expand_bounds_ifn): New function.
(ubsan_expand_null_ifn): Adjust ubsan_type_descriptor call.
(ubsan_build_overflow_builtin): Likewise.
(instrument_bool_enum_load): Likewise.
(ubsan_instrument_float_cast): Likewise.
* ubsan.h (enum ubsan_print_style): New enum.
(ubsan_expand_bounds_ifn): Declare.
(ubsan_type_descriptor): Adjust declaration.  Use a default parameter.
c-family/
* c-gimplify.c: Include c-ubsan.h and pointer-set.h.
(ubsan_walk_array_refs_r): New function.
(c_genericize): Instrument array bounds.
* c-ubsan.c: Include internal-fn.h.
(ubsan_instrument_division): Mark instrumented arrays as having
side effects.  Adjust ubsan_type_descriptor call.
(ubsan_instrument_shift): Likewise.
(ubsan_instrument_vla): Adjust ubsan_type_descriptor call.
(ubsan_instrument_bounds): New function.
(ubsan_array_ref_instrumented_p): New function.
(ubsan_maybe_instrument_array_ref): New function.
* c-ubsan.h (ubsan_instrument_bounds): Declare.
(ubsan_array_ref_instrumented_p): Declare.
(ubsan_maybe_instrument_array_ref): Declare.
testsuite/
* c-c++-common/ubsan/bounds-1.c: New test.
* c-c++-common/ubsan/bounds-2.c: New test.
* c-c++-common/ubsan/bounds-3.c: New test.
* c-c++-common/ubsan/bounds-4.c: New test.
* c-c++-common/ubsan/bounds-5.c: New test.
* c-c++-common/ubsan/bounds-6.c: New test.

diff --git gcc/asan.c gcc/asan.c
index 281a795..b7c76cf 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2761,6 +2761,9 @@ pass_sanopt::execute (function *fun)
  case IFN_UBSAN_NULL:
ubsan_expand_null_ifn (gsi);
break;
+ case IFN_UBSAN_BOUNDS:
+   ubsan_expand_bounds_ifn (gsi);
+   break;
  default:
break;
  }
@@ -2771,6 +2774,10 @@ pass_sanopt::execute (function *fun)
  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
  fprintf (dump_file, \n);
}
+
+ /* ubsan_expand_bounds_ifn might move us to the end of the BB.  */
+ if (gsi_end_p (gsi))
+   break;
}
 }
   return 0;
diff --git gcc/c-family/c-gimplify.c gcc/c-family/c-gimplify.c
index 737be4d..c797d99 100644
--- gcc/c-family/c-gimplify.c
+++ gcc/c-family/c-gimplify.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3.  If not see
 #include c-pretty-print.h
 #include cgraph.h
 #include cilk.h
+#include c-ubsan.h
+#include pointer

Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-06-20 Thread Marek Polacek
On Thu, Jun 19, 2014 at 07:47:54PM +0200, Jakub Jelinek wrote:
 On Thu, Jun 19, 2014 at 04:56:53PM +0200, Marek Polacek wrote:
  +   /* Don't instrument this FMA-like array in non-strict
 
 Also, please don't use FMA to mean flexible member array, it is
 flexible array member, but more importantly, FMA is used for fused
 multiply-add, so IMHO it is better to spell it without acronym.

Just for the record, I've fixed this up in some earlier patch.

Marek


[PATCH] Fix arrays in rtx.u + add minor rtx verification

2014-06-20 Thread Marek Polacek
When implementing -fsanitize=bounds I noticed a whole slew of
errors about accessing u.fld[] field in rtx_def.  Turned out this
is indeed a bug, the array should have a size of 8; u.hwint[] array
had similar issue.  Thus fixed, plus I added some verification code
to genpreds.c (can't do it in gengenrtl.c as that doesn't include
rtl.h) so this won't happen again.

Verified that the bootstrap crashes by bootstrapping with changed
RTX_FLD_WIDTH/RTX_HWINT_WIDTH, otherwise the bootstrapp passes.

Ok for trunk?

2014-06-20  Marek Polacek  pola...@redhat.com

* genpreds.c (verify_rtx_codes): New function.
(main): Call it.
* rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define.
(struct rtx_def): Use them.

diff --git gcc/genpreds.c gcc/genpreds.c
index b14a4ac..3826757 100644
--- gcc/genpreds.c
+++ gcc/genpreds.c
@@ -1471,6 +1471,40 @@ parse_option (const char *opt)
 return 0;
 }
 
+/* Verify RTX codes.  We can't call fatal_error here, so call
+   gcc_unreachable after error to really abort.  */
+
+static void
+verify_rtx_codes (void)
+{
+  unsigned int i, j;
+
+  for (i = 0; i  NUM_RTX_CODE; i++)
+if (strchr (GET_RTX_FORMAT (i), 'w') == NULL)
+  {
+   if (strlen (GET_RTX_FORMAT (i))  RTX_FLD_WIDTH)
+ {
+   error (insufficient size of RTX_FLD_WIDTH);
+   gcc_unreachable ();
+ }
+  }
+else
+  {
+   const size_t len = strlen (GET_RTX_FORMAT (i));
+   for (j = 0; j  len; j++)
+ if (GET_RTX_FORMAT (i)[j] != 'w')
+   {
+ error (rtx format does not contain only hwint entries);
+ gcc_unreachable ();
+   }
+   if (len  RTX_HWINT_WIDTH)
+ {
+   error (insufficient size of RTL_MAX_HWINT_WIDTH);
+   gcc_unreachable ();
+ }
+  }
+}
+
 /* Master control.  */
 int
 main (int argc, char **argv)
@@ -1518,5 +1552,7 @@ main (int argc, char **argv)
   if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
 return FATAL_EXIT_CODE;
 
+  verify_rtx_codes ();
+
   return SUCCESS_EXIT_CODE;
 }
diff --git gcc/rtl.h gcc/rtl.h
index 6ec91a8..3f2e774 100644
--- gcc/rtl.h
+++ gcc/rtl.h
@@ -264,6 +264,12 @@ struct GTY((variable_size)) hwivec_def {
 #define CWI_PUT_NUM_ELEM(RTX, NUM) \
   (RTL_FLAG_CHECK1(CWI_PUT_NUM_ELEM, (RTX), CONST_WIDE_INT)-u2.num_elem = 
(NUM))
 
+/* The maximum number of entries in the FLD array in rtx.  */
+#define RTX_FLD_WIDTH 8
+
+/* The maximum number of entries in the HWINT array in rtx.  */
+#define RTX_HWINT_WIDTH (MAX (REAL_WIDTH, 3))
+
 /* RTL expression (rtx).  */
 
 struct GTY((chain_next (RTX_NEXT (%h)),
@@ -378,8 +384,8 @@ struct GTY((chain_next (RTX_NEXT (%h)),
  The number of operands and their types are controlled
  by the `code' field, according to rtl.def.  */
   union u {
-rtunion fld[1];
-HOST_WIDE_INT hwint[1];
+rtunion fld[RTX_FLD_WIDTH];
+HOST_WIDE_INT hwint[RTX_HWINT_WIDTH];
 struct block_symbol block_sym;
 struct real_value rv;
 struct fixed_value fv;

Marek


Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification

2014-06-20 Thread Marek Polacek
On Fri, Jun 20, 2014 at 09:01:14PM +0200, Jakub Jelinek wrote:
 On Fri, Jun 20, 2014 at 07:36:41PM +0200, Marek Polacek wrote:
  2014-06-20  Marek Polacek  pola...@redhat.com
  
  * genpreds.c (verify_rtx_codes): New function.
  (main): Call it.
  * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define.
  (struct rtx_def): Use them.
 
 Note, e.g. Coverity also complains about this stuff loudly too,
 apparently not just in the problematic case where rtx_def is used
 in a middle of structure, but also when used in flexible array
 like spot.  Most RTLs are allocated through rtx_alloc and the size
 is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE,
 so your rtl.h change IMHO shouldn't affect anything but make the
 expmed.c init_expmed_rtl structure somewhat longer.


 
  --- gcc/genpreds.c
  +++ gcc/genpreds.c
  @@ -1471,6 +1471,40 @@ parse_option (const char *opt)
   return 0;
   }
   
  +/* Verify RTX codes.  We can't call fatal_error here, so call
  +   gcc_unreachable after error to really abort.  */
  +
  +static void
  +verify_rtx_codes (void)
  +{
  +  unsigned int i, j;
  +
  +  for (i = 0; i  NUM_RTX_CODE; i++)
  +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL)
  +  {
  +   if (strlen (GET_RTX_FORMAT (i))  RTX_FLD_WIDTH)
  + {
  +   error (insufficient size of RTX_FLD_WIDTH);
  +   gcc_unreachable ();
 
 I think it would be nice to be more verbose, i.e. say
 which rtx has longer format string than RTX_FLD_WIDTH, and perhaps also
 the size and RTX_FLD_WIDTH value.  Also, can't you use internal_error
 instead of error + gcc_unreachable ?
 
 So perhaps
   internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n,
   GET_RTX_NAME (i), GET_RTX_FORMAT (i),
   (int) RTX_FLD_WIDTH);
 ?
 
Ok, that's much better.  I actually can use internal_error - we have 
that function in both diagnostic.c and errors.c, while fatal_error is
only in diagnostic.c.

  + }
  +  }
  +else
  +  {
  +   const size_t len = strlen (GET_RTX_FORMAT (i));
  +   for (j = 0; j  len; j++)
  + if (GET_RTX_FORMAT (i)[j] != 'w')
  +   {
  + error (rtx format does not contain only hwint entries);
  + gcc_unreachable ();
  +   }
  +   if (len  RTX_HWINT_WIDTH)
  + {
  +   error (insufficient size of RTL_MAX_HWINT_WIDTH);
  +   gcc_unreachable ();
  + }
  +  }
 
 And similarly here.

Fixed.
 
 Otherwise, LGTM, but as I've been discussing this with Marek,
 I'd prefer somebody else to review it.

Sure.  So can anybody look at this, please?

2014-06-20  Marek Polacek  pola...@redhat.com

* genpreds.c (verify_rtx_codes): New function.
(main): Call it.
* rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define.
(struct rtx_def): Use them.

diff --git gcc/genpreds.c gcc/genpreds.c
index b14a4ac..7e62124 100644
--- gcc/genpreds.c
+++ gcc/genpreds.c
@@ -1471,6 +1471,36 @@ parse_option (const char *opt)
 return 0;
 }
 
+/* Verify RTX codes.  */
+
+static void
+verify_rtx_codes (void)
+{
+  unsigned int i, j;
+
+  for (i = 0; i  NUM_RTX_CODE; i++)
+if (strchr (GET_RTX_FORMAT (i), 'w') == NULL)
+  {
+   if (strlen (GET_RTX_FORMAT (i))  RTX_FLD_WIDTH)
+ internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n,
+ GET_RTX_NAME (i), GET_RTX_FORMAT (i),
+ (int) RTX_FLD_WIDTH);
+  }
+else
+  {
+   const size_t len = strlen (GET_RTX_FORMAT (i));
+   for (j = 0; j  len; j++)
+ if (GET_RTX_FORMAT (i)[j] != 'w')
+   internal_error (%s format %s should contain only w, but 
+   has %c\n, GET_RTX_NAME (i), GET_RTX_FORMAT (i),
+   GET_RTX_FORMAT (i)[j]);
+   if (len  RTX_HWINT_WIDTH)
+ internal_error (%s format %s longer than RTX_HWINT_WIDTH %d\n,
+ GET_RTX_NAME (i), GET_RTX_FORMAT (i),
+ (int) RTX_HWINT_WIDTH);
+  }
+}
+
 /* Master control.  */
 int
 main (int argc, char **argv)
@@ -1518,5 +1548,7 @@ main (int argc, char **argv)
   if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
 return FATAL_EXIT_CODE;
 
+  verify_rtx_codes ();
+
   return SUCCESS_EXIT_CODE;
 }
diff --git gcc/rtl.h gcc/rtl.h
index 6ec91a8..3f2e774 100644
--- gcc/rtl.h
+++ gcc/rtl.h
@@ -264,6 +264,12 @@ struct GTY((variable_size)) hwivec_def {
 #define CWI_PUT_NUM_ELEM(RTX, NUM) \
   (RTL_FLAG_CHECK1(CWI_PUT_NUM_ELEM, (RTX), CONST_WIDE_INT)-u2.num_elem = 
(NUM))
 
+/* The maximum number of entries in the FLD array in rtx.  */
+#define RTX_FLD_WIDTH 8
+
+/* The maximum number of entries in the HWINT array in rtx.  */
+#define RTX_HWINT_WIDTH (MAX (REAL_WIDTH, 3))
+
 /* RTL expression (rtx).  */
 
 struct GTY((chain_next (RTX_NEXT (%h)),
@@ -378,8 +384,8 @@ struct GTY((chain_next (RTX_NEXT (%h)),
  The number of operands

Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification

2014-06-20 Thread Marek Polacek
On Fri, Jun 20, 2014 at 11:10:18PM +0200, Jakub Jelinek wrote:
 On Fri, Jun 20, 2014 at 01:55:41PM -0600, Jeff Law wrote:
  like spot.  Most RTLs are allocated through rtx_alloc and the size
  is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE,
  so your rtl.h change IMHO shouldn't affect anything but make the
  expmed.c init_expmed_rtl structure somewhat longer.
  Right.  This comment was actually very helpful in that I wasn't aware of
  precisely which cases Marek was trying to address.
  
  Presumably the [1] sizing is what prevents any compile-time checking of
  this?
 
 First version of Marek's patch did that (never instrumented [], [0] and
 [1] arrays, no matter where they appeared, and instrumented everything
 else).
 Latest patch only never instruments [] (which, by definition can only
 appear at the end of structure), other arrays (no matter what size)
 aren't instrumented if they aren't followed by any fields, or
 if the base of the handled components is not INDIRECT_REF/MEM_REF
 (so, typically is a decl).
 u.fld[1] array is the last field, so we don't warn for that, but when
 rtx_def appears in another structure (in expmed.c) or if e.g. even
 some code had a rtx_def typed variable and accessed say u.fld[1] in there,
 it would be instrumented.

Yeah - init_expmed in expmed.c has
XEXP (all.plus, 1) = all.reg;
which is expanded to
(((all.plus)-u.fld[1]).rt_rtx) = all.reg;
but since the expression (A)-B is the same as A.B (if A is a valid
pointer expression), the above was turned into
all.plus.u.fld[1].rt_rtx) = all.reg;
and that doesn't contain any INDIRECT_REF/MEM_REFs - it's being
instrumented.  With this patch I don't see any -fsanitize=bounds
errors when doing bootstrap-ubsan.
 
 Whether we should have a strict array bounds mode where we would instrument
 even arrays at the end of structures (with the exception of []) is something
 to be discussed.

This should be basically just about adding a new option - e.g.
-fsanitize=bounds-strict.

Marek


Re: [C/C++ PATCH] Add -Wlogical-not-parentheses (PR c/49706)

2014-06-23 Thread Marek Polacek
On Sun, Jun 22, 2014 at 10:33:57PM +0200, Gerald Pfeifer wrote:
 On Mon, 2 Jun 2014, Marek Polacek wrote:
  * c-typeck.c (parser_build_binary_op): Warn when logical not is used
  on the left hand side operand of a comparison. 
 
 This...
 
  +/* Warn about logical not used on the left hand side operand of a 
  comparison.
 
 ...and this...
 
  +  warning_at (location, OPT_Wlogical_not_parentheses,
  + logical not is only applied to the left hand side of 
  + comparison);
 
 ...does not appear consistent with the actual warning.
 
 Why does that warning say is _ONLY_ applied to the left hand side?
 
 Based on the message, I naively assumed that the code should not warn
 about
 
   int same(int a, int b) {
 return !a == !b;
   }
 
 alas this is not the case.  (Code like this occurs in Wine where
 bool types are emulated and !!a or a comparison like above ensure
 that those emulated bools are normalized to either 0 or 1.)
 
 
 I understand there is ambiguity in cases like
 
   return !a == b;
 
 where the warning would be approriately worded and the programmer
 might have intended !(a == b).
 
 
 I do recommend to either omit only from the text of the warning
 or not warn for cases where ! occurs on both sides of the comparison
 (and keep the text as is).

I think the latter is better, incidentally, g++ doesn't warn either.
The following one liner makes cc1 behave as cc1plus.  Thanks for the
report.

Regtested/bootstrapped on x86_64.  Joseph, is this ok?

2014-06-23  Marek Polacek  pola...@redhat.com

* c-typeck.c (parser_build_binary_op): Don't call
warn_logical_not_parentheses if the RHS is TRUTH_NOT_EXPR.

* c-c++-common/pr49706-2.c: New test.

diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 63bd65e..0764630 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -3402,7 +3402,8 @@ parser_build_binary_op (location_t location, enum 
tree_code code,
   code1, arg1.value, code2, arg2.value);
 
   if (warn_logical_not_paren
-   code1 == TRUTH_NOT_EXPR)
+   code1 == TRUTH_NOT_EXPR
+   code2 != TRUTH_NOT_EXPR)
 warn_logical_not_parentheses (location, code, arg1.value, arg2.value);
 
   /* Warn about comparisons against string literals, with the exception
diff --git gcc/testsuite/c-c++-common/pr49706-2.c 
gcc/testsuite/c-c++-common/pr49706-2.c
index e69de29..09cc9eb 100644
--- gcc/testsuite/c-c++-common/pr49706-2.c
+++ gcc/testsuite/c-c++-common/pr49706-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options -Wlogical-not-parentheses } */
+
+/* Test that we don't warn if both operands of the comparison
+   are negated.  */
+
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+
+bool r;
+
+int
+same (int a, int b)
+{
+  r = !a == !b;
+  r = !!a == !!b;
+  r = !!a == !b;
+  r = !a == !!b;
+}

Marek


[PATCH] Don't segv on __atomic_store (PR c/61553)

2014-06-23 Thread Marek Polacek
We ICEd on the following testcase since the void type has a NULL
TYPE_SIZE_UNIT.  I took Andrew's patch from gcc@ ML and added
a testcase.

Regtested/bootstrapped on x86_64-linux, ok for trunk?

2014-06-23  Marek Polacek  pola...@redhat.com
Andrew MacLeod  amacl...@redhat.com

PR c/61553
* c-common.c (get_atomic_generic_size): Don't segfault if the
type doesn't have a size.

* c-c++-common/pr61553.c: New test.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index 077263e..087f036 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -10471,7 +10471,8 @@ get_atomic_generic_size (location_t loc, tree function,
function);
  return 0;
}
-  size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
+  tree type_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
+  size = type_size ? tree_to_uhwi (type_size) : 0;
   if (size != size_0)
{
  error_at (loc, size mismatch in argument %d of %qE, x + 1,
diff --git gcc/testsuite/c-c++-common/pr61553.c 
gcc/testsuite/c-c++-common/pr61553.c
index e69de29..fa97e94 100644
--- gcc/testsuite/c-c++-common/pr61553.c
+++ gcc/testsuite/c-c++-common/pr61553.c
@@ -0,0 +1,8 @@
+/* PR c/61553 */
+/* { dg-do compile } */
+
+void
+foo (char *s)
+{
+  __atomic_store (s, (void *) 0, __ATOMIC_SEQ_CST);
+}

Marek


Re: [PATCH] Don't segv on __atomic_store (PR c/61553)

2014-06-23 Thread Marek Polacek
On Mon, Jun 23, 2014 at 04:39:55PM +0200, Marek Polacek wrote:
 --- gcc/testsuite/c-c++-common/pr61553.c
 +++ gcc/testsuite/c-c++-common/pr61553.c
 @@ -0,0 +1,8 @@
 +/* PR c/61553 */
 +/* { dg-do compile } */
 +
 +void
 +foo (char *s)
 +{
 +  __atomic_store (s, (void *) 0, __ATOMIC_SEQ_CST);

Oops, dg-error disappeared from the final patch.  I'm fixing it with
the following.

2014-06-23  Marek Polacek  pola...@redhat.com

PR c/61553
* c-c++-common/pr61553.c (foo): Add dg-error.

diff --git gcc/testsuite/c-c++-common/pr61553.c 
gcc/testsuite/c-c++-common/pr61553.c
index fa97e94..8a3b699 100644
--- gcc/testsuite/c-c++-common/pr61553.c
+++ gcc/testsuite/c-c++-common/pr61553.c
@@ -4,5 +4,5 @@
 void
 foo (char *s)
 {
-  __atomic_store (s, (void *) 0, __ATOMIC_SEQ_CST);
+  __atomic_store (s, (void *) 0, __ATOMIC_SEQ_CST); /* { dg-error size 
mismatch } */
 }

Marek


[C PATCH] Better column info for return stmts (PR c/61162)

2014-06-25 Thread Marek Polacek
This is the last piece to fix PR61162: it's better to point to the
expression of the return statement (if any) than to the return keyword
itself.

Tested x86_64-unknown-linux-gnu, applying to trunk.

2014-06-25  Marek Polacek  pola...@redhat.com

PR c/61162
* c-parser.c (c_parser_statement_after_labels): Pass the location of
the return expression to c_finish_return.

* gcc.dg/pr61162.c: Adjust dg-warning.
* gcc.dg/pr61162-2.c: New test.

diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index f83ccb0..5842320 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -4948,9 +4948,10 @@ c_parser_statement_after_labels (c_parser *parser)
}
  else
{
+ location_t xloc = c_parser_peek_token (parser)-location;
  struct c_expr expr = c_parser_expression_conv (parser);
  mark_exp_read (expr.value);
- stmt = c_finish_return (loc, expr.value, expr.original_type);
+ stmt = c_finish_return (xloc, expr.value, expr.original_type);
  goto expect_semicolon;
}
  break;
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 4deeae7..b62e830 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -9185,7 +9185,8 @@ c_finish_goto_ptr (location_t loc, tree expr)
 
 /* Generate a C `return' statement.  RETVAL is the expression for what
to return, or a null pointer for `return;' with no value.  LOC is
-   the location of the return statement.  If ORIGTYPE is not NULL_TREE, it
+   the location of the return statement, or the location of the expression,
+   if the statement has any.  If ORIGTYPE is not NULL_TREE, it
is the original type of RETVAL.  */
 
 tree
diff --git gcc/testsuite/gcc.dg/pr61162-2.c gcc/testsuite/gcc.dg/pr61162-2.c
index e69de29..1045408 100644
--- gcc/testsuite/gcc.dg/pr61162-2.c
+++ gcc/testsuite/gcc.dg/pr61162-2.c
@@ -0,0 +1,48 @@
+/* PR c/61162 */
+/* { dg-do compile } */
+/* { dg-options -Wc++-compat -Wpointer-sign -Wpedantic } */
+
+enum e { A };
+struct s { int a; };
+
+enum e
+fn1 (void)
+{
+  return 0; /* { dg-warning 10:enum conversion in return } */
+}
+
+int
+fn2 (struct s s)
+{
+  return s; /* { dg-error 10:incompatible types when returning } */
+}
+
+void
+fn3 (void)
+{
+  return 3; /* { dg-warning 10:in function returning void } */
+}
+
+int
+fn4 (int *a)
+{
+  return a; /* { dg-warning 10:return makes integer from pointer without a 
cast } */
+}
+
+int *
+fn5 (int a)
+{
+  return a; /* { dg-warning 10:return makes pointer from integer without a 
cast } */
+}
+
+unsigned int *
+fn6 (int *i)
+{
+  return i; /* { dg-warning 10:pointer targets in return differ } */
+}
+
+void *
+fn7 (void (*fp) (void))
+{
+  return fp; /* { dg-warning 10:ISO C forbids return between function 
pointer } */
+}
diff --git gcc/testsuite/gcc.dg/pr61162.c gcc/testsuite/gcc.dg/pr61162.c
index 00e64b9..8dcb0c8 100644
--- gcc/testsuite/gcc.dg/pr61162.c
+++ gcc/testsuite/gcc.dg/pr61162.c
@@ -8,5 +8,5 @@ fn1 (void)
 {
   enum e e, q = 0; /* { dg-warning 17:enum conversion in initialization is 
invalid } */
   e = 0; /* { dg-warning 5:enum conversion in assignment is invalid } */
-  1; return 0; /* { dg-warning 6:enum conversion in return is invalid } */
+  1; return 0; /* { dg-warning 13:enum conversion in return is invalid } */
 }

Marek


[PATCH] Fix ubsan/bounds-2.c

2014-06-25 Thread Marek Polacek
On IRC Ramana reported that on ARM ubsan/bounds-2.c test fails with -O0,
since we write to out-of-bounds location and probably rewrite the
frame pointer stored in the stack.  This patch removes such stores
and adds some asm magic so the compiler doesn't optimize loads away as
uninitialized memory read.

Ramana, does this patch help on ARM?
Tested x86_64-unknown-linux-gnu, ok for trunk?

2014-06-25  Marek Polacek  pola...@redhat.com

* c-c++-common/ubsan/bounds-2.c: Adjust dg-output.
(fn1): Remove store to out-of-bounds location.  Add memory barrier.
(fn2): Likewise.
(fn5): Likewise.
(fn6): Likewise.
(fn7): Likewise.
(fn8): Likewise.
(fn9): Likewise.
(fn11): Likewise.

diff --git gcc/testsuite/c-c++-common/ubsan/bounds-2.c 
gcc/testsuite/c-c++-common/ubsan/bounds-2.c
index 95f77c2..3a24d40 100644
--- gcc/testsuite/c-c++-common/ubsan/bounds-2.c
+++ gcc/testsuite/c-c++-common/ubsan/bounds-2.c
@@ -22,7 +22,7 @@ static void __attribute__ ((noinline, noclone))
 fn1 (void)
 {
   volatile int a[5];
-  a[5] = 1;
+  asm ( : : r (a[5]) : memory);
   a[2] = a[5];
 }
 
@@ -30,9 +30,11 @@ static void __attribute__ ((noinline, noclone))
 fn2 (void)
 {
   volatile int a[5];
+  volatile int j;
   int i = 5;
   int *p = i;
-  a[*p] = 1;
+  asm ( : : r (a[*p]) : memory);
+  j = a[*p];
 }
 
 static void __attribute__ ((noinline, noclone))
@@ -54,7 +56,7 @@ fn5 (void)
 {
   int i = 5;
   volatile int a[i];
-  a[i] = 1;
+  asm ( : : r (a[i]) : memory);
   a[2] = a[i];
 }
 
@@ -63,29 +65,32 @@ fn6 (void)
 {
   int i = 5;
   volatile int a[i];
+  volatile int j;
   fn_p (a[i]);
-  a[foo_5 ()] = 1;
+  asm ( : : r (a[foo_5 ()]) : memory);
+  j = a[foo_5 ()];
 }
 
 static void __attribute__ ((noinline, noclone))
 fn7 (void)
 {
-  int n = 5, i;
+  int n = 5;
+  volatile int i;
   volatile int c[n][n][n];
-  c[5][2][2] = 2;
-  c[2][5][2] = 2;
-  c[2][2][5] = 2;
+  asm ( : : r (c[5][2][2]) : memory);
   i = c[5][2][2];
+  asm ( : : r (c[2][5][2]) : memory);
   i = c[2][5][2];
+  asm ( : : r (c[2][2][5]) : memory);
   i = c[2][2][5];
 }
 
 static void __attribute__ ((noinline, noclone))
 fn8 (void)
 {
-  int i = 5;
+  volatile int i;
   volatile struct S s;
-  s.a[10] = 1;
+  asm ( : : r (s.a[10]) : memory);
   i = s.a[10];
 }
 
@@ -93,7 +98,7 @@ static void __attribute__ ((noinline, noclone))
 fn9 (void)
 {
   long int *volatile d[10][5];
-  d[10][0] = 0;
+  asm ( : : r (d[10][0]) : memory);
   d[8][3] = d[10][0];
 }
 
@@ -115,7 +120,7 @@ static void __attribute__ ((noinline, noclone))
 fn11 (void)
 {
   char ***volatile f[5];
-  f[5] = 0;
+  asm ( : : r (f[5]) : memory);
   f[2] = f[5];
 }
 
@@ -148,21 +153,16 @@ main (void)
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 10 out of bounds for type 'int 
\\\[10\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 10 out of bounds for type 'int 
\\\[10\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 10 out of bounds for type 'long int 
\\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 10 out of bounds for type 'long int 
\\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'char 
\\\*\\\*\\\*\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'char 
\\\*\\\*\\\*\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output

Re: [PATCH] Fix ubsan/bounds-2.c

2014-06-25 Thread Marek Polacek
On Wed, Jun 25, 2014 at 03:47:37PM +0200, Jakub Jelinek wrote:
 Please don't invoke undefined behavior in the asm statements.
 So, r (c[5]) is fine, but not c[5][2][2] is not, x[-1] is not, etc.
 I'd say it should be ok to always just take address of the base
 variable in the asm.  Otherwise it looks good to me.

Ah, sure, hopefully the following is fine then:

2014-06-25  Marek Polacek  pola...@redhat.com

* c-c++-common/ubsan/bounds-2.c: Adjust dg-output.
(fn1): Remove store to out-of-bounds location.  Add memory barrier.
(fn2): Likewise.
(fn5): Likewise.
(fn6): Likewise.
(fn7): Likewise.
(fn8): Likewise.
(fn9): Likewise.
(fn11): Likewise.
* c-c++-common/ubsan/bounds-5.c (fn1): Remove store to out-of-bounds
location.  Add memory barrier.
(fn2): Likewise.
(fn3): Likewise.
(fn4): Likewise.
(fn5): Likewise.
* c-c++-common/ubsan/bounds-7.c: New test.

diff --git gcc/testsuite/c-c++-common/ubsan/bounds-2.c 
gcc/testsuite/c-c++-common/ubsan/bounds-2.c
index 95f77c2..7ef71aa 100644
--- gcc/testsuite/c-c++-common/ubsan/bounds-2.c
+++ gcc/testsuite/c-c++-common/ubsan/bounds-2.c
@@ -22,7 +22,7 @@ static void __attribute__ ((noinline, noclone))
 fn1 (void)
 {
   volatile int a[5];
-  a[5] = 1;
+  asm ( : : r (a) : memory);
   a[2] = a[5];
 }
 
@@ -30,9 +30,11 @@ static void __attribute__ ((noinline, noclone))
 fn2 (void)
 {
   volatile int a[5];
+  volatile int j;
   int i = 5;
   int *p = i;
-  a[*p] = 1;
+  asm ( : : r (a) : memory);
+  j = a[*p];
 }
 
 static void __attribute__ ((noinline, noclone))
@@ -54,7 +56,7 @@ fn5 (void)
 {
   int i = 5;
   volatile int a[i];
-  a[i] = 1;
+  asm ( : : r (a) : memory);
   a[2] = a[i];
 }
 
@@ -63,29 +65,32 @@ fn6 (void)
 {
   int i = 5;
   volatile int a[i];
+  volatile int j;
   fn_p (a[i]);
-  a[foo_5 ()] = 1;
+  asm ( : : r (a) : memory);
+  j = a[foo_5 ()];
 }
 
 static void __attribute__ ((noinline, noclone))
 fn7 (void)
 {
-  int n = 5, i;
+  int n = 5;
+  volatile int i;
   volatile int c[n][n][n];
-  c[5][2][2] = 2;
-  c[2][5][2] = 2;
-  c[2][2][5] = 2;
+  asm ( : : r (c[5]) : memory);
   i = c[5][2][2];
+  asm ( : : r (c[2]) : memory);
   i = c[2][5][2];
+  asm ( : : r (c[2]) : memory);
   i = c[2][2][5];
 }
 
 static void __attribute__ ((noinline, noclone))
 fn8 (void)
 {
-  int i = 5;
+  volatile int i;
   volatile struct S s;
-  s.a[10] = 1;
+  asm ( : : r (s.a) : memory);
   i = s.a[10];
 }
 
@@ -93,7 +98,7 @@ static void __attribute__ ((noinline, noclone))
 fn9 (void)
 {
   long int *volatile d[10][5];
-  d[10][0] = 0;
+  asm ( : : r (d[10]) : memory);
   d[8][3] = d[10][0];
 }
 
@@ -115,7 +120,7 @@ static void __attribute__ ((noinline, noclone))
 fn11 (void)
 {
   char ***volatile f[5];
-  f[5] = 0;
+  asm ( : : r (f) : memory);
   f[2] = f[5];
 }
 
@@ -148,21 +153,13 @@ main (void)
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds for type 'int 
\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 10 out of bounds for type 'int 
\\\[10\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 10 out of bounds for type 'int 
\\\[10\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 10 out of bounds for type 'long int 
\\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 10 out of bounds for type 'long int 
\\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*index 5 out of bounds for type 'char 
\\\*\\\*\\\*\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*index 5 out of bounds

[C/C++ PATCH] Implement -Wsizeof-array-argument (PR c/6940)

2014-06-26 Thread Marek Polacek
The following is a revamped patch for -Wsizeof-array-argument.  Almost two
months back there was an initial attempt by Prathamesh:
https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00142.html, but that patch
never made it in.  This version implements the warning for both C and C++
FEs, adds more testing, enables the warning by default (I can move it to
-Wall, of course), makes the warning work properly even for multidimensional
arrays, etc.
Its purpose is to detect suspicious usage of the sizeof operator on an array
function parameter.  A few years back I fixed exactly this kind of bug in
elfutils - so -Wsizeof-array-argument might be indeed useful.  (The warning 
didn't
trigger during GCC bootstrap though.)

Jason/Joseph, could you please look at the C++, resp. C FE parts?

Tested x86_64-unknown-linux-gnu, ok for trunk?

2014-06-26  Marek Polacek  pola...@redhat.com

PR c/6940
* doc/invoke.texi: Document -Wsizeof-array-argument.
c-family/
* c.opt (Wsizeof-array-argument): New option.
c/
* c-decl.c (grokdeclarator): Set C_ARRAY_PARAMETER.
* c-tree.h (C_ARRAY_PARAMETER): Define.
* c-typeck.c (c_expr_sizeof_expr): Warn when using sizeof on an array
function parameter.
cp/
* cp-tree.h (DECL_ARRAY_PARAMETER_P): Define.
* decl.c (grokdeclarator): Set DECL_ARRAY_PARAMETER_P.
* typeck.c (cxx_sizeof_expr): Warn when using sizeof on an array
function parameter.
testsuite/
* c-c++-common/Wsizeof-pointer-memaccess1.c: Use
-Wno-sizeof-array-argument.
* c-c++-common/Wsizeof-pointer-memaccess2.c: Likewise.
* g++.dg/warn/Wsizeof-pointer-memaccess-1.C: Likewise.
* gcc.dg/Wsizeof-pointer-memaccess1.c: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
* gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Likewise.
* c-c++-common/sizeof-array-argument.c: New test.
* gcc.dg/vla-5.c: Add dg-warnings.
../libgomp/
* testsuite/libgomp.c/appendix-a/a.29.1.c (f): Add dg-warnings.

diff --git gcc/gcc/c-family/c.opt gcc/gcc/c-family/c.opt
index 1d02bae..3d3cf14 100644
--- gcc/gcc/c-family/c.opt
+++ gcc/gcc/c-family/c.opt
@@ -526,6 +526,10 @@ Wsizeof-pointer-memaccess
 C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C 
ObjC C++ ObjC++,Wall)
 Warn about suspicious length parameters to certain string functions if the 
argument uses sizeof
 
+Wsizeof-array-argument
+C ObjC C++ ObjC++ Var(warn_sizeof_array_argument) Warning Init(1)
+Warn when sizeof is applied on a parameter declared as an array
+
 Wsuggest-attribute=format
 C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
 Warn about functions which might be candidates for format attributes
diff --git gcc/gcc/c/c-decl.c gcc/gcc/c/c-decl.c
index def10a2..a1bc114 100644
--- gcc/gcc/c/c-decl.c
+++ gcc/gcc/c/c-decl.c
@@ -6092,6 +6092,7 @@ grokdeclarator (const struct c_declarator *declarator,
 if (decl_context == PARM)
   {
tree promoted_type;
+   bool array_parameter_p = false;
 
/* A parameter declared as an array of T is really a pointer to T.
   One declared as a function is really a pointer to a function.  */
@@ -6113,6 +6114,7 @@ grokdeclarator (const struct c_declarator *declarator,
  attributes in parameter array declarator ignored);
 
size_varies = false;
+   array_parameter_p = true;
  }
else if (TREE_CODE (type) == FUNCTION_TYPE)
  {
@@ -6137,6 +6139,7 @@ grokdeclarator (const struct c_declarator *declarator,
   PARM_DECL, declarator-u.id, type);
if (size_varies)
  C_DECL_VARIABLE_SIZE (decl) = 1;
+   C_ARRAY_PARAMETER (decl) = array_parameter_p;
 
/* Compute the type actually passed in the parmlist,
   for the case where there is no prototype.
diff --git gcc/gcc/c/c-tree.h gcc/gcc/c/c-tree.h
index 133930f..f97d0d5 100644
--- gcc/gcc/c/c-tree.h
+++ gcc/gcc/c/c-tree.h
@@ -66,6 +66,9 @@ along with GCC; see the file COPYING3.  If not see
 /* For a FUNCTION_DECL, nonzero if it was an implicit declaration.  */
 #define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
 
+/* For a PARM_DECL, nonzero if it was declared as an array.  */
+#define C_ARRAY_PARAMETER(NODE) DECL_LANG_FLAG_0 (NODE)
+
 /* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
been declared.  */
 #define C_DECL_DECLARED_BUILTIN(EXP)   \
diff --git gcc/gcc/c/c-typeck.c gcc/gcc/c/c-typeck.c
index b62e830..0b63e98 100644
--- gcc/gcc/c/c-typeck.c
+++ gcc/gcc/c/c-typeck.c
@@ -2731,6 +2731,16 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
   else
 {
   bool expr_const_operands = true;
+
+  if (TREE_CODE (expr.value) == PARM_DECL
+  C_ARRAY_PARAMETER (expr.value))
+   {
+ if (warning_at (loc, OPT_Wsizeof_array_argument

Re: [PATCH v2] typeof: Remove type qualifiers for atomic types

2014-06-27 Thread Marek Polacek
On Fri, Jun 27, 2014 at 08:36:38AM +0200, Sebastian Huber wrote:
 Thanks for your patience.  It would be nice if this can be applied to GCC
 4.9 as well.
 
 Can someone please commit this for me, since I don't have write access.

I will commit it for you.

Marek


Re: [c++-concepts] Change constraint equivalence

2014-06-27 Thread Marek Polacek
On Fri, Jun 27, 2014 at 03:22:39AM -0400, Braden Obrzut wrote:
 To bring the implementation in line with changes going into the concepts
 draft, use syntactical equivalence in place of logical equivalence when
 matching declarations.
 
 2014-06-27  Braden Obrzut ad...@maniacsvault.net

Two spaces after you name.

 * gcc/cp/constraint.c (equivalent_constraints): Compare the trees
 directly
 instead of logically to bring implementation in line with standard
 changes.
 * gcc/cp/tree.c (cp_tree_equal): Handle comparison of constraints.
 * gcc/testsuite/g++.dg/concepts/equiv.C: New test.
 * gcc/testsuite/g++.dg/concepts/equiv-err.C: New test.

Please drop gcc/ and gcc/testsuite/ prefixes (the former goes to
cp/ChangeLog, the latter to testsuite/ChangeLog).

Marek


Re: [c++-concepts] Change constraint equivalence

2014-06-27 Thread Marek Polacek
On Fri, Jun 27, 2014 at 03:41:36AM -0400, Braden Obrzut wrote:
 On 06/27/2014 03:27 AM, Marek Polacek wrote:
 Two spaces after you name.
 I'm not sure what happened to the second space.  It's there in the source I
 copied.  I'll have to be sure to double check the paste next time.
 Please drop gcc/ and gcc/testsuite/ prefixes (the former goes to
 cp/ChangeLog, the latter to testsuite/ChangeLog).
 
  Marek
 Are you sure about this?  Andrew has been putting everything in
 ChangeLog.concepts in the root.

Ah, sorry, for concepts you indeed might be using ChangeLog.concepts.

Marek


Re: [PATCH] gcc/c/c-decl.c: Let NEWDECL dereference shared data to fix segment fault issue.

2014-06-29 Thread Marek Polacek
On Sun, Jun 29, 2014 at 10:00:34PM +0200, Jan Hubicka wrote:
  On Sun, 29 Jun 2014, Chen Gang wrote:
  
   NEWDECL dereferences shared data of OLDDECL, or when free NEWDECL, also
   have effect with OLDDECL. At present, only fix the related reference for
   current issue. If find another related issue, can follow this fix.
  
  I'm afraid I can't make any sense of this.
  
  We need a carefully written analysis of the issue you are trying to fix 
  that explains what is going wrong and why, in terms of the underlying 
  design of the code, the proposed change is logically correct to fix the 
  issue.
  
  That is, explain how NEWDECL gets used after merge_decls returns, why your 
  proposed changes to NEWDECL are correct for the subsequent use of NEWDECL, 
  why the previous contents of NEWDECL would be incorrect for the subsequent 
  uses of NEWDECL, and why it is correct for the subsequent uses to make 
  whatever use of NEWDECL is causing problems.  Where does the segfault 
  occur anyway?
 
 Actually this problem was introduced by me (and I made patch for it once 
 already
 but apparently it did not reach the ML). THe problem is that we now create 
 symbols
 to hold information about decl that is no longer represented in trees - 
 sections,
 comdats etc.
 
 Now in duplicate_decl we have two symbol nodes for the duplicated declarations
 and remove one of them at the end.  cgraph_remove_node calls
 cgraph_release_function_body that assumes that we never have two functions 
 with
 same DECL_STRUCT_FUNCTION.
 
 So Cheng is right we need to clear DECL_STRUCT_FUNCTION or we end up 
 ggc_freeing
 it that later ICEs in push_cfun.  We do not need to clear the other fields.
 
 The patch bellow just copy identical hunk of code from cp/decl.c
  
 root@gchen:/upstream/linux# cat elevator.i
 extern int __attribute__ ((__section__(.init.text))) 
   elv_register(void)
 {
  return 0;
 }
 extern typeof(elv_register) elv_register;
  
  Patch submissions should add a test to the testsuite, when it's something 
  small like this.
 
 Added.
 
 thanks for working on this!  I am bootstrapping/regtesting the attacked patch 
 on x86_64-linux
 OK?

Just some typos:

   Chen Gang gang.chen.5...@gmail.com

Two spaces after the name.

   Jan Hubicka  hubi...@ucw.cz
 
   * c-decl.c (duplicate_decls): CLear DECL_STRUCT_FUNCTION before 
 releasing
   symbol.

s/CLear/Clear/

 Index: c/c-decl.c
 ===
 --- c/c-decl.c(revision 212098)
 +++ c/c-decl.c(working copy)
 @@ -2575,7 +2575,14 @@ duplicate_decls (tree newdecl, tree oldd
  
merge_decls (newdecl, olddecl, newtype, oldtype);
  
 -  /* The NEWDECL will no longer be needed.  */
 +  /* The NEWDECL will no longer be needed.
 +
 + Before releasing the node, be sore to remove function from symbol

s/sore/sure/

 + table that might have been inserted there to record comdat group.
 + Be sure to however do not free DECL_STRUCT_FUNCTION becuase this

s/becuase/because/

 + structure is shared in between newdecl and oldecl.  */

s/newdecl/NEWDECL/;s/oldecl/OLDDECL/

Marek


[PATCH] Properly honor no_sanitize_undefined attribute

2014-06-30 Thread Marek Polacek
Apparently I didn't pay much attention to no_sanitize_undefined
attribute when adding new features to ubsan, so we would instrument
stuff even though the function is marked with this attribute.
Thus fixed  new testcases added.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-06-30  Marek Polacek  pola...@redhat.com

* convert.c (convert_to_integer): Don't instrument conversions if the
function has no_sanitize_undefined attribute.
* ubsan.c: Don't run the ubsan pass if the function has
no_sanitize_undefined attribute.
c/
* c-decl.c (grokdeclarator): Don't instrument VLAs if the function
has no_sanitize_undefined attribute.
cp/
* cp-gimplify.c (cp_genericize): Don't instrument returns if the
function has no_sanitize_undefined attribute.
* decl.c (compute_array_index_type): Don't instrument VLAs if the
function has no_sanitize_undefined attribute.
testsuite/
* c-c++-common/ubsan/attrib-2.c: New test.
* g++.dg/ubsan/return-3.C: New test.

diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index def10a2..7895510 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -5505,7 +5505,11 @@ grokdeclarator (const struct c_declarator *declarator,
this_size_varies = size_varies = true;
warn_variable_length_array (name, size);
if (flag_sanitize  SANITIZE_VLA
-decl_context == NORMAL)
+decl_context == NORMAL
+current_function_decl != 0
+!lookup_attribute (no_sanitize_undefined,
+ DECL_ATTRIBUTES
+   (current_function_decl)))
  {
/* Evaluate the array size only once.  */
size = c_save_expr (size);
diff --git gcc/convert.c gcc/convert.c
index 2d9600d..dbb59da 100644
--- gcc/convert.c
+++ gcc/convert.c
@@ -847,7 +847,10 @@ convert_to_integer (tree type, tree expr)
   return build1 (CONVERT_EXPR, type, expr);
 
 case REAL_TYPE:
-  if (flag_sanitize  SANITIZE_FLOAT_CAST)
+  if (flag_sanitize  SANITIZE_FLOAT_CAST
+  current_function_decl != 0
+  !lookup_attribute (no_sanitize_undefined,
+   DECL_ATTRIBUTES (current_function_decl)))
{
  expr = save_expr (expr);
  tree check = ubsan_instrument_float_cast (loc, type, expr);
diff --git gcc/cp/cp-gimplify.c gcc/cp/cp-gimplify.c
index 296bd5f..dfa954b 100644
--- gcc/cp/cp-gimplify.c
+++ gcc/cp/cp-gimplify.c
@@ -1221,7 +1221,7 @@ cp_genericize_tree (tree* t_p)
 
 /* If a function that should end with a return in non-void
function doesn't obviously end with return, add ubsan
-   instrmentation code to verify it at runtime.  */
+   instrumentation code to verify it at runtime.  */
 
 static void
 cp_ubsan_maybe_instrument_return (tree fndecl)
@@ -1334,7 +1334,10 @@ cp_genericize (tree fndecl)
  walk_tree's hash functionality.  */
   cp_genericize_tree (DECL_SAVED_TREE (fndecl));
 
-  if (flag_sanitize  SANITIZE_RETURN)
+  if (flag_sanitize  SANITIZE_RETURN
+   current_function_decl != 0
+   !lookup_attribute (no_sanitize_undefined,
+   DECL_ATTRIBUTES (current_function_decl)))
 cp_ubsan_maybe_instrument_return (fndecl);
 
   /* Do everything else.  */
diff --git gcc/cp/decl.c gcc/cp/decl.c
index d548f61..861e7a8 100644
--- gcc/cp/decl.c
+++ gcc/cp/decl.c
@@ -8469,7 +8469,11 @@ compute_array_index_type (tree name, tree size, 
tsubst_flags_t complain)
 throw_bad_array_length (), void_node);
  finish_expr_stmt (comp);
}
- else if (flag_sanitize  SANITIZE_VLA)
+ else if (flag_sanitize  SANITIZE_VLA
+   current_function_decl != 0
+   !lookup_attribute (no_sanitize_undefined,
+DECL_ATTRIBUTES
+  (current_function_decl)))
{
  /* From C++1y onwards, we throw an exception on a negative
 length size of an array; see above.  */
diff --git gcc/testsuite/c-c++-common/ubsan/attrib-2.c 
gcc/testsuite/c-c++-common/ubsan/attrib-2.c
index e69de29..71f2e58 100644
--- gcc/testsuite/c-c++-common/ubsan/attrib-2.c
+++ gcc/testsuite/c-c++-common/ubsan/attrib-2.c
@@ -0,0 +1,71 @@
+/* { dg-do compile } */
+/* { dg-options -fsanitize=undefined -fsanitize=float-divide-by-zero 
-fsanitize=float-cast-overflow } */
+
+/* Test that we don't instrument functions marked with
+   no_sanitize_undefined attribute.  */
+
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+enum A { B = -3, C = 2 } a;
+bool b;
+
+__attribute__((no_sanitize_undefined))
+static void
+vla_bound (void)
+{
+  int i = -1;
+  volatile int a[i];
+}
+
+__attribute__((no_sanitize_undefined))
+static void
+si_overflow

Re: [PATCH v2] typeof: Remove type qualifiers for atomic types

2014-06-30 Thread Marek Polacek
On Fri, Jun 27, 2014 at 08:49:24AM +0200, Marek Polacek wrote:
 On Fri, Jun 27, 2014 at 08:36:38AM +0200, Sebastian Huber wrote:
  Thanks for your patience.  It would be nice if this can be applied to GCC
  4.9 as well.
  
  Can someone please commit this for me, since I don't have write access.
 
 I will commit it for you.

Now applied to 4.9 as well.

Marek


Re: [PATCH] Properly honor no_sanitize_undefined attribute

2014-06-30 Thread Marek Polacek
On Mon, Jun 30, 2014 at 03:00:11PM +0200, Jakub Jelinek wrote:
 Actually, please change current_function_decl != 0 to
 current_function_decl != NULL_TREE everywhere in the patch.
 Ok with that change.

Ok, I'm applying the following then.

2014-06-30  Marek Polacek  pola...@redhat.com

* convert.c (convert_to_integer): Don't instrument conversions if the
function has no_sanitize_undefined attribute.
* ubsan.c: Don't run the ubsan pass if the function has
no_sanitize_undefined attribute.
c/
* c-decl.c (grokdeclarator): Don't instrument VLAs if the function
has no_sanitize_undefined attribute.
cp/
* cp-gimplify.c (cp_genericize): Don't instrument returns if the
function has no_sanitize_undefined attribute.
* decl.c (compute_array_index_type): Don't instrument VLAs if the
function has no_sanitize_undefined attribute.
testsuite/
* c-c++-common/ubsan/attrib-2.c: New test.
* g++.dg/ubsan/return-3.C: New test.

diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index def10a2..7c37edf 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -5505,7 +5505,11 @@ grokdeclarator (const struct c_declarator *declarator,
this_size_varies = size_varies = true;
warn_variable_length_array (name, size);
if (flag_sanitize  SANITIZE_VLA
-decl_context == NORMAL)
+decl_context == NORMAL
+current_function_decl != NULL_TREE
+!lookup_attribute (no_sanitize_undefined,
+ DECL_ATTRIBUTES
+   (current_function_decl)))
  {
/* Evaluate the array size only once.  */
size = c_save_expr (size);
diff --git gcc/convert.c gcc/convert.c
index 2d9600d..09bc555 100644
--- gcc/convert.c
+++ gcc/convert.c
@@ -847,7 +847,10 @@ convert_to_integer (tree type, tree expr)
   return build1 (CONVERT_EXPR, type, expr);
 
 case REAL_TYPE:
-  if (flag_sanitize  SANITIZE_FLOAT_CAST)
+  if (flag_sanitize  SANITIZE_FLOAT_CAST
+  current_function_decl != NULL_TREE
+  !lookup_attribute (no_sanitize_undefined,
+   DECL_ATTRIBUTES (current_function_decl)))
{
  expr = save_expr (expr);
  tree check = ubsan_instrument_float_cast (loc, type, expr);
diff --git gcc/cp/cp-gimplify.c gcc/cp/cp-gimplify.c
index 296bd5f..a35177b 100644
--- gcc/cp/cp-gimplify.c
+++ gcc/cp/cp-gimplify.c
@@ -1221,7 +1221,7 @@ cp_genericize_tree (tree* t_p)
 
 /* If a function that should end with a return in non-void
function doesn't obviously end with return, add ubsan
-   instrmentation code to verify it at runtime.  */
+   instrumentation code to verify it at runtime.  */
 
 static void
 cp_ubsan_maybe_instrument_return (tree fndecl)
@@ -1334,7 +1334,10 @@ cp_genericize (tree fndecl)
  walk_tree's hash functionality.  */
   cp_genericize_tree (DECL_SAVED_TREE (fndecl));
 
-  if (flag_sanitize  SANITIZE_RETURN)
+  if (flag_sanitize  SANITIZE_RETURN
+   current_function_decl != NULL_TREE
+   !lookup_attribute (no_sanitize_undefined,
+   DECL_ATTRIBUTES (current_function_decl)))
 cp_ubsan_maybe_instrument_return (fndecl);
 
   /* Do everything else.  */
diff --git gcc/cp/decl.c gcc/cp/decl.c
index d548f61..6902bb0 100644
--- gcc/cp/decl.c
+++ gcc/cp/decl.c
@@ -8469,7 +8469,11 @@ compute_array_index_type (tree name, tree size, 
tsubst_flags_t complain)
 throw_bad_array_length (), void_node);
  finish_expr_stmt (comp);
}
- else if (flag_sanitize  SANITIZE_VLA)
+ else if (flag_sanitize  SANITIZE_VLA
+   current_function_decl != NULL_TREE
+   !lookup_attribute (no_sanitize_undefined,
+DECL_ATTRIBUTES
+  (current_function_decl)))
{
  /* From C++1y onwards, we throw an exception on a negative
 length size of an array; see above.  */
diff --git gcc/testsuite/c-c++-common/ubsan/attrib-2.c 
gcc/testsuite/c-c++-common/ubsan/attrib-2.c
index e69de29..71f2e58 100644
--- gcc/testsuite/c-c++-common/ubsan/attrib-2.c
+++ gcc/testsuite/c-c++-common/ubsan/attrib-2.c
@@ -0,0 +1,71 @@
+/* { dg-do compile } */
+/* { dg-options -fsanitize=undefined -fsanitize=float-divide-by-zero 
-fsanitize=float-cast-overflow } */
+
+/* Test that we don't instrument functions marked with
+   no_sanitize_undefined attribute.  */
+
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+enum A { B = -3, C = 2 } a;
+bool b;
+
+__attribute__((no_sanitize_undefined))
+static void
+vla_bound (void)
+{
+  int i = -1;
+  volatile int a[i];
+}
+
+__attribute__((no_sanitize_undefined))
+static void
+si_overflow (void

[C PATCH] Add -Wincompatible-pointer-types option (PR c/58286)

2014-06-30 Thread Marek Polacek
This patch adds the -Wincompatible-pointer-types option for a warning
we already have, so it's possible to suppress this specific warning, or
use it with -Werror= and so on.
As a followup change, I'm considering printing the types of the pointers;
saying merely e.g. assignment from incompatible pointer type seems to be too
austere.  (We say expected T but argument is of type U when passing 
arguments.)
This is for C/ObjC only, since in C++, we'd issue cannot convert error.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-06-30  Marek Polacek  pola...@redhat.com

PR c/58286
* doc/invoke.texi: Document -Wincompatible-pointer-types.
c-family/
* c.opt (Wincompatible-pointer-types): New option.
c/
* c-typeck.c (convert_for_assignment): Pass
OPT_Wincompatible_pointer_types instead of 0 to WARN_FOR_ASSIGNMENT.
testsuite/
* gcc.dg/Wincompatible-pointer-types.c: New test.

diff --git gcc/c-family/c.opt gcc/c-family/c.opt
index 1d02bae..6448b1b 100644
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -443,6 +443,10 @@ Wignored-qualifiers
 C C++ Var(warn_ignored_qualifiers) Warning EnabledBy(Wextra)
 Warn whenever type qualifiers are ignored.
 
+Wincompatible-pointer-types
+C ObjC Var(warn_incompatible_pointer_types) Init(1) Warning
+Warn when there is a conversion between pointers that have incompatible types
+
 Winit-self
 C ObjC C++ ObjC++ Var(warn_init_self) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn about variables which are initialized to themselves
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index b62e830..fff26a3 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -6189,7 +6189,8 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
   else
/* Avoid warning about the volatile ObjC EH puts on decls.  */
if (!objc_ok)
- WARN_FOR_ASSIGNMENT (location, expr_loc, 0,
+ WARN_FOR_ASSIGNMENT (location, expr_loc,
+  OPT_Wincompatible_pointer_types,
   G_(passing argument %d of %qE from 
  incompatible pointer type),
   G_(assignment from incompatible pointer type),
diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index dbc1132..dfae4f0 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -251,7 +251,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
 -Wformat-security  -Wformat-signedness  -Wformat-y2k @gol
 -Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol
--Wignored-qualifiers @gol
+-Wignored-qualifiers  -Wincompatible-pointer-types @gol
 -Wimplicit  -Wimplicit-function-declaration  -Wimplicit-int @gol
 -Winit-self  -Winline @gol
 -Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
@@ -4199,14 +4199,19 @@ This option is only active when @option{-ftree-vrp} is 
active
 (default for @option{-O2} and above). It warns about subscripts to arrays
 that are always out of bounds. This warning is enabled by @option{-Wall}.
 
-@item -Wno-discarded-qualifiers
+@item -Wno-discarded-qualifiers @r{(C and Objective-C only)}
 @opindex Wno-discarded-qualifiers
 @opindex Wdiscarded-qualifiers
 Do not warn if type qualifiers on pointers are being discarded.
 Typically, the compiler will warn if a @code{const char *} variable is
 passed to a function that takes @code{char *} parameter.  This option
-can be used to suppress such a warning.  This warning is only supported
-for C.
+can be used to suppress such a warning.
+
+@item -Wno-incompatible-pointer-types @r{(C and Objective-C only)}
+@opindex Wno-incompatible-pointer-types
+@opindex Wincompatible-pointer-types
+Do not warn when there is a conversion between pointers that have incompatible
+types.
 
 @item -Wno-div-by-zero
 @opindex Wno-div-by-zero
diff --git gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c 
gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c
index e69de29..e765b27 100644
--- gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c
+++ gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c
@@ -0,0 +1,21 @@
+/* PR c/58286 */
+/* { dg-do compile } */
+/* { dg-options -Wno-incompatible-pointer-types } */
+
+void
+fn2 (short *s, long *l)
+{
+}
+
+unsigned *
+fn1 (void)
+{
+  int (*fpi) (int);
+  int (*fpd) (double) = fpi;
+  fpi = fpd;
+  char *di;
+  float *dp = di;
+  di = dp;
+  fn2 (dp, di);
+  return dp;
+}

Marek


[C PATCH] Add -Wint-conversion option

2014-06-30 Thread Marek Polacek
Basically everything I wrote in the patch for -Wincompatible-pointer-types
applies here as well.  A new option, -Wint-conversion (to be compatible
with clang), is added to allow more fine-grained control over the warnings.
I think we should print the types here as well, and moreover, we could hint the
user that  or * may be used to fix the code.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-06-30  Marek Polacek  pola...@redhat.com

* doc/invoke.texi: Document -Wint-conversion.
c-family/
* c.opt (Wint-conversion): New option.
c/
* c-typeck.c (convert_for_assignment): Pass OPT_Wint_conversion
instead of 0 to WARN_FOR_ASSIGNMENT.
testsuite/
* gcc.dg/Wint-conversion.c: New test.

diff --git gcc/c-family/c.opt gcc/c-family/c.opt
index 6448b1b..c89040a 100644
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -474,6 +474,10 @@ Winherited-variadic-ctor
 C++ ObjC++ Var(warn_inh_var_ctor) Init(1) Warning
 Warn about C++11 inheriting constructors when the base has a variadic 
constructor
 
+Wint-conversion
+C ObjC Var(warn_int_conversion) Init(1) Warning
+Warn about incompatible integer to pointer and pointer to integer conversions
+
 Wint-to-pointer-cast
 C ObjC C++ ObjC++ Var(warn_int_to_pointer_cast) Init(1) Warning
 Warn when there is a cast to a pointer from an integer of a different size
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index fff26a3..35bfd14 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -6213,7 +6213,8 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
 or one that results from arithmetic, even including
 a cast to integer type.  */
   if (!null_pointer_constant)
-   WARN_FOR_ASSIGNMENT (location, expr_loc, 0,
+   WARN_FOR_ASSIGNMENT (location, expr_loc,
+OPT_Wint_conversion,
 G_(passing argument %d of %qE makes 
pointer from integer without a cast),
 G_(assignment makes pointer from integer 
@@ -6227,7 +6228,8 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
 }
   else if (codel == INTEGER_TYPE  coder == POINTER_TYPE)
 {
-  WARN_FOR_ASSIGNMENT (location, expr_loc, 0,
+  WARN_FOR_ASSIGNMENT (location, expr_loc,
+  OPT_Wint_conversion,
   G_(passing argument %d of %qE makes integer 
  from pointer without a cast),
   G_(assignment makes integer from pointer 
diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index dfae4f0..e6e71c0 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -253,7 +253,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol
 -Wignored-qualifiers  -Wincompatible-pointer-types @gol
 -Wimplicit  -Wimplicit-function-declaration  -Wimplicit-int @gol
--Winit-self  -Winline @gol
+-Winit-self  -Winline  -Wno-int-conversion @gol
 -Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
 -Winvalid-pch -Wlarger-than=@var{len}  -Wunsafe-loop-optimizations @gol
 -Wlogical-op -Wlogical-not-parentheses -Wlong-long @gol
@@ -4213,6 +4213,12 @@ can be used to suppress such a warning.
 Do not warn when there is a conversion between pointers that have incompatible
 types.
 
+@item -Wno-int-conversion @r{(C and Objective-C only)}
+@opindex Wno-int-conversion
+@opindex Wint-conversion
+Do not warn about incompatible integer to pointer and pointer to integer
+conversions.
+
 @item -Wno-div-by-zero
 @opindex Wno-div-by-zero
 @opindex Wdiv-by-zero
diff --git gcc/testsuite/gcc.dg/Wint-conversion.c 
gcc/testsuite/gcc.dg/Wint-conversion.c
index e69de29..1b7a03e 100644
--- gcc/testsuite/gcc.dg/Wint-conversion.c
+++ gcc/testsuite/gcc.dg/Wint-conversion.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options -Wno-int-conversion } */
+
+int fn1 (int *), *fn2 (int);
+
+int
+fn1 (int *p)
+{
+  int i = p;
+  i = p;
+  fn2 (p);
+  return p;
+}
+
+int *
+fn2 (int i)
+{
+  int *p = i;
+  p = i;
+  fn1 (i);
+  return i;
+}

Marek


Re: [PATCH] Improve -fdump-tree-all efficiency

2014-06-30 Thread Marek Polacek
On Thu, Jun 26, 2014 at 06:42:09AM -0700, Teresa Johnson wrote:
 2014-06-26  Teresa Johnson  tejohn...@google.com
 
 * c-family/c-common.h (get_dump_info): Declare.
 * c-family/c-gimplify.c (c_genericize): Use saved dump files.
 * c-family/c-opts.c (c_common_parse_file): Begin and end dumps
 once around parsing invocation.
 (get_dump_info): New function.
 * cp/class.c (dump_class_hierarchy): Use saved dump files.
 (dump_vtable): Ditto.
 (dump_vtt): Ditto.

Please drop the c-family/ and cp/ prefixes before committing.

Marek


Re: [C PATCH] Add -Wincompatible-pointer-types option (PR c/58286)

2014-07-01 Thread Marek Polacek
On Mon, Jun 30, 2014 at 08:14:52PM +, Joseph S. Myers wrote:
 On Mon, 30 Jun 2014, Marek Polacek wrote:
 
  This patch adds the -Wincompatible-pointer-types option for a warning
  we already have, so it's possible to suppress this specific warning, or
  use it with -Werror= and so on.
  As a followup change, I'm considering printing the types of the pointers;
  saying merely e.g. assignment from incompatible pointer type seems to be 
  too
  austere.  (We say expected T but argument is of type U when passing 
  arguments.)
  This is for C/ObjC only, since in C++, we'd issue cannot convert error.
  
  Bootstrapped/regtested on x86_64-linux, ok for trunk?
 
 OK with the documentation amended to make clear this is for the cases not 
 covered by -Wno-pointer-sign (which in ISO C terms are just as 
 incompatible as the cases covered by the new option).

Thanks, I'm applying the following then:

2014-07-01  Marek Polacek  pola...@redhat.com

PR c/58286
* doc/invoke.texi: Document -Wincompatible-pointer-types.
c-family/
* c.opt (Wincompatible-pointer-types): New option.
c/
* c-typeck.c (convert_for_assignment): Pass
OPT_Wincompatible_pointer_types instead of 0 to WARN_FOR_ASSIGNMENT.
testsuite/
* gcc.dg/Wincompatible-pointer-types.c: New test.

diff --git gcc/c-family/c.opt gcc/c-family/c.opt
index 1d02bae..6448b1b 100644
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -443,6 +443,10 @@ Wignored-qualifiers
 C C++ Var(warn_ignored_qualifiers) Warning EnabledBy(Wextra)
 Warn whenever type qualifiers are ignored.
 
+Wincompatible-pointer-types
+C ObjC Var(warn_incompatible_pointer_types) Init(1) Warning
+Warn when there is a conversion between pointers that have incompatible types
+
 Winit-self
 C ObjC C++ ObjC++ Var(warn_init_self) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn about variables which are initialized to themselves
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index b62e830..fff26a3 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -6189,7 +6189,8 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
   else
/* Avoid warning about the volatile ObjC EH puts on decls.  */
if (!objc_ok)
- WARN_FOR_ASSIGNMENT (location, expr_loc, 0,
+ WARN_FOR_ASSIGNMENT (location, expr_loc,
+  OPT_Wincompatible_pointer_types,
   G_(passing argument %d of %qE from 
  incompatible pointer type),
   G_(assignment from incompatible pointer type),
diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index dbc1132..409fa17 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -251,7 +251,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
 -Wformat-security  -Wformat-signedness  -Wformat-y2k @gol
 -Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol
--Wignored-qualifiers @gol
+-Wignored-qualifiers  -Wincompatible-pointer-types @gol
 -Wimplicit  -Wimplicit-function-declaration  -Wimplicit-int @gol
 -Winit-self  -Winline @gol
 -Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
@@ -4199,14 +4199,20 @@ This option is only active when @option{-ftree-vrp} is 
active
 (default for @option{-O2} and above). It warns about subscripts to arrays
 that are always out of bounds. This warning is enabled by @option{-Wall}.
 
-@item -Wno-discarded-qualifiers
+@item -Wno-discarded-qualifiers @r{(C and Objective-C only)}
 @opindex Wno-discarded-qualifiers
 @opindex Wdiscarded-qualifiers
 Do not warn if type qualifiers on pointers are being discarded.
 Typically, the compiler will warn if a @code{const char *} variable is
 passed to a function that takes @code{char *} parameter.  This option
-can be used to suppress such a warning.  This warning is only supported
-for C.
+can be used to suppress such a warning.
+
+@item -Wno-incompatible-pointer-types @r{(C and Objective-C only)}
+@opindex Wno-incompatible-pointer-types
+@opindex Wincompatible-pointer-types
+Do not warn when there is a conversion between pointers that have incompatible
+types.  This warning is for cases not covered by @option{-Wno-pointer-sign},
+which warns for pointer argument passing or assignment with different 
signedness
 
 @item -Wno-div-by-zero
 @opindex Wno-div-by-zero
diff --git gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c 
gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c
index e69de29..e765b27 100644
--- gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c
+++ gcc/testsuite/gcc.dg/Wincompatible-pointer-types.c
@@ -0,0 +1,21 @@
+/* PR c/58286 */
+/* { dg-do compile } */
+/* { dg-options -Wno-incompatible-pointer-types } */
+
+void
+fn2 (short *s, long *l)
+{
+}
+
+unsigned *
+fn1 (void)
+{
+  int (*fpi) (int);
+  int (*fpd) (double) = fpi;
+  fpi = fpd;
+  char *di;
+  float *dp = di;
+  di = dp;
+  fn2 (dp, di);
+  return dp

Re: [C PATCH] Add -Wint-conversion option

2014-07-01 Thread Marek Polacek
On Mon, Jun 30, 2014 at 08:16:01PM +, Joseph S. Myers wrote:
 On Mon, 30 Jun 2014, Marek Polacek wrote:
 
  Basically everything I wrote in the patch for -Wincompatible-pointer-types
  applies here as well.  A new option, -Wint-conversion (to be compatible
  with clang), is added to allow more fine-grained control over the warnings.
  I think we should print the types here as well, and moreover, we could hint 
  the
  user that  or * may be used to fix the code.
  
  Bootstrapped/regtested on x86_64-linux, ok for trunk?
 
 OK with the documentation amended to make clear this is about *implicit* 
 conversions, not the cases covered by -Wno-int-to-pointer-cast and 
 -Wno-pointer-to-int-cast.

Right, I'm applying the following then:

2014-07-01  Marek Polacek  pola...@redhat.com

* doc/invoke.texi: Document -Wint-conversion.
c-family/
* c.opt (Wint-conversion): New option.
c/
* c-typeck.c (convert_for_assignment): Pass OPT_Wint_conversion
instead of 0 to WARN_FOR_ASSIGNMENT.
testsuite/
* gcc.dg/Wint-conversion.c: New test.

diff --git gcc/c-family/c.opt gcc/c-family/c.opt
index 6448b1b..c89040a 100644
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -474,6 +474,10 @@ Winherited-variadic-ctor
 C++ ObjC++ Var(warn_inh_var_ctor) Init(1) Warning
 Warn about C++11 inheriting constructors when the base has a variadic 
constructor
 
+Wint-conversion
+C ObjC Var(warn_int_conversion) Init(1) Warning
+Warn about incompatible integer to pointer and pointer to integer conversions
+
 Wint-to-pointer-cast
 C ObjC C++ ObjC++ Var(warn_int_to_pointer_cast) Init(1) Warning
 Warn when there is a cast to a pointer from an integer of a different size
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index fff26a3..35bfd14 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -6213,7 +6213,8 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
 or one that results from arithmetic, even including
 a cast to integer type.  */
   if (!null_pointer_constant)
-   WARN_FOR_ASSIGNMENT (location, expr_loc, 0,
+   WARN_FOR_ASSIGNMENT (location, expr_loc,
+OPT_Wint_conversion,
 G_(passing argument %d of %qE makes 
pointer from integer without a cast),
 G_(assignment makes pointer from integer 
@@ -6227,7 +6228,8 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
 }
   else if (codel == INTEGER_TYPE  coder == POINTER_TYPE)
 {
-  WARN_FOR_ASSIGNMENT (location, expr_loc, 0,
+  WARN_FOR_ASSIGNMENT (location, expr_loc,
+  OPT_Wint_conversion,
   G_(passing argument %d of %qE makes integer 
  from pointer without a cast),
   G_(assignment makes integer from pointer 
diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index 409fa17..b1f6f4b 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -253,7 +253,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol
 -Wignored-qualifiers  -Wincompatible-pointer-types @gol
 -Wimplicit  -Wimplicit-function-declaration  -Wimplicit-int @gol
--Winit-self  -Winline @gol
+-Winit-self  -Winline  -Wno-int-conversion @gol
 -Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
 -Winvalid-pch -Wlarger-than=@var{len}  -Wunsafe-loop-optimizations @gol
 -Wlogical-op -Wlogical-not-parentheses -Wlong-long @gol
@@ -4214,6 +4214,14 @@ Do not warn when there is a conversion between pointers 
that have incompatible
 types.  This warning is for cases not covered by @option{-Wno-pointer-sign},
 which warns for pointer argument passing or assignment with different 
signedness
 
+@item -Wno-int-conversion @r{(C and Objective-C only)}
+@opindex Wno-int-conversion
+@opindex Wint-conversion
+Do not warn about incompatible integer to pointer and pointer to integer
+conversions.  This warning is about implicit conversions; for explicit
+conversions the warnings @option{-Wno-int-to-pointer-cast} and
+@option{-Wno-pointer-to-int-cast} may be used.
+
 @item -Wno-div-by-zero
 @opindex Wno-div-by-zero
 @opindex Wdiv-by-zero
diff --git gcc/testsuite/gcc.dg/Wint-conversion.c 
gcc/testsuite/gcc.dg/Wint-conversion.c
index e69de29..1b7a03e 100644
--- gcc/testsuite/gcc.dg/Wint-conversion.c
+++ gcc/testsuite/gcc.dg/Wint-conversion.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options -Wno-int-conversion } */
+
+int fn1 (int *), *fn2 (int);
+
+int
+fn1 (int *p)
+{
+  int i = p;
+  i = p;
+  fn2 (p);
+  return p;
+}
+
+int *
+fn2 (int i)
+{
+  int *p = i;
+  p = i;
+  fn1 (i);
+  return i;
+}

Marek


Re: [C PATCH] Add -Wint-conversion option

2014-07-01 Thread Marek Polacek
On Mon, Jun 30, 2014 at 11:07:57PM +0200, Gerald Pfeifer wrote:
 On Mon, 30 Jun 2014, Jakub Jelinek wrote:
  We don't have gcc-4.10/ directory, because the version of the next 
  release is still to be decided (hopefully at Cauldron next month).
 
 I'm a bit worried we'll miss entries in the meantime.
 
 Can we use gcc-4.10/ for now and rename later if we go for
 GCC V or whatever? :-)

Well, looks like I can't do much right now, so I'll go through my C FE
changes and new ubsan features after we have some actual changes.html,
and post a patch then...

Marek


Re: [C/C++ PATCH] Implement -Wsizeof-array-argument (PR c/6940)

2014-07-03 Thread Marek Polacek
On Wed, Jul 02, 2014 at 07:27:07PM -0700, Jason Merrill wrote:
 On 06/26/2014 03:22 PM, Marek Polacek wrote:
 The following is a revamped patch for -Wsizeof-array-argument.
 Its purpose is to detect suspicious usage of the sizeof operator on an array
 function parameter.
 
 Then the name should be -Wsizeof-array-parm, not -argument.

Yeah, but since clang calls this warnings -Wsizeof-array-argument, I
thought it's better to keep the names in sync.
 
 @@ -9550,6 +9551,8 @@ grokdeclarator (const cp_declarator *declarator,
 array.  */
  returned_attrs = chainon (returned_attrs,
declarator-std_attributes);
 +  if (decl_context == PARM)
 +array_parameter_p = true;
break;
 
 Setting this here means that you'll treat a parameter with pointer-to-array
 type as an array parm.  I think you want to set it here, instead:
 
   /* A parameter declared as an array of T is really a pointer to T.
  One declared as a function is really a pointer to a function.
  One declared as a member is really a pointer to member.  */
 
   if (TREE_CODE (type) == ARRAY_TYPE)
 {
   /* Transfer const-ness of array into that of type pointed to.  */
   type = build_pointer_type (TREE_TYPE (type));
   type_quals = TYPE_UNQUALIFIED;
 }

Ah!  Thanks for catching it.  I added a test for that, with some
typedefs too.  (The C FE didn't need similar fix.)

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-07-03  Marek Polacek  pola...@redhat.com

PR c/6940
* doc/invoke.texi: Document -Wsizeof-array-argument.
c-family/
* c.opt (Wsizeof-array-argument): New option.
c/
* c-decl.c (grokdeclarator): Set C_ARRAY_PARAMETER.
* c-tree.h (C_ARRAY_PARAMETER): Define.
* c-typeck.c (c_expr_sizeof_expr): Warn when using sizeof on an array
function parameter.
cp/
* cp-tree.h (DECL_ARRAY_PARAMETER_P): Define.
* decl.c (grokdeclarator): Set DECL_ARRAY_PARAMETER_P.
* typeck.c (cxx_sizeof_expr): Warn when using sizeof on an array
function parameter.
testsuite/
* c-c++-common/Wsizeof-pointer-memaccess1.c: Use
-Wno-sizeof-array-argument.
* c-c++-common/Wsizeof-pointer-memaccess2.c: Likewise.
* g++.dg/warn/Wsizeof-pointer-memaccess-1.C: Likewise.
* gcc.dg/Wsizeof-pointer-memaccess1.c: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
* gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Likewise.
* c-c++-common/sizeof-array-argument.c: New test.
* gcc.dg/vla-5.c: Add dg-warnings.
../libgomp/
* testsuite/libgomp.c/appendix-a/a.29.1.c (f): Add dg-warnings.

diff --git gcc/gcc/c-family/c.opt gcc/gcc/c-family/c.opt
index c89040a..faef774 100644
--- gcc/gcc/c-family/c.opt
+++ gcc/gcc/c-family/c.opt
@@ -534,6 +534,10 @@ Wsizeof-pointer-memaccess
 C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C 
ObjC C++ ObjC++,Wall)
 Warn about suspicious length parameters to certain string functions if the 
argument uses sizeof
 
+Wsizeof-array-argument
+C ObjC C++ ObjC++ Var(warn_sizeof_array_argument) Warning Init(1)
+Warn when sizeof is applied on a parameter declared as an array
+
 Wsuggest-attribute=format
 C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
 Warn about functions which might be candidates for format attributes
diff --git gcc/gcc/c/c-decl.c gcc/gcc/c/c-decl.c
index 3dec90b..0ca2e0d 100644
--- gcc/gcc/c/c-decl.c
+++ gcc/gcc/c/c-decl.c
@@ -6103,6 +6103,7 @@ grokdeclarator (const struct c_declarator *declarator,
 if (decl_context == PARM)
   {
tree promoted_type;
+   bool array_parameter_p = false;
 
/* A parameter declared as an array of T is really a pointer to T.
   One declared as a function is really a pointer to a function.  */
@@ -6124,6 +6125,7 @@ grokdeclarator (const struct c_declarator *declarator,
  attributes in parameter array declarator ignored);
 
size_varies = false;
+   array_parameter_p = true;
  }
else if (TREE_CODE (type) == FUNCTION_TYPE)
  {
@@ -6148,6 +6150,7 @@ grokdeclarator (const struct c_declarator *declarator,
   PARM_DECL, declarator-u.id, type);
if (size_varies)
  C_DECL_VARIABLE_SIZE (decl) = 1;
+   C_ARRAY_PARAMETER (decl) = array_parameter_p;
 
/* Compute the type actually passed in the parmlist,
   for the case where there is no prototype.
diff --git gcc/gcc/c/c-tree.h gcc/gcc/c/c-tree.h
index 133930f..f97d0d5 100644
--- gcc/gcc/c/c-tree.h
+++ gcc/gcc/c/c-tree.h
@@ -66,6 +66,9 @@ along with GCC; see the file COPYING3.  If not see
 /* For a FUNCTION_DECL, nonzero if it was an implicit declaration.  */
 #define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP

Re: [PATCH] Don't ICE with huge alignment (PR middle-end/60226)

2014-07-03 Thread Marek Polacek
On Mon, Jun 30, 2014 at 01:50:12PM -0600, Jeff Law wrote:
 On 03/04/14 09:40, Marek Polacek wrote:
 This should fix ICE on insane alignment.  Normally, check_user_alignment
 detects e.g. alignment 1  32, but not 1  28.  However, record_align
 is in bits, so it's actually 8 * (1  28) and that's greater than
 INT_MAX.  This patch rejects such code.
 
 In the middle hunk, we should give up when an error occurs, we don't
 want to call finalize_type_size in that case -- we'd ICE in there.
 
 Regtested/bootstrapped on x86_64-linux, ok for trunk?
 
 2014-03-04  Marek Polacek  pola...@redhat.com
 
  PR middle-end/60226
  * stor-layout.c (layout_type): Return if alignment of array elements
  is greater than element size.  Error out if requested alignment is too
  large.
 cp/
  * class.c (layout_class_type): Error out if requested alignment is too
  large.
 testsuite/
  * c-c++-common/pr60226.c: New test.
 Is this still applicable after the wide-int changes?  I haven't looked
 closely.

Yeah, it applies cleanly.  But I tried the int - unsigned change
which Mike suggested and that cures the ICE.  I'll send a patch
momentarily.

Marek


Re: [PATCH] Don't ICE with huge alignment (PR middle-end/60226)

2014-07-03 Thread Marek Polacek
On Mon, Jun 30, 2014 at 03:40:18PM -0700, Mike Stump wrote:
 I glanced at it:
 
 (gdb) p/x TYPE_ALIGN (type)
 $1 = 2147483648
 (gdb) p/x TYPE_ALIGN (type)
 $2 = 0x8000
 
 The callee is int, the caller uses unsigned int.  The assert I see is because 
 the routines are not type correct:
 
 =TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
 
 (gdb) ptype TYPE_ALIGN (type)
 type = unsigned int
 
 
 tree
 round_up_loc (location_t loc, tree value, int divisor)
 {
   tree div = NULL_TREE;
 
 =gcc_assert (divisor  0);
 
 Would be nice if the routine was type correct (wrt unsigned).

Yeah, I did that.  One issue with that is that round_up now wraps
the value, so I had to add a check for huge size before rounding up,
otherwise we'd regress on e.g. PR42611.

How about the following?

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-07-03  Marek Polacek  pola...@redhat.com

PR c/60226
* fold-const.c (round_up_loc): Change the parameter type.
Remove assert.
* fold-const.h (round_up_loc): Adjust declaration.
* stor-layout.c (finalize_record_size): Check for too large types.

* c-c++-common/pr60226.c: New test.

diff --git gcc/fold-const.c gcc/fold-const.c
index d22eac1..c57ac7b 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -16647,11 +16647,10 @@ fold_ignored_result (tree t)
 /* Return the value of VALUE, rounded up to a multiple of DIVISOR. */
 
 tree
-round_up_loc (location_t loc, tree value, int divisor)
+round_up_loc (location_t loc, tree value, unsigned int divisor)
 {
   tree div = NULL_TREE;
 
-  gcc_assert (divisor  0);
   if (divisor == 1)
 return value;
 
diff --git gcc/fold-const.h gcc/fold-const.h
index dcb97a1..3b5fd84 100644
--- gcc/fold-const.h
+++ gcc/fold-const.h
@@ -144,7 +144,7 @@ extern tree combine_comparisons (location_t, enum 
tree_code, enum tree_code,
 extern void debug_fold_checksum (const_tree);
 extern bool may_negate_without_overflow_p (const_tree);
 #define round_up(T,N) round_up_loc (UNKNOWN_LOCATION, T, N)
-extern tree round_up_loc (location_t, tree, int);
+extern tree round_up_loc (location_t, tree, unsigned int);
 #define round_down(T,N) round_down_loc (UNKNOWN_LOCATION, T, N)
 extern tree round_down_loc (location_t, tree, int);
 extern tree size_int_kind (HOST_WIDE_INT, enum size_type_kind);
diff --git gcc/stor-layout.c gcc/stor-layout.c
index cfd436f..19e7adb 100644
--- gcc/stor-layout.c
+++ gcc/stor-layout.c
@@ -1587,6 +1587,11 @@ finalize_record_size (record_layout_info rli)
 unpadded_size_unit
   = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
 
+  if (TREE_CODE (unpadded_size_unit) == INTEGER_CST
+   !TREE_OVERFLOW (unpadded_size_unit)
+   !valid_constant_size_p (unpadded_size_unit))
+error (type %qT is too large, rli-t);
+
   /* Round the size up to be a multiple of the required alignment.  */
   TYPE_SIZE (rli-t) = round_up (unpadded_size, TYPE_ALIGN (rli-t));
   TYPE_SIZE_UNIT (rli-t)
diff --git gcc/testsuite/c-c++-common/pr60226.c 
gcc/testsuite/c-c++-common/pr60226.c
index e69de29..3a1c261 100644
--- gcc/testsuite/c-c++-common/pr60226.c
+++ gcc/testsuite/c-c++-common/pr60226.c
@@ -0,0 +1,14 @@
+/* PR c/60226 */
+/* { dg-do compile } */
+/* { dg-options -Wno-c++-compat { target c } } */
+
+typedef int __attribute__ ((aligned (1  28))) int28;
+int28 foo[4] = {}; /* { dg-error alignment of array elements is greater than 
element size } */
+typedef int __attribute__ ((aligned (1  29))) int29; /* { dg-error 
requested alignment is too large } */
+
+void
+f (void)
+{
+  struct { __attribute__((aligned (1  28))) double a; } x1;
+  struct { __attribute__((aligned (1  29))) double a; } x2; /* { dg-error 
requested alignment is too large } */
+}

Marek


Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-07-03 Thread Marek Polacek
On Sat, Jun 28, 2014 at 06:52:00PM +0200, Gerald Pfeifer wrote:
 On Fri, 20 Jun 2014, Marek Polacek wrote:
 +@item -fsanitize=bounds
 +@opindex fsanitize=bounds
 +
 +This option enables instrumentation of array bounds.  Various out of bounds
 +accesses are detected.  Flexible array members are not instrumented, as well
 +as initializers of variables with static storage.
 
 Can you make this Flexible array members and initializers... (or
 ...as well as...)?  The current wording confused me a bit at first.
 
 And I believe there should be no empty line after @opindex.

Thanks, I'll fix both with the following.  Also
-fsanitize=float-divide-by-zero and -fsanitize=float-cast-overflow
descriptions were at a wrong place, so moved a little bit above.

Applying to trunk as obvious.

2014-07-03  Marek Polacek  pola...@redhat.com

* doc/invoke.texi (-fsanitize=bounds): Tweak wording.
(-fsanitize=float-divide-by-zero): Move to the table with
-fsanitize=undefined suboptions.
(-fsanitize=float-cast-overflow): Likewise.

diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index b1f6f4b..046ea58 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -5400,26 +5400,22 @@ at runtime.  Current suboptions are:
 
 @item -fsanitize=shift
 @opindex fsanitize=shift
-
 This option enables checking that the result of a shift operation is
 not undefined.  Note that what exactly is considered undefined differs
 slightly between C and C++, as well as between ISO C90 and C99, etc.
 
 @item -fsanitize=integer-divide-by-zero
 @opindex fsanitize=integer-divide-by-zero
-
 Detect integer division by zero as well as @code{INT_MIN / -1} division.
 
 @item -fsanitize=unreachable
 @opindex fsanitize=unreachable
-
 With this option, the compiler will turn the @code{__builtin_unreachable}
 call into a diagnostics message call instead.  When reaching the
 @code{__builtin_unreachable} call, the behavior is undefined.
 
 @item -fsanitize=vla-bound
 @opindex fsanitize=vla-bound
-
 This option instructs the compiler to check that the size of a variable
 length array is positive.  This option does not have any effect in
 @option{-std=c++1y} mode, as the standard requires the exception be thrown
@@ -5427,7 +5423,6 @@ instead.
 
 @item -fsanitize=null
 @opindex fsanitize=null
-
 This option enables pointer checking.  Particularly, the application
 built with this option turned on will issue an error message when it
 tries to dereference a NULL pointer, or if a reference (possibly an
@@ -5435,7 +5430,6 @@ rvalue reference) is bound to a NULL pointer.
 
 @item -fsanitize=return
 @opindex fsanitize=return
-
 This option enables return statement checking.  Programs
 built with this option turned on will issue an error message
 when the end of a non-void function is reached without actually
@@ -5443,7 +5437,6 @@ returning a value.  This option works in C++ only.
 
 @item -fsanitize=signed-integer-overflow
 @opindex fsanitize=signed-integer-overflow
-
 This option enables signed integer overflow checking.  We check that
 the result of @code{+}, @code{*}, and both unary and binary @code{-}
 does not overflow in the signed arithmetics.  Note, integer promotion
@@ -5456,20 +5449,12 @@ a++;
 
 @item -fsanitize=bounds
 @opindex fsanitize=bounds
-
 This option enables instrumentation of array bounds.  Various out of bounds
-accesses are detected.  Flexible array members are not instrumented, as well
-as initializers of variables with static storage.
-
-@end table
-
-While @option{-ftrapv} causes traps for signed overflows to be emitted,
-@option{-fsanitize=undefined} gives a diagnostic message.
-This currently works only for the C family of languages.
+accesses are detected.  Flexible array members and initializers of variables
+with static storage are not instrumented.
 
 @item -fsanitize=float-divide-by-zero
 @opindex fsanitize=float-divide-by-zero
-
 Detect floating-point division by zero.  Unlike other similar options,
 @option{-fsanitize=float-divide-by-zero} is not enabled by
 @option{-fsanitize=undefined}, since floating-point division by zero can
@@ -5477,11 +5462,16 @@ be a legitimate way of obtaining infinities and NaNs.
 
 @item -fsanitize=float-cast-overflow
 @opindex fsanitize=float-cast-overflow
-
 This option enables floating-point type to integer conversion checking.
 We check that the result of the conversion does not overflow.
 This option does not work well with @code{FE_INVALID} exceptions enabled.
 
+@end table
+
+While @option{-ftrapv} causes traps for signed overflows to be emitted,
+@option{-fsanitize=undefined} gives a diagnostic message.
+This currently works only for the C family of languages.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions

Marek


Re: [PATCH] Implement -fsanitize=bounds and internal calls in FEs

2014-07-03 Thread Marek Polacek
On Thu, Jul 03, 2014 at 12:46:35PM +0200, Jakub Jelinek wrote:
 On Thu, Jul 03, 2014 at 12:41:46PM +0200, Marek Polacek wrote:
  On Sat, Jun 28, 2014 at 06:52:00PM +0200, Gerald Pfeifer wrote:
   On Fri, 20 Jun 2014, Marek Polacek wrote:
   +@item -fsanitize=bounds
   +@opindex fsanitize=bounds
   +
   +This option enables instrumentation of array bounds.  Various out of 
   bounds
   +accesses are detected.  Flexible array members are not instrumented, as 
   well
   +as initializers of variables with static storage.
   
   Can you make this Flexible array members and initializers... (or
   ...as well as...)?  The current wording confused me a bit at first.
   
   And I believe there should be no empty line after @opindex.
  
  Thanks, I'll fix both with the following.  Also
  -fsanitize=float-divide-by-zero and -fsanitize=float-cast-overflow
  descriptions were at a wrong place, so moved a little bit above.
  
  Applying to trunk as obvious.
  
  2014-07-03  Marek Polacek  pola...@redhat.com
  
  * doc/invoke.texi (-fsanitize=bounds): Tweak wording.
  (-fsanitize=float-divide-by-zero): Move to the table with
  -fsanitize=undefined suboptions.
  (-fsanitize=float-cast-overflow): Likewise.
 
 Those two aren't -fsanitize=undefined suboptions, so shouldn't be included
 in there.

But they're parts of ubsan and at least
-fsanitize=float-divide-by-zero says it is not enabled by
-fsanitize=undefined.  Dunno, I can move it back if you want.

Marek


Re: Strenghten assumption about dynamic type changes (placement new)

2014-07-06 Thread Marek Polacek
On Fri, Jul 04, 2014 at 11:39:52PM +0200, Jan Hubicka wrote:
 Bootstrapped/regtested x86_64-linux, will commit it after bit more
 testing.
...
   * g++.dg/ipa/imm-devirt-1.C: Update testcase.
   * g++.dg/ipa/imm-devirt-2.C: Update testcase.

These testcases fail:

ERROR: g++.dg/ipa/imm-devirt-1.C  -std=gnu++98: error executing dg-final: 
couldn't compile regular expression pattern: parentheses () not balanced
ERROR: g++.dg/ipa/imm-devirt-1.C  -std=gnu++11: error executing dg-final: 
couldn't compile regular expression pattern: parentheses () not balanced
ERROR: g++.dg/ipa/imm-devirt-1.C  -std=gnu++1y: error executing dg-final: 
couldn't compile regular expression pattern: parentheses () not balanced
ERROR: g++.dg/ipa/imm-devirt-2.C  -std=gnu++98: error executing dg-final: 
couldn't compile regular expression pattern: parentheses () not balanced
ERROR: g++.dg/ipa/imm-devirt-2.C  -std=gnu++11: error executing dg-final: 
couldn't compile regular expression pattern: parentheses () not balanced
ERROR: g++.dg/ipa/imm-devirt-2.C  -std=gnu++1y: error executing dg-final: 
couldn't compile regular expression pattern: parentheses () not balanced

I'm fixing that with the following (will commit as obvious).

2014-07-06  Marek Polacek  pola...@redhat.com

* g++.dg/ipa/imm-devirt-1.C: Fix regexp in dg-final.
* g++.dg/ipa/imm-devirt-2.C: Likewise.

diff --git gcc/testsuite/g++.dg/ipa/imm-devirt-1.C 
gcc/testsuite/g++.dg/ipa/imm-devirt-1.C
index 115277f..85f1a8f 100644
--- gcc/testsuite/g++.dg/ipa/imm-devirt-1.C
+++ gcc/testsuite/g++.dg/ipa/imm-devirt-1.C
@@ -62,6 +62,6 @@ int main (int argc, char *argv[])
a direct call.  */
 /* { dg-final { scan-tree-dump Inlining int middleman_1 einline  } } */
 /* { dg-final { scan-tree-dump Inlining int middleman_2 einline  } } */
-/* { dg-final { scan-tree-dump B::foo ( einline  } } */
+/* { dg-final { scan-tree-dump B::foo \\( einline  } } */
 /* { dg-final { scan-tree-dump-times OBJ_TYPE_REF 2 einline  } } */
 /* { dg-final { cleanup-tree-dump einline } } */
diff --git gcc/testsuite/g++.dg/ipa/imm-devirt-2.C 
gcc/testsuite/g++.dg/ipa/imm-devirt-2.C
index 58af089..db85487 100644
--- gcc/testsuite/g++.dg/ipa/imm-devirt-2.C
+++ gcc/testsuite/g++.dg/ipa/imm-devirt-2.C
@@ -92,5 +92,5 @@ int main (int argc, char *argv[])
 }
 
 /* We fold into thunk of C. Eventually we should inline the thunk.  */
-/* { dg-final { scan-tree-dump C::_ZThn24_N1C3fooEi ( einline  } } */
+/* { dg-final { scan-tree-dump C::_ZThn24_N1C3fooEi \\( einline  } } */
 /* { dg-final { cleanup-tree-dump einline } } */

Marek


[PATCH] Implement -fsanitize=object-size

2014-07-13 Thread Marek Polacek
The following is an attempt to implement -fsanitize=object-size.
When it sees a MEM_REF, it goes through the definition statements
and stops on sth like ptr = sth.  Then it tries to determine the
object size using __builtin_object_size and generates an internal
call (in .ubsan pass).  The .sanopt pass then expands this internal
call, and if the pointer points outside of the object, it issues
a runtime error.

Bootstrapped(-ubsan)/regtested on x86_64-linux, ok for trunk?

2014-07-13  Marek Polacek  pola...@redhat.com

* ubsan.h (struct ubsan_mismatch_data):
* asan.c (pass_sanopt::execute): Handle IFN_UBSAN_OBJECT_SIZE.
* doc/invoke.texi: Document -fsanitize=object-size.
* flag-types.h (enum sanitize_code): Add SANITIZE_OBJECT_SIZE and
or it into SANITIZE_UNDEFINED.
* internal-fn.c (expand_UBSAN_OBJECT_SIZE): New function.
* internal-fn.def (UBSAN_OBJECT_SIZE): Define.
* opts.c (common_handle_option): Handle -fsanitize=object-size.
* ubsan.c: Include tree-object-size.h.
(ubsan_expand_objsize_ifn): New function.
(instrument_object_size): New function.
(pass_ubsan::execute): Add object size instrumentation.
* ubsan.h (ubsan_expand_objsize_ifn): Declare.
testsuite/
* c-c++-common/ubsan/object-size-1.c: New test.
* c-c++-common/ubsan/object-size-2.c: New test.
* c-c++-common/ubsan/object-size-3.c: New test.
* c-c++-common/ubsan/object-size-4.c: New test.
* c-c++-common/ubsan/object-size-5.c: New test.
* c-c++-common/ubsan/object-size-6.c: New test.
* c-c++-common/ubsan/object-size-7.c: New test.

diff --git gcc/asan.c gcc/asan.c
index b9a4a91..5954f95 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2764,6 +2764,9 @@ pass_sanopt::execute (function *fun)
  case IFN_UBSAN_BOUNDS:
ubsan_expand_bounds_ifn (gsi);
break;
+ case IFN_UBSAN_OBJECT_SIZE:
+   ubsan_expand_objsize_ifn (gsi);
+   break;
  default:
break;
  }
diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index 4807ffc..fbaac9d 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -5477,6 +5477,12 @@ This option enables instrumentation of array bounds.  
Various out of bounds
 accesses are detected.  Flexible array members and initializers of variables
 with static storage are not instrumented.
 
+@item -fsanitize=object-size
+@opindex fsanitize=object-size
+This option enables instrumentation of memory references using the
+@code{__builtin_object_size} function.  Various out of bounds pointer
+accesses are detected.
+
 @item -fsanitize=float-divide-by-zero
 @opindex fsanitize=float-divide-by-zero
 Detect floating-point division by zero.  Unlike other similar options,
diff --git gcc/flag-types.h gcc/flag-types.h
index 2849455..63d199c 100644
--- gcc/flag-types.h
+++ gcc/flag-types.h
@@ -231,10 +231,11 @@ enum sanitize_code {
   SANITIZE_FLOAT_DIVIDE = 1  12,
   SANITIZE_FLOAT_CAST = 1  13,
   SANITIZE_BOUNDS = 1  14,
+  SANITIZE_OBJECT_SIZE = 1  15,
   SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
   | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
   | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM
-  | SANITIZE_BOUNDS,
+  | SANITIZE_BOUNDS | SANITIZE_OBJECT_SIZE,
   SANITIZE_NONDEFAULT = SANITIZE_FLOAT_DIVIDE | SANITIZE_FLOAT_CAST
 };
 
diff --git gcc/internal-fn.c gcc/internal-fn.c
index 78f59d6..eee3e85 100644
--- gcc/internal-fn.c
+++ gcc/internal-fn.c
@@ -167,6 +167,14 @@ expand_UBSAN_BOUNDS (gimple stmt ATTRIBUTE_UNUSED)
   gcc_unreachable ();
 }
 
+/* This should get expanded in the sanopt pass.  */
+
+static void
+expand_UBSAN_OBJECT_SIZE (gimple stmt ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
 /* Add sub/add overflow checking to the statement STMT.
CODE says whether the operation is +, or -.  */
 
diff --git gcc/internal-fn.def gcc/internal-fn.def
index f0766bc..a2caf94 100644
--- gcc/internal-fn.def
+++ gcc/internal-fn.def
@@ -49,6 +49,7 @@ DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF)
 DEF_INTERNAL_FN (ANNOTATE,  ECF_CONST | ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (UBSAN_BOUNDS, ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
diff --git gcc/opts.c gcc/opts.c
index 419a074..00ec76f 100644
--- gcc/opts.c
+++ gcc/opts.c
@@ -1475,6 +1475,8 @@ common_handle_option (struct gcc_options *opts,
  { float-cast-overflow, SANITIZE_FLOAT_CAST,
sizeof float-cast-overflow - 1 },
  { bounds, SANITIZE_BOUNDS, sizeof bounds - 1

Re: [PATCH][www] disallow /git/ in robots.txt

2014-07-15 Thread Marek Polacek
On Tue, Jul 15, 2014 at 09:54:02AM +0200, Gerald Pfeifer wrote:
 On Tue, 15 Jul 2014, Richard Biener wrote:
  Seems like somebody is mirroring gitweb urls.
 
  2014-07-15  Richard Biener  rguent...@suse.de
  
  * robots.txt: Disallow /git/
 
 Makes sense.  (I checked, and we already block /svn and /viewcvs.)
 
 How did you find out?

Many people, including me, saw that git pull fails due to high load.

Marek


[PATCH] Fix -imacros (PR c/57653)

2014-07-15 Thread Marek Polacek
This is a revised patch that Peter recently submitted
https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01571.html, but
it was lacking a testcase and a better comment.  This patch
adds a testcase (kind of a hacky one), the comment is hopefully
better too.  Joseph already said that the code changes look ok.

Bootstrapped/regtested on x86_64-linux, ok for trunk?
Ok also for 4.9/4.8?

2014-07-14  Marek Polacek  pola...@redhat.com
Manuel López-Ibáñez  m...@gcc.gnu.org

PR c/57653
* c-opts.c (c_finish_options): If -imacros is in effect, return.

* c-c++-common/pr57653.c: New test.
* c-c++-common/pr57653.h: New file.

diff --git gcc/c-family/c-opts.c gcc/c-family/c-opts.c
index 5ee7024..30de1e1 100644
--- gcc/c-family/c-opts.c
+++ gcc/c-family/c-opts.c
@@ -1347,6 +1347,12 @@ c_finish_options (void)
 static void
 push_command_line_include (void)
 {
+  /* This can happen if disabled by -imacros for example.
+ Punt so that we don't set command-line as the filename for
+ the header.  */
+  if (include_cursor  deferred_count)
+return;
+
   if (!done_preinclude)
 {
   done_preinclude = true;
diff --git gcc/testsuite/c-c++-common/pr57653.c 
gcc/testsuite/c-c++-common/pr57653.c
index e69de29..620471e 100644
--- gcc/testsuite/c-c++-common/pr57653.c
+++ gcc/testsuite/c-c++-common/pr57653.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options -imacros ${srcdir}/c-c++-common/pr57653.h } */
+
+__attribute__((used)) static const char s[] = F;
+
+/* { dg-final { scan-assembler-not command-line } } */
diff --git gcc/testsuite/c-c++-common/pr57653.h 
gcc/testsuite/c-c++-common/pr57653.h
index e69de29..5a93388 100644
--- gcc/testsuite/c-c++-common/pr57653.h
+++ gcc/testsuite/c-c++-common/pr57653.h
@@ -0,0 +1 @@
+#define F __FILE__

Marek


[PATCH] Fix ubsan ICE with flexible array members

2014-07-15 Thread Marek Polacek
We were missing a check that the TYPE_MAX_VALUE is not NULL.
If it is, we ICE later when gimplifying the UBSAN_BOUNDS call arguments.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-07-15  Marek Polacek  pola...@redhat.com

* c-ubsan.c (ubsan_instrument_bounds): Don't instrument if
TYPE_MAX_VALUE is NULL.

* gcc.dg/ubsan/bounds-1.c: New test.

diff --git gcc/c-family/c-ubsan.c gcc/c-family/c-ubsan.c
index 3698580..ad5dd0b 100644
--- gcc/c-family/c-ubsan.c
+++ gcc/c-family/c-ubsan.c
@@ -265,7 +265,7 @@ ubsan_instrument_bounds (location_t loc, tree array, tree 
*index,
   tree type = TREE_TYPE (array);
   tree domain = TYPE_DOMAIN (type);
 
-  if (domain == NULL_TREE)
+  if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE)
 return NULL_TREE;
 
   tree bound = TYPE_MAX_VALUE (domain);
diff --git gcc/testsuite/gcc.dg/ubsan/bounds-1.c 
gcc/testsuite/gcc.dg/ubsan/bounds-1.c
index e69de29..6f3cd2d 100644
--- gcc/testsuite/gcc.dg/ubsan/bounds-1.c
+++ gcc/testsuite/gcc.dg/ubsan/bounds-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options -fsanitize=bounds } */
+
+struct T { int c; char d[]; } t = { 1, abcdefg };
+
+int
+baz (int i)
+{
+  return t.d[i];
+}

Marek


[C PATCH] Better location for implicit_decl_warning (PR c/61852)

2014-07-20 Thread Marek Polacek
implicit_decl_warning wasn't getting a location, so the column info
was poor.  It's easy to fix this up.

Bootstrapped/regtested on x86_64-linux, applying to trunk.

2014-07-20  Marek Polacek  pola...@redhat.com

PR c/61852
* c-decl.c (implicit_decl_warning): Add location_t parameter.  Use it.
(implicitly_declare): Pass location to implicit_decl_warning.

* gcc.dg/pr61852.c: New test.

diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index 0ca2e0d..425fc58 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -2951,18 +2951,18 @@ pushdecl_top_level (tree x)
 }
 
 static void
-implicit_decl_warning (tree id, tree olddecl)
+implicit_decl_warning (location_t loc, tree id, tree olddecl)
 {
   if (warn_implicit_function_declaration)
 {
   bool warned;
 
   if (flag_isoc99)
-   warned = pedwarn (input_location, OPT_Wimplicit_function_declaration,
+   warned = pedwarn (loc, OPT_Wimplicit_function_declaration,
  implicit declaration of function %qE, id);
   else
-   warned = warning (OPT_Wimplicit_function_declaration,
- G_(implicit declaration of function %qE), id);
+   warned = warning_at (loc, OPT_Wimplicit_function_declaration,
+G_(implicit declaration of function %qE), id);
   if (olddecl  warned)
locate_old_decl (olddecl);
 }
@@ -3015,7 +3015,7 @@ implicitly_declare (location_t loc, tree functionid)
 then recycle the old declaration but with the new type.  */
  if (!C_DECL_IMPLICIT (decl))
{
- implicit_decl_warning (functionid, decl);
+ implicit_decl_warning (loc, functionid, decl);
  C_DECL_IMPLICIT (decl) = 1;
}
  if (DECL_BUILT_IN (decl))
@@ -3052,7 +3052,7 @@ implicitly_declare (location_t loc, tree functionid)
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
   C_DECL_IMPLICIT (decl) = 1;
-  implicit_decl_warning (functionid, 0);
+  implicit_decl_warning (loc, functionid, 0);
   asmspec_tree = maybe_apply_renaming_pragma (decl, /*asmname=*/NULL);
   if (asmspec_tree)
 set_user_assembler_name (decl, TREE_STRING_POINTER (asmspec_tree));
diff --git gcc/testsuite/gcc.dg/pr61852.c gcc/testsuite/gcc.dg/pr61852.c
index e69de29..f488aca 100644
--- gcc/testsuite/gcc.dg/pr61852.c
+++ gcc/testsuite/gcc.dg/pr61852.c
@@ -0,0 +1,10 @@
+/* PR c/61852 */
+/* { dg-do compile } */
+/* { dg-options -Wimplicit-function-declaration } */
+
+int
+f (int a)
+{
+  int b = a + a + a + ff (a); /* { dg-warning 23:implicit declaration of 
function } */
+  return b;
+}

Marek


[libcpp PATCH] Fix up location of builtin macros (PR c/61861)

2014-07-23 Thread Marek Polacek
Bultin macros like __FILE__, __DATE__, etc. had wrong locus - always
column 1.  This patch fixes it by giving those macros location
of the expansion point, i.e, the location, where builtin macro is used.
It now also does the correct thing if we do e.g.
#define F __FILE__.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-07-23  Marek Polacek  pola...@redhat.com

PR c/61861
* macro.c (builtin_macro): Add location parameter.  Set
location of builtin macro to the expansion point.
(enter_macro_context): Pass location to builtin_macro.

* gcc.dg/pr61861.c: New test.

diff --git gcc/gcc/testsuite/gcc.dg/pr61861.c gcc/gcc/testsuite/gcc.dg/pr61861.c
index e69de29..d902868 100644
--- gcc/gcc/testsuite/gcc.dg/pr61861.c
+++ gcc/gcc/testsuite/gcc.dg/pr61861.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-prune-output expected } */
+
+extern void foo (int);
+extern void bar (int, char *);
+
+#define F __FILE__ /* { dg-error 11:passing argument } */
+#define T __TIME__ /* { dg-error 11:passing argument } */
+#define D __DATE__ /* { dg-error 11:passing argument } */
+#define L __LINE__ /* { dg-error 11:passing argument } */
+
+#define F2 foo /* { dg-error 12:passing argument } */
+#define T2 foo /* { dg-error 12:passing argument } */
+#define D2 foo /* { dg-error 12:passing argument } */
+#define L2 42 /* { dg-error 12:passing argument } */
+
+void
+f (void)
+{
+  foo (__FILE__); /* { dg-error 8:passing argument } */
+  foo (__BASE_FILE__); /* { dg-error 8:passing argument } */
+  foo (__TIME__); /* { dg-error 8:passing argument } */
+  foo (__DATE__); /* { dg-error 8:passing argument } */
+  foo (__TIMESTAMP__); /* { dg-error 8:passing argument } */
+  bar (1, __LINE__); /* { dg-error 11:passing argument } */
+  bar (__COUNTER__, __COUNTER__); /* { dg-error 21:passing argument } */
+
+  foo (F); /* { dg-message 8:in expansion of } */
+  foo (T); /* { dg-message 8:in expansion of } */
+  foo (D); /* { dg-message 8:in expansion of } */
+  bar (1, L); /* { dg-message 11:in expansion of } */
+
+  foo (F2); /* { dg-message 8:in expansion of } */
+  foo (T2); /* { dg-message 8:in expansion of } */
+  foo (D2); /* { dg-message 8:in expansion of } */
+  bar (1, L2); /* { dg-message 11:in expansion of } */
+}
diff --git gcc/libcpp/macro.c gcc/libcpp/macro.c
index 3b8fa40..556628b 100644
--- gcc/libcpp/macro.c
+++ gcc/libcpp/macro.c
@@ -84,7 +84,7 @@ struct macro_arg_token_iter
 
 static int enter_macro_context (cpp_reader *, cpp_hashnode *,
const cpp_token *, source_location);
-static int builtin_macro (cpp_reader *, cpp_hashnode *);
+static int builtin_macro (cpp_reader *, cpp_hashnode *, source_location);
 static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
 const cpp_token **, unsigned int);
 static void push_extended_tokens_context (cpp_reader *, cpp_hashnode *,
@@ -399,9 +399,10 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode 
*node)
 /* Convert builtin macros like __FILE__ to a token and push it on the
context stack.  Also handles _Pragma, for which a new token may not
be created.  Returns 1 if it generates a new token context, 0 to
-   return the token to the caller.  */
+   return the token to the caller.  LOC is the location of the expansion
+   point of the macro.  */
 static int
-builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
+builtin_macro (cpp_reader *pfile, cpp_hashnode *node, source_location loc)
 {
   const uchar *buf;
   size_t len;
@@ -429,6 +430,8 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
   /* Set pfile-cur_token as required by _cpp_lex_direct.  */
   pfile-cur_token = _cpp_temp_token (pfile);
   cpp_token *token = _cpp_lex_direct (pfile);
+  /* We should point to the expansion point of the builtin macro.  */
+  token-src_loc = loc;
   if (pfile-context-tokens_kind == TOKENS_KIND_EXTENDED)
 {
   /* We are tracking tokens resulting from macro expansion.
@@ -1212,7 +1215,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode 
*node,
 
   pfile-about_to_expand_macro_p = false;
   /* Handle built-in macros and the _Pragma operator.  */
-  return builtin_macro (pfile, node);
+  return builtin_macro (pfile, node, location);
 }
 
 /* De-allocate the memory used by BUFF which is an array of instances

Marek


[ubsan PATCH] Fix bounds-2.c test with -fstack-protector-strong

2014-07-23 Thread Marek Polacek
Jakub reported to me that bounds-2.c test fails with
-fstack-protector-strong -Os.  The following hack fixes it.

Tested x86_64-linux, applying to trunk as obvious.

2014-07-23  Marek Polacek  pola...@redhat.com

* c-c++-common/ubsan/bounds-2.c (fn4): Adjust to check the array size
in the structure. 

diff --git gcc/testsuite/c-c++-common/ubsan/bounds-2.c 
gcc/testsuite/c-c++-common/ubsan/bounds-2.c
index 7ef71aa..73229dc 100644
--- gcc/testsuite/c-c++-common/ubsan/bounds-2.c
+++ gcc/testsuite/c-c++-common/ubsan/bounds-2.c
@@ -4,6 +4,7 @@
 /* Test runtime errors.  */
 
 struct S { int a[10]; };
+struct T { int a[5]; int s[2]; };
 
 int
 foo_5 (void)
@@ -47,8 +48,9 @@ fn3 (void)
 static void __attribute__ ((noinline, noclone))
 fn4 (void)
 {
-  volatile int a[5];
-  a[foo_5 ()] = 1;
+  struct T t;
+  asm ( : : r (t.a) : memory);
+  t.a[foo_5 ()] = 1;
 }
 
 static void __attribute__ ((noinline, noclone))

Marek


Re: [libcpp PATCH] Fix up location of builtin macros (PR c/61861)

2014-07-23 Thread Marek Polacek
CCing Dodji, please, can you have a look?  (I don't believe it is
caused by yours
https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01063.html though,
this was wrong even in 4.8 and maybe earlier.)

On Wed, Jul 23, 2014 at 03:15:53PM +0200, Marek Polacek wrote:
 Bultin macros like __FILE__, __DATE__, etc. had wrong locus - always
 column 1.  This patch fixes it by giving those macros location
 of the expansion point, i.e, the location, where builtin macro is used.
 It now also does the correct thing if we do e.g.
 #define F __FILE__.
 
 Bootstrapped/regtested on x86_64-linux, ok for trunk?
 
 2014-07-23  Marek Polacek  pola...@redhat.com
 
   PR c/61861
   * macro.c (builtin_macro): Add location parameter.  Set
   location of builtin macro to the expansion point.
   (enter_macro_context): Pass location to builtin_macro.
 
   * gcc.dg/pr61861.c: New test.
 
 diff --git gcc/gcc/testsuite/gcc.dg/pr61861.c 
 gcc/gcc/testsuite/gcc.dg/pr61861.c
 index e69de29..d902868 100644
 --- gcc/gcc/testsuite/gcc.dg/pr61861.c
 +++ gcc/gcc/testsuite/gcc.dg/pr61861.c
 @@ -0,0 +1,37 @@
 +/* { dg-do compile } */
 +/* { dg-prune-output expected } */
 +
 +extern void foo (int);
 +extern void bar (int, char *);
 +
 +#define F __FILE__ /* { dg-error 11:passing argument } */
 +#define T __TIME__ /* { dg-error 11:passing argument } */
 +#define D __DATE__ /* { dg-error 11:passing argument } */
 +#define L __LINE__ /* { dg-error 11:passing argument } */
 +
 +#define F2 foo /* { dg-error 12:passing argument } */
 +#define T2 foo /* { dg-error 12:passing argument } */
 +#define D2 foo /* { dg-error 12:passing argument } */
 +#define L2 42 /* { dg-error 12:passing argument } */
 +
 +void
 +f (void)
 +{
 +  foo (__FILE__); /* { dg-error 8:passing argument } */
 +  foo (__BASE_FILE__); /* { dg-error 8:passing argument } */
 +  foo (__TIME__); /* { dg-error 8:passing argument } */
 +  foo (__DATE__); /* { dg-error 8:passing argument } */
 +  foo (__TIMESTAMP__); /* { dg-error 8:passing argument } */
 +  bar (1, __LINE__); /* { dg-error 11:passing argument } */
 +  bar (__COUNTER__, __COUNTER__); /* { dg-error 21:passing argument } */
 +
 +  foo (F); /* { dg-message 8:in expansion of } */
 +  foo (T); /* { dg-message 8:in expansion of } */
 +  foo (D); /* { dg-message 8:in expansion of } */
 +  bar (1, L); /* { dg-message 11:in expansion of } */
 +
 +  foo (F2); /* { dg-message 8:in expansion of } */
 +  foo (T2); /* { dg-message 8:in expansion of } */
 +  foo (D2); /* { dg-message 8:in expansion of } */
 +  bar (1, L2); /* { dg-message 11:in expansion of } */
 +}
 diff --git gcc/libcpp/macro.c gcc/libcpp/macro.c
 index 3b8fa40..556628b 100644
 --- gcc/libcpp/macro.c
 +++ gcc/libcpp/macro.c
 @@ -84,7 +84,7 @@ struct macro_arg_token_iter
  
  static int enter_macro_context (cpp_reader *, cpp_hashnode *,
   const cpp_token *, source_location);
 -static int builtin_macro (cpp_reader *, cpp_hashnode *);
 +static int builtin_macro (cpp_reader *, cpp_hashnode *, source_location);
  static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
const cpp_token **, unsigned int);
  static void push_extended_tokens_context (cpp_reader *, cpp_hashnode *,
 @@ -399,9 +399,10 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode 
 *node)
  /* Convert builtin macros like __FILE__ to a token and push it on the
 context stack.  Also handles _Pragma, for which a new token may not
 be created.  Returns 1 if it generates a new token context, 0 to
 -   return the token to the caller.  */
 +   return the token to the caller.  LOC is the location of the expansion
 +   point of the macro.  */
  static int
 -builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
 +builtin_macro (cpp_reader *pfile, cpp_hashnode *node, source_location loc)
  {
const uchar *buf;
size_t len;
 @@ -429,6 +430,8 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
/* Set pfile-cur_token as required by _cpp_lex_direct.  */
pfile-cur_token = _cpp_temp_token (pfile);
cpp_token *token = _cpp_lex_direct (pfile);
 +  /* We should point to the expansion point of the builtin macro.  */
 +  token-src_loc = loc;
if (pfile-context-tokens_kind == TOKENS_KIND_EXTENDED)
  {
/* We are tracking tokens resulting from macro expansion.
 @@ -1212,7 +1215,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode 
 *node,
  
pfile-about_to_expand_macro_p = false;
/* Handle built-in macros and the _Pragma operator.  */
 -  return builtin_macro (pfile, node);
 +  return builtin_macro (pfile, node, location);
  }
  
  /* De-allocate the memory used by BUFF which is an array of instances
 
   Marek

Marek


Re: [libcpp PATCH] Fix up location of builtin macros (PR c/61861)

2014-07-23 Thread Marek Polacek
[Though Dodji is on a vacation for next two weeks, so if anyone else
can review this patch, it would be appreciated.]

On Wed, Jul 23, 2014 at 05:39:51PM +0200, Marek Polacek wrote:
 CCing Dodji, please, can you have a look?  (I don't believe it is
 caused by yours
 https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01063.html though,
 this was wrong even in 4.8 and maybe earlier.)
 
 On Wed, Jul 23, 2014 at 03:15:53PM +0200, Marek Polacek wrote:
  Bultin macros like __FILE__, __DATE__, etc. had wrong locus - always
  column 1.  This patch fixes it by giving those macros location
  of the expansion point, i.e, the location, where builtin macro is used.
  It now also does the correct thing if we do e.g.
  #define F __FILE__.
  
  Bootstrapped/regtested on x86_64-linux, ok for trunk?
  
  2014-07-23  Marek Polacek  pola...@redhat.com
  
  PR c/61861
  * macro.c (builtin_macro): Add location parameter.  Set
  location of builtin macro to the expansion point.
  (enter_macro_context): Pass location to builtin_macro.
  
  * gcc.dg/pr61861.c: New test.
  
  diff --git gcc/gcc/testsuite/gcc.dg/pr61861.c 
  gcc/gcc/testsuite/gcc.dg/pr61861.c
  index e69de29..d902868 100644
  --- gcc/gcc/testsuite/gcc.dg/pr61861.c
  +++ gcc/gcc/testsuite/gcc.dg/pr61861.c
  @@ -0,0 +1,37 @@
  +/* { dg-do compile } */
  +/* { dg-prune-output expected } */
  +
  +extern void foo (int);
  +extern void bar (int, char *);
  +
  +#define F __FILE__ /* { dg-error 11:passing argument } */
  +#define T __TIME__ /* { dg-error 11:passing argument } */
  +#define D __DATE__ /* { dg-error 11:passing argument } */
  +#define L __LINE__ /* { dg-error 11:passing argument } */
  +
  +#define F2 foo /* { dg-error 12:passing argument } */
  +#define T2 foo /* { dg-error 12:passing argument } */
  +#define D2 foo /* { dg-error 12:passing argument } */
  +#define L2 42 /* { dg-error 12:passing argument } */
  +
  +void
  +f (void)
  +{
  +  foo (__FILE__); /* { dg-error 8:passing argument } */
  +  foo (__BASE_FILE__); /* { dg-error 8:passing argument } */
  +  foo (__TIME__); /* { dg-error 8:passing argument } */
  +  foo (__DATE__); /* { dg-error 8:passing argument } */
  +  foo (__TIMESTAMP__); /* { dg-error 8:passing argument } */
  +  bar (1, __LINE__); /* { dg-error 11:passing argument } */
  +  bar (__COUNTER__, __COUNTER__); /* { dg-error 21:passing argument } */
  +
  +  foo (F); /* { dg-message 8:in expansion of } */
  +  foo (T); /* { dg-message 8:in expansion of } */
  +  foo (D); /* { dg-message 8:in expansion of } */
  +  bar (1, L); /* { dg-message 11:in expansion of } */
  +
  +  foo (F2); /* { dg-message 8:in expansion of } */
  +  foo (T2); /* { dg-message 8:in expansion of } */
  +  foo (D2); /* { dg-message 8:in expansion of } */
  +  bar (1, L2); /* { dg-message 11:in expansion of } */
  +}
  diff --git gcc/libcpp/macro.c gcc/libcpp/macro.c
  index 3b8fa40..556628b 100644
  --- gcc/libcpp/macro.c
  +++ gcc/libcpp/macro.c
  @@ -84,7 +84,7 @@ struct macro_arg_token_iter
   
   static int enter_macro_context (cpp_reader *, cpp_hashnode *,
  const cpp_token *, source_location);
  -static int builtin_macro (cpp_reader *, cpp_hashnode *);
  +static int builtin_macro (cpp_reader *, cpp_hashnode *, source_location);
   static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
   const cpp_token **, unsigned int);
   static void push_extended_tokens_context (cpp_reader *, cpp_hashnode *,
  @@ -399,9 +399,10 @@ _cpp_builtin_macro_text (cpp_reader *pfile, 
  cpp_hashnode *node)
   /* Convert builtin macros like __FILE__ to a token and push it on the
  context stack.  Also handles _Pragma, for which a new token may not
  be created.  Returns 1 if it generates a new token context, 0 to
  -   return the token to the caller.  */
  +   return the token to the caller.  LOC is the location of the expansion
  +   point of the macro.  */
   static int
  -builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
  +builtin_macro (cpp_reader *pfile, cpp_hashnode *node, source_location loc)
   {
 const uchar *buf;
 size_t len;
  @@ -429,6 +430,8 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
 /* Set pfile-cur_token as required by _cpp_lex_direct.  */
 pfile-cur_token = _cpp_temp_token (pfile);
 cpp_token *token = _cpp_lex_direct (pfile);
  +  /* We should point to the expansion point of the builtin macro.  */
  +  token-src_loc = loc;
 if (pfile-context-tokens_kind == TOKENS_KIND_EXTENDED)
   {
 /* We are tracking tokens resulting from macro expansion.
  @@ -1212,7 +1215,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode 
  *node,
   
 pfile-about_to_expand_macro_p = false;
 /* Handle built-in macros and the _Pragma operator.  */
  -  return builtin_macro (pfile, node);
  +  return builtin_macro (pfile, node, location);
   }
   
   /* De-allocate the memory used by BUFF which is an array of instances

Re: [PATCH] Fix -imacros (PR c/57653)

2014-07-23 Thread Marek Polacek
On Thu, Jul 17, 2014 at 02:40:27AM -0600, Jeff Law wrote:
 I was really hoping someone could add tests from the old (2004?) thread
 between DJ and Per to ensure we weren't regressing any of those cases while
 fixing 57653.  In fact, I think I'd pre-approved with those tests added ;-)

All I could find was a test (mentioned twice by DJ) that was crashing with
-imacros and an empty .h and .c file.  I added it in the following.
I'm keeping the test I already had in the previous patch, because it
tests something that is fixed with this patch.

Bootstrapped/regtested on x86_64-linux, applying to trunk.

2014-07-23  Marek Polacek  pola...@redhat.com

PR c/57653
* c-opts.c (c_finish_options): If -imacros is in effect, return.

* c-c++-common/pr57653.c: New test.
* c-c++-common/pr57653.h: New file.
* c-c++-common/pr57653-2.c: New test.
* c-c++-common/pr57653-2.h: New file.

diff --git gcc/c-family/c-opts.c gcc/c-family/c-opts.c
index 968b703..3f8e6e6 100644
--- gcc/c-family/c-opts.c
+++ gcc/c-family/c-opts.c
@@ -1438,6 +1438,12 @@ c_finish_options (void)
 static void
 push_command_line_include (void)
 {
+  /* This can happen if disabled by -imacros for example.
+ Punt so that we don't set command-line as the filename for
+ the header.  */
+  if (include_cursor  deferred_count)
+return;
+
   if (!done_preinclude)
 {
   done_preinclude = true;
diff --git gcc/testsuite/c-c++-common/pr57653-2.c 
gcc/testsuite/c-c++-common/pr57653-2.c
index e69de29..086f6be 100644
--- gcc/testsuite/c-c++-common/pr57653-2.c
+++ gcc/testsuite/c-c++-common/pr57653-2.c
@@ -0,0 +1,4 @@
+/* { dg-do preprocess } */
+/* { dg-options -imacros ${srcdir}/c-c++-common/pr57653-2.h } */
+
+/* Empty.  */
diff --git gcc/testsuite/c-c++-common/pr57653-2.h 
gcc/testsuite/c-c++-common/pr57653-2.h
index e69de29..8b13789 100644
--- gcc/testsuite/c-c++-common/pr57653-2.h
+++ gcc/testsuite/c-c++-common/pr57653-2.h
@@ -0,0 +1 @@
+
diff --git gcc/testsuite/c-c++-common/pr57653-3.c 
gcc/testsuite/c-c++-common/pr57653-3.c
deleted file mode 100644
index e69de29..000
diff --git gcc/testsuite/c-c++-common/pr57653.c 
gcc/testsuite/c-c++-common/pr57653.c
index e69de29..620471e 100644
--- gcc/testsuite/c-c++-common/pr57653.c
+++ gcc/testsuite/c-c++-common/pr57653.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options -imacros ${srcdir}/c-c++-common/pr57653.h } */
+
+__attribute__((used)) static const char s[] = F;
+
+/* { dg-final { scan-assembler-not command-line } } */
diff --git gcc/testsuite/c-c++-common/pr57653.h 
gcc/testsuite/c-c++-common/pr57653.h
index e69de29..5a93388 100644
--- gcc/testsuite/c-c++-common/pr57653.h
+++ gcc/testsuite/c-c++-common/pr57653.h
@@ -0,0 +1 @@
+#define F __FILE__

Marek


[committed] Fix pr61077.c test

2014-07-26 Thread Marek Polacek
Marc reported that using .* regexp can cause spurious fails, so
fixed by using \[^\n\]* instead.

Tested on x86_64-linux, applying to trunk.

2014-07-26  Marek Polacek  pola...@redhat.com

* gcc.dg/pr61077.c: Use \[^\n\]* instead of .* in the regexp.

diff --git gcc/testsuite/gcc.dg/pr61077.c gcc/testsuite/gcc.dg/pr61077.c
index c0513f7..e29f23c 100644
--- gcc/testsuite/gcc.dg/pr61077.c
+++ gcc/testsuite/gcc.dg/pr61077.c
@@ -5,8 +5,8 @@
 _Atomic int
 main (_Atomic int argc, _Atomic char **argv)
 /* { dg-warning qualified return type return { target *-*-* } 6 } */
-/* { dg-warning qualified parameter type.*int parameter { target *-*-* } 6 
} */
-/* { dg-warning qualified parameter type.*char parameter { target *-*-* } 
6 } */
+/* { dg-warning qualified parameter type\[^\n\]*int parameter { target 
*-*-* } 6 } */
+/* { dg-warning qualified parameter type\[^\n\]*char parameter { target 
*-*-* } 6 } */
 {
   return 0;
 }

Marek


[PATCH] Fix ICE with -Wodr (PR middle-end/61913)

2014-07-27 Thread Marek Polacek
Wodr in common.opt was missing a Var, which means:
1) we ICE with -Wodr, since -Wodr isn't handled in opts.c;
2) -Wno-odr wouldn't work.
Thus fixed.  I'd think this doesn't need a testcase...

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-07-27  Marek Polacek  pola...@redhat.com

PR middle-end/61913
* common.opt (Wodr): Add Var.

diff --git gcc/common.opt gcc/common.opt
index a385ee0..3b04044 100644
--- gcc/common.opt
+++ gcc/common.opt
@@ -588,7 +588,7 @@ Wmissing-noreturn
 Common Alias(Wsuggest-attribute=noreturn)
 
 Wodr
-Common Warning
+Common Var(warn_odr_violations) Warning
 Warn about some C++ One Definition Rule violations during link time 
optimization
 
 Woverflow

Marek


Re: [PATCH] Fix ICE with -Wodr (PR middle-end/61913)

2014-07-28 Thread Marek Polacek
On Mon, Jul 28, 2014 at 10:23:36AM +0200, Jan Hubicka wrote:
  On Sun, Jul 27, 2014 at 1:02 PM, Marek Polacek pola...@redhat.com wrote:
   Wodr in common.opt was missing a Var, which means:
   1) we ICE with -Wodr, since -Wodr isn't handled in opts.c;
   2) -Wno-odr wouldn't work.
   Thus fixed.  I'd think this doesn't need a testcase...
  
   Bootstrapped/regtested on x86_64-linux, ok for trunk?
  
  Ok.  Does this mean we don't have a -Wodr testcase?
 
 We ICE at -Wno-odr (thanks for fixing it! I was somewhat puzzled by fact
 that I need to declare var that is not needed at all).
 
 But there is no -Wodr testcase as I do not know how to match warnings at LTO
 time. If there is a way, I will add one.

Heh, I was just trying to create some testcase for -Wodr, but failed.
pr60720_0.c testcase says:

/* ???  lto.exp does not allow to scan for
   :1:12: warning: type of 'x' does not match original declaration
extern int x[];
   ^
   :1:5: note: previously declared here
int x;
^  */

Bummer :(.

Marek


[DOC PATCH] Fix -Wno-odr entry

2014-07-28 Thread Marek Polacek
-Wodr entry was missing an @item.  Plus some corrections.

Ok for trunk?

2014-07-28  Marek Polacek  pola...@redhat.com

* doc/invoke.texi (-Wno-odr): Fix @item entry.  Tweak wording.

diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
index aaa5a68..7cebb9e 100644
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
@@ -4927,11 +4927,11 @@ attribute.
 @opindex Woverflow
 Do not warn about compile-time overflow in constant expressions.
 
-@opindex Wodr
+@item -Wno-odr
 @opindex Wno-odr
 @opindex Wodr
-Warn about One Definition Rule violations during link time optimization.
-Require @option{-flto-odr-type-merging} to be enabled. Enabled by default
+Warn about One Definition Rule violations during link-time optimization.
+Requires @option{-flto-odr-type-merging} to be enabled.  Enabled by default.
 
 @item -Wopenmp-simd
 @opindex Wopenm-simd

Marek


Re: Warn when returning the address of a temporary (middle-end) v2

2014-07-29 Thread Marek Polacek
On Tue, Jul 29, 2014 at 02:58:03PM -0400, David Malcolm wrote:
 This is possibly a dumb question, but what happens for a static local,
 rather than an auto local? e.g.
 
 int *f (void)
 {
 static int i;
 return i;
 }

This is fine.  The variable i has a static storage duration, so is allocated
when the program begins and is deallocated when the program ends.  There's only
one instance of the variable i. 

Marek


Re: [wwwdocs] Add gcc-5/{changes,criteria}.html

2014-07-30 Thread Marek Polacek
On Wed, Jul 30, 2014 at 08:31:35AM +0200, Tobias Burnus wrote:
 This patch adds the files gcc-5/{changes,criteria}.html - and populates the
 former with Fortran changes; the latter is a copy of the GCC 4.9 file.
 
 Is the patch OK?
 
Thanks for the patch!

  gcc-5/changes.html  |   60 +
  gcc-5/criteria.html |  144 
 
  index.html  |3 -
  3 files changed, 206 insertions(+), 1 deletion(-)
 
 Index: htdocs/index.html
 ===
 RCS file: /cvs/gcc/wwwdocs/htdocs/index.html,v
 retrieving revision 1.932
 diff -u -r1.932 index.html
 --- htdocs/index.html 16 Jul 2014 14:26:39 -  1.932
 +++ htdocs/index.html 30 Jul 2014 06:30:21 -
 @@ -161,7 +161,8 @@
  /dd
  
  dtspan class=versionDevelopment:/span
 -  GCC 4.10.0 (a href=gcc-4.9/criteria.htmlrelease criteria/a)
 +  GCC 4.10.0 (a href=gcc-5/criteria.htmlrelease criteria/a,

I guess s/GCC 4.10.0/GCC 5.0/.

 +  a href=gcc-5/changes.htmlchanges/a)
  /dtdd
Status:
!--GCC 4.10 status below--

Here as well.

Marek


Re: [C PATCH] warn for empty struct -Wc++-compat

2014-11-10 Thread Marek Polacek
On Tue, Nov 11, 2014 at 03:24:48AM +0530, Prathamesh Kulkarni wrote:
 * gcc/c/c-decl.c
   (warn_cxx_compat_finish_struct): Add new parameter of type location_t.
 Warn for empty struct.
   (finish_struct): Pass loc to warn_cxx_compat_finish_struct.
 
 * gcc/testsuite/gcc.dg/Wcxx-compat-22.c: New test-case.

No gcc/c/ and gcc/testsuite/ prefixes.

 Index: gcc/c/c-decl.c
 ===
 --- gcc/c/c-decl.c(revision 217287)
 +++ gcc/c/c-decl.c(working copy)
 @@ -7506,12 +7506,15 @@
  /* Finish up struct info used by -Wc++-compat.  */
  
  static void
 -warn_cxx_compat_finish_struct (tree fieldlist)
 +warn_cxx_compat_finish_struct (tree fieldlist, location_t record_loc)
  {
unsigned int ix;
tree x;
struct c_binding *b;
  
 +  if (fieldlist == NULL_TREE)
 +warning_at (record_loc, OPT_Wc___compat, empty struct has size 0 in C, 
 1 in C++);

This line is too long.

The patch doesn't seem to handle empty unions.

Marek


Re: [C PATCH] warn for empty struct -Wc++-compat

2014-11-11 Thread Marek Polacek
On Tue, Nov 11, 2014 at 04:45:46AM +0530, Prathamesh Kulkarni wrote:
 Index: gcc/c/c-decl.c
 ===
 --- gcc/c/c-decl.c(revision 217287)
 +++ gcc/c/c-decl.c(working copy)
 @@ -606,6 +606,8 @@
/* If warn_cxx_compat, a list of typedef names used when defining
   fields in this struct.  */
vectree typedefs_seen;
 +  /* code to distinguish between struct/union */
 +  enum tree_code code;
  
I don't think this is desirable, you might just pass T down from
finish_struct to warn_cxx_compat_finish_struct.

 @@ -7506,12 +7509,19 @@
  /* Finish up struct info used by -Wc++-compat.  */
  
  static void
 -warn_cxx_compat_finish_struct (tree fieldlist)
 +warn_cxx_compat_finish_struct (tree fieldlist, location_t record_loc)
  {
unsigned int ix;
tree x;
struct c_binding *b;
  
 +  if (fieldlist == NULL_TREE)
 +{
 +  warning_at (record_loc, OPT_Wc___compat,
 +   empty %s has size 0 in C, 1 in C++,
 +   (struct_parse_info-code == RECORD_TYPE) ? struct : 
 union);
 +}
 +

I think this won't work well wrt translations, so you need to have
an if here.  See the pedwarns at the beginning of finish_struct.

 Index: gcc/testsuite/gcc.dg/Wcxx-compat-22.c
 ===
 --- gcc/testsuite/gcc.dg/Wcxx-compat-22.c (revision 0)
 +++ gcc/testsuite/gcc.dg/Wcxx-compat-22.c (working copy)
 @@ -0,0 +1,4 @@
 +/* { dg-do compile } */
 +/* { dg-options -Wc++-compat } */
 +struct A {}; /* { dg-warning empty struct has size 0 in C } */
 +union B {}; /* { dg-warning empty union has size 0 in C } */

Please also test an empty struct in a struct.

Thanks,

Marek


Re: [C PATCH] warn for empty struct -Wc++-compat

2014-11-11 Thread Marek Polacek
On Tue, Nov 11, 2014 at 12:13:32PM +0100, Marc Glisse wrote:
 On Tue, 11 Nov 2014, Marek Polacek wrote:
 
 @@ -7506,12 +7509,19 @@
  /* Finish up struct info used by -Wc++-compat.  */
 
  static void
 -warn_cxx_compat_finish_struct (tree fieldlist)
 +warn_cxx_compat_finish_struct (tree fieldlist, location_t record_loc)
  {
unsigned int ix;
tree x;
struct c_binding *b;
 
 +  if (fieldlist == NULL_TREE)
 +{
 +  warning_at (record_loc, OPT_Wc___compat,
 + empty %s has size 0 in C, 1 in C++,
 + (struct_parse_info-code == RECORD_TYPE) ? struct : 
 union);
 +}
 +
 
 I think this won't work well wrt translations, so you need to have
 an if here.  See the pedwarns at the beginning of finish_struct.
 
 Do keywords like struct/union really require translation?

C keywords don't require translation, but you always need to have
complete sentences in diagnostics so I better pointed it out.  Joseph
would know better than me though.

Marek


[PATCH] Peg down -(-A) - A transformation

2014-11-11 Thread Marek Polacek
While match.pd has been changed to not transform -(-A) to A
when the overflow does not wrap or the signed integer ovreflow
checking is enabled, fold_negate_expr still happily does such
a transformation.  That's bad because then we can't detect
an overflow, as on the following testcase.  But I allowed this
transformation for constants, because VRP seems to rely on that
(abs_extent_range calls fold_unary).

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-11-11  Marek Polacek  pola...@redhat.com

* fold-const.c (fold_unary_loc): Don't call fold_negate_expr
when doing signed integer sanitization or when the type overflow
wraps.

* c-c++-common/ubsan/overflow-negate-3.c: New test.

diff --git gcc/fold-const.c gcc/fold-const.c
index f3562ff..33311fb 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -7862,9 +7862,15 @@ fold_unary_loc (location_t loc, enum tree_code code, 
tree type, tree op0)
   return fold_view_convert_expr (type, op0);
 
 case NEGATE_EXPR:
-  tem = fold_negate_expr (loc, arg0);
-  if (tem)
-   return fold_convert_loc (loc, type, tem);
+  if (TREE_CODE (arg0) == INTEGER_CST
+ || TREE_CODE (arg0) == REAL_CST
+ || TYPE_OVERFLOW_WRAPS (type)
+ || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
+   {
+ tem = fold_negate_expr (loc, arg0);
+ if (tem)
+   return fold_convert_loc (loc, type, tem);
+   }
   return NULL_TREE;
 
 case ABS_EXPR:
diff --git gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c 
gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
index e69de29..cf4f9bc 100644
--- gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
+++ gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options -fsanitize=signed-integer-overflow } */
+
+#define INT_MIN (-__INT_MAX__ - 1)
+
+int
+main ()
+{
+  volatile int x = INT_MIN;
+  int y = x;
+  y = -(-y);
+  x = y;
+  return 0;
+}
+
+/* { dg-output negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */

Marek


Re: [C PATCH] warn for empty struct -Wc++-compat

2014-11-11 Thread Marek Polacek
On Tue, Nov 11, 2014 at 11:27:21PM +0530, Prathamesh Kulkarni wrote:
 I tried the following:
 struct A { struct B {}; int x; } /* { dg-warning empty struct has
 size 0 in C } */
/* { dg-bogus delcaration
 does not declare anything } */
 but it fails in excess errors.
 How do I resolve this ?
 
Try something like
/* { dg-warning empty struct has size 0 in C|declaration does not declare 
anything } */

 Index: gcc/c/c-decl.c
 ===
 --- gcc/c/c-decl.c(revision 217287)
 +++ gcc/c/c-decl.c(working copy)
 @@ -7506,12 +7506,28 @@
  /* Finish up struct info used by -Wc++-compat.  */
  
  static void
 -warn_cxx_compat_finish_struct (tree fieldlist)
 +warn_cxx_compat_finish_struct (tree fieldlist, enum tree_code code, 
 location_t record_loc)

This line is too long, please indent the last argument properly on
next line.

unsigned int ix;
tree x;
struct c_binding *b;
  
 +  if (fieldlist == NULL_TREE)
 +{
 +  if (code == RECORD_TYPE)
 + {
 +   warning_at (record_loc, OPT_Wc___compat,
 +   empty struct has size 0 in C, size 1 in C++);
 + }
 +  else if (code == UNION_TYPE)
 + {
 +   warning_at (record_loc, OPT_Wc___compat,
 +   empty union has size 0 in C, size 1 in C++);
 + }

Drop the { } around warning_at's.

 +  else
 + gcc_unreachable ();
 +}
 +

I don't think this is needed.

Thanks,

Marek


Re: [C PATCH] warn for empty struct -Wc++-compat

2014-11-11 Thread Marek Polacek
On Wed, Nov 12, 2014 at 02:08:03AM +0530, Prathamesh Kulkarni wrote:
 Is this version okay ?

I have no further comments on this patch, so deferring to Joseph.

Thanks,

Marek


Re: [PATCH] Peg down -(-A) - A transformation

2014-11-12 Thread Marek Polacek
On Tue, Nov 11, 2014 at 07:45:40PM +0100, Richard Biener wrote:
 On November 11, 2014 6:49:34 PM CET, Jakub Jelinek ja...@redhat.com wrote:
 On Tue, Nov 11, 2014 at 06:40:25PM +0100, Marek Polacek wrote:
  --- gcc/fold-const.c
  +++ gcc/fold-const.c
  @@ -7862,9 +7862,15 @@ fold_unary_loc (location_t loc, enum tree_code
 code, tree type, tree op0)
 return fold_view_convert_expr (type, op0);
   
   case NEGATE_EXPR:
  -  tem = fold_negate_expr (loc, arg0);
  -  if (tem)
  -  return fold_convert_loc (loc, type, tem);
  +  if (TREE_CODE (arg0) == INTEGER_CST
  +|| TREE_CODE (arg0) == REAL_CST
  +|| TYPE_OVERFLOW_WRAPS (type)
  +|| (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
  +  {
  +tem = fold_negate_expr (loc, arg0);
  +if (tem)
  +  return fold_convert_loc (loc, type, tem);
  +  }
 
 a) if arg0 is INTEGER_CST, but e.g. INT_MIN, should we
really fold it for -fsanitize=signed-integer-overflow
(I'd say in that case we should fold only if it is not
the minimum value)

Ok.  We don't sanitize constant folded expressions (e.g. INT_MAX +
1), but this can be easily done.

 Right. I think you should fix VRP instead.
 
With the following no VRP tweaks are needed (I hope).

 b) if the argument is not INTEGRAL_TYPE_P (type), shouldn't
we fold no matter what flag_sanitize says?  Is the REAL_CST
case needed in that case?
 
 Yes and no I guess.

Done.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-11-12  Marek Polacek  pola...@redhat.com

* fold-const.c (fold_unary_loc): Don't call fold_negate_expr
when the result is undefined.

* c-c++-common/ubsan/overflow-negate-3.c: New test.

diff --git gcc/fold-const.c gcc/fold-const.c
index 756f469..3688f5a 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -7854,9 +7854,16 @@ fold_unary_loc (location_t loc, enum tree_code code, 
tree type, tree op0)
   return fold_view_convert_expr (type, op0);
 
 case NEGATE_EXPR:
-  tem = fold_negate_expr (loc, arg0);
-  if (tem)
-   return fold_convert_loc (loc, type, tem);
+  if (!INTEGRAL_TYPE_P (type)
+  || (TREE_CODE (arg0) == INTEGER_CST
+  !tree_int_cst_equal (arg0, TYPE_MIN_VALUE (type)))
+ || TYPE_OVERFLOW_WRAPS (type)
+ || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
+   {
+ tem = fold_negate_expr (loc, arg0);
+ if (tem)
+   return fold_convert_loc (loc, type, tem);
+   }
   return NULL_TREE;
 
 case ABS_EXPR:
diff --git gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c 
gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
index e69de29..e6db394 100644
--- gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
+++ gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options -fsanitize=signed-integer-overflow } */
+
+#define INT_MIN (-__INT_MAX__ - 1)
+
+int
+main ()
+{
+  int x = INT_MIN;
+  int y;
+  asm ( : +g (x));
+  y = -(-x);
+  asm ( : +g (y));
+  y = -(-INT_MIN);
+  asm ( : +g (y));
+}
+
+/* { dg-output negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */

Marek


[PATCH] Don't perform A - (-B) - A + B when sanitizing

2014-11-12 Thread Marek Polacek
In the following testcase generic_simplify folded A - (-B) - A + B,
which means we didn't detect an overflow.  So I've tweaked match.pd.

But fold-const.c still can do such a transformation as well, so I had
to tweak it there as well in the same way.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-11-12  Marek Polacek  pola...@redhat.com

* match.pd (A - (-B) - A + B): Check for TYPE_OVERFLOW_WRAPS
and SANITIZE_SI_OVERFLOW.
* fold-const.c (fold_binary_loc): Likewise.

* c-c++-common/ubsan/overflow-sub-4.c: New test.
* c-c++-common/ubsan/overflow-sub-2.c: Adjust dg-output.
* c-c++-common/ubsan/overflow-int128.c: Likewise.

diff --git gcc/fold-const.c gcc/fold-const.c
index 756f469..504e1b6 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -10544,6 +10544,8 @@ fold_binary_loc (location_t loc,
 
   /* A - B - A + (-B) if B is easily negatable.  */
   if (negate_expr_p (arg1)
+  (TYPE_OVERFLOW_WRAPS (type)
+ || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
   ((FLOAT_TYPE_P (type)
/* Avoid this transformation if B is a positive REAL_CST.  */
(TREE_CODE (arg1) != REAL_CST
diff --git gcc/match.pd gcc/match.pd
index 29b5ab2..5a485f3 100644
--- gcc/match.pd
+++ gcc/match.pd
@@ -291,7 +291,9 @@ along with GCC; see the file COPYING3.  If not see
  (simplify
   (minus (convert1? @0) (convert2? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
-tree_nop_conversion_p (type, TREE_TYPE (@1)))
+tree_nop_conversion_p (type, TREE_TYPE (@1))
+(TYPE_OVERFLOW_WRAPS (type)
+  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
(plus (convert @0) (convert @1
  /* -(-A) - A */
  (simplify
diff --git gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c 
gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c
index daf6a54..88c4762 100644
--- gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c
+++ gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c
@@ -43,12 +43,12 @@ main (void)
 }
 
 /* { dg-output signed integer overflow: -2147483648 - 1 cannot be represented 
in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be 
represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -2147483548 \\+ -1024 cannot 
be represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be 
represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -2147482648 \\+ -1048576 
cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -2147483648 - 1 cannot be 
represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -2147483548 - 1024 cannot be 
represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -2147483648 - 1 cannot be 
represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -2147482648 - 1048576 cannot 
be represented in type 'int'\[^\n\r]*(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* - 1 cannot be 
represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be 
represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1024 cannot 
be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be 
represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1048576 
cannot be represented in type 'long int'\[^\n\r]* } */
+/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* - 1 cannot be 
represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* - 1024 cannot be 
represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* - 1 cannot be 
represented in type 'long int'\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow: -\[^\n\r]* - 1048576 cannot 
be represented in type 'long int'\[^\n\r]* } */
diff --git gcc/testsuite/c-c++-common/ubsan/overflow-int128.c 
gcc/testsuite/c-c++-common/ubsan/overflow-int128.c
index 125d6bf..4384d7c 100644
--- gcc/testsuite/c-c++-common/ubsan/overflow-int128.c
+++ gcc/testsuite/c-c++-common/ubsan/overflow-int128.c
@@ -41,7 +41,7 @@ main (void)
 /* { dg-output \[^\n\r]*signed integer overflow: 
0x7f9b \\+ 1024 cannot be represented in type 
'__int128'(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*signed integer overflow: -1 \\+ 
0x8000 cannot be represented

Re: [PATCH][dejagnu] truncate absolute file path into relative for dg-output

2014-11-12 Thread Marek Polacek
On Tue, Nov 11, 2014 at 04:51:38PM +, Jiong Wang wrote:
 currently, only sanitizer tess (asan/tsan/ubsan) and a couple of fortran test 
 will invoke dg-output.
 
 pass x86-64 c/c++ regression.
 pass aarch64-none-linux-gnu c/c++ regression.

This patch broke a few tests in ubsan.exp.  The reason is that...

 diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
 index a0d1e7d..8168a77 100644
 --- a/gcc/testsuite/lib/gcc-dg.exp
 +++ b/gcc/testsuite/lib/gcc-dg.exp
 @@ -281,6 +281,8 @@ if { [info procs ${tool}_load] != [list] \
   }
   set result [list $status [lindex $result 1]]
   }
 +
 + set result [list [lindex $result 0] [prune_gcc_output [lindex $result 
 1]]]

... prune_gcc_output prunes more than just absolute file paths, it
prunes even the note:  messages.  And several ubsan tests have
/* { dg-output \[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r) } */
but since the note's are already gone, the test fails.

The following patch moves the path prunning code into a separate
procedure and fixes the failures.

Ok for trunk?

2014-11-12  Marek Polacek  pola...@redhat.com

* lib/gcc-dg.exp (${tool}_load): Call prune_file_path instead
of prune_gcc_output.
* lib/prune.exp (prune_file_path): New procedure.

diff --git gcc/testsuite/lib/gcc-dg.exp gcc/testsuite/lib/gcc-dg.exp
index 8168a77..6df8ae1 100644
--- gcc/testsuite/lib/gcc-dg.exp
+++ gcc/testsuite/lib/gcc-dg.exp
@@ -282,7 +282,7 @@ if { [info procs ${tool}_load] != [list] \
set result [list $status [lindex $result 1]]
}
 
-   set result [list [lindex $result 0] [prune_gcc_output [lindex $result 
1]]]
+   set result [list [lindex $result 0] [prune_file_path [lindex $result 
1]]]
return $result
 }
 }
diff --git gcc/testsuite/lib/prune.exp gcc/testsuite/lib/prune.exp
index 65028c2..df0e053 100644
--- gcc/testsuite/lib/prune.exp
+++ gcc/testsuite/lib/prune.exp
@@ -68,13 +68,19 @@ proc prune_gcc_output { text } {
 # Ignore harmless warnings from Xcode 4.0.
 regsub -all (^|\n)\[^\n\]*ld: warning: could not create compact unwind 
for\[^\n\]* $text  text
 
+#send_user After:$text\n
+
+return $text
+}
+
+proc prune_file_path { text } {
+global srcdir
+
 # Truncate absolute file path into relative path.
 set topdir [file dirname [file dirname [file dirname $srcdir]]]
 regsub -all $srcdir\/ $text  text
 regsub -all $topdir\/ $text  text
 
-#send_user After:$text\n
-
 return $text
 }
 
Marek


Re: [PATCH] Don't perform A - (-B) - A + B when sanitizing

2014-11-12 Thread Marek Polacek
On Wed, Nov 12, 2014 at 10:49:38AM +0100, Richard Biener wrote:
 TYPE_OVERFLOW_WRAPS returns nonsense for !integral types and thus
 this check likely restricts the transform to non-floats for example.
 The macro documentation states given an integral type ... thus
 it should be sth like
 
   (!INTEGRAL_TYPE_P (type)
  || TYPE_OVERFLOW_WRAPS (type)
  || (flag_sanitize ...
 
Ah, I can see now.

 and the TYPE_OVERFLOW_* macros should probably be guarded with
 tree checking against use on non-integral types (you might want
 to do that as a followup).
 
Sure.

 ((FLOAT_TYPE_P (type)
  /* Avoid this transformation if B is a positive REAL_CST.  
  */
  (TREE_CODE (arg1) != REAL_CST
  diff --git gcc/match.pd gcc/match.pd
  index 29b5ab2..5a485f3 100644
  --- gcc/match.pd
  +++ gcc/match.pd
  @@ -291,7 +291,9 @@ along with GCC; see the file COPYING3.  If not see
(simplify
 (minus (convert1? @0) (convert2? (negate @1)))
 (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
  -tree_nop_conversion_p (type, TREE_TYPE (@1)))
  +tree_nop_conversion_p (type, TREE_TYPE (@1))
  +(TYPE_OVERFLOW_WRAPS (type)
  +  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
 
 This has the same issue with unnecessarily restricting FLOAT types, so
 can you fix that here and in the two other patterns already guarded
 with flag_sanitize?
 
Done.  Note that one pattern had SANITIZE_SI_OVERFLOW check, but not
the TYPE_OVERFLOW_WRAPS check.  Which leads me to thinking that we
might want a new predicate for

 (!INTEGRAL_TYPE_P (type)
  || TYPE_OVERFLOW_WRAPS (type)
  || (flag_sanitize ...))

Do you agree?  If so, I'll do that as another followup.

 Ok with that changes.

Thanks, I'll install the following then.

2014-11-12  Marek Polacek  pola...@redhat.com

* fold-const.c (fold_binary_loc): Don't fold if the result
is undefined.
* match.pd (A + (-B) - A - B, A - (-B) - A + B,
-(-A) - A): Likewise.

* c-c++-common/ubsan/overflow-sub-4.c: New test.
* c-c++-common/ubsan/overflow-sub-2.c: Adjust dg-output.
* c-c++-common/ubsan/overflow-int128.c: Likewise.

diff --git gcc/fold-const.c gcc/fold-const.c
index 756f469..85fada3 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -10544,6 +10544,9 @@ fold_binary_loc (location_t loc,
 
   /* A - B - A + (-B) if B is easily negatable.  */
   if (negate_expr_p (arg1)
+  (!INTEGRAL_TYPE_P (type)
+ || TYPE_OVERFLOW_WRAPS (type)
+ || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
   ((FLOAT_TYPE_P (type)
/* Avoid this transformation if B is a positive REAL_CST.  */
(TREE_CODE (arg1) != REAL_CST
diff --git gcc/match.pd gcc/match.pd
index 39abe25..4e5e6c5 100644
--- gcc/match.pd
+++ gcc/match.pd
@@ -285,19 +285,25 @@ along with GCC; see the file COPYING3.  If not see
   /* Apply STRIP_NOPS on @0 and the negate.  */
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
 tree_nop_conversion_p (type, TREE_TYPE (@1))
-(flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
+(!INTEGRAL_TYPE_P (type)
+  || TYPE_OVERFLOW_WRAPS (type)
+  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
(minus (convert @0) (convert @1
  /* A - (-B) - A + B */
  (simplify
   (minus (convert1? @0) (convert2? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
-tree_nop_conversion_p (type, TREE_TYPE (@1)))
+tree_nop_conversion_p (type, TREE_TYPE (@1))
+(!INTEGRAL_TYPE_P (type)
+  || TYPE_OVERFLOW_WRAPS (type)
+  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
(plus (convert @0) (convert @1
  /* -(-A) - A */
  (simplify
   (negate (convert? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
-(TYPE_OVERFLOW_WRAPS (type)
+(!INTEGRAL_TYPE_P (type)
+  || TYPE_OVERFLOW_WRAPS (type)
   || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
(convert @1)))
 
diff --git gcc/testsuite/c-c++-common/ubsan/overflow-int128.c 
gcc/testsuite/c-c++-common/ubsan/overflow-int128.c
index 125d6bf..4384d7c 100644
--- gcc/testsuite/c-c++-common/ubsan/overflow-int128.c
+++ gcc/testsuite/c-c++-common/ubsan/overflow-int128.c
@@ -41,7 +41,7 @@ main (void)
 /* { dg-output \[^\n\r]*signed integer overflow: 
0x7f9b \\+ 1024 cannot be represented in type 
'__int128'(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*signed integer overflow: -1 \\+ 
0x8000 cannot be represented in type 
'__int128'(\n|\r\n|\r) } */
 /* { dg-output \[^\n\r]*signed integer overflow: 
0x8000 \\+ -1 cannot be represented in type 
'__int128'(\n|\r\n|\r) } */
-/* { dg-output \[^\n\r]*signed integer overflow: 
0x8000 \\+ -1 cannot be represented in type 
'__int128'(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*signed integer overflow

Re: [PR c/52952] More precise locations within format strings

2014-11-12 Thread Marek Polacek
On Wed, Nov 12, 2014 at 03:35:06PM +0100, Manuel López-Ibáñez wrote:
  ../../libcpp/line-map.c:667:65: error: suggest braces around empty body in 
  an 'if' statement [-Werror=empty-body]
 
 I just (r217418) bootstrapped this code and it did not produce this
 error (or warning).  Could you give more details?

Have you tried the bootstrap without checking enabled?

Marek


Re: [PATCH] Don't perform A - (-B) - A + B when sanitizing

2014-11-12 Thread Marek Polacek
On Wed, Nov 12, 2014 at 03:22:41PM +0100, Richard Biener wrote:
 TYPE_OVERFLOW_SANITIZES?

Can I call it sanitize_fold_p and put it as a static inline fn
into tree.h?

Marek


[PATCH] Introduce TYPE_OVERFLOW_SANITIZED

2014-11-12 Thread Marek Polacek
This patch introduces TYPE_OVERFLOW_SANITIZED predicate to
consolidate a common check.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-11-12  Marek Polacek  pola...@redhat.com

* tree.h (TYPE_OVERFLOW_SANITIZED): Define.
* fold-const.c (fold_binary_loc): Use it.
* match.pd: Likewise.

diff --git gcc/fold-const.c gcc/fold-const.c
index 4321b1e..1fb48cc 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -10538,9 +10538,7 @@ fold_binary_loc (location_t loc,
 
   /* A - B - A + (-B) if B is easily negatable.  */
   if (negate_expr_p (arg1)
-  (!INTEGRAL_TYPE_P (type)
- || TYPE_OVERFLOW_WRAPS (type)
- || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
+  TYPE_OVERFLOW_SANITIZED (type)
   ((FLOAT_TYPE_P (type)
/* Avoid this transformation if B is a positive REAL_CST.  */
(TREE_CODE (arg1) != REAL_CST
diff --git gcc/match.pd gcc/match.pd
index d94a8f5..28298f4 100644
--- gcc/match.pd
+++ gcc/match.pd
@@ -285,26 +285,20 @@ along with GCC; see the file COPYING3.  If not see
   /* Apply STRIP_NOPS on @0 and the negate.  */
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
 tree_nop_conversion_p (type, TREE_TYPE (@1))
-(!INTEGRAL_TYPE_P (type)
-  || TYPE_OVERFLOW_WRAPS (type)
-  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+TYPE_OVERFLOW_SANITIZED (type))
(minus (convert @0) (convert @1
  /* A - (-B) - A + B */
  (simplify
   (minus (convert1? @0) (convert2? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
 tree_nop_conversion_p (type, TREE_TYPE (@1))
-(!INTEGRAL_TYPE_P (type)
-  || TYPE_OVERFLOW_WRAPS (type)
-  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+TYPE_OVERFLOW_SANITIZED (type))
(plus (convert @0) (convert @1
  /* -(-A) - A */
  (simplify
   (negate (convert? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
-(!INTEGRAL_TYPE_P (type)
-  || TYPE_OVERFLOW_WRAPS (type)
-  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+TYPE_OVERFLOW_SANITIZED (type))
(convert @1)))
 
  /* We can't reassociate floating-point or fixed-point plus or minus
diff --git gcc/tree.h gcc/tree.h
index 0577d51..dc12bc6 100644
--- gcc/tree.h
+++ gcc/tree.h
@@ -789,6 +789,13 @@ extern void omp_clause_range_check_failed (const_tree, 
const char *, int,
 #define TYPE_OVERFLOW_TRAPS(TYPE) \
   (!TYPE_UNSIGNED (TYPE)  flag_trapv)
 
+/* True if it is possible to perform folding on TYPE wrt signed
+   overflow.  */
+#define TYPE_OVERFLOW_SANITIZED(TYPE)  \
+  (!INTEGRAL_TYPE_P (TYPE) \
+   || TYPE_OVERFLOW_WRAPS (TYPE)   \
+   || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
+
 /* True if pointer types have undefined overflow.  */
 #define POINTER_TYPE_OVERFLOW_UNDEFINED (flag_strict_overflow)
 

Marek


Re: [PATCH 2/5] remove the remaining uses of if_marked

2014-11-12 Thread Marek Polacek
On Thu, Nov 13, 2014 at 12:55:40AM -0500, tsaund...@mozilla.com wrote:
 From: Trevor Saunders tsaund...@mozilla.com
 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
 index b70c56c..227509a 100644
 --- a/gcc/config/i386/i386.c
 +++ b/gcc/config/i386/i386.c
 @@ -14032,14 +14032,34 @@ legitimize_tls_address (rtx x, enum tls_model 
 model, bool for_mov)
 to symbol DECL if BEIMPORT is true.  Otherwise create or return the
 unique refptr-DECL symbol corresponding to symbol DECL.  */
  
 -static GTY((if_marked (tree_map_marked_p), param_is (struct tree_map)))
 -  htab_t dllimport_map;
 +struct dllimport_hasher : ggc_cache_hashertree_map *
 +{
 +  static inline hashval_t hash (tree_map *m) { return m-hash; }
 +  static inline bool
 +  equal (tree_map *a, tree_map *b)
 +  {
 +return a-base.from == b-base.from;
 +  }
 +
 +  static void
 +handle_cache_entry (tree_map *m)
 +  {
 + extern void gt_ggc_mx (tree_map *);
 + if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
 +   return;
 + else if (ggc_marked_p (m-base.from))
 +   gt_ggc_mx (m);
 + else
 +   m = static_casttree_map * (HTAB_DELETED_ENTRY);
 +  }
 +};
 +

Note that the formatting is a bit off here (and in ubsan.c too).

Marek


Re: [PATCH] Introduce TYPE_OVERFLOW_SANITIZED

2014-11-13 Thread Marek Polacek
On Thu, Nov 13, 2014 at 09:45:50AM +0100, Richard Biener wrote:
 Hmm, I'd have expected to test !TYPE_OVERFLOW_SANITIZED (),
 that is, have the predicate inverted.  At least that's how
 I understand the name - an overflow is to be preserved for
 sanitization.
 
I guess that macro name is a little bit baffling ;).

 So - can you invert the predicates (and uses)?  In the
 sanitizer you then can guard instrumentations with
 TYPE_OVERFLOW_SANITIZED.
 
Done.

 Ok with that change.

Thanks, this is the inverted version:

2014-11-13  Marek Polacek  pola...@redhat.com

* tree.h (TYPE_OVERFLOW_SANITIZED): Define.
* fold-const.c (fold_binary_loc): Use it.
* match.pd: Likewise.

diff --git gcc/fold-const.c gcc/fold-const.c
index 4321b1e..8c19c1f 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -10538,9 +10538,7 @@ fold_binary_loc (location_t loc,
 
   /* A - B - A + (-B) if B is easily negatable.  */
   if (negate_expr_p (arg1)
-  (!INTEGRAL_TYPE_P (type)
- || TYPE_OVERFLOW_WRAPS (type)
- || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
+  !TYPE_OVERFLOW_SANITIZED (type)
   ((FLOAT_TYPE_P (type)
/* Avoid this transformation if B is a positive REAL_CST.  */
(TREE_CODE (arg1) != REAL_CST
diff --git gcc/match.pd gcc/match.pd
index 1d7b153..9a1ce93 100644
--- gcc/match.pd
+++ gcc/match.pd
@@ -285,26 +285,20 @@ along with GCC; see the file COPYING3.  If not see
   /* Apply STRIP_NOPS on @0 and the negate.  */
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
 tree_nop_conversion_p (type, TREE_TYPE (@1))
-(!INTEGRAL_TYPE_P (type)
-  || TYPE_OVERFLOW_WRAPS (type)
-  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+!TYPE_OVERFLOW_SANITIZED (type))
(minus (convert @0) (convert @1
  /* A - (-B) - A + B */
  (simplify
   (minus (convert1? @0) (convert2? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
 tree_nop_conversion_p (type, TREE_TYPE (@1))
-(!INTEGRAL_TYPE_P (type)
-  || TYPE_OVERFLOW_WRAPS (type)
-  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+!TYPE_OVERFLOW_SANITIZED (type))
(plus (convert @0) (convert @1
  /* -(-A) - A */
  (simplify
   (negate (convert? (negate @1)))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
-(!INTEGRAL_TYPE_P (type)
-  || TYPE_OVERFLOW_WRAPS (type)
-  || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+!TYPE_OVERFLOW_SANITIZED (type))
(convert @1)))
 
  /* We can't reassociate floating-point or fixed-point plus or minus
diff --git gcc/tree.h gcc/tree.h
index 0577d51..108b52d 100644
--- gcc/tree.h
+++ gcc/tree.h
@@ -789,6 +789,12 @@ extern void omp_clause_range_check_failed (const_tree, 
const char *, int,
 #define TYPE_OVERFLOW_TRAPS(TYPE) \
   (!TYPE_UNSIGNED (TYPE)  flag_trapv)
 
+/* True if an overflow is to be preserved for sanitization.  */
+#define TYPE_OVERFLOW_SANITIZED(TYPE)  \
+  (INTEGRAL_TYPE_P (TYPE)  \
+!TYPE_OVERFLOW_WRAPS (TYPE)  \
+(flag_sanitize  SANITIZE_SI_OVERFLOW))
+
 /* True if pointer types have undefined overflow.  */
 #define POINTER_TYPE_OVERFLOW_UNDEFINED (flag_strict_overflow)
 

Marek


Re: [PATCH, libgfortran] PR 60324 Unbounded stack allocations in libgfortran

2014-11-13 Thread Marek Polacek
On Thu, Nov 13, 2014 at 02:05:52PM +0200, Janne Blomqvist wrote:
 Thanks for the quick review, committed as r217480.

This broke bootstrap because of implicit declaration of free.

The following (untested) should fix it, ok for trunk?

2014-11-13  Marek Polacek  pola...@redhat.com

* intrinsics/access.c: Include stdlib.h.
* intrinsics/chdir.c: Likewise.
* intrinsics/chmod.c: Likewise.

diff --git gcc/intrinsics/access.c gcc/intrinsics/access.c
index 65a0a10..0c18da0 100644
--- gcc/intrinsics/access.c
+++ gcc/intrinsics/access.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 #ifdef HAVE_UNISTD_H
diff --git gcc/intrinsics/chdir.c gcc/intrinsics/chdir.c
index 87419a8..193e482 100644
--- gcc/intrinsics/chdir.c
+++ gcc/intrinsics/chdir.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 #ifdef HAVE_UNISTD_H
diff --git gcc/intrinsics/chmod.c gcc/intrinsics/chmod.c
index c42fa8c..bdcb676 100644
--- gcc/intrinsics/chmod.c
+++ gcc/intrinsics/chmod.c
@@ -28,6 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #if defined(HAVE_SYS_STAT_H)
 
 #include string.h/* For memcpy. */
+#include stdlib.h/* For free.  */
 #include sys/stat.h  /* For stat, chmod and umask.  */
 
 
Marek


Re: [PATCH, libgfortran] PR 60324 Unbounded stack allocations in libgfortran

2014-11-13 Thread Marek Polacek
On Thu, Nov 13, 2014 at 04:59:09PM +0100, Jakub Jelinek wrote:
 On Thu, Nov 13, 2014 at 04:57:08PM +0100, Marek Polacek wrote:
  On Thu, Nov 13, 2014 at 02:05:52PM +0200, Janne Blomqvist wrote:
   Thanks for the quick review, committed as r217480.
  
  This broke bootstrap because of implicit declaration of free.
  
  The following (untested) should fix it, ok for trunk?
  
  2014-11-13  Marek Polacek  pola...@redhat.com
  
  * intrinsics/access.c: Include stdlib.h.
  * intrinsics/chdir.c: Likewise.
  * intrinsics/chmod.c: Likewise.
 
 Ok, thanks.

The previous version was incomplete.  The following should be.

Applying to trunk.

2014-11-13  Marek Polacek  pola...@redhat.com

* intrinsics/access.c: Include stdlib.h.
* intrinsics/chdir.c: Likewise.
* intrinsics/chmod.c: Likewise.
* intrinsics/link.c: Likewise.
* intrinsics/perror.c: Likewise.
* intrinsics/rename.c: Likewise.
* intrinsics/symlnk.c: Likewise.
* intrinsics/unlink.c: Likewise.

diff --git gcc/intrinsics/access.c gcc/intrinsics/access.c
index 65a0a10..0c18da0 100644
--- gcc/intrinsics/access.c
+++ gcc/intrinsics/access.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 #ifdef HAVE_UNISTD_H
diff --git gcc/intrinsics/chdir.c gcc/intrinsics/chdir.c
index 87419a8..193e482 100644
--- gcc/intrinsics/chdir.c
+++ gcc/intrinsics/chdir.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 #ifdef HAVE_UNISTD_H
diff --git gcc/intrinsics/chmod.c gcc/intrinsics/chmod.c
index c42fa8c..bdcb676 100644
--- gcc/intrinsics/chmod.c
+++ gcc/intrinsics/chmod.c
@@ -28,6 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #if defined(HAVE_SYS_STAT_H)
 
 #include string.h/* For memcpy. */
+#include stdlib.h/* For free.  */
 #include sys/stat.h  /* For stat, chmod and umask.  */
 
 
diff --git gcc/intrinsics/link.c gcc/intrinsics/link.c
index c6084a1..dd9c470 100644
--- gcc/intrinsics/link.c
+++ gcc/intrinsics/link.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 #ifdef HAVE_UNISTD_H
diff --git gcc/intrinsics/perror.c gcc/intrinsics/perror.c
index a8f0972..2bb1305 100644
--- gcc/intrinsics/perror.c
+++ gcc/intrinsics/perror.c
@@ -27,6 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 #include errno.h
 #include string.h
+#include stdlib.h
 
 /* SUBROUTINE PERROR(STRING)
CHARACTER(len=*), INTENT(IN) :: STRING   */
diff --git gcc/intrinsics/rename.c gcc/intrinsics/rename.c
index aabf821..78c3d81 100644
--- gcc/intrinsics/rename.c
+++ gcc/intrinsics/rename.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 
diff --git gcc/intrinsics/symlnk.c gcc/intrinsics/symlnk.c
index 5c53cb7..52a3c4b 100644
--- gcc/intrinsics/symlnk.c
+++ gcc/intrinsics/symlnk.c
@@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #include libgfortran.h
 
 #include errno.h
+#include stdlib.h
 #include string.h
 
 #ifdef HAVE_UNISTD_H
diff --git gcc/intrinsics/unlink.c gcc/intrinsics/unlink.c
index 2971a62..4752988 100644
--- gcc/intrinsics/unlink.c
+++ gcc/intrinsics/unlink.c
@@ -25,6 +25,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 #include libgfortran.h
 
+#include stdlib.h
 #include string.h
 #include errno.h
 

Marek


[PATCH] -fsanitize=unreachable overhaul (PR sanitizer/63839)

2014-11-13 Thread Marek Polacek
As Richi pointed in the pr audit trail, instrumenting via folding is
bad.  In this case we changed __builtin_unreachable, created by the
inliner, into BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE which requires
VOPS, which is a no-no in folding.  So this patch:
- marks BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE as const to match
  BUILT_IN_UNREACHABLE,
- moves the __builtin_unreachable instrumentation into sanopt pass,
- disables optimize_unreachable when doing the __builtin_unreachable
  instrumentation,
- marks BUILT_IN_UNREACHABLE as cold (I don't see how this could
  make a difference?).  Now, BUILT_IN_TRAP should probably be also
  marked as const+cold; I'm happy to do that as a follow-up.

Bootstrapped/regtested on power8-linux, ok for trunk?

2014-11-13  Marek Polacek  pola...@redhat.com

PR sanitizer/63839
* asan.c (ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST,
ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST): Define.
* builtin-attrs.def (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST):
Define.
* builtins.c (fold_builtin_0): Don't include ubsan.h.  Don't
instrument BUILT_IN_UNREACHABLE here.
* builtins.def (BUILT_IN_UNREACHABLE): Make cold.
* sanitizer.def (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE): Make
const.
* sanopt.c (pass_sanopt::execute): Instrument BUILT_IN_UNREACHABLE.
* tree-ssa-ccp.c (optimize_unreachable): Bail out if
SANITIZE_UNREACHABLE.
* ubsan.c (ubsan_instrument_unreachable): Rewrite for GIMPLE.
* ubsan.h (ubsan_instrument_unreachable): Adjust declaration.
testsuite/
* c-c++-common/ubsan/pr63839.c: New test.
* c-c++-common/ubsan/unreachable-2.c: New test.

diff --git gcc/asan.c gcc/asan.c
index 79dede7..2961b44 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2346,6 +2346,9 @@ initialize_sanitizer_builtins (void)
 #define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
 #undef ATTR_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
+#undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
+  ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
 #undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
   ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
@@ -2355,6 +2358,9 @@ initialize_sanitizer_builtins (void)
 #undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
   /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
+#undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
+  /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
 #undef DEF_SANITIZER_BUILTIN
 #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
   decl = add_builtin_function (__builtin_ NAME, TYPE, ENUM,  \
diff --git gcc/builtin-attrs.def gcc/builtin-attrs.def
index 9c05a94..c707367 100644
--- gcc/builtin-attrs.def
+++ gcc/builtin-attrs.def
@@ -145,6 +145,8 @@ DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LIST, 
ATTR_SENTINEL,  \
ATTR_NULL, ATTR_NOTHROW_LIST)
 DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LEAF_LIST, ATTR_SENTINEL,\
ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
+DEF_ATTR_TREE_LIST (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST, ATTR_CONST,\
+   ATTR_NULL, ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
 
 /* Functions whose pointer parameter(s) are all nonnull.  */
 DEF_ATTR_TREE_LIST (ATTR_NONNULL_LIST, ATTR_NONNULL, ATTR_NULL, ATTR_NULL)
diff --git gcc/builtins.c gcc/builtins.c
index 1cd65ed..311c0e3 100644
--- gcc/builtins.c
+++ gcc/builtins.c
@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3.  If not see
 #include diagnostic-core.h
 #include builtins.h
 #include asan.h
-#include ubsan.h
 #include cilk.h
 #include ipa-ref.h
 #include lto-streamer.h
@@ -9803,14 +9802,6 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore 
ATTRIBUTE_UNUSED)
 case BUILT_IN_CLASSIFY_TYPE:
   return fold_builtin_classify_type (NULL_TREE);
 
-case BUILT_IN_UNREACHABLE:
-  if (flag_sanitize  SANITIZE_UNREACHABLE
-  (current_function_decl == NULL
- || !lookup_attribute (no_sanitize_undefined,
-   DECL_ATTRIBUTES (current_function_decl
-   return ubsan_instrument_unreachable (loc);
-  break;
-
 default:
   break;
 }
diff --git gcc/builtins.def gcc/builtins.def
index 0406016..8699a41 100644
--- gcc/builtins.def
+++ gcc/builtins.def
@@ -803,7 +803,7 @@ DEF_GCC_BUILTIN(BUILT_IN_SETJMP, setjmp, 
BT_FN_INT_PTR, ATTR_NOTHROW_L
 DEF_EXT_LIB_BUILTIN(BUILT_IN_STRFMON, strfmon, 
BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
 DEF_LIB_BUILTIN(BUILT_IN_STRFTIME, strftime, 
BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
 DEF_GCC_BUILTIN(BUILT_IN_TRAP

[PATCH] Remove doubled ECF_LEAF

2014-11-13 Thread Marek Polacek
Bootstrapped/regtested on power8-linux, ok for trunk?

2014-11-13  Marek Polacek  pola...@redhat.com

* tree.c (build_common_builtin_nodes): Remove doubled ECF_LEAF.

diff --git gcc/tree.c gcc/tree.c
index cf37a19..5c6fe0b 100644
--- gcc/tree.c
+++ gcc/tree.c
@@ -9935,7 +9935,7 @@ build_common_builtin_nodes (void)
   local_define_builtin (__builtin_unreachable, ftype, 
BUILT_IN_UNREACHABLE,
__builtin_unreachable,
ECF_NOTHROW | ECF_LEAF | ECF_NORETURN
-   | ECF_CONST | ECF_LEAF);
+   | ECF_CONST);
 }
 
   if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)

Marek


Re: [PATCH] -fsanitize=unreachable overhaul (PR sanitizer/63839)

2014-11-14 Thread Marek Polacek
On Fri, Nov 14, 2014 at 09:36:40AM +0100, Richard Biener wrote:
 So please leave existing non-cold things as non-cold.
 
  Bootstrapped/regtested on power8-linux, ok for trunk?
 
 Ok with that change.

Thanks, this is the version with the builtins.def hunk dropped.

Applying to trunk.

2014-11-14  Marek Polacek  pola...@redhat.com

PR sanitizer/63839
* asan.c (ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST,
ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST): Define.
* builtin-attrs.def (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST):
Define.
* builtins.c (fold_builtin_0): Don't include ubsan.h.  Don't
instrument BUILT_IN_UNREACHABLE here.
* sanitizer.def (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE): Make
const.
* sanopt.c (pass_sanopt::execute): Instrument BUILT_IN_UNREACHABLE.
* tree-ssa-ccp.c (optimize_unreachable): Bail out if
SANITIZE_UNREACHABLE.
* ubsan.c (ubsan_instrument_unreachable): Rewrite for GIMPLE.
* ubsan.h (ubsan_instrument_unreachable): Adjust declaration.
testsuite/
* c-c++-common/ubsan/pr63839.c: New test.
* c-c++-common/ubsan/unreachable-2.c: New test.

diff --git gcc/asan.c gcc/asan.c
index 79dede7..2961b44 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2346,6 +2346,9 @@ initialize_sanitizer_builtins (void)
 #define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
 #undef ATTR_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
+#undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
+  ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
 #undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
   ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
@@ -2355,6 +2358,9 @@ initialize_sanitizer_builtins (void)
 #undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
   /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
+#undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
+  /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
 #undef DEF_SANITIZER_BUILTIN
 #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
   decl = add_builtin_function (__builtin_ NAME, TYPE, ENUM,  \
diff --git gcc/builtin-attrs.def gcc/builtin-attrs.def
index 9c05a94..c707367 100644
--- gcc/builtin-attrs.def
+++ gcc/builtin-attrs.def
@@ -145,6 +145,8 @@ DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LIST, 
ATTR_SENTINEL,  \
ATTR_NULL, ATTR_NOTHROW_LIST)
 DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LEAF_LIST, ATTR_SENTINEL,\
ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
+DEF_ATTR_TREE_LIST (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST, ATTR_CONST,\
+   ATTR_NULL, ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
 
 /* Functions whose pointer parameter(s) are all nonnull.  */
 DEF_ATTR_TREE_LIST (ATTR_NONNULL_LIST, ATTR_NONNULL, ATTR_NULL, ATTR_NULL)
diff --git gcc/builtins.c gcc/builtins.c
index 1cd65ed..311c0e3 100644
--- gcc/builtins.c
+++ gcc/builtins.c
@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3.  If not see
 #include diagnostic-core.h
 #include builtins.h
 #include asan.h
-#include ubsan.h
 #include cilk.h
 #include ipa-ref.h
 #include lto-streamer.h
@@ -9803,14 +9802,6 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore 
ATTRIBUTE_UNUSED)
 case BUILT_IN_CLASSIFY_TYPE:
   return fold_builtin_classify_type (NULL_TREE);
 
-case BUILT_IN_UNREACHABLE:
-  if (flag_sanitize  SANITIZE_UNREACHABLE
-  (current_function_decl == NULL
- || !lookup_attribute (no_sanitize_undefined,
-   DECL_ATTRIBUTES (current_function_decl
-   return ubsan_instrument_unreachable (loc);
-  break;
-
 default:
   break;
 }
diff --git gcc/sanitizer.def gcc/sanitizer.def
index cddc5ea..3fc8c83 100644
--- gcc/sanitizer.def
+++ gcc/sanitizer.def
@@ -394,7 +394,7 @@ 
DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS,
 DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE,
  __ubsan_handle_builtin_unreachable,
  BT_FN_VOID_PTR,
- ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
+ ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_MISSING_RETURN,
  __ubsan_handle_missing_return,
  BT_FN_VOID_PTR,
diff --git gcc/sanopt.c gcc/sanopt.c
index 0fc032a..fe2e42d 100644
--- gcc/sanopt.c
+++ gcc/sanopt.c
@@ -312,6 +312,21 @@ pass_sanopt::execute (function *fun)
  break;
}
}
+ else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+   {
+ tree callee = gimple_call_fndecl (stmt);
+ switch (DECL_FUNCTION_CODE (callee

Re: [PATCH] Peg down -(-A) - A transformation

2014-11-14 Thread Marek Polacek
On Wed, Nov 12, 2014 at 11:53:19AM +0100, Richard Biener wrote:
 Err - please adjust fold_negate_expr instead.

Like this?

(It's not best that for -trapv/-fsanitize=s-i-o we don't emit
compile-time warning integer overflow in expression for -INT_MIN,
because the warning relies on the folding.)

Bootstrapped/regtested on power8-linux.

2014-11-14  Marek Polacek  pola...@redhat.com

* fold-const.c (fold_negate_expr): Don't fold INTEGER_CST if
that overflows when SANITIZE_SI_OVERFLOW is on.  Guard -(-A)
folding with TYPE_OVERFLOW_SANITIZED.

* c-c++-common/ubsan/overflow-negate-3.c: New test.

diff --git gcc/fold-const.c gcc/fold-const.c
index ee9ed7b..8994aa4 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -555,7 +555,8 @@ fold_negate_expr (location_t loc, tree t)
 case INTEGER_CST:
   tem = fold_negate_const (t, type);
   if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
- || !TYPE_OVERFLOW_TRAPS (type))
+ || (!TYPE_OVERFLOW_TRAPS (type)
+  (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
return tem;
   break;
 
@@ -612,7 +613,9 @@ fold_negate_expr (location_t loc, tree t)
   break;
 
 case NEGATE_EXPR:
-  return TREE_OPERAND (t, 0);
+  if (!TYPE_OVERFLOW_SANITIZED (type))
+   return TREE_OPERAND (t, 0);
+  break;
 
 case PLUS_EXPR:
   if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
diff --git gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c 
gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
index e69de29..e6db394 100644
--- gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
+++ gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options -fsanitize=signed-integer-overflow } */
+
+#define INT_MIN (-__INT_MAX__ - 1)
+
+int
+main ()
+{
+  int x = INT_MIN;
+  int y;
+  asm ( : +g (x));
+  y = -(-x);
+  asm ( : +g (y));
+  y = -(-INT_MIN);
+  asm ( : +g (y));
+}
+
+/* { dg-output negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */
+/* { dg-output \[^\n\r]*negation of -2147483648 cannot be represented in type 
'int'\[^\n\r]*; cast to an unsigned type to negate this value to 
itself\[^\n\r]*(\n|\r\n|\r) } */

Marek


[PATCH] Use TYPE_DECLs for TYPE_NAMEs (PR sanitizer/63866)

2014-11-14 Thread Marek Polacek
We ICEd when dumping the IPA symbol table when -fsanitize=undefined
and -fdump-ipa-* options were enabled on every testcase where we
sanitized something and thus internal ubsan data have been created.
The problem was that the C++ printer expects a decl as a TYPE_NAME,
but we were sticking an identifier node into the TYPE_NAME.
Fixed by creating a proper TYPE_DECL and then putting this TYPE_DECL
into TYPE_NAME and TYPE_STUB_DECL.  Ditto for asan.c.

While at it, I noticed that we don't cache ubsan_type_descriptor_type,
oops.  So I've fixed that as well.

Bootstrapped/regtested on power8-linux, ok for trunk?

2014-11-14  Marek Polacek  pola...@redhat.com

PR sanitizer/63866
* asan.c (asan_global_struct): Create a TYPE_DECL for __asan_global,
put it into TYPE_NAME and TYPE_STUB_DECL.
* ubsan.c (ubsan_type_descriptor_type): New variable.
Function renamed to ...
(ubsan_get_type_descriptor_type): ... this.  Cache
return value in ubsan_type_descriptor_type variable.
Create a TYPE_DECL for __ubsan_type_descriptor, put it into
TYPE_NAME and TYPE_STUB_DECL.
(ubsan_get_source_location_type): Create a TYPE_DECL for
__ubsan_source_location, put it into TYPE_NAME and TYPE_STUB_DECL.
(ubsan_type_descriptor, ubsan_create_data): Call
ubsan_get_type_descriptor_type instead of ubsan_type_descriptor_type.
Create a TYPE_DECL for name, put it into TYPE_NAME and TYPE_STUB_DECL.

* c-c++-common/ubsan/pr63866.c: New test.

diff --git gcc/asan.c gcc/asan.c
index 2961b44..d50e098 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2168,8 +2168,13 @@ asan_global_struct (void)
   if (i)
DECL_CHAIN (fields[i - 1]) = fields[i];
 }
+  tree type_decl = build_decl (input_location, TYPE_DECL,
+  get_identifier (__asan_global), ret);
+  DECL_IGNORED_P (type_decl) = 1;
+  DECL_ARTIFICIAL (type_decl) = 1;
   TYPE_FIELDS (ret) = fields[0];
-  TYPE_NAME (ret) = get_identifier (__asan_global);
+  TYPE_NAME (ret) = type_decl;
+  TYPE_STUB_DECL (ret) = type_decl;
   layout_type (ret);
   return ret;
 }
diff --git gcc/testsuite/c-c++-common/ubsan/pr63866.c 
gcc/testsuite/c-c++-common/ubsan/pr63866.c
index e69de29..e70daa7 100644
--- gcc/testsuite/c-c++-common/ubsan/pr63866.c
+++ gcc/testsuite/c-c++-common/ubsan/pr63866.c
@@ -0,0 +1,11 @@
+/* PR sanitizer/63866 */
+/* { dg-do compile } */
+/* { dg-options -fsanitize=undefined -fdump-ipa-cgraph } */
+
+int
+foo (int x, int y)
+{
+  return x + y;
+}
+
+/* { dg-final { cleanup-ipa-dump cgraph } } */
diff --git gcc/ubsan.c gcc/ubsan.c
index b5b1b92..98a6c2f 100644
--- gcc/ubsan.c
+++ gcc/ubsan.c
@@ -179,6 +179,9 @@ ubsan_encode_value (tree t, bool in_expand_p)
 }
 }
 
+/* Cached ubsan_get_type_descriptor_type () return value.  */
+static GTY(()) tree ubsan_type_descriptor_type;
+
 /* Build
struct __ubsan_type_descriptor
{
@@ -189,11 +192,15 @@ ubsan_encode_value (tree t, bool in_expand_p)
type.  */
 
 static tree
-ubsan_type_descriptor_type (void)
+ubsan_get_type_descriptor_type (void)
 {
   static const char *field_names[3]
 = { __typekind, __typeinfo, __typename };
   tree fields[3], ret;
+
+  if (ubsan_type_descriptor_type)
+return ubsan_type_descriptor_type;
+
   tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
   tree flex_arr_type = build_array_type (char_type_node, itype);
 
@@ -208,9 +215,16 @@ ubsan_type_descriptor_type (void)
   if (i)
DECL_CHAIN (fields[i - 1]) = fields[i];
 }
+  tree type_decl = build_decl (input_location, TYPE_DECL,
+  get_identifier (__ubsan_type_descriptor),
+  ret);
+  DECL_IGNORED_P (type_decl) = 1;
+  DECL_ARTIFICIAL (type_decl) = 1;
   TYPE_FIELDS (ret) = fields[0];
-  TYPE_NAME (ret) = get_identifier (__ubsan_type_descriptor);
+  TYPE_NAME (ret) = type_decl;
+  TYPE_STUB_DECL (ret) = type_decl;
   layout_type (ret);
+  ubsan_type_descriptor_type = ret;
   return ret;
 }
 
@@ -249,8 +263,14 @@ ubsan_get_source_location_type (void)
   if (i)
DECL_CHAIN (fields[i - 1]) = fields[i];
 }
+  tree type_decl = build_decl (input_location, TYPE_DECL,
+  get_identifier (__ubsan_source_location),
+  ret);
+  DECL_IGNORED_P (type_decl) = 1;
+  DECL_ARTIFICIAL (type_decl) = 1;
   TYPE_FIELDS (ret) = fields[0];
-  TYPE_NAME (ret) = get_identifier (__ubsan_source_location);
+  TYPE_NAME (ret) = type_decl;
+  TYPE_STUB_DECL (ret) = type_decl;
   layout_type (ret);
   ubsan_source_location_type = ret;
   return ret;
@@ -333,7 +353,7 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style 
pstyle)
   if (decl != NULL_TREE  varpool_node::get (decl))
 return build_fold_addr_expr (decl);
 
-  tree dtype = ubsan_type_descriptor_type ();
+  tree dtype = ubsan_get_type_descriptor_type ();
   tree type2 = type;
   const char *tname = NULL;
   char

[PATCH] Fix Cilk+ ICEs with overflow builtins (PR middle-end/63884)

2014-11-15 Thread Marek Polacek
The problem here is that the Cilk+ code wasn't prepared to handle
internal calls that the new overflow builtins entail.  Fixed by
checking that the CALL_EXPR_FN isn't NULL.

Looking at cilk-plus.exp, I think this file will need some tweaks
now that the C default is gnu11...

Bootstrapped/regtested on powerpc64-linux, ok for trunk?

2014-11-15  Marek Polacek  pola...@redhat.com

PR middle-end/63884
c-family/
* array-notation-common.c (is_sec_implicit_index_fn): Return false
for NULL fndecl.
(extract_array_notation_exprs): Return for NULL node.
testsuite/
* c-c++-common/cilk-plus/AN/pr63884.c: New test.

diff --git gcc/c-family/array-notation-common.c 
gcc/c-family/array-notation-common.c
index f8bce04..cb5708c 100644
--- gcc/c-family/array-notation-common.c
+++ gcc/c-family/array-notation-common.c
@@ -35,6 +35,9 @@ along with GCC; see the file COPYING3.  If not see
 bool
 is_sec_implicit_index_fn (tree fndecl)
 {
+  if (!fndecl)
+return false;
+
   if (TREE_CODE (fndecl) == ADDR_EXPR)
 fndecl = TREE_OPERAND (fndecl, 0);
 
@@ -327,6 +330,9 @@ extract_array_notation_exprs (tree node, bool 
ignore_builtin_fn,
  vectree, va_gc **array_list)
 {
   size_t ii = 0;  
+
+  if (!node)
+return;
   if (TREE_CODE (node) == ARRAY_NOTATION_REF)
 {
   vec_safe_push (*array_list, node);
diff --git gcc/testsuite/c-c++-common/cilk-plus/AN/pr63884.c 
gcc/testsuite/c-c++-common/cilk-plus/AN/pr63884.c
index e69de29..c876a8d 100644
--- gcc/testsuite/c-c++-common/cilk-plus/AN/pr63884.c
+++ gcc/testsuite/c-c++-common/cilk-plus/AN/pr63884.c
@@ -0,0 +1,10 @@
+/* PR middle-end/63884 */
+/* { dg-do compile } */
+/* { dg-options -fcilkplus } */
+
+int
+foo (int x, int y)
+{
+  int r;
+  return __builtin_sadd_overflow (x, y, r);
+}

Marek


Re: [PATCH] gcc/ubsan.c: Extend 'pretty_name' space to avoid memory overflow

2014-11-16 Thread Marek Polacek
On Mon, Nov 17, 2014 at 06:40:26AM +0800, Chen Gang wrote:
 According to the next code, 'pretty_name' may need additional bytes more
 than 16. For simplify thinking and being extensible in future, extent it
 to 256 bytes, directly.

I think + 128 bytes should be enough for everyone.

Marek


Re: [PATCH] gcc/ubsan.c: Extend 'pretty_name' space to avoid memory overflow

2014-11-17 Thread Marek Polacek
On Mon, Nov 17, 2014 at 08:38:19AM +0100, Jakub Jelinek wrote:
 On Mon, Nov 17, 2014 at 08:16:32AM +0100, Marek Polacek wrote:
  On Mon, Nov 17, 2014 at 06:40:26AM +0800, Chen Gang wrote:
   According to the next code, 'pretty_name' may need additional bytes more
   than 16. For simplify thinking and being extensible in future, extent it
   to 256 bytes, directly.
  
  I think + 128 bytes should be enough for everyone.
 
 I disagree.
 Consider:
 typedef char 
 A[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1];
 A a;
 
 int foo (int j)
 {
   
 a[j][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
  = 1;
 }
 You need 1159 bytes in that case.  Easily to construct testcase that needs
 arbitrary amount.

Ah, I haven't looked at the UBSAN_PRINT_ARRAY case.

 I think easiest would be to rewrite the code so that it uses pretty_printer
 to construct the string, grep asan.c for asan_pp .  Or obstacks, but you don't
 have a printer to print integers into it easily.
   if (dom  TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
 pos += sprintf (pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
   else
 /* ??? We can't determine the variable name; print VLA unspec.  */
 pretty_name[pos++] = '*';
 looks wrong anyway, as not all integers fit into uhwi.
 Guess you could use wide_int to add 1 there and pp_wide_int.

Ok.

Marek


[PATCH] Fix for fold_negate_expr (PR sanitizer/63879)

2014-11-19 Thread Marek Polacek
The problem here is that negate_expr_p returns true (as it should)
for UINT_MAX(OVF), but fold_negate_expr didn't actually fold it,
and that is a no-no; if negate_expr_p is true, fold_negate_expr must
not return NULL_TREE.  I added the following hunk for bootstrap and
regtest for better coverage:

@@ -752,6 +755,12 @@ fold_negate_expr (location_t loc, tree t)
   break;
 }
 
+#ifdef ENABLE_CHECKING
+  if (negate_expr_p (t))
+internal_error (fold_negate_expr should never return NULL_TREE 
+   if negate_expr_p is true);
+#endif
+
   return NULL_TREE;
 }

Fixed by adjusting fold_negate_expr so that it folds non-trapping
wrapping constants.  The SANITIZE_SI_OVERFLOW check is important
to not regress -Woverflow warnings (ug).

negate_expr_p hunk is to match the NEGATE_EXPR case in fold_negate_expr.
 
Bootstrapped/regtested on power8-linux, ok for trunk?

2014-11-19  Marek Polacek  pola...@redhat.com

PR sanitizer/63879
* fold-const.c (negate_expr_p) case NEGATE_EXPR: Return
!TYPE_OVERFLOW_SANITIZED.
(fold_negate_expr) case INTEGER_CST: Fold when overflow
does not trap and when overflow wraps, or when SANITIZE_SI_OVERFLOW
is 0.

* c-c++-common/ubsan/pr63879-1.c: New test.
* c-c++-common/ubsan/pr63879-2.c: New test.

diff --git gcc/fold-const.c gcc/fold-const.c
index f6fb8af..719e06e 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -408,9 +408,11 @@ negate_expr_p (tree t)
   TYPE_OVERFLOW_WRAPS (type));
 
 case FIXED_CST:
-case NEGATE_EXPR:
   return true;
 
+case NEGATE_EXPR:
+  return !TYPE_OVERFLOW_SANITIZED (type);
+
 case REAL_CST:
   /* We want to canonicalize to positive real constants.  Pretend
  that only negative ones can be easily negated.  */
@@ -555,7 +557,8 @@ fold_negate_expr (location_t loc, tree t)
   tem = fold_negate_const (t, type);
   if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
  || (!TYPE_OVERFLOW_TRAPS (type)
-  (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0))
+  TYPE_OVERFLOW_WRAPS (type))
+ || (flag_sanitize  SANITIZE_SI_OVERFLOW) == 0)
return tem;
   break;
 
diff --git gcc/testsuite/c-c++-common/ubsan/pr63879-1.c 
gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
index e69de29..2035849 100644
--- gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
+++ gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
@@ -0,0 +1,23 @@
+/* PR sanitizer/63879 */
+/* { dg-do compile } */
+/* { dg-options -fsanitize=undefined } */
+
+struct A
+{
+  int inode;
+} * a;
+int b, c;
+void
+fn1 ()
+{
+  int d = 0;
+  while (b)
+{
+  if (a-inode)
+d++;
+  a = 0;
+}
+  c = d - 1;
+  for (; c = 0; c--)
+;
+}
diff --git gcc/testsuite/c-c++-common/ubsan/pr63879-2.c 
gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
index e69de29..34eb8e7 100644
--- gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
+++ gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
@@ -0,0 +1,13 @@
+/* PR sanitizer/63879 */
+/* { dg-do compile } */
+/* { dg-options -fsanitize=undefined } */
+
+int a;
+void
+fn1 ()
+{
+  int b = 2;
+  for (; a;)
+while (b = 0)
+  b--;
+}

Marek


[PATCH] Fix sanitizer/63690

2014-11-19 Thread Marek Polacek
As the testcase shows, we should really check first that we
have a MEM_REF, otherwise subsequent TREE_OPERAND might ICE.
On an invalid testcase we might get e.g. STRING_CST.

Bootstrapped/regtested on power8-linux, ok for trunk?

2014-11-19  Marek Polacek  pola...@redhat.com

PR sanitizer/63690
* ubsan.c (instrument_object_size): Check for MEM_REF.

* gcc.dg/ubsan/pr63690.c: New test.

diff --git gcc/testsuite/gcc.dg/ubsan/pr63690.c 
gcc/testsuite/gcc.dg/ubsan/pr63690.c
index e69de29..bcf520a 100644
--- gcc/testsuite/gcc.dg/ubsan/pr63690.c
+++ gcc/testsuite/gcc.dg/ubsan/pr63690.c
@@ -0,0 +1,9 @@
+/* PR sanitizer/63690 */
+/* { dg-do compile } */
+/* { dg-options -fsanitize=undefined } */
+
+void
+foo (void)
+{
+  (*c)++;
+}
diff --git gcc/ubsan.c gcc/ubsan.c
index 7d1e341..ad5665f 100644
--- gcc/ubsan.c
+++ gcc/ubsan.c
@@ -1539,7 +1539,13 @@ instrument_object_size (gimple_stmt_iterator *gsi, bool 
is_lhs)
 return;
 
   bool decl_p = DECL_P (inner);
-  tree base = decl_p ? inner : TREE_OPERAND (inner, 0);
+  tree base;
+  if (decl_p)
+base = inner;
+  else if (TREE_CODE (inner) == MEM_REF)
+base = TREE_OPERAND (inner, 0);
+  else
+return;
   tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
 
   while (TREE_CODE (base) == SSA_NAME)

Marek


Re: [PATCH] Fix sanitizer/63690

2014-11-19 Thread Marek Polacek
On Wed, Nov 19, 2014 at 03:12:05PM +0100, Jakub Jelinek wrote:
 On Wed, Nov 19, 2014 at 02:51:11PM +0100, Marek Polacek wrote:
  As the testcase shows, we should really check first that we
  have a MEM_REF, otherwise subsequent TREE_OPERAND might ICE.
  On an invalid testcase we might get e.g. STRING_CST.
 
 Well, addr_object_size should handle STRING_CSTs just fine, so
 why not handle STRING_CSTs in there too (similarly to decl_p = true
 case).
 Supposedly you want decl_p = true for them and need to tweak
   if (!POINTER_TYPE_P (TREE_TYPE (base))  !DECL_P (base))
 but otherwise it should work.
 On the other side,
 int
 foo (int x)
 {
   return foobar[x];
 }
 is already handled by -fsanitize=bounds and for some reason

Right - I've checked that this is the case.  I could mention
that in the original submission.

 gimple_assign_load_p doesn't consider handled components with
 STRING_CST as base as loads so for -fsanitize=object-size
 we aren't called for that.

Thanks for review,

Marek


Re: [PATCH] rs6000: Fix signed integer overflows

2014-11-19 Thread Marek Polacek
On Wed, Nov 19, 2014 at 04:24:25PM +0100, Markus Trippelsdorf wrote:
  ;; Return 1 if op is a constant integer valid for addition
 @@ -827,7 +827,7 @@
  (define_predicate mask_operand
(match_code const_int)
  {
 -  HOST_WIDE_INT c, lsb;
 +  unsigned HOST_WIDE_INT c, lsb;
  
c = INTVAL (op);
  
 @@ -872,7 +872,7 @@
  (define_predicate mask_operand_wrap
(match_code const_int)
  {
 -  HOST_WIDE_INT c, lsb;
 +  unsigned HOST_WIDE_INT c, lsb;
  
c = INTVAL (op);
  
 @@ -897,7 +897,7 @@
  (define_predicate mask64_operand
(match_code const_int)
  {
 -  HOST_WIDE_INT c, lsb;
 +  unsigned HOST_WIDE_INT c, lsb;
  
c = INTVAL (op);
  
 @@ -923,7 +923,7 @@
  (define_predicate mask64_2_operand
(match_code const_int)
  {
 -  HOST_WIDE_INT c, lsb;
 +  unsigned HOST_WIDE_INT c, lsb;
  
c = INTVAL (op);

Shouldn't you use UINTVAL then?

Marek


Re: [patch] Warn on undefined loop exit

2014-11-19 Thread Marek Polacek
On Wed, Nov 19, 2014 at 04:32:43PM +, Andrew Stubbs wrote:
 +  if (warning_at (gimple_location (elt-stmt),
 +  OPT_Waggressive_loop_optimizations,
 +  Loop exit may only be reached after 
 undefined behaviour.))

Warnings should start with a lowercase and should be without
a fullstop at the end.

Marek


[PATCH] Fix sanitizer/63788

2014-11-19 Thread Marek Polacek
As discussed in the PR, the problem here is that when running gfortran,
the __builtin_object_size decl isn't available, because c-family's
c_define_builtins wasn't called.  One way how to fix this is to build
the __builtin_object_size decl in initialize_sanitizer_builtins, if
needed.  Alternatively we could just bail in instrument_object_size
if builtin_decl_explicit (BUILT_IN_OBJECT_SIZE) returns NULL_TREE...

No test attached since we don't have any Fortran ubsan infrastructure,
I've just tried
./xgcc -B ./ -B ../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ 
-Wl,-rpath=../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -B 
../x86_64-unknown-linux-gnu/libgfortran/.libs/ -O -fsanitize=undefined 
testcase.f -lgfortran; ./a.out
on the testcase attached in PR - and it doesn't ICE.

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-19  Marek Polacek  pola...@redhat.com

PR sanitizer/63788
* asan.c (initialize_sanitizer_builtins): Add BT_FN_SIZE_CONST_PTR_INT
var.  Conditionally build BUILT_IN_OBJECT_SIZE decl.
(ATTR_PURE_NOTHROW_LEAF_LIST): Define.

diff --git gcc/asan.c gcc/asan.c
index ff08f1b..c2ed3d5 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2294,6 +2294,9 @@ initialize_sanitizer_builtins (void)
pointer_sized_int_node, NULL_TREE);
   tree BT_FN_VOID_INT
 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
+  tree BT_FN_SIZE_CONST_PTR_INT
+= build_function_type_list (size_type_node, const_ptr_type_node,
+   integer_type_node, NULL_TREE);
   tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
   tree BT_FN_IX_CONST_VPTR_INT[5];
   tree BT_FN_IX_VPTR_IX_INT[5];
@@ -2365,6 +2368,8 @@ initialize_sanitizer_builtins (void)
 #undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
   /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
+#undef ATTR_PURE_NOTHROW_LEAF_LIST
+#define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
 #undef DEF_SANITIZER_BUILTIN
 #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
   decl = add_builtin_function (__builtin_ NAME, TYPE, ENUM,  \
@@ -2374,6 +2379,15 @@ initialize_sanitizer_builtins (void)
 
 #include sanitizer.def
 
+  /* -fsanitize=object-size uses __builtin_object_size, but that might
+ not be available for e.g. Fortran at this point.  We use
+ DEF_SANITIZER_BUILTIN here only as a convenience macro.  */
+  if ((flag_sanitize  SANITIZE_OBJECT_SIZE)
+   !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
+DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, object_size,
+  BT_FN_SIZE_CONST_PTR_INT,
+  ATTR_PURE_NOTHROW_LEAF_LIST)
+
 #undef DEF_SANITIZER_BUILTIN
 }
 

Marek


[PATCH] Fix ubsan and C++14 constexpr ICEs (PR sanitizer/63956)

2014-11-20 Thread Marek Polacek
This patch fixes a bunch of ICEs related to C++14 constexprs and
-fsanitize=undefined.  We should ignore ubsan internal functions
and ubsan builtins in constexpr functions in cxx_eval_call_expression.

Also add proper printing of internal functions into the C++ printer.

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-20  Marek Polacek  pola...@redhat.com

PR sanitizer/63956
* constexpr.c: Include ubsan.h.
(cxx_eval_call_expression): Bail out for IFN_UBSAN_{NULL,BOUNDS}
internal functions and for ubsan builtins in constexpr functions.
* error.c: Include internal-fn.h.
(dump_expr): Add printing of internal functions.

* g++.dg/ubsan/pr63956.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 2678223..684e36f 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include gimplify.h
 #include builtins.h
 #include tree-inline.h
+#include ubsan.h
 
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X) \
@@ -1151,6 +1152,16 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
   constexpr_call *entry;
   bool depth_ok;
 
+  if (fun == NULL_TREE)
+switch (CALL_EXPR_IFN (t))
+  {
+  case IFN_UBSAN_NULL:
+  case IFN_UBSAN_BOUNDS:
+   return void_node;
+  default:
+   break;
+  }
+
   if (TREE_CODE (fun) != FUNCTION_DECL)
 {
   /* Might be a constexpr function pointer.  */
@@ -1171,6 +1182,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
 }
   if (DECL_CLONED_FUNCTION_P (fun))
 fun = DECL_CLONED_FUNCTION (fun);
+
+  if (!current_function_decl  is_ubsan_builtin_p (fun))
+return void_node;
+
   if (is_builtin_fn (fun))
 return cxx_eval_builtin_function_call (ctx, t,
   addr, non_constant_p, overflow_p);
diff --git gcc/cp/error.c gcc/cp/error.c
index 76f86cb..09789ad 100644
--- gcc/cp/error.c
+++ gcc/cp/error.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include tree-pretty-print.h
 #include c-family/c-objc.h
 #include ubsan.h
+#include internal-fn.h
 
 #include new// For placement-new.
 
@@ -2037,6 +2038,14 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
tree fn = CALL_EXPR_FN (t);
bool skipfirst = false;
 
+   /* Deal with internal functions.  */
+   if (fn == NULL_TREE)
+ {
+   pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t)));
+   dump_call_expr_args (pp, t, flags, skipfirst);
+   break;
+ }
+
if (TREE_CODE (fn) == ADDR_EXPR)
  fn = TREE_OPERAND (fn, 0);
 
diff --git gcc/testsuite/g++.dg/ubsan/pr63956.C 
gcc/testsuite/g++.dg/ubsan/pr63956.C
index e69de29..7bc0b77 100644
--- gcc/testsuite/g++.dg/ubsan/pr63956.C
+++ gcc/testsuite/g++.dg/ubsan/pr63956.C
@@ -0,0 +1,172 @@
+// PR sanitizer/63956
+// { dg-do compile }
+// { dg-options -std=c++14 
-fsanitize=undefined,float-divide-by-zero,float-cast-overflow }
+
+#define SA(X) static_assert((X),#X)
+#define INT_MIN (-__INT_MAX__ - 1)
+
+constexpr int
+fn1 (int a, int b)
+{
+  if (b != 2)
+a = b;
+  return a;
+}
+
+constexpr int i1 = fn1 (5, 3);
+constexpr int i2 = fn1 (5, -2);
+constexpr int i3 = fn1 (5, sizeof (int) * __CHAR_BIT__);
+constexpr int i4 = fn1 (5, 256);
+constexpr int i5 = fn1 (5, 2);
+constexpr int i6 = fn1 (-2, 4);
+constexpr int i7 = fn1 (0, 2);
+
+SA (i1 == 40);
+SA (i5 == 5);
+SA (i7 == 0);
+
+constexpr int
+fn2 (int a, int b)
+{
+  if (b != 2)
+a = b;
+  return a;
+}
+
+constexpr int j1 = fn2 (4, 1);
+constexpr int j2 = fn2 (4, -1);
+constexpr int j3 = fn2 (10, sizeof (int) * __CHAR_BIT__);
+constexpr int j4 = fn2 (1, 256);
+constexpr int j5 = fn2 (5, 2);
+constexpr int j6 = fn2 (-2, 4);
+constexpr int j7 = fn2 (0, 4);
+
+SA (j1 == 2);
+SA (j5 == 5);
+SA (j7 == 0);
+
+constexpr int
+fn3 (int a, int b)
+{
+  if (b != 2)
+a = a / b;
+  return a;
+}
+
+constexpr int k1 = fn3 (8, 4);
+constexpr int k2 = fn3 (7, 0); // { dg-error is not a constant 
expression|constexpr call flows off }
+constexpr int k3 = fn3 (INT_MIN, -1); // { dg-error overflow in constant 
expression|constexpr call flows off }
+
+SA (k1 == 2);
+
+constexpr float
+fn4 (float a, float b)
+{
+  if (b != 2.0)
+a = a / b;
+  return a;
+}
+
+constexpr float l1 = fn4 (5.0, 3.0);
+constexpr float l2 = fn4 (7.0, 0.0); // { dg-error is not a constant 
expression|constexpr call flows off }
+
+constexpr int
+fn5 (const int *a, int b)
+{
+  if (b != 2)
+b = a[b];
+  return b;
+}
+
+constexpr int m1[4] = { 1, 2, 3, 4 };
+constexpr int m2 = fn5 (m1, 3);
+constexpr int m3 = fn5 (m1, 4); // { dg-error array subscript out of 
bound|constexpr call flows off }
+
+constexpr int
+fn6 (const int a, int b)
+{
+  if (b != 2)
+b = a;
+  return b;
+}
+
+constexpr int
+fn7 (const int *a, int b

Re: [PATCH] Fix ubsan and C++14 constexpr ICEs (PR sanitizer/63956)

2014-11-20 Thread Marek Polacek
On Thu, Nov 20, 2014 at 06:27:25PM +0100, Jakub Jelinek wrote:
 On Thu, Nov 20, 2014 at 06:14:52PM +0100, Marek Polacek wrote:
  +  if (!current_function_decl  is_ubsan_builtin_p (fun))
  +return void_node;
  +
 
 I don't understand the !current_function_decl here.
 
That is because I only wanted to ignore ubsan builtins in constexpr
functions (in constexpr context), to not to break shift-5.c, where
for C++ we expect 
error: 'ubsan routine call' is not a constant expression

But that sounds dubious to me now, so I went ahead and did away with
that.  Which means that compile-time diagnostics is now the same no
matter whether -fsanitize=undefined is on.

 Also, looking at is_ubsan_builtin_p definition, I'd say
 it should IMHO at least test DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
 before comparing the function name, you can declare
 __builtin_ubsan_foobarbaz () and use it and it won't be a builtin.
 
Um, ok.

 As for the testcase, I'd like to understand if C++ FE should reject
 the constexpr functions when used with arguments that trigger undefined
 behavior.  But certainly the behavior should not depend on whether
 -fsanitize=undefined or not.

With this patch we generate the same compile-time diagnostics with
-fsanitize=undefined as without it in the new testcase.

 Also, what is the reason for constexpr call flows off the end errors?
 Shouldn't that be avoided if any error is found while interpreting the
 function?

Maybe.  Short testcase:

constexpr int
foo (int i, int j)
{
  if (i != 42)
i /= j;
  return i;
}
constexpr int i = foo (2, 0);

The reason is that we issue flows off the end if the result of a constexpr
function is NULL_TREE - and in this case it was.
Perhaps we should set ctx-quiet if an error is encountered during evaluation
of a constexpr function?

Here's updated patch.  Thanks.

2014-11-20  Marek Polacek  pola...@redhat.com

PR sanitizer/63956
* ubsan.c (is_ubsan_builtin_p): Check also built-in class.
cp/
* constexpr.c: Include ubsan.h.
(cxx_eval_call_expression): Bail out for IFN_UBSAN_{NULL,BOUNDS}
internal functions and for ubsan builtins.
* error.c: Include internal-fn.h.
(dump_expr): Add printing of internal functions.
testsuite/
* c-c++-common/ubsan/shift-5.c: Don't use -w for C++.  Change
dg-error to dg-warning for C++.
* g++.dg/ubsan/div-by-zero-1.C: Don't use -w.  Change dg-error
to dg-warning.
* g++.dg/ubsan/pr63956.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 2678223..32f07be 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include gimplify.h
 #include builtins.h
 #include tree-inline.h
+#include ubsan.h
 
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X) \
@@ -1151,6 +1152,16 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
   constexpr_call *entry;
   bool depth_ok;
 
+  if (fun == NULL_TREE)
+switch (CALL_EXPR_IFN (t))
+  {
+  case IFN_UBSAN_NULL:
+  case IFN_UBSAN_BOUNDS:
+   return void_node;
+  default:
+   break;
+  }
+
   if (TREE_CODE (fun) != FUNCTION_DECL)
 {
   /* Might be a constexpr function pointer.  */
@@ -1171,6 +1182,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
 }
   if (DECL_CLONED_FUNCTION_P (fun))
 fun = DECL_CLONED_FUNCTION (fun);
+
+  if (is_ubsan_builtin_p (fun))
+return void_node;
+
   if (is_builtin_fn (fun))
 return cxx_eval_builtin_function_call (ctx, t,
   addr, non_constant_p, overflow_p);
diff --git gcc/cp/error.c gcc/cp/error.c
index 76f86cb..09789ad 100644
--- gcc/cp/error.c
+++ gcc/cp/error.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include tree-pretty-print.h
 #include c-family/c-objc.h
 #include ubsan.h
+#include internal-fn.h
 
 #include new// For placement-new.
 
@@ -2037,6 +2038,14 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
tree fn = CALL_EXPR_FN (t);
bool skipfirst = false;
 
+   /* Deal with internal functions.  */
+   if (fn == NULL_TREE)
+ {
+   pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t)));
+   dump_call_expr_args (pp, t, flags, skipfirst);
+   break;
+ }
+
if (TREE_CODE (fn) == ADDR_EXPR)
  fn = TREE_OPERAND (fn, 0);
 
diff --git gcc/testsuite/c-c++-common/ubsan/shift-5.c 
gcc/testsuite/c-c++-common/ubsan/shift-5.c
index 6f9c52a..f8a88e0 100644
--- gcc/testsuite/c-c++-common/ubsan/shift-5.c
+++ gcc/testsuite/c-c++-common/ubsan/shift-5.c
@@ -1,32 +1,43 @@
 /* { dg-do compile } */
-/* { dg-options -fsanitize=shift -w } */
+/* { dg-options -fsanitize=shift -w { target c } } */
+/* { dg-options -fsanitize=shift { target c++ } } */
 /* { dg-shouldfail ubsan } */
 
-int x

Re: [patch] Warn on undefined loop exit

2014-11-20 Thread Marek Polacek
On Thu, Nov 20, 2014 at 05:27:35PM +0100, Richard Biener wrote:
 +  if (exit_warned  problem_stmts != vNULL)
 +{
 
 !problem_stmts.empty ()

/home/marek/src/gcc/gcc/tree-ssa-loop-niter.c: In function ‘void 
maybe_lower_iteration_bound(loop*)’:
/home/marek/src/gcc/gcc/tree-ssa-loop-niter.c:3420:38: error: ‘struct 
vecgimple_statement_base*’ has no member named ‘empty’
if (exit_warned  !problem_stmts.empty ())
  ^
make: *** [tree-ssa-loop-niter.o] Error 1

I'm applying the following.

2014-11-20  Marek Polacek  pola...@redhat.com

* tree-ssa-loop-niter.c (maybe_lower_iteration_bound): Fix typo.

diff --git gcc/tree-ssa-loop-niter.c gcc/tree-ssa-loop-niter.c
index 8ba365c..d17227f 100644
--- gcc/tree-ssa-loop-niter.c
+++ gcc/tree-ssa-loop-niter.c
@@ -3417,7 +3417,7 @@ maybe_lower_iteration_bound (struct loop *loop)
}
}
 
- if (exit_warned  !problem_stmts.empty ())
+ if (exit_warned  !problem_stmts.is_empty ())
{
  gimple stmt;
  int index;

Marek


[C++ PATCH] Allow void type as a literal type in C++14

2014-11-21 Thread Marek Polacek
I noticed that C++14 [basic.types] says that a type is a literal type
if it is: void, [...].  Yet our literal_type_p doesn't consider void
type as a literal type.  The following is an attempt to fix that along
with a testcase.  It seems that void was only added in C++14, so check
for cxx14 as well.

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-21  Marek Polacek  pola...@redhat.com

* constexpr.c (literal_type_p): Return true for void type in C++14.

* g++.dg/cpp0x/constexpr-function2.C: Limit dg-error to C++11.
* g++.dg/cpp0x/constexpr-neg1.C: Likewise.
* g++.dg/cpp1y/constexpr-void1.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 2678223..0a258cf 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -59,7 +59,8 @@ literal_type_p (tree t)
 {
   if (SCALAR_TYPE_P (t)
   || TREE_CODE (t) == VECTOR_TYPE
-  || TREE_CODE (t) == REFERENCE_TYPE)
+  || TREE_CODE (t) == REFERENCE_TYPE
+  || (VOID_TYPE_P (t)  cxx_dialect = cxx14))
 return true;
   if (CLASS_TYPE_P (t))
 {
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C 
gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C
index 8c51c9d..95ee244 100644
--- gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C
@@ -23,7 +23,7 @@ constexpr int area = squarei(side); // { dg-error 
side|argument }
 int next(constexpr int x) // { dg-error parameter }
 { return x + 1; }
 
-constexpr void f(int x)   // { dg-error return type .void }
+constexpr void f(int x)   // { dg-error return type .void  { target 
c++11_only } }
 { /* ... */ }
 
 constexpr int prev(int x)
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C 
gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
index 35f5e8e..dfa1d6b 100644
--- gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
@@ -29,7 +29,7 @@ int next(constexpr int x) {   // { dg-error parameter }
 extern constexpr int memsz;// { dg-error definition }
 
 // error: return type is void
-constexpr void f(int x)// { dg-error void }
+constexpr void f(int x)// { dg-error void  { target 
c++11_only } }
 { /* ... */ }
 // error: use of decrement
 constexpr int prev(int x)
diff --git gcc/testsuite/g++.dg/cpp1y/constexpr-void1.C 
gcc/testsuite/g++.dg/cpp1y/constexpr-void1.C
index e69de29..10ef5bc 100644
--- gcc/testsuite/g++.dg/cpp1y/constexpr-void1.C
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-void1.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++14 } }
+
+struct S
+{
+  int i = 20;
+
+  constexpr void
+  foo (void)
+  {
+if (i  20)
+  __builtin_abort ();
+  }
+};

Marek


[C++ PATCH] Detect UB in shifts in constexpr functions

2014-11-24 Thread Marek Polacek
Constant expressions can't contain undefined behavior, which means that
using an expression containing UB in a context requiring a constant
expression makes the program invalid and we're required to diagnose that.
We fail to diagnose UB if using shifts, because fold_binary_loc returns
zero for a shift containing UB.  So I wrote a function that checks whether
the shift operation is ok.
I'm not sure yet if anything else needs similar treatment.

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-24  Marek Polacek  pola...@redhat.com

* constexpr.c (cxx_eval_check_shift_p): New function.
(cxx_eval_binary_expression): Call it.

* g++.dg/cpp0x/constexpr-shift1.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 2678223..2047a09 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -1451,6 +1451,43 @@ verify_constant (tree t, bool allow_non_constant, bool 
*non_constant_p,
   return *non_constant_p;
 }
 
+/* Return true if the shift operation on LHS and RHS is undefined.  */
+
+static bool
+cxx_eval_check_shift_p (enum tree_code code, tree lhs, tree rhs)
+{
+  if (code != LSHIFT_EXPR  code != RSHIFT_EXPR)
+return false;
+
+  tree lhstype = TREE_TYPE (lhs);
+  unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
+
+  /* [expr.shift] The behavior is undefined if the right operand
+ is negative, or greater than or equal to the length in bits
+ of the promoted left operand.  */
+  if (tree_int_cst_sgn (rhs) == -1 || compare_tree_int (rhs, uprec) = 0)
+return true;
+
+  /* The value of E1  E2 is E1 left-shifted E2 bit positions; [...]
+ if E1 has a signed type and non-negative value, and E1x2^E2 is
+ representable in the corresponding unsigned type of the result type,
+ then that value, converted to the result type, is the resulting value;
+ otherwise, the behavior is undefined.  */
+  if (code == LSHIFT_EXPR  !TYPE_UNSIGNED (lhstype))
+{
+  if (tree_int_cst_sgn (lhs) == -1)
+   return true;
+  tree t = build_int_cst (unsigned_type_node, uprec - 1);
+  t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
+  tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
+  t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
+  if (tree_int_cst_lt (integer_one_node, t))
+   return true;
+}
+
+  return false;
+}
+
 /* Subroutine of cxx_eval_constant_expression.
Attempt to reduce the unary expression tree T to a compile time value.
If successful, return the value.  Otherwise issue a diagnostic
@@ -1506,7 +1543,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, 
tree t,
   enum tree_code code = TREE_CODE (t);
   tree type = TREE_TYPE (t);
   r = fold_binary_loc (loc, code, type, lhs, rhs);
-  if (r == NULL_TREE)
+  if (r == NULL_TREE || cxx_eval_check_shift_p (code, lhs, rhs))
 {
   if (lhs == orig_lhs  rhs == orig_rhs)
r = t;
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C 
gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
index e69de29..2551fbe 100644
--- gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
@@ -0,0 +1,73 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int
+fn1 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i1 = fn1 (1, -1);
+
+constexpr int
+fn2 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i2 = fn2 (1, 200);
+
+constexpr int
+fn3 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i3 = fn3 (-1, 2);
+
+constexpr int
+fn4 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i4 = fn4 (__INT_MAX__, 2);
+
+constexpr int
+fn5 (int i, int j)
+{
+  return i  j;
+}
+
+constexpr int i5 = fn5 (__INT_MAX__, 1);
+
+constexpr int
+fn6 (unsigned int i, unsigned int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i6 = fn6 (1, -1);
+
+constexpr int
+fn7 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i7 = fn7 (1, -1);
+
+constexpr int
+fn8 (int i, int j)
+{
+  return i  j;
+}
+
+constexpr int i8 = fn8 (-1, 1);
+
+constexpr int
+fn9 (int i, int j)
+{
+  return i  j;  // { dg-error is not a constant expression }
+}
+
+constexpr int i9 = fn9 (1, 200);

Marek


[C PATCH] Fix PR63877

2014-11-24 Thread Marek Polacek
This PR is basically the same as PR54113, except this time it's about
-Wmissing-declarations and not about -Wmissing-prototypes.  The problem
here is that we were emitting bogus warning for a correct use of an
inline function.  Thus fixed in the same way as PR54113, that is, don't
warn for inline functions.

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-24  Marek Polacek  pola...@redhat.com

PR c/63877
* c-decl.c (start_function): Disable -Wmissing-declarations warning
for inline functions.

* gcc.dg/pr63877.c: New test.

diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index 9288e2c..6413e6f 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -8353,7 +8353,8 @@ start_function (struct c_declspecs *declspecs, struct 
c_declarator *declarator,
   else if (warn_missing_declarations
TREE_PUBLIC (decl1)
old_decl == 0
-   !MAIN_NAME_P (DECL_NAME (decl1)))
+   !MAIN_NAME_P (DECL_NAME (decl1))
+   !DECL_DECLARED_INLINE_P (decl1))
 warning_at (loc, OPT_Wmissing_declarations,
no previous declaration for %qD,
decl1);
diff --git gcc/testsuite/gcc.dg/pr63877.c gcc/testsuite/gcc.dg/pr63877.c
index e69de29..5969b39 100644
--- gcc/testsuite/gcc.dg/pr63877.c
+++ gcc/testsuite/gcc.dg/pr63877.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options -Wmissing-declarations } */
+
+inline int foo (void) { return 42; } /* { dg-bogus no previous declaration } 
*/
+extern int foo (void);

Marek


Re: [C++ PATCH] Detect UB in shifts in constexpr functions

2014-11-24 Thread Marek Polacek
On Mon, Nov 24, 2014 at 04:49:25PM +0100, Jakub Jelinek wrote:
 On Mon, Nov 24, 2014 at 02:51:14PM +0100, Marek Polacek wrote:
  --- gcc/cp/constexpr.c
  +++ gcc/cp/constexpr.c
  @@ -1451,6 +1451,43 @@ verify_constant (tree t, bool allow_non_constant, 
  bool *non_constant_p,
 return *non_constant_p;
   }
   
  +/* Return true if the shift operation on LHS and RHS is undefined.  */
  +
  +static bool
  +cxx_eval_check_shift_p (enum tree_code code, tree lhs, tree rhs)
  +{
  +  if (code != LSHIFT_EXPR  code != RSHIFT_EXPR)
  +return false;
  +
  +  tree lhstype = TREE_TYPE (lhs);
  +  unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
  +
  +  /* [expr.shift] The behavior is undefined if the right operand
  + is negative, or greater than or equal to the length in bits
  + of the promoted left operand.  */
  +  if (tree_int_cst_sgn (rhs) == -1 || compare_tree_int (rhs, uprec) = 0)
  +return true;
 
 I think VERIFY_CONSTANT doesn't guarantee both operands are INTEGER_CSTs.

Oh well.  I ran the testsuite with an assert checking that I always have
INTEGER_CSTs and didn't see any ICEs.

 Consider say:
 
 constexpr int p = 1;
 constexpr int foo (int a)
 {
   return a  (int) p;
 }
 constexpr int bar (int a)
 {
   return ((int) p)  a;
 }
 constexpr int q = foo (5);
 constexpr int r = bar (2);
 constexpr int s = bar (0);
 
 Now, for foo (5) and bar (2) fold_binary_loc returns NULL and thus
 your cxx_eval_check_shift_p is not called, for bar (0) it returns
 non-NULL and while the result still is not a constant expression and
 right now is diagnosed, with your patch it would ICE.
 
 So, I'd just return false if either lhs or rhs are not INTEGER_CSTs.
 
Ok, I'll add that.  Thank for pointing that out.

  +
  +  /* The value of E1  E2 is E1 left-shifted E2 bit positions; [...]
  + if E1 has a signed type and non-negative value, and E1x2^E2 is
  + representable in the corresponding unsigned type of the result type,
  + then that value, converted to the result type, is the resulting value;
  + otherwise, the behavior is undefined.  */
  +  if (code == LSHIFT_EXPR  !TYPE_UNSIGNED (lhstype))
  +{
  +  if (tree_int_cst_sgn (lhs) == -1)
  +   return true;
  +  tree t = build_int_cst (unsigned_type_node, uprec - 1);
  +  t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
  +  tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
  +  t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
  +  if (tree_int_cst_lt (integer_one_node, t))
  +   return true;
 
 I'll leave to Jason whether this shouldn't be using the various
 cxx_eval_*_expression calls instead, or perhaps int_const_binop or wide_int
 stuff directly.

ISTR int_const_binop calls wide_int routines wi::rshift/wi::lshift and these
return 0 and do not have any overflow flag, so that might not help (?).

Marek


Re: [C++ PATCH] Detect UB in shifts in constexpr functions

2014-11-24 Thread Marek Polacek
On Mon, Nov 24, 2014 at 05:05:08PM +0100, Jakub Jelinek wrote:
 On Mon, Nov 24, 2014 at 04:58:22PM +0100, Marek Polacek wrote:
   Consider say:
   
   constexpr int p = 1;
   constexpr int foo (int a)
   {
 return a  (int) p;
   }
   constexpr int bar (int a)
   {
 return ((int) p)  a;
   }
   constexpr int q = foo (5);
   constexpr int r = bar (2);
   constexpr int s = bar (0);
   
   Now, for foo (5) and bar (2) fold_binary_loc returns NULL and thus
   your cxx_eval_check_shift_p is not called, for bar (0) it returns
   non-NULL and while the result still is not a constant expression and
   right now is diagnosed, with your patch it would ICE.
   
   So, I'd just return false if either lhs or rhs are not INTEGER_CSTs.
   
  Ok, I'll add that.  Thank for pointing that out.
 
 Note, the above only with -m32 obviously, or supposedly for bar
 you could change return type and the cast and type of r/s to
 __PTRDIFF_TYPE__ or so.  foo, as gcc always casts the shift count to int,
 would supposedly need to stay the way it is and might produce different
 diagnostics between -m32 and -m64.

I changed int to __PTRDIFF_TYPE__.
You're right: with -m64 I get:
i.C: In function ‘constexpr int foo(int)’:
i.C:4:22: error: cast from ‘const int*’ to ‘int’ loses precision [-fpermissive]
   return a  (int) p;
  ^
but not with -m32.  I dropped the foo from the testcase.

 I meant for the above computation, there you don't check any overflow.

I see.  I'm happy to change it, whatever you/Jason prefer.

The following is a version with INTEGER_CST check and a new test.

2014-11-24  Marek Polacek  pola...@redhat.com

* constexpr.c (cxx_eval_check_shift_p): New function.
(cxx_eval_binary_expression): Call it.

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

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 2678223..049ec0f 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -1451,6 +1451,45 @@ verify_constant (tree t, bool allow_non_constant, bool 
*non_constant_p,
   return *non_constant_p;
 }
 
+/* Return true if the shift operation on LHS and RHS is undefined.  */
+
+static bool
+cxx_eval_check_shift_p (enum tree_code code, tree lhs, tree rhs)
+{
+  if ((code != LSHIFT_EXPR  code != RSHIFT_EXPR)
+  || TREE_CODE (lhs) != INTEGER_CST
+  || TREE_CODE (rhs) != INTEGER_CST)
+return false;
+
+  tree lhstype = TREE_TYPE (lhs);
+  unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
+
+  /* [expr.shift] The behavior is undefined if the right operand
+ is negative, or greater than or equal to the length in bits
+ of the promoted left operand.  */
+  if (tree_int_cst_sgn (rhs) == -1 || compare_tree_int (rhs, uprec) = 0)
+return true;
+
+  /* The value of E1  E2 is E1 left-shifted E2 bit positions; [...]
+ if E1 has a signed type and non-negative value, and E1x2^E2 is
+ representable in the corresponding unsigned type of the result type,
+ then that value, converted to the result type, is the resulting value;
+ otherwise, the behavior is undefined.  */
+  if (code == LSHIFT_EXPR  !TYPE_UNSIGNED (lhstype))
+{
+  if (tree_int_cst_sgn (lhs) == -1)
+   return true;
+  tree t = build_int_cst (unsigned_type_node, uprec - 1);
+  t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
+  tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
+  t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
+  if (tree_int_cst_lt (integer_one_node, t))
+   return true;
+}
+
+  return false;
+}
+
 /* Subroutine of cxx_eval_constant_expression.
Attempt to reduce the unary expression tree T to a compile time value.
If successful, return the value.  Otherwise issue a diagnostic
@@ -1506,7 +1545,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, 
tree t,
   enum tree_code code = TREE_CODE (t);
   tree type = TREE_TYPE (t);
   r = fold_binary_loc (loc, code, type, lhs, rhs);
-  if (r == NULL_TREE)
+  if (r == NULL_TREE || cxx_eval_check_shift_p (code, lhs, rhs))
 {
   if (lhs == orig_lhs  rhs == orig_rhs)
r = t;
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C 
gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
index e69de29..2551fbe 100644
--- gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
@@ -0,0 +1,73 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int
+fn1 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i1 = fn1 (1, -1);
+
+constexpr int
+fn2 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i2 = fn2 (1, 200);
+
+constexpr int
+fn3 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression }
+}
+
+constexpr int i3 = fn3 (-1, 2);
+
+constexpr int
+fn4 (int i, int j)
+{
+  return i  j; // { dg-error is not a constant expression

Re: [PATCH] Fix sanitizer/63788

2014-11-26 Thread Marek Polacek
Ping.

On Wed, Nov 19, 2014 at 08:09:21PM +0100, Marek Polacek wrote:
 As discussed in the PR, the problem here is that when running gfortran,
 the __builtin_object_size decl isn't available, because c-family's
 c_define_builtins wasn't called.  One way how to fix this is to build
 the __builtin_object_size decl in initialize_sanitizer_builtins, if
 needed.  Alternatively we could just bail in instrument_object_size
 if builtin_decl_explicit (BUILT_IN_OBJECT_SIZE) returns NULL_TREE...
 
 No test attached since we don't have any Fortran ubsan infrastructure,
 I've just tried
 ./xgcc -B ./ -B ../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ 
 -Wl,-rpath=../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -B 
 ../x86_64-unknown-linux-gnu/libgfortran/.libs/ -O -fsanitize=undefined 
 testcase.f -lgfortran; ./a.out
 on the testcase attached in PR - and it doesn't ICE.
 
 Bootstrapped/regtested on ppc64-linux, ok for trunk?
 
 2014-11-19  Marek Polacek  pola...@redhat.com
 
   PR sanitizer/63788
   * asan.c (initialize_sanitizer_builtins): Add BT_FN_SIZE_CONST_PTR_INT
   var.  Conditionally build BUILT_IN_OBJECT_SIZE decl.
   (ATTR_PURE_NOTHROW_LEAF_LIST): Define.
 
 diff --git gcc/asan.c gcc/asan.c
 index ff08f1b..c2ed3d5 100644
 --- gcc/asan.c
 +++ gcc/asan.c
 @@ -2294,6 +2294,9 @@ initialize_sanitizer_builtins (void)
   pointer_sized_int_node, NULL_TREE);
tree BT_FN_VOID_INT
  = build_function_type_list (void_type_node, integer_type_node, 
 NULL_TREE);
 +  tree BT_FN_SIZE_CONST_PTR_INT
 += build_function_type_list (size_type_node, const_ptr_type_node,
 + integer_type_node, NULL_TREE);
tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
tree BT_FN_IX_CONST_VPTR_INT[5];
tree BT_FN_IX_VPTR_IX_INT[5];
 @@ -2365,6 +2368,8 @@ initialize_sanitizer_builtins (void)
  #undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
  #define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
/* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
 +#undef ATTR_PURE_NOTHROW_LEAF_LIST
 +#define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
  #undef DEF_SANITIZER_BUILTIN
  #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
decl = add_builtin_function (__builtin_ NAME, TYPE, ENUM,
 \
 @@ -2374,6 +2379,15 @@ initialize_sanitizer_builtins (void)
  
  #include sanitizer.def
  
 +  /* -fsanitize=object-size uses __builtin_object_size, but that might
 + not be available for e.g. Fortran at this point.  We use
 + DEF_SANITIZER_BUILTIN here only as a convenience macro.  */
 +  if ((flag_sanitize  SANITIZE_OBJECT_SIZE)
 +   !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
 +DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, object_size,
 +BT_FN_SIZE_CONST_PTR_INT,
 +ATTR_PURE_NOTHROW_LEAF_LIST)
 +
  #undef DEF_SANITIZER_BUILTIN
  }
  
 
   Marek

Marek


[C/C++ PATCH] Don't convert RHS of a shift-expression to int (PR c/63862)

2014-11-26 Thread Marek Polacek
Both C11 and C++14 standards specify that integral promotions are
performed on both operands of a shift-expression.  This we do just
fine.  But then we convert the right operand to integer_type_node.
Not only is this unnecessary, it can also be harfmul, because for
e.g. 
void
foo (unsigned int x)
{
  if (-1  x != -1)
bar ();
}
with (int) x we lose info that x is nonnegative, which means that
tree_expr_nonnegative_p cannot fold this expr.  Another problem
with the conversion is that we weren't able to detect e.g. shift
by 0x1ULL, since after the conversion this is 0.

This patch does away with the conversion to integer type for both
C and C++ FEs.  It exposed an ubsan bug where I was using incorrect
type for a MINUS_EXPR.  With this patch, the XFAIL in shiftopt-1.c
is not needed anymore.

Joseph, is that C FE part ok?
Jason, is that C++ FE part ok?
Jakub, is that ubsan part ok?

Bootstrapped/regtested on ppc64-linux; ubsan.exp tested even on x86_64.

2014-11-26  Marek Polacek  pola...@redhat.com

PR c/63862
c-family/
* c-ubsan.c (ubsan_instrument_shift): Change the type of a MINUS_EXPR
to op1_utype.
c/
* c-typeck.c (build_binary_op) RSHIFT_EXPR, LSHIFT_EXPR: Don't
convert the right operand to integer type.
cp/
* typeck.c (cp_build_binary_op) RSHIFT_EXPR, LSHIFT_EXPR: Don't
convert the right operand to integer type.
testsuite/
* gcc.c-torture/execute/shiftopt-1.c: Don't XFAIL anymore.
* c-c++-common/ubsan/shift-7.c: New test.

diff --git gcc/c-family/c-ubsan.c gcc/c-family/c-ubsan.c
index 90b03f2..96afc67 100644
--- gcc/c-family/c-ubsan.c
+++ gcc/c-family/c-ubsan.c
@@ -151,7 +151,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
!TYPE_UNSIGNED (type0)
flag_isoc99)
 {
-  tree x = fold_build2 (MINUS_EXPR, unsigned_type_node, uprecm1,
+  tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
fold_convert (op1_utype, op1));
   tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
   tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 67efb46..bf0f306 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -10513,11 +10513,6 @@ build_binary_op (location_t location, enum tree_code 
code,
 
  /* Use the type of the value to be shifted.  */
  result_type = type0;
- /* Convert the non vector shift-count to an integer, regardless
-of size of value being shifted.  */
- if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
-  TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = convert (integer_type_node, op1);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
@@ -10563,11 +10558,6 @@ build_binary_op (location_t location, enum tree_code 
code,
 
  /* Use the type of the value to be shifted.  */
  result_type = type0;
- /* Convert the non vector shift-count to an integer, regardless
-of size of value being shifted.  */
- if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
-  TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = convert (integer_type_node, op1);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
diff --git gcc/cp/typeck.c gcc/cp/typeck.c
index 8b66acc..6ca346b 100644
--- gcc/cp/typeck.c
+++ gcc/cp/typeck.c
@@ -4295,10 +4295,6 @@ cp_build_binary_op (location_t location,
 right shift count = width of type);
}
}
- /* Convert the shift-count to an integer, regardless of
-size of value being shifted.  */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = cp_convert (integer_type_node, op1, complain);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
@@ -4344,10 +4340,6 @@ cp_build_binary_op (location_t location,
 left shift count = width of type);
}
}
- /* Convert the shift-count to an integer, regardless of
-size of value being shifted.  */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = cp_convert (integer_type_node, op1, complain);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
diff --git gcc/testsuite/c-c++-common/ubsan/shift-7.c 
gcc/testsuite/c-c++-common/ubsan/shift-7.c
index e69de29..1e33273 100644
--- gcc/testsuite/c-c++-common/ubsan/shift-7.c
+++ gcc/testsuite/c-c++-common/ubsan/shift-7.c
@@ -0,0 +1,27 @@
+/* PR c/63862 */
+/* { dg-do run } */
+/* { dg-options -fsanitize=undefined } */
+
+unsigned long long int __attribute__ ((noinline, noclone))
+foo (unsigned long long int i, unsigned long long int j)
+{
+  asm ();
+  return i  j

Re: [C/C++ PATCH] Don't convert RHS of a shift-expression to int (PR c/63862)

2014-11-26 Thread Marek Polacek
On Wed, Nov 26, 2014 at 06:50:29PM +0100, Jakub Jelinek wrote:
 On Wed, Nov 26, 2014 at 06:39:44PM +0100, Marek Polacek wrote:
  Both C11 and C++14 standards specify that integral promotions are
  performed on both operands of a shift-expression.  This we do just
  fine.  But then we convert the right operand to integer_type_node.
  Not only is this unnecessary, it can also be harfmul, because for
  e.g. 
  void
  foo (unsigned int x)
  {
if (-1  x != -1)
  bar ();
  }
  with (int) x we lose info that x is nonnegative, which means that
  tree_expr_nonnegative_p cannot fold this expr.  Another problem
  with the conversion is that we weren't able to detect e.g. shift
  by 0x1ULL, since after the conversion this is 0.
 
 Have you checked what the expander does with it?  Say trying to
 shift something by __int128 count or similar might upset it.

I tried
int
main ()
{
  __int128 x = 1;
  __int128 y = 200;
  __int128 z;
  asm ( : +g (x), +g (y));
  z = x  y;
  asm ( : +g (z));
  return z;
}
and that works (even with ubsan) as expected.  I haven't checked .expand
(I don't think I'd be able to judge the difference anyway), but on the
testcase above the assembly is the same with -O, with -O0 I see:

movq%rbx, -24(%rbp)
movq%rax, -48(%rbp)
movq%rdx, -40(%rbp)
-   movq-48(%rbp), %rax
-   movl%eax, %ecx
movq-32(%rbp), %rax
movq-24(%rbp), %rdx
+   movzbl  -48(%rbp), %ecx
shldq   %rax, %rdx
salq%cl, %rax
testb   $64, %cl

 Wonder about if we don't make similar assumptions in the middle-end.
 It might make a difference (sometimes positive, sometimes negative)
 for vectorization too.
 
I don't really know; I assume the testsuite would have catched it if
something went awry.

  2014-11-26  Marek Polacek  pola...@redhat.com
  
  PR c/63862
  c-family/
  * c-ubsan.c (ubsan_instrument_shift): Change the type of a MINUS_EXPR
  to op1_utype.
 
 This part is ok regardless of the rest.

Thanks,

Marek


Re: [PATCH] Fix ubsan and C++14 constexpr ICEs (PR sanitizer/63956)

2014-11-27 Thread Marek Polacek
On Wed, Nov 26, 2014 at 12:03:45PM -0500, Jason Merrill wrote:
 On 11/20/2014 02:04 PM, Marek Polacek wrote:
 +  if (fun == NULL_TREE)
 +switch (CALL_EXPR_IFN (t))
 +  {
 +  case IFN_UBSAN_NULL:
 +  case IFN_UBSAN_BOUNDS:
 +return void_node;
 +  default:
 +break;
 +  }
 
 Other IFNs should make the call non-constant.

Ok.
 
 -/* { dg-error is not a constant expression  { target c++ } 12 } */
 +/* { dg-warning right shift count is negative  { target c++ } 12 } */
 
 This should be an xfail (pending the delayed folding work) instead of a
 different test.

Just to check that I understand correctly, the point is that with
delayed folding we'd give an error here?

I added the xfails.

 +constexpr int n3 = fn7 ((const int *) 0, 8); // { dg-error is not a 
 constant expression|constexpr call flows off }
 
 The flows off the end error is a bug and should not be tested for. I'm
 going to check in a fix.

Fixed.

Bootstrapped/regtested on ppc64-linux.

2014-11-27  Marek Polacek  pola...@redhat.com

PR sanitizer/63956
* ubsan.c (is_ubsan_builtin_p): Check also built-in class.
cp/
* constexpr.c: Include ubsan.h.
(cxx_eval_call_expression): Bail out for IFN_UBSAN_{NULL,BOUNDS}
internal functions and for ubsan builtins.
* error.c: Include internal-fn.h.
(dump_expr): Add printing of internal functions.
testsuite/
* c-c++-common/ubsan/shift-5.c: Add xfails.
* g++.dg/ubsan/div-by-zero-1.C: Don't use -w.  Add xfail.
* g++.dg/ubsan/pr63956.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index ef9ef70..45d5959 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include gimplify.h
 #include builtins.h
 #include tree-inline.h
+#include ubsan.h
 
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X) \
@@ -1151,6 +1152,19 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
   constexpr_call *entry;
   bool depth_ok;
 
+  if (fun == NULL_TREE)
+switch (CALL_EXPR_IFN (t))
+  {
+  case IFN_UBSAN_NULL:
+  case IFN_UBSAN_BOUNDS:
+   return void_node;
+  default:
+   if (!ctx-quiet)
+ error_at (loc, call to internal function);
+   *non_constant_p = true;
+   return t;
+  }
+
   if (TREE_CODE (fun) != FUNCTION_DECL)
 {
   /* Might be a constexpr function pointer.  */
@@ -1171,6 +1185,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
 }
   if (DECL_CLONED_FUNCTION_P (fun))
 fun = DECL_CLONED_FUNCTION (fun);
+
+  if (is_ubsan_builtin_p (fun))
+return void_node;
+
   if (is_builtin_fn (fun))
 return cxx_eval_builtin_function_call (ctx, t,
   addr, non_constant_p, overflow_p);
diff --git gcc/cp/error.c gcc/cp/error.c
index 5dcc149..ff26fb9 100644
--- gcc/cp/error.c
+++ gcc/cp/error.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include tree-pretty-print.h
 #include c-family/c-objc.h
 #include ubsan.h
+#include internal-fn.h
 
 #include new// For placement-new.
 
@@ -2039,6 +2040,14 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
tree fn = CALL_EXPR_FN (t);
bool skipfirst = false;
 
+   /* Deal with internal functions.  */
+   if (fn == NULL_TREE)
+ {
+   pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t)));
+   dump_call_expr_args (pp, t, flags, skipfirst);
+   break;
+ }
+
if (TREE_CODE (fn) == ADDR_EXPR)
  fn = TREE_OPERAND (fn, 0);
 
diff --git gcc/testsuite/c-c++-common/ubsan/shift-5.c 
gcc/testsuite/c-c++-common/ubsan/shift-5.c
index 6f9c52a..d779571 100644
--- gcc/testsuite/c-c++-common/ubsan/shift-5.c
+++ gcc/testsuite/c-c++-common/ubsan/shift-5.c
@@ -2,31 +2,41 @@
 /* { dg-options -fsanitize=shift -w } */
 /* { dg-shouldfail ubsan } */
 
-int x;
 int
-foo (void)
+foo (int x)
 {
   /* None of the following should pass.  */
   switch (x)
 {
 case 1  -1:
-/* { dg-error case label does not reduce to an integer constant  {target c 
} 12 } */
-/* { dg-error is not a constant expression  { target c++ } 12 } */
+/* { dg-error case label does not reduce to an integer constant  { target 
c } 11 } */
+/* { dg-error   { xfail { *-*-* } } 11 } */
 case -1  -1:
-/* { dg-error case label does not reduce to an integer constant  {target c 
} 15 } */
-/* { dg-error is not a constant expression  { target c++ } 15 } */
+/* { dg-error case label does not reduce to an integer constant  { target 
c } 14 } */
+/* { dg-error   { xfail { *-*-* } } 14 } */
 case 1  -1:
-/* { dg-error case label does not reduce to an integer constant  {target c 
} 18 } */
-/* { dg-error is not a constant expression  { target c++ } 18 } */
+/* { dg-error case label does not reduce to an integer constant  { target 
c

Re: [C++ PATCH] Detect UB in shifts in constexpr functions

2014-11-27 Thread Marek Polacek
On Wed, Nov 26, 2014 at 11:56:26AM -0500, Jason Merrill wrote:
 Please give diagnostics explaining what's wrong with the shift rather than
 the generic is not a constant expression.

Done.
 
 +  tree t = build_int_cst (unsigned_type_node, uprec - 1);
 +  t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
 +  tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
 +  t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
 +  if (tree_int_cst_lt (integer_one_node, t))
 
 This could also use a comment explaining the logic.

Ok.

How about the following then?

Bootstrapped/regtested on ppc64-linux.

2014-11-27  Marek Polacek  pola...@redhat.com

* constexpr.c (cxx_eval_check_shift_p): New function.
(cxx_eval_binary_expression): Call it.

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

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index ef9ef70..d305298 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -1451,6 +1451,48 @@ verify_constant (tree t, bool allow_non_constant, bool 
*non_constant_p,
   return *non_constant_p;
 }
 
+/* Return true if the shift operation on LHS and RHS is undefined.  */
+
+static bool
+cxx_eval_check_shift_p (enum tree_code code, tree lhs, tree rhs)
+{
+  if ((code != LSHIFT_EXPR  code != RSHIFT_EXPR)
+  || TREE_CODE (lhs) != INTEGER_CST
+  || TREE_CODE (rhs) != INTEGER_CST)
+return false;
+
+  tree lhstype = TREE_TYPE (lhs);
+  unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
+
+  /* [expr.shift] The behavior is undefined if the right operand
+ is negative, or greater than or equal to the length in bits
+ of the promoted left operand.  */
+  if (tree_int_cst_sgn (rhs) == -1 || compare_tree_int (rhs, uprec) = 0)
+return true;
+
+  /* The value of E1  E2 is E1 left-shifted E2 bit positions; [...]
+ if E1 has a signed type and non-negative value, and E1x2^E2 is
+ representable in the corresponding unsigned type of the result type,
+ then that value, converted to the result type, is the resulting value;
+ otherwise, the behavior is undefined.  */
+  if (code == LSHIFT_EXPR  !TYPE_UNSIGNED (lhstype))
+{
+  if (tree_int_cst_sgn (lhs) == -1)
+   return true;
+  /* For signed x  y the following:
+(unsigned) x  ((prec (lhs) - 1) - y)
+if  1, is undefined.  */
+  tree t = build_int_cst (unsigned_type_node, uprec - 1);
+  t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
+  tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
+  t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
+  if (tree_int_cst_lt (integer_one_node, t))
+   return true;
+}
+
+  return false;
+}
+
 /* Subroutine of cxx_eval_constant_expression.
Attempt to reduce the unary expression tree T to a compile time value.
If successful, return the value.  Otherwise issue a diagnostic
@@ -1513,6 +1555,9 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, 
tree t,
   else
r = build2_loc (loc, code, type, lhs, rhs);
 }
+  else if (cxx_eval_check_shift_p (code, lhs, rhs))
+error_at (loc, shift expression %q+E overflows,
+ build2_loc (loc, code, type, lhs, rhs));
   VERIFY_CONSTANT (r);
   return r;
 }
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C 
gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
index e69de29..48c2ab1 100644
--- gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-shift1.C
@@ -0,0 +1,73 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int
+fn1 (int i, int j)
+{
+  return i  j; // { dg-error shift expression }
+}
+
+constexpr int i1 = fn1 (1, -1);
+
+constexpr int
+fn2 (int i, int j)
+{
+  return i  j; // { dg-error shift expression }
+}
+
+constexpr int i2 = fn2 (1, 200);
+
+constexpr int
+fn3 (int i, int j)
+{
+  return i  j; // { dg-error shift expression }
+}
+
+constexpr int i3 = fn3 (-1, 2);
+
+constexpr int
+fn4 (int i, int j)
+{
+  return i  j; // { dg-error shift expression }
+}
+
+constexpr int i4 = fn4 (__INT_MAX__, 2);
+
+constexpr int
+fn5 (int i, int j)
+{
+  return i  j;
+}
+
+constexpr int i5 = fn5 (__INT_MAX__, 1);
+
+constexpr int
+fn6 (unsigned int i, unsigned int j)
+{
+  return i  j; // { dg-error shift expression }
+}
+
+constexpr int i6 = fn6 (1, -1);
+
+constexpr int
+fn7 (int i, int j)
+{
+  return i  j; // { dg-error shift expression }
+}
+
+constexpr int i7 = fn7 (1, -1);
+
+constexpr int
+fn8 (int i, int j)
+{
+  return i  j;
+}
+
+constexpr int i8 = fn8 (-1, 1);
+
+constexpr int
+fn9 (int i, int j)
+{
+  return i  j;  // { dg-error shift expression }
+}
+
+constexpr int i9 = fn9 (1, 200);
diff --git gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C 
gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C
index e69de29..a739fd2 100644
--- gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C
@@ -0,0 +1,9 @@
+// { dg-do

Re: [C/C++ PATCH] Don't convert RHS of a shift-expression to int (PR c/63862)

2014-11-27 Thread Marek Polacek
On Thu, Nov 27, 2014 at 10:56:06AM +0100, Richard Biener wrote:
 But then rather than using integer_type_node I'd convert to
 unsigned_type_node (if that doesn't work you know we have some nasty
 dependence on negative shift counts working)

Yeah, I think adding the conversion into c_gimplify_expr is the best
thing we can do until we have type demotion/promotion pass.  Seems
that unsigned_type_node there works well.
(What happened to Kai's type elevation pass?)

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-27  Marek Polacek  pola...@redhat.com

PR c/63862
c-family/
* c-ubsan.c (ubsan_instrument_shift): Change the type of a MINUS_EXPR
to op1_utype.
* c-gimplify.c (c_gimplify_expr): Convert right operand of a shift
expression to unsigned_type_node.
c/
* c-typeck.c (build_binary_op) RSHIFT_EXPR, LSHIFT_EXPR: Don't
convert the right operand to integer type.
cp/
* typeck.c (cp_build_binary_op) RSHIFT_EXPR, LSHIFT_EXPR: Don't
convert the right operand to integer type.
testsuite/
* gcc.c-torture/execute/shiftopt-1.c: Don't XFAIL anymore.
* c-c++-common/ubsan/shift-7.c: New test.

diff --git gcc/c-family/c-gimplify.c gcc/c-family/c-gimplify.c
index 85b4223..8e0eb4c 100644
--- gcc/c-family/c-gimplify.c
+++ gcc/c-family/c-gimplify.c
@@ -242,6 +242,24 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p 
ATTRIBUTE_UNUSED,
 
   switch (code)
 {
+case LSHIFT_EXPR:
+case RSHIFT_EXPR:
+  {
+   /* We used to convert the right operand of a shift-expression
+  to an integer_type_node in the FEs.  But it is unnecessary
+  and not desirable for diagnostics and sanitizers.  We keep
+  this here to not pessimize the code, but we convert to an
+  unsigned type, because negative shift counts are undefined
+  anyway.
+  We should get rid of this conversion when we have a proper
+  type demotion/promotion pass.  */
+   tree *op1_p = TREE_OPERAND (*expr_p, 1);
+   if (TREE_CODE (TREE_TYPE (*op1_p)) != VECTOR_TYPE
+TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)) != unsigned_type_node)
+ *op1_p = convert (unsigned_type_node, *op1_p);
+   break;
+  }
+
 case DECL_EXPR:
   /* This is handled mostly by gimplify.c, but we have to deal with
 not warning about int x = x; as it is a GCC extension to turn off
diff --git gcc/c-family/c-ubsan.c gcc/c-family/c-ubsan.c
index 90b03f2..96afc67 100644
--- gcc/c-family/c-ubsan.c
+++ gcc/c-family/c-ubsan.c
@@ -151,7 +151,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
!TYPE_UNSIGNED (type0)
flag_isoc99)
 {
-  tree x = fold_build2 (MINUS_EXPR, unsigned_type_node, uprecm1,
+  tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
fold_convert (op1_utype, op1));
   tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
   tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 67efb46..bf0f306 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -10513,11 +10513,6 @@ build_binary_op (location_t location, enum tree_code 
code,
 
  /* Use the type of the value to be shifted.  */
  result_type = type0;
- /* Convert the non vector shift-count to an integer, regardless
-of size of value being shifted.  */
- if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
-  TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = convert (integer_type_node, op1);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
@@ -10563,11 +10558,6 @@ build_binary_op (location_t location, enum tree_code 
code,
 
  /* Use the type of the value to be shifted.  */
  result_type = type0;
- /* Convert the non vector shift-count to an integer, regardless
-of size of value being shifted.  */
- if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
-  TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = convert (integer_type_node, op1);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
diff --git gcc/cp/typeck.c gcc/cp/typeck.c
index 8b66acc..6ca346b 100644
--- gcc/cp/typeck.c
+++ gcc/cp/typeck.c
@@ -4295,10 +4295,6 @@ cp_build_binary_op (location_t location,
 right shift count = width of type);
}
}
- /* Convert the shift-count to an integer, regardless of
-size of value being shifted.  */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-   op1 = cp_convert (integer_type_node, op1, complain);
  /* Avoid converting op1 to result_type later.  */
  converted = 1;
}
@@ -4344,10 +4340,6 @@ cp_build_binary_op (location_t location

Re: [PATCH] Fix PR preprocessor/58893 access to uninitialized memory

2014-09-26 Thread Marek Polacek
On Fri, Sep 26, 2014 at 02:16:05PM +0200, Bernd Edlinger wrote:
 Boot-Strapped and Regression-tested on x86_64-linux-gnu
 Ok for trunk?

-ENOPATCH.

Marek


[PATCH] gcc.c-torture/ cleanup

2014-09-30 Thread Marek Polacek
I did this as a part of preparing the testsuite to cope with the
(possible) gnu11 default.  But I think it's a reasonable cleanup
on its own.  With gnu11, we'd start to warn about defaulting to
int, missing function declarations, and functions without return
type.  I added -fgnu89-inline when a test relies on a gnu89 inline
semantics, and -std=gnu89 if a test relies on gnu89 standard.

I have patches that cover the rest of C testsuite, but let's do this
piecewise.

Tested on x86_64-linux: vanilla results == results with this patch ==
results with this patch and gnu11 as a default.

Does this approach make sense?

2014-09-30  Marek Polacek  pola...@redhat.com

* gcc.c-torture/compile/2120-2.c: Use -fgnu89-inline.
* gcc.c-torture/compile/2009-1.c: Likewise.
* gcc.c-torture/compile/2009-2.c: Likewise.
* gcc.c-torture/compile/20021120-1.c: Likewise.
* gcc.c-torture/compile/20021120-2.c: Likewise.
* gcc.c-torture/compile/20050215-1.c: Likewise.
* gcc.c-torture/compile/20050215-2.c: Likewise.
* gcc.c-torture/compile/20050215-3.c: Likewise.
* gcc.c-torture/compile/pr37669.c: Likewise.
* gcc.c-torture/execute/20020107-1.c: Likewise.
* gcc.c-torture/execute/restrict-1.c: Likewise.
* gcc.c-torture/compile/20090721-1.c: Fix defaulting to int.
* gcc.c-torture/execute/930529-1.c: Likewise.
* gcc.c-torture/execute/920612-1.c: Likewise.
* gcc.c-torture/execute/920711-1.c: Likewise.
* gcc.c-torture/execute/990127-2.c: Likewise.
* gcc.c-torture/execute/pr40386.c: Likewise.
* gcc.c-torture/execute/pr57124.c: Likewise.
* gcc.c-torture/compile/pr34808.c: Add function declarations.
* gcc.c-torture/compile/pr42299.c: Likewise.
* gcc.c-torture/compile/pr48517.c: Use -std=gnu89.
* gcc.c-torture/compile/simd-6.c: Likewise.
* gcc.c-torture/execute/pr53645-2.c: Likewise.
* gcc.c-torture/execute/pr53645.c: Likewise.
* gcc.c-torture/execute/20001121-1.c: Use -fgnu89-inline.  Add function
declarations.
* gcc.c-torture/execute/980608-1.c: Likewise.
* gcc.c-torture/execute/bcp-1.c: Likewise.
* gcc.c-torture/execute/p18298.c: Likewise.
* gcc.c-torture/execute/unroll-1.c: Likewise.
* gcc.c-torture/execute/va-arg-7.c: Likewise.
* gcc.c-torture/execute/va-arg-8.c: Likewise.
* gcc.c-torture/execute/930526-1.c: Use -fgnu89-inline.  Add function
declarations.  Fix defaulting to int.
* gcc.c-torture/execute/961223-1.c: Likewise.
* gcc.c-torture/execute/loop-2c.c: Use -fgnu89-inline and
-Wno-pointer-to-int-cast.  Fix defaulting to int.

diff --git gcc/gcc/testsuite/gcc.c-torture/compile/2120-2.c 
gcc/gcc/testsuite/gcc.c-torture/compile/2120-2.c
index 737eb92..939c52d 100644
--- gcc/gcc/testsuite/gcc.c-torture/compile/2120-2.c
+++ gcc/gcc/testsuite/gcc.c-torture/compile/2120-2.c
@@ -1,3 +1,5 @@
+/* { dg-options -fgnu89-inline } */
+
 extern __inline__ int
 odd(int i)
 {
diff --git gcc/gcc/testsuite/gcc.c-torture/compile/2009-1.c 
gcc/gcc/testsuite/gcc.c-torture/compile/2009-1.c
index b4b80ae..5d036c9 100644
--- gcc/gcc/testsuite/gcc.c-torture/compile/2009-1.c
+++ gcc/gcc/testsuite/gcc.c-torture/compile/2009-1.c
@@ -1,3 +1,4 @@
+/* { dg-options -fgnu89-inline } */
 /* { dg-require-weak  } */
 /* { dg-require-alias  } */
 #define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
diff --git gcc/gcc/testsuite/gcc.c-torture/compile/2009-2.c 
gcc/gcc/testsuite/gcc.c-torture/compile/2009-2.c
index e06809f..ea1176a 100644
--- gcc/gcc/testsuite/gcc.c-torture/compile/2009-2.c
+++ gcc/gcc/testsuite/gcc.c-torture/compile/2009-2.c
@@ -1,3 +1,4 @@
+/* { dg-options -fgnu89-inline } */
 /* { dg-require-weak  } */
 /* { dg-require-alias  } */
 #define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
diff --git gcc/gcc/testsuite/gcc.c-torture/compile/20021120-1.c 
gcc/gcc/testsuite/gcc.c-torture/compile/20021120-1.c
index 423f8ec..3dc4928 100644
--- gcc/gcc/testsuite/gcc.c-torture/compile/20021120-1.c
+++ gcc/gcc/testsuite/gcc.c-torture/compile/20021120-1.c
@@ -4,6 +4,8 @@
 /* Verify that GCC doesn't get confused by the
redefinition of an extern inline function. */
 
+/* { dg-options -fgnu89-inline } */
+
 extern int inline foo () { return 0; }
 extern int inline bar () { return 0; }
 static int inline bar () { return foo(); }
diff --git gcc/gcc/testsuite/gcc.c-torture/compile/20021120-2.c 
gcc/gcc/testsuite/gcc.c-torture/compile/20021120-2.c
index 51f0e25..cd9eda0 100644
--- gcc/gcc/testsuite/gcc.c-torture/compile/20021120-2.c
+++ gcc/gcc/testsuite/gcc.c-torture/compile/20021120-2.c
@@ -4,6 +4,8 @@
 /* Verify that GCC doesn't get confused by the
redefinition of an extern inline function. */
 
+/* { dg-options -fgnu89-inline } */
+
 extern int inline foo () { return 0; }
 extern int inline bar

[PATCH] gcc.dg/tree-ssa/ cleanup

2014-10-02 Thread Marek Polacek
This patch is a cleanup of tests in gcc.dg/tree-ssa/ directory.
It is quite large, but trivial - mostly only missing declarations
and defaulting to int.  See 
https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02656.html
for more info.

Tested on x86_64-linux: vanilla results == results with this patch ==
results with this patch and gnu11 as a default.

Ok for trunk?

2014-10-02  Marek Polacek  pola...@redhat.com

* gcc.dg/tree-ssa/20030530-2.c: Add function declarations.
* gcc.dg/tree-ssa/20030708-1.c: Likewise.
* gcc.dg/tree-ssa/20030709-2.c: Likewise.
* gcc.dg/tree-ssa/20030710-1.c: Likewise.
* gcc.dg/tree-ssa/20030711-1.c: Likewise.
* gcc.dg/tree-ssa/20030711-2.c: Likewise.
* gcc.dg/tree-ssa/20030711-3.c: Likewise.
* gcc.dg/tree-ssa/20030728-1.c: Likewise.
* gcc.dg/tree-ssa/20030731-1.c: Likewise.
* gcc.dg/tree-ssa/20030731-2.c: Likewise.
* gcc.dg/tree-ssa/20030807-1.c: Likewise.
* gcc.dg/tree-ssa/20030807-3.c: Likewise.
* gcc.dg/tree-ssa/20030807-7.c: Likewise.
* gcc.dg/tree-ssa/20030807-9.c: Likewise.
* gcc.dg/tree-ssa/20030814-2.c: Likewise.
* gcc.dg/tree-ssa/20030814-3.c: Likewise.
* gcc.dg/tree-ssa/20030814-4.c: Likewise.
* gcc.dg/tree-ssa/20030814-5.c: Likewise.
* gcc.dg/tree-ssa/20030820-1.c: Likewise.
* gcc.dg/tree-ssa/20030820-2.c: Likewise.
* gcc.dg/tree-ssa/20030821-1.c: Likewise.
* gcc.dg/tree-ssa/20030917-1.c: Likewise.
* gcc.dg/tree-ssa/20030917-2.c: Likewise.
* gcc.dg/tree-ssa/20031022-1.c: Likewise.
* gcc.dg/tree-ssa/20040209-1.c: Likewise.
* gcc.dg/tree-ssa/20040211-1.c: Likewise.
* gcc.dg/tree-ssa/alias-13.c: Likewise.
* gcc.dg/tree-ssa/alias-28.c: Likewise.
* gcc.dg/tree-ssa/asm-3.c: Likewise.
* gcc.dg/tree-ssa/coalesce-1.c: Likewise.
* gcc.dg/tree-ssa/foldstring-1.c: Likewise.
* gcc.dg/tree-ssa/forwprop-25.c: Likewise.
* gcc.dg/tree-ssa/forwprop-26.c: Likewise.
* gcc.dg/tree-ssa/isolate-3.c: Likewise.
* gcc.dg/tree-ssa/isolate-5.c: Likewise.
* gcc.dg/tree-ssa/loadpre7.c: Likewise.
* gcc.dg/tree-ssa/pr22117.c: Likewise.
* gcc.dg/tree-ssa/pr23744.c: Likewise.
* gcc.dg/tree-ssa/pr24117.c: Likewise.
* gcc.dg/tree-ssa/pr24840.c: Likewise.
* gcc.dg/tree-ssa/pr25734.c: Likewise.
* gcc.dg/tree-ssa/pr33723.c: Likewise.
* gcc.dg/tree-ssa/pr33920.c: Likewise.
* gcc.dg/tree-ssa/pr34146-2.c: Likewise.
* gcc.dg/tree-ssa/pr34146.c: Likewise.
* gcc.dg/tree-ssa/pr38385.c: Likewise.
* gcc.dg/tree-ssa/pr49642-1.c: Likewise.
* gcc.dg/tree-ssa/pr49642-2.c: Likewise.
* gcc.dg/tree-ssa/pr59597.c: Likewise.
* gcc.dg/tree-ssa/sra-1.c: Likewise.
* gcc.dg/tree-ssa/sra-2.c: Likewise.
* gcc.dg/tree-ssa/sra-5.c: Likewise.
* gcc.dg/tree-ssa/sra-6.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-10.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-2.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-31.c: Likewise.
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-14.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-29.c: Likewise.
* gcc.dg/tree-ssa/ssa-vrp-thread-1.c: Likewise.
* gcc.dg/tree-ssa/vrp46.c: Likewise.
* gcc.dg/tree-ssa/vrp56.c: Likewise.
* gcc.dg/tree-ssa/vrp67.c: Likewise.
* gcc.dg/tree-ssa/vrp72.c: Likewise.
* gcc.dg/tree-ssa/vrp73.c: Likewise.
* gcc.dg/tree-ssa/vrp75.c: Likewise.
* gcc.dg/tree-ssa/20030611-1.c: Fix defaulting to int.
* gcc.dg/tree-ssa/20030703-1.c: Likewise.
* gcc.dg/tree-ssa/20030729-1.c: Likewise.
* gcc.dg/tree-ssa/20030807-11.c: Likewise.
* gcc.dg/tree-ssa/20030917-3.c: Likewise.
* gcc.dg/tree-ssa/20040121-1.c: Likewise.
* gcc.dg/tree-ssa/20040216-1.c: Likewise.
* gcc.dg/tree-ssa/20040302-1.c: Likewise.
* gcc.dg/tree-ssa/20040319-1.c: Likewise.
* gcc.dg/tree-ssa/20040326-2.c: Likewise.
* gcc.dg/tree-ssa/20040729-1.c: Likewise.
* gcc.dg/tree-ssa/attr-alias-2.c: Likewise.
* gcc.dg/tree-ssa/cunroll-1.c: Likewise.
* gcc.dg/tree-ssa/cunroll-3.c: Likewise.
* gcc.dg/tree-ssa/cunroll-5.c: Likewise.
* gcc.dg/tree-ssa/foldconst-4.c: Likewise.
* gcc.dg/tree-ssa/foldconst-5.c: Likewise.
* gcc.dg/tree-ssa/ifc-4.c: Likewise.
* gcc.dg/tree-ssa/ifc-6.c: Likewise.
* gcc.dg/tree-ssa/inline-10.c: Likewise.
* gcc.dg/tree-ssa/inline-9.c: Likewise.
* gcc.dg/tree-ssa/ipa-cp-1.c: Likewise.
* gcc.dg/tree-ssa/ipa-split-5.c: Likewise.
* gcc.dg/tree-ssa/local-pure-const.c: Likewise.
* gcc.dg/tree-ssa/nonzero-1.c: Likewise.
* gcc.dg/tree-ssa/pr23434.c: Likewise.
* gcc.dg/tree-ssa/pr33922.c: Likewise

Re: [PATCH] gcc.dg/tree-ssa/ cleanup

2014-10-02 Thread Marek Polacek
On Thu, Oct 02, 2014 at 01:34:20PM +0200, Jakub Jelinek wrote:
 Wouldn't it be worthwhile to avoid such changes for dozen or two randomly
 selected testcases from these and instead add -std=gnu89 for them?
 Just making sure we don't get rid of all the tests for non-prototyped call
 and/or defaulting to int.

Yeah, probably, thanks.

The following uses -std=gnu89 for ~15 tests.

2014-10-02  Marek Polacek  pola...@redhat.com

* gcc.dg/tree-ssa/20030731-1.c: Use -std=gnu89.
* gcc.dg/tree-ssa/20030729-1.c: Likewise.
* gcc.dg/tree-ssa/20030807-8.c: Likewise.
* gcc.dg/tree-ssa/20040326-1.c: Likewise.
* gcc.dg/tree-ssa/vrp27.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-2.c: Likewise.
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Likewise.
* gcc.dg/tree-ssa/20040302-1.c: Likewise.
* gcc.dg/tree-ssa/vrp09.c: Likewise.
* gcc.dg/tree-ssa/inline-7.c: Likewise.
* gcc.dg/tree-ssa/attr-alias.c: Likewise.
* gcc.dg/tree-ssa/loadpre8.c: Likewise.
* gcc.dg/tree-ssa/20041008-1.c: Likewise.
* gcc.dg/tree-ssa/20030917-1.c: Likewise.
* gcc.dg/tree-ssa/20030917-2.c: Likewise.
* gcc.dg/tree-ssa/20030530-2.c: Add function declarations.
* gcc.dg/tree-ssa/20030708-1.c: Likewise.
* gcc.dg/tree-ssa/20030709-2.c: Likewise.
* gcc.dg/tree-ssa/20030710-1.c: Likewise.
* gcc.dg/tree-ssa/20030711-1.c: Likewise.
* gcc.dg/tree-ssa/20030711-2.c: Likewise.
* gcc.dg/tree-ssa/20030711-3.c: Likewise.
* gcc.dg/tree-ssa/20030728-1.c: Likewise.
* gcc.dg/tree-ssa/20030731-2.c: Likewise.
* gcc.dg/tree-ssa/20030807-1.c: Likewise.
* gcc.dg/tree-ssa/20030807-3.c: Likewise.
* gcc.dg/tree-ssa/20030807-7.c: Likewise.
* gcc.dg/tree-ssa/20030807-9.c: Likewise.
* gcc.dg/tree-ssa/20030814-2.c: Likewise.
* gcc.dg/tree-ssa/20030814-3.c: Likewise.
* gcc.dg/tree-ssa/20030814-4.c: Likewise.
* gcc.dg/tree-ssa/20030814-5.c: Likewise.
* gcc.dg/tree-ssa/20030820-1.c: Likewise.
* gcc.dg/tree-ssa/20030820-2.c: Likewise.
* gcc.dg/tree-ssa/20030821-1.c: Likewise.
* gcc.dg/tree-ssa/20031022-1.c: Likewise.
* gcc.dg/tree-ssa/20040209-1.c: Likewise.
* gcc.dg/tree-ssa/20040211-1.c: Likewise.
* gcc.dg/tree-ssa/alias-13.c: Likewise.
* gcc.dg/tree-ssa/alias-28.c: Likewise.
* gcc.dg/tree-ssa/asm-3.c: Likewise.
* gcc.dg/tree-ssa/coalesce-1.c: Likewise.
* gcc.dg/tree-ssa/foldstring-1.c: Likewise.
* gcc.dg/tree-ssa/forwprop-25.c: Likewise.
* gcc.dg/tree-ssa/forwprop-26.c: Likewise.
* gcc.dg/tree-ssa/isolate-3.c: Likewise.
* gcc.dg/tree-ssa/isolate-5.c: Likewise.
* gcc.dg/tree-ssa/loadpre7.c: Likewise.
* gcc.dg/tree-ssa/pr22117.c: Likewise.
* gcc.dg/tree-ssa/pr23744.c: Likewise.
* gcc.dg/tree-ssa/pr24117.c: Likewise.
* gcc.dg/tree-ssa/pr24840.c: Likewise.
* gcc.dg/tree-ssa/pr25734.c: Likewise.
* gcc.dg/tree-ssa/pr33723.c: Likewise.
* gcc.dg/tree-ssa/pr33920.c: Likewise.
* gcc.dg/tree-ssa/pr34146-2.c: Likewise.
* gcc.dg/tree-ssa/pr34146.c: Likewise.
* gcc.dg/tree-ssa/pr38385.c: Likewise.
* gcc.dg/tree-ssa/pr49642-1.c: Likewise.
* gcc.dg/tree-ssa/pr49642-2.c: Likewise.
* gcc.dg/tree-ssa/pr59597.c: Likewise.
* gcc.dg/tree-ssa/sra-1.c: Likewise.
* gcc.dg/tree-ssa/sra-2.c: Likewise.
* gcc.dg/tree-ssa/sra-5.c: Likewise.
* gcc.dg/tree-ssa/sra-6.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-10.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-31.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-14.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-29.c: Likewise.
* gcc.dg/tree-ssa/ssa-vrp-thread-1.c: Likewise.
* gcc.dg/tree-ssa/vrp46.c: Likewise.
* gcc.dg/tree-ssa/vrp56.c: Likewise.
* gcc.dg/tree-ssa/vrp67.c: Likewise.
* gcc.dg/tree-ssa/vrp72.c: Likewise.
* gcc.dg/tree-ssa/vrp73.c: Likewise.
* gcc.dg/tree-ssa/vrp75.c: Likewise.
* gcc.dg/tree-ssa/20030611-1.c: Fix defaulting to int.
* gcc.dg/tree-ssa/20030703-1.c: Likewise.
* gcc.dg/tree-ssa/20030807-11.c: Likewise.
* gcc.dg/tree-ssa/20030917-3.c: Likewise.
* gcc.dg/tree-ssa/20040121-1.c: Likewise.
* gcc.dg/tree-ssa/20040216-1.c: Likewise.
* gcc.dg/tree-ssa/20040319-1.c: Likewise.
* gcc.dg/tree-ssa/20040326-2.c: Likewise.
* gcc.dg/tree-ssa/20040729-1.c: Likewise.
* gcc.dg/tree-ssa/attr-alias-2.c: Likewise.
* gcc.dg/tree-ssa/cunroll-1.c: Likewise.
* gcc.dg/tree-ssa/cunroll-3.c: Likewise.
* gcc.dg/tree-ssa/cunroll-5.c: Likewise.
* gcc.dg/tree-ssa/foldconst-4.c: Likewise.
* gcc.dg/tree-ssa/foldconst-5.c: Likewise.
* gcc.dg/tree-ssa/ifc-4.c: Likewise.
* gcc.dg/tree-ssa/ifc-6

  1   2   3   4   5   6   7   8   9   10   >