public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCHes to xvalue handling
@ 2018-05-23 17:25 Jason Merrill
  2018-05-25 16:50 ` Sudakshina Das
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2018-05-23 17:25 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 688 bytes --]

The first patch implements the adjustments from core issues 616 and
1213 to the value category of subobjects of class prvalues: they were
considered prvalues themselves, but that was kind of nonsensical.  Now
they are considered xvalues.  Along with this, I've removed the
diagnostic distinction between xvalues and prvalues when trying to use
one or the other as an lvalue; the important thing is that they are
rvalues.

The second patch corrects various issues with casts and xvalues/rvalue
references: we were treating an xvalue operand to dynamic_cast as an
lvalue, and we were objecting to casts from prvalue to rvalue
reference type.

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

[-- Attachment #2: subob-xval.diff --]
[-- Type: text/x-patch, Size: 9181 bytes --]

commit e7b8c6f89b5e4c69bc2e74ade15a5364b9fac45e
Author: Jason Merrill <jason@redhat.com>
Date:   Tue May 22 15:40:24 2018 -0400

            CWG 616, 1213 - value category of subobject references.
    
            * tree.c (lvalue_kind): A reference to a subobject of a prvalue is
            an xvalue.
            * typeck2.c (build_m_component_ref): Likewise.
            * typeck.c (cp_build_addr_expr_1, lvalue_or_else): Remove diagnostic
            distinction between temporary and xvalue.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 15b9697a63b..efb8c2bf926 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -87,6 +87,7 @@ lvalue_kind (const_tree ref)
     {
     case SAVE_EXPR:
       return clk_none;
+
       /* preincrements and predecrements are valid lvals, provided
 	 what they refer to are valid lvals.  */
     case PREINCREMENT_EXPR:
@@ -94,7 +95,14 @@ lvalue_kind (const_tree ref)
     case TRY_CATCH_EXPR:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      return lvalue_kind (TREE_OPERAND (ref, 0));
+    case ARRAY_REF:
+    case VIEW_CONVERT_EXPR:
+      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+      if (op1_lvalue_kind == clk_class)
+	/* in the case of an array operand, the result is an lvalue if that
+	   operand is an lvalue and an xvalue otherwise */
+	op1_lvalue_kind = clk_rvalueref;
+      return op1_lvalue_kind;
 
     case MEMBER_REF:
     case DOTSTAR_EXPR:
@@ -104,6 +112,11 @@ lvalue_kind (const_tree ref)
 	op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
       if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
 	op1_lvalue_kind = clk_none;
+      else if (op1_lvalue_kind == clk_class)
+	/* The result of a .* expression whose second operand is a pointer to a
+	   data member is an lvalue if the first operand is an lvalue and an
+	   xvalue otherwise.  */
+	op1_lvalue_kind = clk_rvalueref;
       return op1_lvalue_kind;
 
     case COMPONENT_REF:
@@ -119,6 +132,11 @@ lvalue_kind (const_tree ref)
 	    return lvalue_kind (TREE_OPERAND (ref, 1));
 	}
       op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+      if (op1_lvalue_kind == clk_class)
+	/* If E1 is an lvalue, then E1.E2 is an lvalue;
+	   otherwise E1.E2 is an xvalue.  */
+	op1_lvalue_kind = clk_rvalueref;
+
       /* Look at the member designator.  */
       if (!op1_lvalue_kind)
 	;
@@ -165,7 +183,6 @@ lvalue_kind (const_tree ref)
       /* FALLTHRU */
     case INDIRECT_REF:
     case ARROW_EXPR:
-    case ARRAY_REF:
     case PARM_DECL:
     case RESULT_DECL:
     case PLACEHOLDER_EXPR:
@@ -203,11 +220,7 @@ lvalue_kind (const_tree ref)
 	     type-dependent expr, that is, but we shouldn't be testing
 	     lvalueness if we can't even tell the types yet!  */
 	  gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
-	  if (CLASS_TYPE_P (TREE_TYPE (ref))
-	      || TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
-	    return clk_class;
-	  else
-	    return clk_none;
+	  goto default_;
 	}
       op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)
 				    ? TREE_OPERAND (ref, 1)
@@ -257,18 +270,14 @@ lvalue_kind (const_tree ref)
     case PAREN_EXPR:
       return lvalue_kind (TREE_OPERAND (ref, 0));
 
-    case VIEW_CONVERT_EXPR:
-      if (location_wrapper_p (ref))
-	return lvalue_kind (TREE_OPERAND (ref, 0));
-      /* Fallthrough.  */
-
     default:
+    default_:
       if (!TREE_TYPE (ref))
 	return clk_none;
       if (CLASS_TYPE_P (TREE_TYPE (ref))
 	  || TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
 	return clk_class;
-      break;
+      return clk_none;
     }
 
   /* If one operand is not an lvalue at all, then this expression is
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index ecb334d19d2..82089c45105 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5860,11 +5860,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
 	{
 	  if (!(complain & tf_error))
 	    return error_mark_node;
-	  if (kind & clk_class)
-	    /* Make this a permerror because we used to accept it.  */
-	    permerror (input_location, "taking address of temporary");
-	  else
-	    error ("taking address of xvalue (rvalue reference)");
+	  /* Make this a permerror because we used to accept it.  */
+	  permerror (input_location, "taking address of rvalue");
 	}
     }
 
@@ -9866,11 +9863,8 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
     {
       if (!(complain & tf_error))
 	return 0;
-      if (kind & clk_class)
-	/* Make this a permerror because we used to accept it.  */
-	permerror (input_location, "using temporary as lvalue");
-      else
-	error ("using xvalue (rvalue reference) as lvalue");
+      /* Make this a permerror because we used to accept it.  */
+      permerror (input_location, "using rvalue as lvalue");
     }
   return 1;
 }
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index ad0774c6731..40233e68716 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1965,7 +1965,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
 
   if (TYPE_PTRDATAMEM_P (ptrmem_type))
     {
-      cp_lvalue_kind kind = lvalue_kind (datum);
+      bool is_lval = real_lvalue_p (datum);
       tree ptype;
 
       /* Compute the type of the field, as described in [expr.ref].
@@ -1995,9 +1995,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
 	return error_mark_node;
 
       /* If the object expression was an rvalue, return an rvalue.  */
-      if (kind & clk_class)
-	datum = rvalue (datum);
-      else if (kind & clk_rvalueref)
+      if (!is_lval)
 	datum = move (datum);
       return datum;
     }
diff --git a/gcc/testsuite/g++.dg/cpp0x/addressof2.C b/gcc/testsuite/g++.dg/cpp0x/addressof2.C
index bf218cca481..a38dce003a7 100644
--- a/gcc/testsuite/g++.dg/cpp0x/addressof2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/addressof2.C
@@ -17,7 +17,7 @@ auto c = __builtin_addressof (s);
 auto d = addressof (s);
 auto e = __builtin_addressof (s.s);		// { dg-error "attempt to take address of bit-field" }
 auto f = addressof (s.s);			// { dg-error "cannot bind bitfield" }
-auto g = __builtin_addressof (S{});		// { dg-error "taking address of temporary" }
+auto g = __builtin_addressof (S{});		// { dg-error "taking address of rvalue" }
 auto h = addressof (S{});			// { dg-error "cannot bind non-const lvalue reference of type" }
 auto i = __builtin_addressof (S::t);		// { dg-error "invalid use of non-static data member" }
 auto j = __builtin_addressof (S::foo);		// { dg-error "invalid use of non-static member function" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype49.C b/gcc/testsuite/g++.dg/cpp0x/decltype49.C
index c3174982f82..d0a37823d4b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/decltype49.C
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype49.C
@@ -7,4 +7,4 @@ int A::*ipm = &A::i;
 template <class T, class U> class assert_same_type;
 template <class T> class assert_same_type<T,T> { };
 
-assert_same_type<decltype(A().*ipm),int> x2;
+assert_same_type<decltype(A().*ipm),int&&> x2;
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C b/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C
index 1ca3c415475..10a655dc1e5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C
@@ -4,9 +4,9 @@ template <class T> T&& declval();
 
 int main()
 {
-  &declval<int>();		        // { dg-error "xvalue" }
-  declval<int>() = declval<int>();	// { dg-error "xvalue" }
-  declval<int>()++;			// { dg-error "xvalue" }
-  --declval<int>();			// { dg-error "xvalue" }
-  declval<int>() += 1;			// { dg-error "xvalue" }
+  &declval<int>();		        // { dg-error "rvalue" }
+  declval<int>() = declval<int>();	// { dg-error "rvalue" }
+  declval<int>()++;			// { dg-error "rvalue" }
+  --declval<int>();			// { dg-error "rvalue" }
+  declval<int>() += 1;			// { dg-error "rvalue" }
 }
diff --git a/gcc/testsuite/g++.dg/ext/c99struct1.C b/gcc/testsuite/g++.dg/ext/c99struct1.C
index 93e84b46039..bd5be2dbbf5 100644
--- a/gcc/testsuite/g++.dg/ext/c99struct1.C
+++ b/gcc/testsuite/g++.dg/ext/c99struct1.C
@@ -6,7 +6,7 @@ struct s { int a[1]; };
 void
 foo5 (void)
 {
-	  ((struct s) { { 0 } }).a[0] = 1;
+  int i = ((struct s) { { 0 } }).a[0];
 }
 
 
diff --git a/gcc/testsuite/g++.dg/ext/complit11.C b/gcc/testsuite/g++.dg/ext/complit11.C
index 0662543d941..07418aba985 100644
--- a/gcc/testsuite/g++.dg/ext/complit11.C
+++ b/gcc/testsuite/g++.dg/ext/complit11.C
@@ -6,7 +6,7 @@ struct A { int i; };
 template<int t>
 void foo()
 {
-    ((struct A) { 0 }).i += 1;	// { dg-error "temporary" }
+    ((struct A) { 0 }).i += 1;	// { dg-error "lvalue" }
 }
 
 void g(void)
diff --git a/gcc/testsuite/g++.old-deja/g++.law/temps1.C b/gcc/testsuite/g++.old-deja/g++.law/temps1.C
index ad42f425751..d1ac15d6e90 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/temps1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/temps1.C
@@ -17,4 +17,4 @@ struct cookie
 };
 
 cookie cat(&foo("apabepa"));// { dg-warning "deprecated conversion|forbids converting a string constant" "dep" }
-// { dg-warning "taking address of temporary" "add" { target *-*-* } .-1 }
+// { dg-warning "taking address of rvalue" "add" { target *-*-* } .-1 }

[-- Attachment #3: rval-cast.diff --]
[-- Type: text/x-patch, Size: 4287 bytes --]

commit 23a88cb6641f097dd0a9faebfafbe2f1e876714b
Author: Jason Merrill <jason@redhat.com>
Date:   Thu May 3 08:39:26 2018 -0400

            Fix cast to rvalue reference from prvalue.
    
            * cvt.c (diagnose_ref_binding): Handle rvalue reference.
            * rtti.c (build_dynamic_cast_1): Don't try to build a reference to
            non-class type.  Handle xvalue argument.
            * typeck.c (build_reinterpret_cast_1): Allow cast from prvalue to
            rvalue reference.
            * semantics.c (finish_compound_literal): Do direct-initialization,
            not cast, to initialize a reference.

diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 30b44b7d7ea..3f87317a47d 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -381,7 +381,8 @@ diagnose_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
 {
   tree ttl = TREE_TYPE (reftype);
 
-  if (!CP_TYPE_CONST_NON_VOLATILE_P (ttl))
+  if (!TYPE_REF_IS_RVALUE (reftype)
+      && !CP_TYPE_CONST_NON_VOLATILE_P (ttl))
     {
       const char *msg;
 
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 426a23276e0..6692fb7ff86 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -616,22 +616,22 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
   else
     {
       expr = mark_lvalue_use (expr);
-
-      exprtype = build_reference_type (TREE_TYPE (expr));
+      exprtype = TREE_TYPE (expr);
 
       /* T is a reference type, v shall be an lvalue of a complete class
 	 type, and the result is an lvalue of the type referred to by T.  */
-
-      if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
+      if (! MAYBE_CLASS_TYPE_P (exprtype))
 	{
 	  errstr = _("source is not of class type");
 	  goto fail;
 	}
-      if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
+      if (!COMPLETE_TYPE_P (complete_type (exprtype)))
 	{
 	  errstr = _("source is of incomplete class type");
 	  goto fail;
 	}
+
+      exprtype = cp_build_reference_type (exprtype, !lvalue_p (expr));
     }
 
   /* The dynamic_cast operator shall not cast away constness.  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 94e8f54254d..46251deaa6c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2734,7 +2734,10 @@ finish_compound_literal (tree type, tree compound_literal,
       compound_literal
 	= finish_compound_literal (TREE_TYPE (type), compound_literal,
 				   complain, fcl_context);
-      return cp_build_c_cast (type, compound_literal, complain);
+      /* The prvalue is then used to direct-initialize the reference.  */
+      tree r = (perform_implicit_conversion_flags
+		(type, compound_literal, complain, LOOKUP_NORMAL));
+      return convert_from_reference (r);
     }
 
   if (!TYPE_OBJ_P (type))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 82089c45105..a694499190f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -7315,13 +7315,19 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
     type = cv_unqualified (type);
 
   /* [expr.reinterpret.cast]
-     An lvalue expression of type T1 can be cast to the type
+     A glvalue expression of type T1 can be cast to the type
      "reference to T2" if an expression of type "pointer to T1" can be
      explicitly converted to the type "pointer to T2" using a
      reinterpret_cast.  */
   if (TYPE_REF_P (type))
     {
-      if (! lvalue_p (expr))
+      if (TYPE_REF_IS_RVALUE (type))
+	{
+	  if (!obvalue_p (expr))
+	    /* Perform the temporary materialization conversion.  */
+	    expr = get_target_expr_sfinae (expr, complain);
+	}
+      else if (!lvalue_p (expr))
 	{
           if (complain & tf_error)
             error ("invalid cast of an rvalue expression of type "
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C b/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C
new file mode 100644
index 00000000000..3ae5691c5fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C
@@ -0,0 +1,11 @@
+// Test that a prvalue can be used where a glvalue is expected.
+// { dg-do compile { target c++11 } }
+
+struct A { virtual void f(); };
+struct B : A {};
+
+auto && a = static_cast<A&&>(B());
+auto && b = reinterpret_cast<A&&>(B());
+auto && c = dynamic_cast<A&&>(B());
+auto && d = dynamic_cast<B&&>(static_cast<A&&>(B()));
+auto && e = const_cast<B&&>(B());

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

* Re: C++ PATCHes to xvalue handling
  2018-05-23 17:25 C++ PATCHes to xvalue handling Jason Merrill
@ 2018-05-25 16:50 ` Sudakshina Das
  2018-05-25 20:16   ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: Sudakshina Das @ 2018-05-25 16:50 UTC (permalink / raw)
  To: Jason Merrill, gcc-patches List; +Cc: nd

On 23/05/18 18:21, Jason Merrill wrote:
> The first patch implements the adjustments from core issues 616 and
> 1213 to the value category of subobjects of class prvalues: they were
> considered prvalues themselves, but that was kind of nonsensical.  Now
> they are considered xvalues.  Along with this, I've removed the
> diagnostic distinction between xvalues and prvalues when trying to use
> one or the other as an lvalue; the important thing is that they are
> rvalues.
> 
> The second patch corrects various issues with casts and xvalues/rvalue
> references: we were treating an xvalue operand to dynamic_cast as an
> lvalue, and we were objecting to casts from prvalue to rvalue
> reference type.
> 

With the second patch:
commit f7d2790049fd1e59af4b69ee12f7c101cfe4cdab
Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed May 23 17:21:39 2018 +0000

         Fix cast to rvalue reference from prvalue.

         * cvt.c (diagnose_ref_binding): Handle rvalue reference.
         * rtti.c (build_dynamic_cast_1): Don't try to build a reference to
         non-class type.  Handle xvalue argument.
         * typeck.c (build_reinterpret_cast_1): Allow cast from prvalue to
         rvalue reference.
         * semantics.c (finish_compound_literal): Do direct-initialization,
         not cast, to initialize a reference.

     git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@260622 
138bc75d-0d04-0410-961f-82ee72b054a4

I have observed the following failure in Spec2017 while building 
510.parest_r on aarch64-none-linux-gnu

aarch64-none-linux-gnu-g++ -c -o 
source/numerics/matrices.all_dimensions.o -DSPEC -DNDEBUG -Iinclude -I. 
-DSPEC_AUTO_SUPPRESS_OPENMP  -mcpu=cortex-a57+crypto -Ofast 
-fomit-frame-pointer     -fpermissive    -DSPEC_LP64 
source/numerics/matrices.all_dimensions.cc

source/numerics/matrices.all_dimensions.cc: In static member function 
'static void dealii::MatrixTools::apply_boundary_values(const 
std::map<unsigned int, double>&, dealii::BlockSparseMatrix<number>&, 
dealii::BlockVector<number>&, dealii::BlockVector<number>&, bool)':

source/numerics/matrices.all_dimensions.cc:469:50: error: lvalue 
required as unary '&' operand

         [this_sparsity.get_rowstart_indices()[row]];

                                                   ^

source/numerics/matrices.all_dimensions.cc:472:55: error: lvalue 
required as unary '&' operand

            [this_sparsity.get_rowstart_indices()[row]+1],

                                                        ^

source/numerics/matrices.all_dimensions.cc:474:55: error: lvalue 
required as unary '&' operand

            [this_sparsity.get_rowstart_indices()[row+1]],

                                                        ^

source/numerics/matrices.all_dimensions.cc:479:49: error: lvalue 
required as unary '&' operand

        [this_sparsity.get_rowstart_indices()[row]],

                                                  ^

source/numerics/matrices.all_dimensions.cc:481:51: error: lvalue 
required as unary '&' operand

        [this_sparsity.get_rowstart_indices()[row+1]],

                                                    ^

source/numerics/matrices.all_dimensions.cc:510:50: error: lvalue 
required as unary '&' operand

           [this_sparsity.get_rowstart_indices()[0]]);

Sudi

> Tested x86_64-pc-linux-gnu, applying to trunk.
> 

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

* Re: C++ PATCHes to xvalue handling
  2018-05-25 16:50 ` Sudakshina Das
@ 2018-05-25 20:16   ` Jason Merrill
  2018-05-25 20:59     ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2018-05-25 20:16 UTC (permalink / raw)
  To: Sudakshina Das; +Cc: gcc-patches List, nd

On Fri, May 25, 2018 at 12:40 PM, Sudakshina Das <sudi.das@arm.com> wrote:
> On 23/05/18 18:21, Jason Merrill wrote:
>>
>> The first patch implements the adjustments from core issues 616 and
>> 1213 to the value category of subobjects of class prvalues: they were
>> considered prvalues themselves, but that was kind of nonsensical.  Now
>> they are considered xvalues.  Along with this, I've removed the
>> diagnostic distinction between xvalues and prvalues when trying to use
>> one or the other as an lvalue; the important thing is that they are
>> rvalues.
>>
>> The second patch corrects various issues with casts and xvalues/rvalue
>> references: we were treating an xvalue operand to dynamic_cast as an
>> lvalue, and we were objecting to casts from prvalue to rvalue
>> reference type.
>>
>
> With the second patch:
> commit f7d2790049fd1e59af4b69ee12f7c101cfe4cdab
> Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Wed May 23 17:21:39 2018 +0000
>
>         Fix cast to rvalue reference from prvalue.
>
>         * cvt.c (diagnose_ref_binding): Handle rvalue reference.
>         * rtti.c (build_dynamic_cast_1): Don't try to build a reference to
>         non-class type.  Handle xvalue argument.
>         * typeck.c (build_reinterpret_cast_1): Allow cast from prvalue to
>         rvalue reference.
>         * semantics.c (finish_compound_literal): Do direct-initialization,
>         not cast, to initialize a reference.
>
>     git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@260622
> 138bc75d-0d04-0410-961f-82ee72b054a4
>
> I have observed the following failure in Spec2017 while building
> 510.parest_r on aarch64-none-linux-gnu
>
> aarch64-none-linux-gnu-g++ -c -o source/numerics/matrices.all_dimensions.o
> -DSPEC -DNDEBUG -Iinclude -I. -DSPEC_AUTO_SUPPRESS_OPENMP
> -mcpu=cortex-a57+crypto -Ofast -fomit-frame-pointer     -fpermissive
> -DSPEC_LP64 source/numerics/matrices.all_dimensions.cc
>
> source/numerics/matrices.all_dimensions.cc: In static member function
> 'static void dealii::MatrixTools::apply_boundary_values(const
> std::map<unsigned int, double>&, dealii::BlockSparseMatrix<number>&,
> dealii::BlockVector<number>&, dealii::BlockVector<number>&, bool)':
>
> source/numerics/matrices.all_dimensions.cc:469:50: error: lvalue required as
> unary '&' operand
>
>         [this_sparsity.get_rowstart_indices()[row]];
>
>                                                   ^
>
> source/numerics/matrices.all_dimensions.cc:472:55: error: lvalue required as
> unary '&' operand
>
>            [this_sparsity.get_rowstart_indices()[row]+1],
>
>                                                        ^
>
> source/numerics/matrices.all_dimensions.cc:474:55: error: lvalue required as
> unary '&' operand
>
>            [this_sparsity.get_rowstart_indices()[row+1]],
>
>                                                        ^
>
> source/numerics/matrices.all_dimensions.cc:479:49: error: lvalue required as
> unary '&' operand
>
>        [this_sparsity.get_rowstart_indices()[row]],
>
>                                                  ^
>
> source/numerics/matrices.all_dimensions.cc:481:51: error: lvalue required as
> unary '&' operand
>
>        [this_sparsity.get_rowstart_indices()[row+1]],
>
>                                                    ^
>
> source/numerics/matrices.all_dimensions.cc:510:50: error: lvalue required as
> unary '&' operand
>
>           [this_sparsity.get_rowstart_indices()[0]]);
>
> Sudi

Thanks, investigating.

Jason

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

* Re: C++ PATCHes to xvalue handling
  2018-05-25 20:16   ` Jason Merrill
@ 2018-05-25 20:59     ` Jason Merrill
  2018-05-29  9:34       ` Sudakshina Das
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2018-05-25 20:59 UTC (permalink / raw)
  To: Sudakshina Das; +Cc: gcc-patches List, nd

[-- Attachment #1: Type: text/plain, Size: 3676 bytes --]

On Fri, May 25, 2018 at 4:08 PM, Jason Merrill <jason@redhat.com> wrote:
> On Fri, May 25, 2018 at 12:40 PM, Sudakshina Das <sudi.das@arm.com> wrote:
>> On 23/05/18 18:21, Jason Merrill wrote:
>>>
>>> The first patch implements the adjustments from core issues 616 and
>>> 1213 to the value category of subobjects of class prvalues: they were
>>> considered prvalues themselves, but that was kind of nonsensical.  Now
>>> they are considered xvalues.  Along with this, I've removed the
>>> diagnostic distinction between xvalues and prvalues when trying to use
>>> one or the other as an lvalue; the important thing is that they are
>>> rvalues.
>>>
>>> The second patch corrects various issues with casts and xvalues/rvalue
>>> references: we were treating an xvalue operand to dynamic_cast as an
>>> lvalue, and we were objecting to casts from prvalue to rvalue
>>> reference type.
>>>
>>
>> With the second patch:
>> commit f7d2790049fd1e59af4b69ee12f7c101cfe4cdab
>> Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
>> Date:   Wed May 23 17:21:39 2018 +0000
>>
>>         Fix cast to rvalue reference from prvalue.
>>
>>         * cvt.c (diagnose_ref_binding): Handle rvalue reference.
>>         * rtti.c (build_dynamic_cast_1): Don't try to build a reference to
>>         non-class type.  Handle xvalue argument.
>>         * typeck.c (build_reinterpret_cast_1): Allow cast from prvalue to
>>         rvalue reference.
>>         * semantics.c (finish_compound_literal): Do direct-initialization,
>>         not cast, to initialize a reference.
>>
>>     git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@260622
>> 138bc75d-0d04-0410-961f-82ee72b054a4
>>
>> I have observed the following failure in Spec2017 while building
>> 510.parest_r on aarch64-none-linux-gnu
>>
>> aarch64-none-linux-gnu-g++ -c -o source/numerics/matrices.all_dimensions.o
>> -DSPEC -DNDEBUG -Iinclude -I. -DSPEC_AUTO_SUPPRESS_OPENMP
>> -mcpu=cortex-a57+crypto -Ofast -fomit-frame-pointer     -fpermissive
>> -DSPEC_LP64 source/numerics/matrices.all_dimensions.cc
>>
>> source/numerics/matrices.all_dimensions.cc: In static member function
>> 'static void dealii::MatrixTools::apply_boundary_values(const
>> std::map<unsigned int, double>&, dealii::BlockSparseMatrix<number>&,
>> dealii::BlockVector<number>&, dealii::BlockVector<number>&, bool)':
>>
>> source/numerics/matrices.all_dimensions.cc:469:50: error: lvalue required as
>> unary '&' operand
>>
>>         [this_sparsity.get_rowstart_indices()[row]];
>>
>>                                                   ^
>>
>> source/numerics/matrices.all_dimensions.cc:472:55: error: lvalue required as
>> unary '&' operand
>>
>>            [this_sparsity.get_rowstart_indices()[row]+1],
>>
>>                                                        ^
>>
>> source/numerics/matrices.all_dimensions.cc:474:55: error: lvalue required as
>> unary '&' operand
>>
>>            [this_sparsity.get_rowstart_indices()[row+1]],
>>
>>                                                        ^
>>
>> source/numerics/matrices.all_dimensions.cc:479:49: error: lvalue required as
>> unary '&' operand
>>
>>        [this_sparsity.get_rowstart_indices()[row]],
>>
>>                                                  ^
>>
>> source/numerics/matrices.all_dimensions.cc:481:51: error: lvalue required as
>> unary '&' operand
>>
>>        [this_sparsity.get_rowstart_indices()[row+1]],
>>
>>                                                    ^
>>
>> source/numerics/matrices.all_dimensions.cc:510:50: error: lvalue required as
>> unary '&' operand
>>
>>           [this_sparsity.get_rowstart_indices()[0]]);
>>
>> Sudi
>
> Thanks, investigating.

Fixed thus.

[-- Attachment #2: subob-xval2.diff --]
[-- Type: text/x-patch, Size: 1715 bytes --]

commit 2c71bc15d22c4b831ff2e27ef7759de4dc78ef6c
Author: Jason Merrill <jason@redhat.com>
Date:   Fri May 25 16:25:10 2018 -0400

            CWG 616, 1213 - value category of subobject references.
    
            * tree.c (lvalue_kind): Fix handling of ARRAY_REF of pointer.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9d978160292..f21daaca1d0 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -95,14 +95,24 @@ lvalue_kind (const_tree ref)
     case TRY_CATCH_EXPR:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-    case ARRAY_REF:
     case VIEW_CONVERT_EXPR:
-      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
-      if (op1_lvalue_kind == clk_class)
-	/* in the case of an array operand, the result is an lvalue if that
-	   operand is an lvalue and an xvalue otherwise */
-	op1_lvalue_kind = clk_rvalueref;
-      return op1_lvalue_kind;
+      return lvalue_kind (TREE_OPERAND (ref, 0));
+
+    case ARRAY_REF:
+      {
+	tree op1 = TREE_OPERAND (ref, 0);
+	if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
+	  {
+	    op1_lvalue_kind = lvalue_kind (op1);
+	    if (op1_lvalue_kind == clk_class)
+	      /* in the case of an array operand, the result is an lvalue if
+		 that operand is an lvalue and an xvalue otherwise */
+	      op1_lvalue_kind = clk_rvalueref;
+	    return op1_lvalue_kind;
+	  }
+	else
+	  return clk_ordinary;
+      }
 
     case MEMBER_REF:
     case DOTSTAR_EXPR:
diff --git a/gcc/testsuite/g++.dg/template/array31.C b/gcc/testsuite/g++.dg/template/array31.C
new file mode 100644
index 00000000000..007d0dccf89
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array31.C
@@ -0,0 +1,7 @@
+int *g();
+
+template <class T> 
+void f(int i)
+{
+  int *p = &g()[3];
+}

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

* Re: C++ PATCHes to xvalue handling
  2018-05-25 20:59     ` Jason Merrill
@ 2018-05-29  9:34       ` Sudakshina Das
  0 siblings, 0 replies; 5+ messages in thread
From: Sudakshina Das @ 2018-05-29  9:34 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List, nd

Hi Jason

On 25/05/18 21:55, Jason Merrill wrote:
> On Fri, May 25, 2018 at 4:08 PM, Jason Merrill <jason@redhat.com> wrote:
>> On Fri, May 25, 2018 at 12:40 PM, Sudakshina Das <sudi.das@arm.com> wrote:
>>> On 23/05/18 18:21, Jason Merrill wrote:
>>>>
>>>> The first patch implements the adjustments from core issues 616 and
>>>> 1213 to the value category of subobjects of class prvalues: they were
>>>> considered prvalues themselves, but that was kind of nonsensical.  Now
>>>> they are considered xvalues.  Along with this, I've removed the
>>>> diagnostic distinction between xvalues and prvalues when trying to use
>>>> one or the other as an lvalue; the important thing is that they are
>>>> rvalues.
>>>>
>>>> The second patch corrects various issues with casts and xvalues/rvalue
>>>> references: we were treating an xvalue operand to dynamic_cast as an
>>>> lvalue, and we were objecting to casts from prvalue to rvalue
>>>> reference type.
>>>>
>>>
>>> With the second patch:
>>> commit f7d2790049fd1e59af4b69ee12f7c101cfe4cdab
>>> Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
>>> Date:   Wed May 23 17:21:39 2018 +0000
>>>
>>>          Fix cast to rvalue reference from prvalue.
>>>
>>>          * cvt.c (diagnose_ref_binding): Handle rvalue reference.
>>>          * rtti.c (build_dynamic_cast_1): Don't try to build a reference to
>>>          non-class type.  Handle xvalue argument.
>>>          * typeck.c (build_reinterpret_cast_1): Allow cast from prvalue to
>>>          rvalue reference.
>>>          * semantics.c (finish_compound_literal): Do direct-initialization,
>>>          not cast, to initialize a reference.
>>>
>>>      git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@260622
>>> 138bc75d-0d04-0410-961f-82ee72b054a4
>>>
>>> I have observed the following failure in Spec2017 while building
>>> 510.parest_r on aarch64-none-linux-gnu
>>>
>>> aarch64-none-linux-gnu-g++ -c -o source/numerics/matrices.all_dimensions.o
>>> -DSPEC -DNDEBUG -Iinclude -I. -DSPEC_AUTO_SUPPRESS_OPENMP
>>> -mcpu=cortex-a57+crypto -Ofast -fomit-frame-pointer     -fpermissive
>>> -DSPEC_LP64 source/numerics/matrices.all_dimensions.cc
>>>
>>> source/numerics/matrices.all_dimensions.cc: In static member function
>>> 'static void dealii::MatrixTools::apply_boundary_values(const
>>> std::map<unsigned int, double>&, dealii::BlockSparseMatrix<number>&,
>>> dealii::BlockVector<number>&, dealii::BlockVector<number>&, bool)':
>>>
>>> source/numerics/matrices.all_dimensions.cc:469:50: error: lvalue required as
>>> unary '&' operand
>>>
>>>          [this_sparsity.get_rowstart_indices()[row]];
>>>
>>>                                                    ^
>>>
>>> source/numerics/matrices.all_dimensions.cc:472:55: error: lvalue required as
>>> unary '&' operand
>>>
>>>             [this_sparsity.get_rowstart_indices()[row]+1],
>>>
>>>                                                         ^
>>>
>>> source/numerics/matrices.all_dimensions.cc:474:55: error: lvalue required as
>>> unary '&' operand
>>>
>>>             [this_sparsity.get_rowstart_indices()[row+1]],
>>>
>>>                                                         ^
>>>
>>> source/numerics/matrices.all_dimensions.cc:479:49: error: lvalue required as
>>> unary '&' operand
>>>
>>>         [this_sparsity.get_rowstart_indices()[row]],
>>>
>>>                                                   ^
>>>
>>> source/numerics/matrices.all_dimensions.cc:481:51: error: lvalue required as
>>> unary '&' operand
>>>
>>>         [this_sparsity.get_rowstart_indices()[row+1]],
>>>
>>>                                                     ^
>>>
>>> source/numerics/matrices.all_dimensions.cc:510:50: error: lvalue required as
>>> unary '&' operand
>>>
>>>            [this_sparsity.get_rowstart_indices()[0]]);
>>>
>>> Sudi
>>
>> Thanks, investigating.
> 
> Fixed thus.

Thanks for fixing this!

Sudi
> 

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

end of thread, other threads:[~2018-05-29  9:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-23 17:25 C++ PATCHes to xvalue handling Jason Merrill
2018-05-25 16:50 ` Sudakshina Das
2018-05-25 20:16   ` Jason Merrill
2018-05-25 20:59     ` Jason Merrill
2018-05-29  9:34       ` Sudakshina Das

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).