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]

Patch to fix TYPE_MAIN_VARIANT for arrays of qualified type andia64-hpux bootstrap


This patch fixes bootstrap on ia64-hp-hpux11.23, where there were
bootstrap comparison failures in some way connected to inconsistent
TYPE_MAIN_VARIANT of array types.

There was inconsistency in the C front end about where
TYPE_MAIN_VARIANT of arrays of qualified element type pointed and how
such array types were created.  This patch fixes this by following the
C++ front end rule that TYPE_MAIN_VARIANT points to an array of
unqualified type (or an array of arrays of such type, etc., for
multidimensional arrays), and auditing all uses of build_array_type
and TYPE_MAIN_VARIANT in the C front end, changing them if it appears
that they might be problematic in this regard; the general handling of
type qualifiers in grokdeclarator was also audited.  (I haven't
audited TYPE_MAIN_VARIANT uses elsewhere in the compiler, in
particular those in dwarf2out.c discussed in bug 8354 and
<http://gcc.gnu.org/ml/gcc-patches/2004-02/msg01995.html>; this patch
will simply change the debug output from one inaccurate representation
of the C types to another; I expect C++ already gets a similar
inaccurate representation.)

Tests Wwrite-strings-1.c and lvalue-3.c show problems that already
existed and are fixed by this patch.  array-quals-2.c illustrates
problems that could have arisen in an incomplete patch that didn't fix
existing uses of TYPE_MAIN_VARIANT.  Wwrite-strings-1.c seems to be a
regression from 3.4.

I think this patch might fix bug 18166 (lvalue-3.c being the test for
such an issue), but this needs testing before that bug can be closed.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Applied
to mainline.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-01-29  Joseph S. Myers  <joseph@codesourcery.com>

	* c-common.c (fix_string_type): Just use c_build_qualified_type to
	build string type.
	(c_build_qualified_type): Build qualified array types with
	TYPE_MAIN_VARIANT pointing to corresponding unqualified type.
	* c-decl.c (c_make_fname_decl): Build unqualified array type
	before qualified type.
	(grokdeclarator): Use TYPE_MAIN_VARIANT of typedef type if element
	type is qualified, not just if type itself is.  Don't apply
	qualifiers to array type when declarator is processed.  Apply
	qualifiers to field type whether or not it is an array type.
	Don't handle array types specially for applying qualifiers to
	variables.
	* c-typeck.c (composite_type): Build unqualified element type and
	array type when forming composite of array types.
	(common_pointer_type, comptypes, comp_target_types,
	type_lists_compatible_p, build_indirect_ref, build_array_ref,
	convert_for_assignment): Don't apply TYPE_MAIN_VARIANT to array
	types.
	(type_lists_compatible_p): Cache TREE_VALUE (args1) and TREE_VALUE
	(args2) in variables a1 and a2.

testsuite:
2005-01-29  Joseph S. Myers  <joseph@codesourcery.com>

	* gcc.dg/Wwrite-strings-1.c, gcc.dg/array-quals-2.c,
	gcc.dg/lvalue-3.c: New tests.
	* gcc.dg/concat.c: Update expected messages.

diff -rupN GCC.orig/gcc/c-common.c GCC/gcc/c-common.c
--- GCC.orig/gcc/c-common.c	2005-01-28 21:16:11.000000000 +0000
+++ GCC/gcc/c-common.c	2005-01-28 23:11:30.000000000 +0000
@@ -862,12 +862,7 @@ fix_string_type (tree value)
   i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
   a_type = build_array_type (e_type, i_type);
   if (flag_const_strings)
-    {
-      /* bleah, c_build_qualified_type should set TYPE_MAIN_VARIANT.  */
-      tree qa_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
-      TYPE_MAIN_VARIANT (qa_type) = a_type;
-      a_type = qa_type;
-    }
+    a_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
 
   TREE_TYPE (value) = a_type;
   TREE_CONSTANT (value) = 1;
@@ -2483,9 +2478,28 @@ c_build_qualified_type (tree type, int t
     return type;
 
   if (TREE_CODE (type) == ARRAY_TYPE)
-    return build_array_type (c_build_qualified_type (TREE_TYPE (type),
-						     type_quals),
-			     TYPE_DOMAIN (type));
+    {
+      tree t;
+      tree element_type = c_build_qualified_type (TREE_TYPE (type),
+						  type_quals);
+
+      /* See if we already have an identically qualified type.  */
+      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+	{
+	  if (TYPE_QUALS (strip_array_types (t)) == type_quals
+	      && TYPE_NAME (t) == TYPE_NAME (type)
+	      && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+	      && attribute_list_equal (TYPE_ATTRIBUTES (t),
+				       TYPE_ATTRIBUTES (type)))
+	    break;
+	}
+      if (!t)
+	{
+	  t = build_variant_type_copy (type);
+	  TREE_TYPE (t) = element_type;
+	}
+      return t;
+    }
 
   /* A restrict-qualified pointer type must be a pointer to object or
      incomplete type.  Note that the use of POINTER_TYPE_P also allows
diff -rupN GCC.orig/gcc/c-decl.c GCC/gcc/c-decl.c
--- GCC.orig/gcc/c-decl.c	2005-01-28 21:16:11.000000000 +0000
+++ GCC/gcc/c-decl.c	2005-01-28 22:12:47.000000000 +0000
@@ -2632,9 +2632,9 @@ c_make_fname_decl (tree id, int type_dep
   tree decl, type, init;
   size_t length = strlen (name);
 
-  type =  build_array_type
-          (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
-	   build_index_type (size_int (length)));
+  type = build_array_type (char_type_node,
+			   build_index_type (size_int (length)));
+  type = c_build_qualified_type (type, TYPE_QUAL_CONST);
 
   decl = build_decl (VAR_DECL, id, type);
 
@@ -3861,7 +3861,7 @@ grokdeclarator (const struct c_declarato
       if (volatilep > 1)
 	pedwarn ("duplicate %<volatile%>");
     }
-  if (!flag_gen_aux_info && (TYPE_QUALS (type)))
+  if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
     type = TYPE_MAIN_VARIANT (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
 		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
@@ -3946,7 +3946,13 @@ grokdeclarator (const struct c_declarato
 
   /* Now figure out the structure of the declarator proper.
      Descend through it, creating more complex types, until we reach
-     the declared identifier (or NULL_TREE, in an absolute declarator).  */
+     the declared identifier (or NULL_TREE, in an absolute declarator).
+     At each stage we maintain an unqualified version of the type
+     together with any qualifiers that should be applied to it with
+     c_build_qualified_type; this way, array types including
+     multidimensional array types are first built up in unqualified
+     form and then the qualified form is created with
+     TYPE_MAIN_VARIANT pointing to the unqualified form.  */
 
   while (declarator && declarator->kind != cdk_id)
     {
@@ -4146,13 +4152,7 @@ grokdeclarator (const struct c_declarato
 	    if (pedantic && !COMPLETE_TYPE_P (type))
 	      pedwarn ("array type has incomplete element type");
 
-	    /* Build the array type itself, then merge any constancy
-	       or volatility into the target type.  We must do it in
-	       this order to ensure that the TYPE_MAIN_VARIANT field
-	       of the array type is set correctly.  */
 	    type = build_array_type (type, itype);
-	    if (type_quals)
-	      type = c_build_qualified_type (type, type_quals);
 
 	    if (size_varies)
 	      C_TYPE_VARIABLE_SIZE (type) = 1;
@@ -4278,7 +4278,8 @@ grokdeclarator (const struct c_declarato
 	}
     }
 
-  /* Now TYPE has the actual type.  */
+  /* Now TYPE has the actual type, apart from any qualifiers in
+     TYPE_QUALS.  */
 
   /* Check the type and width of a bit-field.  */
   if (bitfield)
@@ -4447,11 +4448,7 @@ grokdeclarator (const struct c_declarato
 	    error ("field %qs has incomplete type", name);
 	    type = error_mark_node;
 	  }
-	/* Move type qualifiers down to element of an array.  */
-	if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
-	  type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
-							   type_quals),
-				   TYPE_DOMAIN (type));
+	type = c_build_qualified_type (type, type_quals);
 	decl = build_decl (FIELD_DECL, declarator->u.id, type);
 	DECL_NONADDRESSABLE_P (decl) = bitfield;
 
@@ -4556,17 +4553,7 @@ grokdeclarator (const struct c_declarato
 	/* An uninitialized decl with `extern' is a reference.  */
 	int extern_ref = !initialized && storage_class == csc_extern;
 
-	/* Move type qualifiers down to element of an array.  */
-	if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
-	  {
-	    int saved_align = TYPE_ALIGN(type);
-	    type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
-							     type_quals),
-				     TYPE_DOMAIN (type));
-	    TYPE_ALIGN (type) = saved_align;
-	  }
-	else if (type_quals)
-	  type = c_build_qualified_type (type, type_quals);
+	type = c_build_qualified_type (type, type_quals);
 
 	/* C99 6.2.2p7: It is invalid (compile-time undefined
 	   behavior) to create an 'extern' declaration for a
diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-01-28 21:16:11.000000000 +0000
+++ GCC/gcc/c-typeck.c	2005-01-29 12:55:35.000000000 +0000
@@ -277,7 +277,9 @@ composite_type (tree t1, tree t2)
     case ARRAY_TYPE:
       {
 	tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
-	
+	int quals;
+	tree unqual_elt;
+
 	/* We should not have any type quals on arrays at all.  */
 	gcc_assert (!TYPE_QUALS (t1) && !TYPE_QUALS (t2));
 	
@@ -292,8 +294,16 @@ composite_type (tree t1, tree t2)
 	if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
 	  return build_type_attribute_variant (t2, attributes);
 	
-	/* Merge the element types, and have a size if either arg has one.  */
-	t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+	/* Merge the element types, and have a size if either arg has
+	   one.  We may have qualifiers on the element types.  To set
+	   up TYPE_MAIN_VARIANT correctly, we need to form the
+	   composite of the unqualified types and add the qualifiers
+	   back at the end.  */
+	quals = TYPE_QUALS (strip_array_types (elt));
+	unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
+	t1 = build_array_type (unqual_elt,
+			       TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+	t1 = c_build_qualified_type (t1, quals);
 	return build_type_attribute_variant (t1, attributes);
       }
 
@@ -415,8 +425,8 @@ static tree
 common_pointer_type (tree t1, tree t2)
 {
   tree attributes;
-  tree pointed_to_1;
-  tree pointed_to_2;
+  tree pointed_to_1, mv1;
+  tree pointed_to_2, mv2;
   tree target;
 
   /* Save time if the two types are the same.  */
@@ -436,11 +446,15 @@ common_pointer_type (tree t1, tree t2)
   attributes = targetm.merge_type_attributes (t1, t2);
 
   /* Find the composite type of the target types, and combine the
-     qualifiers of the two types' targets.  */
-  pointed_to_1 = TREE_TYPE (t1);
-  pointed_to_2 = TREE_TYPE (t2);
-  target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1),
-			   TYPE_MAIN_VARIANT (pointed_to_2));
+     qualifiers of the two types' targets.  Do not lose qualifiers on
+     array element types by taking the TYPE_MAIN_VARIANT.  */
+  mv1 = pointed_to_1 = TREE_TYPE (t1);
+  mv2 = pointed_to_2 = TREE_TYPE (t2);
+  if (TREE_CODE (mv1) != ARRAY_TYPE)
+    mv1 = TYPE_MAIN_VARIANT (pointed_to_1);
+  if (TREE_CODE (mv2) != ARRAY_TYPE)
+    mv2 = TYPE_MAIN_VARIANT (pointed_to_2);
+  target = composite_type (mv1, mv2);
   t1 = build_pointer_type (c_build_qualified_type
 			   (target,
 			    TYPE_QUALS (pointed_to_1) |
@@ -632,7 +646,8 @@ comptypes (tree type1, tree type2)
      definition.  Note that we already checked for equality of the type
      qualifiers (just above).  */
 
-  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+  if (TREE_CODE (t1) != ARRAY_TYPE
+      && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return 1;
 
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
@@ -734,13 +749,21 @@ static int
 comp_target_types (tree ttl, tree ttr, int reflexive)
 {
   int val;
+  tree mvl, mvr;
 
   /* Give objc_comptypes a crack at letting these types through.  */
   if ((val = objc_comptypes (ttl, ttr, reflexive)) >= 0)
     return val;
 
-  val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
-		   TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
+  /* Do not lose qualifiers on element types of array types that are
+     pointer targets by taking their TYPE_MAIN_VARIANT.  */
+  mvl = TREE_TYPE (ttl);
+  mvr = TREE_TYPE (ttr);
+  if (TREE_CODE (mvl) != ARRAY_TYPE)
+    mvl = TYPE_MAIN_VARIANT (mvl);
+  if (TREE_CODE (mvr) != ARRAY_TYPE)
+    mvr = TYPE_MAIN_VARIANT (mvr);
+  val = comptypes (mvl, mvr);
 
   if (val == 2 && pedantic)
     pedwarn ("types are not quite compatible");
@@ -1042,61 +1065,67 @@ type_lists_compatible_p (tree args1, tre
 
   while (1)
     {
+      tree a1, mv1, a2, mv2;
       if (args1 == 0 && args2 == 0)
 	return val;
       /* If one list is shorter than the other,
 	 they fail to match.  */
       if (args1 == 0 || args2 == 0)
 	return 0;
+      mv1 = a1 = TREE_VALUE (args1);
+      mv2 = a2 = TREE_VALUE (args2);
+      if (mv1 && mv1 != error_mark_node && TREE_CODE (mv1) != ARRAY_TYPE)
+	mv1 = TYPE_MAIN_VARIANT (mv1);
+      if (mv2 && mv2 != error_mark_node && TREE_CODE (mv2) != ARRAY_TYPE)
+	mv2 = TYPE_MAIN_VARIANT (mv2);
       /* A null pointer instead of a type
 	 means there is supposed to be an argument
 	 but nothing is specified about what type it has.
 	 So match anything that self-promotes.  */
-      if (TREE_VALUE (args1) == 0)
+      if (a1 == 0)
 	{
-	  if (c_type_promotes_to (TREE_VALUE (args2)) != TREE_VALUE (args2))
+	  if (c_type_promotes_to (a2) != a2)
 	    return 0;
 	}
-      else if (TREE_VALUE (args2) == 0)
+      else if (a2 == 0)
 	{
-	  if (c_type_promotes_to (TREE_VALUE (args1)) != TREE_VALUE (args1))
+	  if (c_type_promotes_to (a1) != a1)
 	    return 0;
 	}
       /* If one of the lists has an error marker, ignore this arg.  */
-      else if (TREE_CODE (TREE_VALUE (args1)) == ERROR_MARK
-	       || TREE_CODE (TREE_VALUE (args2)) == ERROR_MARK)
+      else if (TREE_CODE (a1) == ERROR_MARK
+	       || TREE_CODE (a2) == ERROR_MARK)
 	;
-      else if (!(newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
-				     TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
+      else if (!(newval = comptypes (mv1, mv2)))
 	{
 	  /* Allow  wait (union {union wait *u; int *i} *)
 	     and  wait (union wait *)  to be compatible.  */
-	  if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
-	      && (TYPE_NAME (TREE_VALUE (args1)) == 0
-		  || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1)))
-	      && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
-	      && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
-				     TYPE_SIZE (TREE_VALUE (args2))))
+	  if (TREE_CODE (a1) == UNION_TYPE
+	      && (TYPE_NAME (a1) == 0
+		  || TYPE_TRANSPARENT_UNION (a1))
+	      && TREE_CODE (TYPE_SIZE (a1)) == INTEGER_CST
+	      && tree_int_cst_equal (TYPE_SIZE (a1),
+				     TYPE_SIZE (a2)))
 	    {
 	      tree memb;
-	      for (memb = TYPE_FIELDS (TREE_VALUE (args1));
+	      for (memb = TYPE_FIELDS (a1);
 		   memb; memb = TREE_CHAIN (memb))
-		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
+		if (comptypes (TREE_TYPE (memb), a2))
 		  break;
 	      if (memb == 0)
 		return 0;
 	    }
-	  else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
-		   && (TYPE_NAME (TREE_VALUE (args2)) == 0
-		       || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2)))
-		   && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
-		   && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
-					  TYPE_SIZE (TREE_VALUE (args1))))
+	  else if (TREE_CODE (a2) == UNION_TYPE
+		   && (TYPE_NAME (a2) == 0
+		       || TYPE_TRANSPARENT_UNION (a2))
+		   && TREE_CODE (TYPE_SIZE (a2)) == INTEGER_CST
+		   && tree_int_cst_equal (TYPE_SIZE (a2),
+					  TYPE_SIZE (a1)))
 	    {
 	      tree memb;
-	      for (memb = TYPE_FIELDS (TREE_VALUE (args2));
+	      for (memb = TYPE_FIELDS (a2);
 		   memb; memb = TREE_CHAIN (memb))
-		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
+		if (comptypes (TREE_TYPE (memb), a1))
 		  break;
 	      if (memb == 0)
 		return 0;
@@ -1542,7 +1571,12 @@ build_indirect_ref (tree ptr, const char
       else
 	{
 	  tree t = TREE_TYPE (type);
-	  tree ref = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (t), pointer);
+	  tree mvt = t;
+	  tree ref;
+
+	  if (TREE_CODE (mvt) != ARRAY_TYPE)
+	    mvt = TYPE_MAIN_VARIANT (mvt);
+	  ref = build1 (INDIRECT_REF, mvt, pointer);
 
 	  if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
 	    {
@@ -1670,7 +1704,9 @@ build_array_ref (tree array, tree index)
 	    pedwarn ("ISO C90 forbids subscripting non-lvalue array");
 	}
 
-      type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
+      type = TREE_TYPE (TREE_TYPE (array));
+      if (TREE_CODE (type) != ARRAY_TYPE)
+	type = TYPE_MAIN_VARIANT (type);
       rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
       /* Array ref is const/volatile if the array elements are
          or if the array is.  */
@@ -3597,9 +3633,15 @@ convert_for_assignment (tree type, tree 
     {
       tree ttl = TREE_TYPE (type);
       tree ttr = TREE_TYPE (rhstype);
+      tree mvl = ttl;
+      tree mvr = ttr;
       bool is_opaque_pointer;
       int target_cmp = 0;   /* Cache comp_target_types () result.  */
 
+      if (TREE_CODE (mvl) != ARRAY_TYPE)
+	mvl = TYPE_MAIN_VARIANT (mvl);
+      if (TREE_CODE (mvr) != ARRAY_TYPE)
+	mvr = TYPE_MAIN_VARIANT (mvr);
       /* Opaque pointers are treated like void pointers.  */
       is_opaque_pointer = (targetm.vector_opaque_p (type)
                            || targetm.vector_opaque_p (rhstype))
@@ -3612,8 +3654,8 @@ convert_for_assignment (tree type, tree 
       if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
 	  || (target_cmp = comp_target_types (type, rhstype, 0))
 	  || is_opaque_pointer
-	  || (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl))
-	      == c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr))))
+	  || (c_common_unsigned_type (mvl)
+	      == c_common_unsigned_type (mvr)))
 	{
 	  if (pedantic
 	      && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/Wwrite-strings-1.c GCC/gcc/testsuite/gcc.dg/Wwrite-strings-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/Wwrite-strings-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/Wwrite-strings-1.c	2005-01-28 22:40:37.000000000 +0000
@@ -0,0 +1,8 @@
+/* Test pointer initialization and dereference don't lose qualifiers
+   on array types.  This test wrongly failed to diagnose the loss of
+   const.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-Wwrite-strings" } */
+typedef char T[1];
+T *p = &""; /* { dg-warning "warning: initialization from incompatible pointer type" } */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/array-quals-2.c GCC/gcc/testsuite/gcc.dg/array-quals-2.c
--- GCC.orig/gcc/testsuite/gcc.dg/array-quals-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/array-quals-2.c	2005-01-28 22:32:16.000000000 +0000
@@ -0,0 +1,14 @@
+/* Test that pointers to arrays of differently qualified types aren't
+   permitted in conditional expressions, and that qualifiers aren't
+   lost in forming composite types.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+typedef const char T[1];
+typedef const char T2[1];
+typedef volatile char U[1];
+T *p;
+T2 *p2;
+U *q;
+void *f(void) { return 1 ? p : q; } /* { dg-warning "warning: pointer type mismatch in conditional expression" } */
+T *g(void) { return 1 ? p : p2; }
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/concat.c GCC/gcc/testsuite/gcc.dg/concat.c
--- GCC.orig/gcc/testsuite/gcc.dg/concat.c	2004-11-04 11:52:50.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/concat.c	2005-01-29 15:39:47.000000000 +0000
@@ -8,8 +8,8 @@
 
 void foo ()
 {
-  char s1[] = __FUNCTION__".";	     /* { dg-error "(parse|syntax|expected|invalid)" } */
-  char s2[] = __PRETTY_FUNCTION__".";/* { dg-error "(parse|syntax|expected|invalid)" } */
+  char s1[] = __FUNCTION__".";	     /* { dg-error "(parse|syntax|expected|invalid|array)" } */
+  char s2[] = __PRETTY_FUNCTION__".";/* { dg-error "(parse|syntax|expected|invalid|array)" } */
   char s3[] = "."__FUNCTION__;	     /* { dg-error "(parse|syntax|expected|invalid)" } */
   char s4[] = "."__PRETTY_FUNCTION__;/* { dg-error "(parse|syntax|expected|invalid)" } */
   char s5[] = "."".";                /* No error.  */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/lvalue-3.c GCC/gcc/testsuite/gcc.dg/lvalue-3.c
--- GCC.orig/gcc/testsuite/gcc.dg/lvalue-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/lvalue-3.c	2005-01-28 22:11:58.000000000 +0000
@@ -0,0 +1,14 @@
+/* Test that assignment of a read-only variable that gets const-ness
+   from a read-only field is diagnosed.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct s { const int a; } x;
+typeof (x.a) b;
+void
+f (void)
+{
+  x.a = 1; /* { dg-error "error: assignment of read-only member 'a'" } */
+  b = 1; /* { dg-error "error: assignment of read-only variable 'b'" } */
+}


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