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] Fix PR c/13382


Hi,

This is a minor regression present on mainline and 3.3 branch at -O.  The 
compiler gives an erroneous error message

error: request for member `aMember' in something not a structure or union

for

   aPointer->aMember

with

struct t
{
  int aMember;
};

struct t *const aPointer = 0;


The problem is that the null initializer is represented by null_pointer_node 
at the tree level.  When this initializer is used instead of the variable 
(because of the constness), the type checker issues an error because the 
type pointed to by null_pointer_node is 'void'.  Casting 0 to (struct t *) 
makes the error disappear.

I think the most correct fix is to represent the null initializer by the 
casted 0 at the tree-level.  This is implemented by pr13382-1.diff.
Bootstrapped/regtested on i586-redhat-linux-gnu (3.3 branch, except Ada).

However, since initializing pointers with 0 is a common idiom in C and the 
problem is really a corner case, I don't think it is worth while for the 
compiler to call convert() on each 0 pointer it sees.  So pr13382-2.diff 
implements the ad-hoc fix, where convert() is only called if needed.


2003-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR c/13382
        * c-typeck.c (convert_for_assignment): When converting from
	integral type to pointer type, always call convert.


2003-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR c/13382
        * c-typeck.c (decl_constant_value): Convert null_pointer_node
	to the appropriate type before returning it.


2003-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * gcc.dg/null-pointer-1.c: New test.


-- 
Eric Botcazou
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.213.2.10
diff -u -p -r1.213.2.10 c-typeck.c
--- c-typeck.c	13 Oct 2003 21:18:33 -0000	1.213.2.10
+++ c-typeck.c	20 Dec 2003 12:50:01 -0000
@@ -4263,12 +4263,10 @@ convert_for_assignment (type, rhs, errty
 	     && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
 	     && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
 	     && integer_zerop (TREE_OPERAND (rhs, 0))))
-	{
 	  warn_for_assignment ("%s makes pointer from integer without a cast",
 			       errtype, funname, parmnum);
-	  return convert (type, rhs);
-	}
-      return null_pointer_node;
+
+      return convert (type, rhs);
     }
   else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
     {
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.213.2.10
diff -u -p -r1.213.2.10 c-typeck.c
--- c-typeck.c	13 Oct 2003 21:18:33 -0000	1.213.2.10
+++ c-typeck.c	21 Dec 2003 13:59:03 -0000
@@ -783,7 +783,12 @@ decl_constant_value (decl)
       && TREE_CONSTANT (DECL_INITIAL (decl))
       /* Check for cases where this is sub-optimal, even though valid.  */
       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
-    return DECL_INITIAL (decl);
+    {
+      if (DECL_INITIAL (decl) == null_pointer_node)
+	return convert (TREE_TYPE (decl), DECL_INITIAL (decl));
+      else
+	return DECL_INITIAL (decl);
+    }
   return decl;
 }
 
/* PR c/13382 */
/* Origin: Richard Hutchinson <richard.hutchinson@asa.co.uk> */

/* Verify that the null initializer is converted to the right
   pointer type.  */

/* { dg-do compile } */
/* { dg-options "-O" */

struct t
{
  int aMember;
};

struct t *const aPointer = 0;

void foo()
{
  int anInt = (aPointer == 0) ? 0 : aPointer->aMember;
}

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