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] Don't lose type qualifiers


For this testcase here:

extern volatile unsigned long foo;
typedef unsigned long ulong;
extern volatile ulong foo;
volatile ulong foo;

We were losing the type qualifiers off of the type for volatile ulong
foo.

This patch fixes the problem unless anyone has an alternate way they'd
like to see it solved. And yes, the last two hunks are formatting
changes only. I just found them while I was fixing up other things.

Also I can make this into a testcase, but only if people think it should
be. :)

OK? Add the testcase too?

Bootstrapped and tested on x86-linux. No regressions that I could see,
but things have been volatile the last couple of days.

-eric

-- 
Eric Christopher <echristo@redhat.com>

2004-05-27  Eric Christopher  <echristo@redhat.com>

	* c-typeck.c (common_type): Don't lose type qualifiers
	when creating new variants.

Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.304
diff -u -p -w -r1.304 c-typeck.c
--- c-typeck.c	14 May 2004 02:32:55 -0000	1.304
+++ c-typeck.c	27 May 2004 23:43:37 -0000
@@ -276,45 +276,64 @@ common_type (tree t1, tree t2)
 
       /* Same precision.  Prefer long longs to longs to ints when the
 	 same precision, following the C99 rules on integer type rank
-	 (which are equivalent to the C90 rules for C90 types).  */
+	 (which are equivalent to the C90 rules for C90 types).
+	 Make sure that we don't lose the type qualifications when
+	 creating the new variant.  */
 
       if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
 	  || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
-	return build_type_attribute_variant (long_long_unsigned_type_node,
-					     attributes);
+	{
+	  t1 = build_qualified_type (long_long_unsigned_type_node,
+				     TYPE_QUALS (t1));
+	  return build_type_attribute_variant (t1, attributes);
+	}
 
       if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
 	  || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
 	{
+	  tree ntype;
+
 	  if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-	     t1 = long_long_unsigned_type_node;
+	     ntype = long_long_unsigned_type_node;
 	  else
-	     t1 = long_long_integer_type_node;
-	  return build_type_attribute_variant (t1, attributes);
+	     ntype = long_long_integer_type_node;
+
+	  ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
+	  return build_type_attribute_variant (ntype, attributes);
 	}
 
       if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
 	  || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
-	return build_type_attribute_variant (long_unsigned_type_node,
-					     attributes);
+	{
+	  t1 = build_qualified_type (long_unsigned_type_node,
+				     TYPE_QUALS (t1));
+	  return build_type_attribute_variant (t1, attributes);
+	}
 
       if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
 	  || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
 	{
+	  tree ntype;
+
 	  /* But preserve unsignedness from the other type,
 	     since long cannot hold all the values of an unsigned int.  */
 	  if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-	     t1 = long_unsigned_type_node;
+	     ntype = long_unsigned_type_node;
 	  else
-	     t1 = long_integer_type_node;
-	  return build_type_attribute_variant (t1, attributes);
+	     ntype = long_integer_type_node;
+
+	  ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
+	  return build_type_attribute_variant (ntype, attributes);
 	}
 
       /* Likewise, prefer long double to double even if same size.  */
       if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
 	  || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
-	return build_type_attribute_variant (long_double_type_node,
-					     attributes);
+	{
+	  t1 = build_qualified_type (long_double_type_node,
+				     TYPE_QUALS (t1));
+	  return build_type_attribute_variant (t1, attributes);
+	}
 
       /* Otherwise prefer the unsigned one.  */
 
@@ -503,7 +522,8 @@ comptypes (tree type1, tree type2, int f
 
   /* Different classes of types can't be compatible.  */
 
-  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
+  if (TREE_CODE (t1) != TREE_CODE (t2))
+    return 0;
 
   /* Qualifiers must match.  */
 
@@ -7109,4 +7129,3 @@ build_binary_op (enum tree_code code, tr
     return result;
   }
 }
-



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