This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/20280] [4.0/4.1 regression] ICE in create_tmp_var, at gimplify.c:368


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-04 06:34 -------
Subject: Re: [PR c++/20280] hoist indirect_ref out of addressable cond_exprs

On Mar  3, 2005, Andrew Pinski <pinskia@physics.uc.edu> wrote:

> On Mar 3, 2005, at 2:50 AM, Alexandre Oliva wrote:

>> I'm bootstrapping this on x86_64-linux-gnu, along with the patch for
>> PR c++/20103; it's also passed C++ regression testing.  Ok to install
>> if bootstrap and all-languages regression testing passes?

> I think this is the wrong approach,

Err...  But AFAICT this is exactly the approach RTH suggested to cope
with the issue, except for the removal of the unnecessary artificial
decl before gimplification.

> we should be doing the same for all types (well except for
> bitfields) and not just "addressable" types,

Agreed.  That's relatively easy to fix.

Improved patch follows.  Ok to install?

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/19199
	PR c++/20280
	* call.c (build_conditional_expr): Hoist indirect_ref out of
	cond_expr if the result is a non-bitfield lvalue.

Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.531
diff -u -p -r1.531 call.c
--- gcc/cp/call.c 24 Feb 2005 21:55:10 -0000 1.531
+++ gcc/cp/call.c 4 Mar 2005 06:32:44 -0000
@@ -3111,6 +3111,9 @@ build_conditional_expr (tree arg1, tree 
   tree result = NULL_TREE;
   tree result_type = NULL_TREE;
   bool lvalue_p = true;
+  bool indirect_p = false;
+  cp_lvalue_kind arg2_lvalue_kind;
+  cp_lvalue_kind arg3_lvalue_kind;
   struct z_candidate *candidates = 0;
   struct z_candidate *cand;
   void *p;
@@ -3288,11 +3291,26 @@ build_conditional_expr (tree arg1, tree 
 
      If the second and third operands are lvalues and have the same
      type, the result is of that type and is an lvalue.  */
-  if (real_lvalue_p (arg2) 
-      && real_lvalue_p (arg3) 
+  if ((arg2_lvalue_kind = real_lvalue_p (arg2))
+      && (arg3_lvalue_kind = real_lvalue_p (arg3))
       && same_type_p (arg2_type, arg3_type))
     {
-      result_type = arg2_type;
+      if ((arg2_lvalue_kind & clk_bitfield) == clk_none
+	  && (arg3_lvalue_kind & clk_bitfield) == clk_none)
+	{
+	  indirect_p = true;
+	  result_type = build_pointer_type (arg2_type);
+	  if (TREE_CODE (arg2) == INDIRECT_REF)
+	    arg2 = TREE_OPERAND (arg2, 0);
+	  else
+	    arg2 = fold_if_not_in_template (build_address (arg2));
+	  if (TREE_CODE (arg3) == INDIRECT_REF)
+	    arg3 = TREE_OPERAND (arg3, 0);
+	  else
+	    arg3 = fold_if_not_in_template (build_address (arg3));
+	}
+      else
+	result_type = arg2_type;
       goto valid_operands;
     }
 
@@ -3458,6 +3476,14 @@ build_conditional_expr (tree arg1, tree 
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
+  if (indirect_p)
+    {
+      if (TREE_CODE (TREE_TYPE (result)) == POINTER_TYPE)
+	result = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (result)), result);
+      else
+	gcc_assert (TREE_CODE (result) == THROW_EXPR);
+    }
+
   /* Expand both sides into the same slot, hopefully the target of the
      ?: expression.  We used to check for TARGET_EXPRs here, but now we
      sometimes wrap them in NOP_EXPRs so the test would fail.  */
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/19199
	PR c++/20280
	* g++.dg/tree-ssa/pr20280.C: New.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20280.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20280.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20280.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20280.C 4 Mar 2005 06:32:58 -0000
@@ -0,0 +1,80 @@
+// PR c++/20280
+
+// { dg-do compile }
+
+// Gimplification of the COND_EXPR used to fail because it had an
+// addressable type, and create_tmp_var rejected that.
+
+struct A
+{
+    ~A();
+};
+
+struct B : A {};
+
+A& foo();
+
+void bar(bool b)
+{
+    (B&) (b ? foo() : foo());
+}
+
+// Make sure bit-fields and addressable types don't cause crashes.
+// These were not in the original bug report.
+
+// Added by Alexandre Oliva <aoliva@redhat.com>
+
+// Copyright 2005 Free Software Foundation
+
+struct X
+{
+  long i : 32, j, k : 32;
+};
+
+void g(long&);
+void h(const long&);
+
+void f(X &x, bool b)
+{
+  (b ? x.i : x.j) = 1;
+  (b ? x.j : x.k) = 2;
+  (b ? x.i : x.k) = 3;
+
+  (void)(b ? x.i : x.j);
+  (void)(b ? x.i : x.k);
+  (void)(b ? x.j : x.k);
+
+  g (b ? x.i : x.j); // { dg-error "cannot bind bitfield" }
+  g (b ? x.i : x.k); // { dg-error "cannot bind bitfield" }
+  g (b ? x.j : x.k); // { dg-error "cannot bind bitfield" }
+
+  // Hmm...  I don't think these should be accepted.  The conditional
+  // expressions are lvalues for sure, and 8.5.3/5 exempts lvalues
+  // that are bit-fields, but not lvalues that are conditional
+  // expressions involving bit-fields.
+  h (b ? x.i : x.j);
+  h (b ? x.i : x.k);
+  h (b ? x.j : x.k);
+
+  (long &)(b ? x.i : x.j); // { dg-error "address of bit-field" }
+  (long &)(b ? x.i : x.k); // { dg-error "address of bit-field" }
+  (long &)(b ? x.j : x.k); // { dg-error "address of bit-field" }
+}
+
+// What follows is from PR c++/19199, yet another bug on cond-expr
+// lvalues.  We used to return a reference to a temporary in qMin.
+
+enum Foo { A, B };
+
+template<typename T> const T &qMin(const T &a, const T &b) 
+{
+  return a < b ? a : b;
+}
+
+int testref (int,  char **)
+{
+  Foo f = A;
+  Foo g = B;
+  Foo h = qMin(f, g);
+  return 0;
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20280


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]