[gnu.gcc.bug] gcc 1.32 misses dropped `volatile' in cases

raeburn@ATHENA.MIT.EDU (Ken Raeburn) (01/04/89)

According to my understanding, gcc should complain about the
assignment in the following file, since the entire structure is
volatile, but it accepts it without comment.  If the assignment is
changed to "& foo -> two", it complains properly about the
incompatible pointers.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

struct frep_regs {
    int one, two, three;
    int seven[7];
};

extern volatile struct frep_regs * foo;

extern int * bar;

void quux (void) {
    bar =  foo -> seven;
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Aside from this problem, the following code seems to be helpful in
catching casts that drop `volatile' or `const' qualifiers, for
example, casting

	volatile caddr_t foo	/* address of per-device regs */

to assign to

	struct quux_regs * qr	/* regs for frobbing QUUX37 combo mag-tape
				   drive and compact disk player */

without properly qualifying the latter as `volatile'.  Another
example, using the above source file, would be

	bar = (int *) & foo -> two;

I changed toplev.c to set the variable warn_qual if -Wqual is
specified in the argument list (okay, so it's not the greatest of
names, but -Wcast sounds more like lint's "questionable cast"), and
made the following change to c-typeck.c:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

***************
*** 2677,2682 ****
--- 2680,2686 ----
       tree expr;
  {
    register tree value;
+   tree expr_type = TREE_TYPE (expr);
  
    if (type == error_mark_node)
      return error_mark_node;
***************
*** 2690,2695 ****
--- 2694,2719 ----
              warning ("ANSI C forbids casting nonscalar to the same type");
          }
        return expr;
+     }
+ 
+   if (warn_qual
+       && (TREE_CODE (expr_type) == POINTER_TYPE
+           || TREE_CODE (expr_type) == ARRAY_TYPE)
+       && TREE_CODE (type) == POINTER_TYPE)
+     {
+       /* Attempt to determine whether the cast is going to drop any
+          'volatile' or 'const' info.  If we wanted to be masochistic,
+          we could examine structures pointed to, pointers they
+          contain, ad nauseam.  For the moment, just make some minimal
+          attempt...  We'll just look at the direct target of a
+          pointer.  */
+       tree target1, target2;
+       target1 = TREE_TYPE (expr_type);
+       target2 = TREE_TYPE (type);
+       if (TREE_VOLATILE (target1) && !TREE_VOLATILE (target2))
+         warning ("pointer cast drops ``volatile'' qualifier");
+       if (TREE_READONLY (target1) && !TREE_READONLY (target2))
+         warning ("pointer cast drops ``const'' qualifier");
      }
  
    value = convert (TYPE_MAIN_VARIANT (type), default_conversion (expr));

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The declaration of warn_qual should be in flags.h, but I've had it in
c-typeck.c to minimize the number of files that get recompiled.

~~ Ken