This is the mail archive of the gcc-patches@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]

[4.5 C] Fix PR c/35235 (qualifiers on non-lvalue arrays)


This patch fixes PR c/35235, where GCC's notions of type qualifiers on 
rvalues carried over to being visible in standard C when a non-lvalue 
array was converted to a pointer.

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to 
c-4_5-branch.  (I originally intended this as a regression fix for trunk, 
but it ran into problems with the NOP stripping in 
default_function_array_conversion changing some non-lvalues into lvalues, 
and I didn't want to perturb that on trunk at this stage.  So I put it on 
c-4_5-branch, where the NOP stripping has been removed but this patch is 
still needed to fix the reported bug, and will merge it to trunk after the 
constant expressions changes after 4.5 branches.)

Index: testsuite/ChangeLog.c45
===================================================================
--- testsuite/ChangeLog.c45	(revision 143922)
+++ testsuite/ChangeLog.c45	(working copy)
@@ -1,3 +1,8 @@
+2009-02-04  Joseph Myers  <joseph@codesourcery.com>
+
+	PR c/35235
+	* gcc.dg/c99-array-lval-8.c: New test.
+
 2008-12-10  Joseph Myers  <joseph@codesourcery.com>
 
 	* gcc.dg/bconstp-3.c, gcc.dg/bconstp-4.c: New tests.
Index: testsuite/gcc.dg/c99-array-lval-8.c
===================================================================
--- testsuite/gcc.dg/c99-array-lval-8.c	(revision 0)
+++ testsuite/gcc.dg/c99-array-lval-8.c	(revision 0)
@@ -0,0 +1,30 @@
+/* Test for non-lvalue arrays: test that qualifiers on non-lvalues
+   containing arrays do not remain when those arrays decay to
+   pointers.  PR 35235.  */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+int a;
+
+void
+f (void)
+{
+  const struct {
+    int a[1];
+  } s;
+  int *p1 = s.a; /* { dg-error "qualifiers" } */
+  int *p2 = (a ? s : s).a;
+  /* In this case, the qualifier is properly on the array element type
+     not on the rvalue structure and so is not discarded.  */
+  struct {
+    const int a[1];
+  } t;
+  int *p3 = t.a; /* { dg-error "qualifiers" } */
+  int *p4 = (a ? t : t).a; /* { dg-error "qualifiers" } */
+  /* The issue could also lead to code being wrongly accepted.  */
+  const struct {
+    int a[1][1];
+  } u;
+  const int (*p5)[1] = u.a;
+  const int (*p6)[1] = (a ? u : u).a; /* { dg-error "pointer" } */
+}
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 143922)
+++ c-typeck.c	(working copy)
@@ -1891,6 +1891,7 @@
   enum tree_code code = TREE_CODE (type);
   tree field = NULL;
   tree ref;
+  bool datum_lvalue = lvalue_p (datum);
 
   if (!objc_is_public (datum, component))
     return error_mark_node;
@@ -1923,19 +1924,30 @@
 	  tree subdatum = TREE_VALUE (field);
 	  int quals;
 	  tree subtype;
+	  bool use_datum_quals;
 
 	  if (TREE_TYPE (subdatum) == error_mark_node)
 	    return error_mark_node;
 
+	  /* If this is an rvalue, it does not have qualifiers in C
+	     standard terms and we must avoid propagating such
+	     qualifiers down to a non-lvalue array that is then
+	     converted to a pointer.  */
+	  use_datum_quals = (datum_lvalue
+			     || TREE_CODE (TREE_TYPE (subdatum)) != ARRAY_TYPE);
+
 	  quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum)));
-	  quals |= TYPE_QUALS (TREE_TYPE (datum));
+	  if (use_datum_quals)
+	    quals |= TYPE_QUALS (TREE_TYPE (datum));
 	  subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals);
 
 	  ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
 			NULL_TREE);
-	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
+	  if (TREE_READONLY (subdatum)
+	      || (use_datum_quals && TREE_READONLY (datum)))
 	    TREE_READONLY (ref) = 1;
-	  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
+	  if (TREE_THIS_VOLATILE (subdatum)
+	      || (use_datum_quals && TREE_THIS_VOLATILE (datum)))
 	    TREE_THIS_VOLATILE (ref) = 1;
 
 	  if (TREE_DEPRECATED (subdatum))
Index: ChangeLog.c45
===================================================================
--- ChangeLog.c45	(revision 143922)
+++ ChangeLog.c45	(working copy)
@@ -1,3 +1,9 @@
+2009-02-04  Joseph Myers  <joseph@codesourcery.com>
+
+	PR c/35235
+	* c-typeck.c (build_component_ref): Do not copy qualifiers from
+	non-lvalue to component.
+
 2009-01-17  Joseph Myers  <joseph@codesourcery.com>
 
 	* builtins.c (fold_builtin_sincos): Build COMPOUND_EXPR in

-- 
Joseph S. Myers
joseph@codesourcery.com


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