public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] Fix up cxx_eval_pointer_plus_expression (PR c++/65736)
@ 2015-04-11 14:02 Jakub Jelinek
  2015-04-12 18:27 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2015-04-11 14:02 UTC (permalink / raw)
  To: Jason Merrill, Marek Polacek; +Cc: gcc-patches

Hi!

The following patch fixes a bunch of issues in
cxx_eval_pointer_plus_expression:
1) as it does STRIP_NOPS, the pointed type can change, and thus the
   op01 constant in p+ might not be divisible by the other type size
2) we should restore the original type, rather than returning expression
   of type after STRIP_NOPS
3) just in case, I've added a check TYPE_SIZE_UNIT is a constant

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

2015-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/65736
	* constexpr.c (cxx_eval_pointer_plus_expression): Don't fold for VLAs,
	don't fold if op01 isn't divisible by TYPE_SIZE_UNIT.  Convert
	the expression to the original type at the end.

	* g++.dg/cpp0x/pr65736.C: New test.

--- gcc/cp/constexpr.c.jj	2015-04-03 15:32:31.000000000 +0200
+++ gcc/cp/constexpr.c	2015-04-11 10:28:12.154482385 +0200
@@ -2929,6 +2929,7 @@ cxx_eval_pointer_plus_expression (const
 				  bool lval, bool *non_constant_p,
 				  bool *overflow_p)
 {
+  tree orig_type = TREE_TYPE (t);
   tree op00 = TREE_OPERAND (t, 0);
   tree op01 = TREE_OPERAND (t, 1);
   location_t loc = EXPR_LOCATION (t);
@@ -2945,7 +2946,9 @@ cxx_eval_pointer_plus_expression (const
   /* &A[i] p+ j => &A[i + j] */
   if (TREE_CODE (op00) == ARRAY_REF
       && TREE_CODE (TREE_OPERAND (op00, 1)) == INTEGER_CST
-      && TREE_CODE (op01) == INTEGER_CST)
+      && TREE_CODE (op01) == INTEGER_CST
+      && TYPE_SIZE_UNIT (TREE_TYPE (op00))
+      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (op00))) == INTEGER_CST)
     {
       tree type = TREE_TYPE (op00);
       t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (op00, 1));
@@ -2953,15 +2956,21 @@ cxx_eval_pointer_plus_expression (const
       /* Don't fold an out-of-bound access.  */
       if (!tree_int_cst_le (t, nelts))
 	return NULL_TREE;
+      op01 = cp_fold_convert (ssizetype, op01);
+      /* Don't fold if op01 can't be divided exactly by TYPE_SIZE_UNIT.
+	 constexpr int A[1]; ... (char *)&A[0] + 1 */
+      if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
+					   op01, TYPE_SIZE_UNIT (type))))
+	return NULL_TREE;
       /* Make sure to treat the second operand of POINTER_PLUS_EXPR
 	 as signed.  */
-      op01 = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype,
-			      cp_fold_convert (ssizetype, op01),
+      op01 = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, op01,
 			      TYPE_SIZE_UNIT (type));
       t = size_binop_loc (loc, PLUS_EXPR, op01, t);
       t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (op00, 0),
 		      t, NULL_TREE, NULL_TREE);
       t = cp_build_addr_expr (t, tf_warning_or_error);
+      t = cp_fold_convert (orig_type, t);
       return cxx_eval_constant_expression (ctx, t, lval, non_constant_p,
 					   overflow_p);
     }
--- gcc/testsuite/g++.dg/cpp0x/pr65736.C.jj	2015-04-11 10:32:06.807729783 +0200
+++ gcc/testsuite/g++.dg/cpp0x/pr65736.C	2015-04-11 10:31:11.000000000 +0200
@@ -0,0 +1,5 @@
+// PR c++/65736
+// { dg-do compile { target c++11 } }
+
+int a[1];                                                                                                                                 
+char *b[1] { (char *)&a[0] + 1 };

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [C++ PATCH] Fix up cxx_eval_pointer_plus_expression (PR c++/65736)
  2015-04-11 14:02 [C++ PATCH] Fix up cxx_eval_pointer_plus_expression (PR c++/65736) Jakub Jelinek
@ 2015-04-12 18:27 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2015-04-12 18:27 UTC (permalink / raw)
  To: Jakub Jelinek, Marek Polacek; +Cc: gcc-patches

OK.

Jason

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-04-12 18:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-11 14:02 [C++ PATCH] Fix up cxx_eval_pointer_plus_expression (PR c++/65736) Jakub Jelinek
2015-04-12 18:27 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).