Am Montag, den 09.11.2020, 23:41 +0000 schrieb Joseph Myers:
> On Sat, 7 Nov 2020, Uecker, Martin wrote:

> >   t = (const T) { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
> >   test (&t);
> > }
> > 
> > Not sure what to do about it, maybe 'convert' is not
> > the right function to use.
> 
> I think 'convert' is fine, but new code is probably needed in whatever 
> implements the optimization for assignment from compound literals so that 
> it works when there is a conversion that only changes qualifiers.

This seems to work now.

> > diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> > index 96840377d90..aeacd30badd 100644
> > --- a/gcc/c/c-typeck.c
> > +++ b/gcc/c/c-typeck.c
> > @@ -2080,6 +2080,8 @@ convert_lvalue_to_rvalue (location_t loc, struct 
> > c_expr exp,
> >      exp = default_function_array_conversion (loc, exp);
> >    if (!VOID_TYPE_P (TREE_TYPE (exp.value)))
> >      exp.value = require_complete_type (loc, exp.value);
> > +  if (convert_p && !error_operand_p (exp.value))
> > +    exp.value = convert (build_qualified_type (TREE_TYPE (exp.value), 
> > TYPE_UNQUALIFIED),
> > exp.value);
> 
> I think it might be safest to avoid doing any conversion in the case where 
> the value is still of array type at this point (C90 non-lvalue arrays).

I added a test for arrays, but I am not sure what effect it has.
What would be C90 non-lvalue arrays?  Anything I can test?


diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 413109c916c..286f3d9cd6c 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2080,6 +2080,9 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr 
exp,
     exp = default_function_array_conversion (loc, exp);
   if (!VOID_TYPE_P (TREE_TYPE (exp.value)))
     exp.value = require_complete_type (loc, exp.value);
+  if (convert_p && !error_operand_p (exp.value)
+      && (TREE_CODE (TREE_TYPE (exp.value)) != ARRAY_TYPE))
+    exp.value = convert (build_qualified_type (TREE_TYPE (exp.value), 
TYPE_UNQUALIFIED), exp.value);
   if (really_atomic_lvalue (exp.value))
     {
       vec<tree, va_gc> *params;
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 2566ec7f0af..f83b161b2e8 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -5518,6 +5518,18 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, 
tree *to_p,
            return GS_OK;
          }
 
+       case NOP_EXPR:
+         /* Pull out compound literal expressions from a NOP_EXPR.
+            Those are created in the C FE to drop qualifiers during
+            lvalue conversion.  */
+         if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
+           {
+             *from_p = TREE_OPERAND (*from_p, 0);
+             ret = GS_OK;
+             changed = true;
+           }
+         break;
+
        case COMPOUND_LITERAL_EXPR:
          {
            tree complit = TREE_OPERAND (*expr_p, 1);
diff --git a/gcc/testsuite/gcc.dg/cond-constqual-1.c 
b/gcc/testsuite/gcc.dg/cond-constqual-1.c
index 3354c7214a4..b5a09cb0038 100644
--- a/gcc/testsuite/gcc.dg/cond-constqual-1.c
+++ b/gcc/testsuite/gcc.dg/cond-constqual-1.c
@@ -11,5 +11,5 @@ test (void)
   __typeof__ (1 ? foo (0) : 0) texpr;
   __typeof__ (1 ? i : 0) texpr2;
   texpr = 0;  /* { dg-bogus "read-only variable" "conditional expression with 
call to const function" } */
-  texpr2 = 0; /* { dg-error "read-only variable" "conditional expression with 
const variable" } */
+  texpr2 = 0; /* { dg-bogus "read-only variable" "conditional expression with 
const variable" } */
 }
diff --git a/gcc/testsuite/gcc.dg/lvalue-11.c b/gcc/testsuite/gcc.dg/lvalue-11.c
new file mode 100644
index 00000000000..45a97d86890
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lvalue-11.c
@@ -0,0 +1,46 @@
+/* test that lvalue conversions drops qualifiers, Bug 97702 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+
+void f(void)
+{
+ const int j;
+ typeof((0,j)) i10; i10 = j;;
+ typeof(+j) i11; i11 = j;;
+ typeof(-j) i12; i12 = j;;
+ typeof(1?j:0) i13; i13 = j;;
+ typeof((int)j) i14; i14 = j;;
+ typeof((const int)j) i15; i15 = j;;
+}
+
+void g(void)
+{
+ volatile int j;
+ typeof((0,j)) i21; i21 = j;;
+ typeof(+j) i22; i22 = j;;
+ typeof(-j) i23; i23 = j;;
+ typeof(1?j:0) i24; i24 = j;;
+ typeof((int)j) i25; i25 = j;;
+ typeof((volatile int)j) i26; i26 = j;;
+}
+
+void h(void)
+{
+ _Atomic int j;
+ typeof((0,j)) i32; i32 = j;;
+ typeof(+j) i33; i33 = j;;
+ typeof(-j) i34; i34 = j;;
+ typeof(1?j:0) i35; i35 = j;;
+ typeof((int)j) i36; i36 = j;;
+ typeof((_Atomic int)j) i37; i37 = j;;
+}
+
+void e(void)
+{
+ int* restrict j;
+ typeof((0,j)) i43; i43 = j;;
+ typeof(1?j:0) i44; i44 = j;;
+ typeof((int*)j) i45; i45 = j;;
+ typeof((int* restrict)j) i46; i46 = j;;
+}
diff --git a/gcc/testsuite/gcc.dg/pr60195.c b/gcc/testsuite/gcc.dg/pr60195.c
index 0a50a30be25..8eccf7f63ad 100644
--- a/gcc/testsuite/gcc.dg/pr60195.c
+++ b/gcc/testsuite/gcc.dg/pr60195.c
@@ -15,7 +15,7 @@ atomic_int
 fn2 (void)
 {
   atomic_int y = 0;
-  y;
+  y;           /* { dg-warning "statement with no effect" } */
   return y;
 }
 

Reply via email to