From: Ian Lance Taylor Date: Mon, 1 Jun 2009 16:35:01 +0000 (+0000) Subject: attribs.c (register_attribute): Use CONST_CAST. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67165eb379fa57c009beb29b180cd630eacbac8e;p=platform%2Fupstream%2Fgcc.git attribs.c (register_attribute): Use CONST_CAST. ./: * attribs.c (register_attribute): Use CONST_CAST. * collect2.c (main): Use CONST_CAST2. (scan_prog_file): Likewise. * gcc.c (process_command, main): Likewise. * toplev.c (toplev_main): Likewise. * c-typeck.c (handle_warn_cast_qual): New static function, partially broken out of build_c_cast. (build_c_cast): Call handle_warn_cast_qual. * doc/invoke.texi (Warning Options): Document new effect of -Wcast-qual. ./java: * jcf-io.c (find_class): Use CONST_CAST. ./testsuite: * gcc.dg/cast-qual-3.c: New testcase. * g++.dg/warn/Wcast-qual2.C: New testcase. From-SVN: r148053 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9789c01..d9f67d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2009-06-01 Ian Lance Taylor + + * attribs.c (register_attribute): Use CONST_CAST. + * collect2.c (main): Use CONST_CAST2. + (scan_prog_file): Likewise. + * gcc.c (process_command, main): Likewise. + * toplev.c (toplev_main): Likewise. + + * c-typeck.c (handle_warn_cast_qual): New static function, + partially broken out of build_c_cast. + (build_c_cast): Call handle_warn_cast_qual. + * doc/invoke.texi (Warning Options): Document new effect of + -Wcast-qual. + 2009-06-01 Aldy Hernandez * diagnostic.c (diagnostic_build_prefix): Always print columns. diff --git a/gcc/attribs.c b/gcc/attribs.c index 5b18aa3..5ae462e 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -1,6 +1,6 @@ /* Functions dealing with attribute handling, used by most front ends. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -195,15 +195,15 @@ void register_attribute (const struct attribute_spec *attr) { struct substring str; - const void **slot; + void **slot; str.str = attr->name; str.length = strlen (str.str); - slot = (const void **)htab_find_slot_with_hash (attribute_hash, &str, - substring_hash (str.str, str.length), - INSERT); + slot = htab_find_slot_with_hash (attribute_hash, &str, + substring_hash (str.str, str.length), + INSERT); gcc_assert (!*slot); - *slot = attr; + *slot = (void *) CONST_CAST (struct attribute_spec *, attr); } /* Return the spec for the attribute named NAME. */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 43cb6f3..28fb8b8 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4055,6 +4055,93 @@ build_compound_expr (tree expr1, tree expr2) return ret; } +/* Issue -Wcast-qual warnings when appropriate. TYPE is the type to + which we are casting. OTYPE is the type of the expression being + cast. Both TYPE and OTYPE are pointer types. -Wcast-qual appeared + on the command line. */ + +static void +handle_warn_cast_qual (tree type, tree otype) +{ + tree in_type = type; + tree in_otype = otype; + int added = 0; + int discarded = 0; + bool is_const; + + /* Check that the qualifiers on IN_TYPE are a superset of the + qualifiers of IN_OTYPE. The outermost level of POINTER_TYPE + nodes is uninteresting and we stop as soon as we hit a + non-POINTER_TYPE node on either type. */ + do + { + in_otype = TREE_TYPE (in_otype); + in_type = TREE_TYPE (in_type); + + /* GNU C allows cv-qualified function types. 'const' means the + function is very pure, 'volatile' means it can't return. We + need to warn when such qualifiers are added, not when they're + taken away. */ + if (TREE_CODE (in_otype) == FUNCTION_TYPE + && TREE_CODE (in_type) == FUNCTION_TYPE) + added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype)); + else + discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type)); + } + while (TREE_CODE (in_type) == POINTER_TYPE + && TREE_CODE (in_otype) == POINTER_TYPE); + + if (added) + warning (OPT_Wcast_qual, "cast adds new qualifiers to function type"); + + if (discarded) + /* There are qualifiers present in IN_OTYPE that are not present + in IN_TYPE. */ + warning (OPT_Wcast_qual, + "cast discards qualifiers from pointer target type"); + + if (added || discarded) + return; + + /* A cast from **T to const **T is unsafe, because it can cause a + const value to be changed with no additional warning. We only + issue this warning if T is the same on both sides, and we only + issue the warning if there are the same number of pointers on + both sides, as otherwise the cast is clearly unsafe anyhow. A + cast is unsafe when a qualifier is added at one level and const + is not present at all outer levels. + + To issue this warning, we check at each level whether the cast + adds new qualifiers not already seen. We don't need to special + case function types, as they won't have the same + TYPE_MAIN_VARIANT. */ + + if (TYPE_MAIN_VARIANT (in_type) != TYPE_MAIN_VARIANT (in_otype)) + return; + if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE) + return; + + in_type = type; + in_otype = otype; + is_const = TYPE_READONLY (TREE_TYPE (in_type)); + do + { + in_type = TREE_TYPE (in_type); + in_otype = TREE_TYPE (in_otype); + if ((TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype)) != 0 + && !is_const) + { + warning (OPT_Wcast_qual, + ("new qualifiers in middle of multi-level non-const cast " + "are unsafe")); + break; + } + if (is_const) + is_const = TYPE_READONLY (in_type); + } + while (TREE_CODE (in_type) == POINTER_TYPE); +} + /* Build an expression representing a cast to type TYPE of expression EXPR. */ tree @@ -4139,46 +4226,10 @@ build_c_cast (tree type, tree expr) otype = TREE_TYPE (value); /* Optionally warn about potentially worrisome casts. */ - if (warn_cast_qual && TREE_CODE (type) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE) - { - tree in_type = type; - tree in_otype = otype; - int added = 0; - int discarded = 0; - - /* Check that the qualifiers on IN_TYPE are a superset of - the qualifiers of IN_OTYPE. The outermost level of - POINTER_TYPE nodes is uninteresting and we stop as soon - as we hit a non-POINTER_TYPE node on either type. */ - do - { - in_otype = TREE_TYPE (in_otype); - in_type = TREE_TYPE (in_type); - - /* GNU C allows cv-qualified function types. 'const' - means the function is very pure, 'volatile' means it - can't return. We need to warn when such qualifiers - are added, not when they're taken away. */ - if (TREE_CODE (in_otype) == FUNCTION_TYPE - && TREE_CODE (in_type) == FUNCTION_TYPE) - added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype)); - else - discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type)); - } - while (TREE_CODE (in_type) == POINTER_TYPE - && TREE_CODE (in_otype) == POINTER_TYPE); - - if (added) - warning (OPT_Wcast_qual, "cast adds new qualifiers to function type"); - - if (discarded) - /* There are qualifiers present in IN_OTYPE that are not - present in IN_TYPE. */ - warning (OPT_Wcast_qual, "cast discards qualifiers from pointer target type"); - } + handle_warn_cast_qual (type, otype); /* Warn about possible alignment problems. */ if (STRICT_ALIGNMENT diff --git a/gcc/collect2.c b/gcc/collect2.c index 277ddd6..d15a81a 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -857,9 +857,12 @@ main (int argc, char **argv) /* Do not invoke xcalloc before this point, since locale needs to be set first, in case a diagnostic is issued. */ - ld1 = (const char **)(ld1_argv = XCNEWVEC (char *, argc+4)); - ld2 = (const char **)(ld2_argv = XCNEWVEC (char *, argc+11)); - object = (const char **)(object_lst = XCNEWVEC (char *, argc)); + ld1_argv = XCNEWVEC (char *, argc + 4); + ld1 = CONST_CAST2 (const char **, char **, ld1_argv); + ld2_argv = XCNEWVEC (char *, argc + 11); + ld2 = CONST_CAST2 (const char **, char **, ld2_argv); + object_lst = XCNEWVEC (char *, argc); + object = CONST_CAST2 (const char **, char **, object_lst); #ifdef DEBUG debug = 1; @@ -904,7 +907,8 @@ main (int argc, char **argv) -fno-exceptions -w */ num_c_args += 5; - c_ptr = (const char **) (c_argv = XCNEWVEC (char *, num_c_args)); + c_argv = XCNEWVEC (char *, num_c_args); + c_ptr = CONST_CAST2 (const char **, char **, c_argv); if (argc < 2) fatal ("no arguments"); @@ -1406,7 +1410,8 @@ main (int argc, char **argv) if (strip_flag) { char **real_strip_argv = XCNEWVEC (char *, 3); - const char ** strip_argv = (const char **) real_strip_argv; + const char ** strip_argv = CONST_CAST2 (const char **, char **, + real_strip_argv); strip_argv[0] = strip_file_name; strip_argv[1] = output_file; @@ -2090,7 +2095,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass) void (*quit_handler) (int); #endif char *real_nm_argv[4]; - const char **nm_argv = (const char **) real_nm_argv; + const char **nm_argv = CONST_CAST2 (const char **, char**, real_nm_argv); int argc = 0; struct pex_obj *pex; const char *errmsg; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index df831e3..85b3ae8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3694,6 +3694,19 @@ Warn whenever a pointer is cast so as to remove a type qualifier from the target type. For example, warn if a @code{const char *} is cast to an ordinary @code{char *}. +Also warn when making a cast which introduces a type qualifier in an +unsafe way. For example, casting @code{char **} to @code{const char **} +is unsafe, as in this example: + +@smallexample + /* p is char ** value. */ + const char **q = (const char **) p; + /* Assignment of readonly string to const char * is OK. */ + *q = "string"; + /* Now char** pointer points to read-only memory. */ + **p = 'b'; +@end smallexample + @item -Wcast-align @opindex Wcast-align @opindex Wno-cast-align diff --git a/gcc/gcc.c b/gcc/gcc.c index 9168a34..538be05 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -3636,10 +3636,15 @@ process_command (int argc, const char **argv) } /* Convert new-style -- options to old-style. */ - translate_options (&argc, (const char *const **) &argv); + translate_options (&argc, + CONST_CAST2 (const char *const **, const char ***, + &argv)); /* Do language-specific adjustment/addition of flags. */ - lang_specific_driver (&argc, (const char *const **) &argv, &added_libraries); + lang_specific_driver (&argc, + CONST_CAST2 (const char *const **, const char ***, + &argv), + &added_libraries); /* Scan argv twice. Here, the first time, just count how many switches there will be in their vector, and how many input files in theirs. @@ -6466,7 +6471,7 @@ main (int argc, char **argv) Make a table of specified input files (infiles, n_infiles). Decode switches that are handled locally. */ - process_command (argc, (const char **) argv); + process_command (argc, CONST_CAST2 (const char **, char **, argv)); /* Initialize the vector of specs to just the default. This means one element containing 0s, as a terminator. */ diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 16fbfea..6754403 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,7 @@ +2009-06-01 Ian Lance Taylor + + * jcf-io.c (find_class): Use CONST_CAST. + 2009-05-27 Ian Lance Taylor * Make-lang.in ($(XGCJ)$(exeext)): Change $(COMPILER) to diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c index b968214..28a48bb 100644 --- a/gcc/java/jcf-io.c +++ b/gcc/java/jcf-io.c @@ -1,6 +1,6 @@ /* Utility routines for finding and reading Java(TM) .class files. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, - 2006, 2007, 2008 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -399,9 +399,8 @@ find_class (const char *classname, int classname_length, JCF *jcf) /* Remember that this class could not be found so that we do not have to look again. */ - *(const void **)htab_find_slot_with_hash (memoized_class_lookups, - classname, hash, INSERT) - = classname; + *htab_find_slot_with_hash (memoized_class_lookups, classname, hash, INSERT) + = (void *) CONST_CAST (char *, classname); return NULL; found: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e10c59..f76815a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-06-01 Ian Lance Taylor + + * gcc.dg/cast-qual-3.c: New testcase. + * g++.dg/warn/Wcast-qual2.C: New testcase. + 2009-06-01 Aldy Hernandez * lib/gcc-dg.exp (dg-bogus): Override dg-bogus. diff --git a/gcc/testsuite/g++.dg/warn/Wcast-qual2.C b/gcc/testsuite/g++.dg/warn/Wcast-qual2.C new file mode 100644 index 0000000..88fdcfb --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wcast-qual2.C @@ -0,0 +1,167 @@ +/* { dg-do compile } */ +/* { dg-options "-Wcast-qual" } */ + +/* The files gcc.dg/cast-qual-3.c and g++.dg/warn/Wcast-qual2.c are + duals. they are intended to show that gcc -Wcast-qual and g++ + -Wcast-qual emit warnings in the same cases. If you change this + file, please also change the other one. */ + +void +f1 (void *bar) +{ + const void *p1 = (const void *) bar; + const char *p2 = (const char *) bar; + const void **p3 = (const void **) bar; + const char **p4 = (const char **) bar; + const void * const *p5 = (const void * const *) bar; + const char * const *p6 = (const char * const *) bar; + void * const *p7 = (void * const *) bar; + char * const *p8 = (char * const *) bar; + const void ***p9 = (const void ***) bar; + const char ***p10 = (const char ***) bar; + void * const **p11 = (void * const **) bar; + char * const **p12 = (char * const **) bar; + void ** const *p13 = (void ** const *) bar; + char ** const *p14 = (char ** const *) bar; + const void * const **p15 = (const void * const **) bar; + const char * const **p16 = (const char * const **) bar; + const void ** const *p17 = (const void ** const *) bar; + const char ** const *p18 = (const char ** const *) bar; + void * const * const * p19 = (void * const * const *) bar; + char * const * const * p20 = (char * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; + const char * const * const *p22 = (const char * const * const *) bar; +} + +void +f2 (void **bar) +{ + const void *p1 = (const void *) bar; + const char *p2 = (const char *) bar; + const void **p3 = (const void **) bar; /* { dg-warning "cast" } */ + const char **p4 = (const char **) bar; + const void * const *p5 = (const void * const *) bar; + const char * const *p6 = (const char * const *) bar; + void * const *p7 = (void * const *) bar; + char * const *p8 = (char * const *) bar; + const void ***p9 = (const void ***) bar; + const char ***p10 = (const char ***) bar; + void * const **p11 = (void * const **) bar; + char * const **p12 = (char * const **) bar; + void ** const *p13 = (void ** const *) bar; + char ** const *p14 = (char ** const *) bar; + const void * const **p15 = (const void * const **) bar; + const char * const **p16 = (const char * const **) bar; + const void ** const *p17 = (const void ** const *) bar; + const char ** const *p18 = (const char ** const *) bar; + void * const * const * p19 = (void * const * const *) bar; + char * const * const * p20 = (char * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; + const char * const * const *p22 = (const char * const * const *) bar; +} + +void +f3 (void ***bar) +{ + const void *p1 = (const void *) bar; + const char *p2 = (const char *) bar; + const void **p3 = (const void **) bar; + const char **p4 = (const char **) bar; + const void * const *p5 = (const void * const *) bar; + const char * const *p6 = (const char * const *) bar; + void * const *p7 = (void * const *) bar; + char * const *p8 = (char * const *) bar; + const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */ + const char ***p10 = (const char ***) bar; + void * const **p11 = (void * const **) bar; /* { dg-warning "cast" } */ + char * const **p12 = (char * const **) bar; + void ** const *p13 = (void ** const *) bar; + char ** const *p14 = (char ** const *) bar; + const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */ + const char * const **p16 = (const char * const **) bar; + const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */ + const char ** const *p18 = (const char ** const *) bar; + void * const * const * p19 = (void * const * const *) bar; + char * const * const * p20 = (char * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; + const char * const * const *p22 = (const char * const * const *) bar; +} + +void +f4 (void * const **bar) +{ + const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */ + void * const **p11 = (void * const **) bar; + void ** const *p13 = (void ** const *) bar; /* { dg-warning "cast" } */ + const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */ + const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */ + void * const * const * p19 = (void * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; +} + +void +f5 (char ***bar) +{ + volatile const char ***p9 = (volatile const char ***) bar; /* { dg-warning "cast" } */ + volatile char * const **p11 = (volatile char * const **) bar; /* { dg-warning "cast" } */ + volatile char ** const *p13 = (volatile char ** const *) bar; /* { dg-warning "cast" } */ + volatile const char * const **p15 = (volatile const char * const **) bar; /* { dg-warning "cast" } */ + volatile const char ** const *p17 = (volatile const char ** const *) bar; /* { dg-warning "cast" } */ + volatile char * const * const * p19 = (volatile char * const * const *) bar; + volatile const char * const * const *p21 = (volatile const char * const * const *) bar; +} + +void +f6 (char ***bar) +{ + const char * volatile **p9 = (const char * volatile **) bar; /* { dg-warning "cast" } */ + char * volatile const **p11 = (char * volatile const **) bar; /* { dg-warning "cast" } */ + char * volatile * const *p13 = (char * volatile * const *) bar; + const char * volatile const **p15 = (const char * volatile const **) bar; /* { dg-warning "cast" } */ + const char * volatile * const *p17 = (const char * volatile * const *) bar; /* { dg-warning "cast" } */ + char * volatile const * const * p19 = (char * volatile const * const *) bar; + const char * volatile const * const *p21 = (const char * volatile const * const *) bar; +} + +void +f7 (char ***bar) +{ + const char ** volatile *p9 = (const char ** volatile *) bar; /* { dg-warning "cast" } */ + char * const * volatile *p11 = (char * const * volatile *) bar; /* { dg-warning "cast" } */ + char ** volatile const *p13 = (char ** volatile const *) bar; + const char * const * volatile *p15 = (const char * const * volatile *) bar; /* { dg-warning "cast" } */ + const char ** volatile const *p17 = (const char ** volatile const *) bar; /* { dg-warning "cast" } */ + char * const * volatile const * p19 = (char * const * volatile const *) bar; + const char * const * volatile const *p21 = (const char * const * volatile const *) bar; +} + +typedef int (intfn) (int); +typedef intfn *pintfn; +typedef const intfn *constfn; + +void +f8 (constfn ***bar) +{ + const constfn *p1 = (const constfn *) bar; + const pintfn *p2 = (const pintfn *) bar; + const constfn **p3 = (const constfn **) bar; + const pintfn **p4 = (const pintfn **) bar; + const constfn * const *p5 = (const constfn * const *) bar; + const pintfn * const *p6 = (const pintfn * const *) bar; + constfn * const *p7 = (constfn * const *) bar; + pintfn * const *p8 = (pintfn * const *) bar; + const constfn ***p9 = (const constfn ***) bar; /* { dg-warning "cast" } */ + const pintfn ***p10 = (const pintfn ***) bar; /* { dg-warning "cast" } */ + constfn * const **p11 = (constfn * const **) bar; /* { dg-warning "cast" } */ + pintfn * const **p12 = (pintfn * const **) bar; /* { dg-warning "cast" } */ + constfn ** const *p13 = (constfn ** const *) bar; + pintfn ** const *p14 = (pintfn ** const *) bar; + const constfn * const **p15 = (const constfn * const **) bar; /* { dg-warning "cast" } */ + const pintfn * const **p16 = (const pintfn * const **) bar; /* { dg-warning "cast" } */ + const constfn ** const *p17 = (const constfn ** const *) bar; /* { dg-warning "cast" } */ + const pintfn ** const *p18 = (const pintfn ** const *) bar; /* { dg-warning "cast" } */ + constfn * const * const * p19 = (constfn * const * const *) bar; + pintfn * const * const * p20 = (pintfn * const * const *) bar; + const constfn * const * const *p21 = (const constfn * const * const *) bar; + const pintfn * const * const *p22 = (const pintfn * const * const *) bar; +} diff --git a/gcc/testsuite/gcc.dg/cast-qual-3.c b/gcc/testsuite/gcc.dg/cast-qual-3.c new file mode 100644 index 0000000..88fdcfb --- /dev/null +++ b/gcc/testsuite/gcc.dg/cast-qual-3.c @@ -0,0 +1,167 @@ +/* { dg-do compile } */ +/* { dg-options "-Wcast-qual" } */ + +/* The files gcc.dg/cast-qual-3.c and g++.dg/warn/Wcast-qual2.c are + duals. they are intended to show that gcc -Wcast-qual and g++ + -Wcast-qual emit warnings in the same cases. If you change this + file, please also change the other one. */ + +void +f1 (void *bar) +{ + const void *p1 = (const void *) bar; + const char *p2 = (const char *) bar; + const void **p3 = (const void **) bar; + const char **p4 = (const char **) bar; + const void * const *p5 = (const void * const *) bar; + const char * const *p6 = (const char * const *) bar; + void * const *p7 = (void * const *) bar; + char * const *p8 = (char * const *) bar; + const void ***p9 = (const void ***) bar; + const char ***p10 = (const char ***) bar; + void * const **p11 = (void * const **) bar; + char * const **p12 = (char * const **) bar; + void ** const *p13 = (void ** const *) bar; + char ** const *p14 = (char ** const *) bar; + const void * const **p15 = (const void * const **) bar; + const char * const **p16 = (const char * const **) bar; + const void ** const *p17 = (const void ** const *) bar; + const char ** const *p18 = (const char ** const *) bar; + void * const * const * p19 = (void * const * const *) bar; + char * const * const * p20 = (char * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; + const char * const * const *p22 = (const char * const * const *) bar; +} + +void +f2 (void **bar) +{ + const void *p1 = (const void *) bar; + const char *p2 = (const char *) bar; + const void **p3 = (const void **) bar; /* { dg-warning "cast" } */ + const char **p4 = (const char **) bar; + const void * const *p5 = (const void * const *) bar; + const char * const *p6 = (const char * const *) bar; + void * const *p7 = (void * const *) bar; + char * const *p8 = (char * const *) bar; + const void ***p9 = (const void ***) bar; + const char ***p10 = (const char ***) bar; + void * const **p11 = (void * const **) bar; + char * const **p12 = (char * const **) bar; + void ** const *p13 = (void ** const *) bar; + char ** const *p14 = (char ** const *) bar; + const void * const **p15 = (const void * const **) bar; + const char * const **p16 = (const char * const **) bar; + const void ** const *p17 = (const void ** const *) bar; + const char ** const *p18 = (const char ** const *) bar; + void * const * const * p19 = (void * const * const *) bar; + char * const * const * p20 = (char * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; + const char * const * const *p22 = (const char * const * const *) bar; +} + +void +f3 (void ***bar) +{ + const void *p1 = (const void *) bar; + const char *p2 = (const char *) bar; + const void **p3 = (const void **) bar; + const char **p4 = (const char **) bar; + const void * const *p5 = (const void * const *) bar; + const char * const *p6 = (const char * const *) bar; + void * const *p7 = (void * const *) bar; + char * const *p8 = (char * const *) bar; + const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */ + const char ***p10 = (const char ***) bar; + void * const **p11 = (void * const **) bar; /* { dg-warning "cast" } */ + char * const **p12 = (char * const **) bar; + void ** const *p13 = (void ** const *) bar; + char ** const *p14 = (char ** const *) bar; + const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */ + const char * const **p16 = (const char * const **) bar; + const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */ + const char ** const *p18 = (const char ** const *) bar; + void * const * const * p19 = (void * const * const *) bar; + char * const * const * p20 = (char * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; + const char * const * const *p22 = (const char * const * const *) bar; +} + +void +f4 (void * const **bar) +{ + const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */ + void * const **p11 = (void * const **) bar; + void ** const *p13 = (void ** const *) bar; /* { dg-warning "cast" } */ + const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */ + const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */ + void * const * const * p19 = (void * const * const *) bar; + const void * const * const *p21 = (const void * const * const *) bar; +} + +void +f5 (char ***bar) +{ + volatile const char ***p9 = (volatile const char ***) bar; /* { dg-warning "cast" } */ + volatile char * const **p11 = (volatile char * const **) bar; /* { dg-warning "cast" } */ + volatile char ** const *p13 = (volatile char ** const *) bar; /* { dg-warning "cast" } */ + volatile const char * const **p15 = (volatile const char * const **) bar; /* { dg-warning "cast" } */ + volatile const char ** const *p17 = (volatile const char ** const *) bar; /* { dg-warning "cast" } */ + volatile char * const * const * p19 = (volatile char * const * const *) bar; + volatile const char * const * const *p21 = (volatile const char * const * const *) bar; +} + +void +f6 (char ***bar) +{ + const char * volatile **p9 = (const char * volatile **) bar; /* { dg-warning "cast" } */ + char * volatile const **p11 = (char * volatile const **) bar; /* { dg-warning "cast" } */ + char * volatile * const *p13 = (char * volatile * const *) bar; + const char * volatile const **p15 = (const char * volatile const **) bar; /* { dg-warning "cast" } */ + const char * volatile * const *p17 = (const char * volatile * const *) bar; /* { dg-warning "cast" } */ + char * volatile const * const * p19 = (char * volatile const * const *) bar; + const char * volatile const * const *p21 = (const char * volatile const * const *) bar; +} + +void +f7 (char ***bar) +{ + const char ** volatile *p9 = (const char ** volatile *) bar; /* { dg-warning "cast" } */ + char * const * volatile *p11 = (char * const * volatile *) bar; /* { dg-warning "cast" } */ + char ** volatile const *p13 = (char ** volatile const *) bar; + const char * const * volatile *p15 = (const char * const * volatile *) bar; /* { dg-warning "cast" } */ + const char ** volatile const *p17 = (const char ** volatile const *) bar; /* { dg-warning "cast" } */ + char * const * volatile const * p19 = (char * const * volatile const *) bar; + const char * const * volatile const *p21 = (const char * const * volatile const *) bar; +} + +typedef int (intfn) (int); +typedef intfn *pintfn; +typedef const intfn *constfn; + +void +f8 (constfn ***bar) +{ + const constfn *p1 = (const constfn *) bar; + const pintfn *p2 = (const pintfn *) bar; + const constfn **p3 = (const constfn **) bar; + const pintfn **p4 = (const pintfn **) bar; + const constfn * const *p5 = (const constfn * const *) bar; + const pintfn * const *p6 = (const pintfn * const *) bar; + constfn * const *p7 = (constfn * const *) bar; + pintfn * const *p8 = (pintfn * const *) bar; + const constfn ***p9 = (const constfn ***) bar; /* { dg-warning "cast" } */ + const pintfn ***p10 = (const pintfn ***) bar; /* { dg-warning "cast" } */ + constfn * const **p11 = (constfn * const **) bar; /* { dg-warning "cast" } */ + pintfn * const **p12 = (pintfn * const **) bar; /* { dg-warning "cast" } */ + constfn ** const *p13 = (constfn ** const *) bar; + pintfn ** const *p14 = (pintfn ** const *) bar; + const constfn * const **p15 = (const constfn * const **) bar; /* { dg-warning "cast" } */ + const pintfn * const **p16 = (const pintfn * const **) bar; /* { dg-warning "cast" } */ + const constfn ** const *p17 = (const constfn ** const *) bar; /* { dg-warning "cast" } */ + const pintfn ** const *p18 = (const pintfn ** const *) bar; /* { dg-warning "cast" } */ + constfn * const * const * p19 = (constfn * const * const *) bar; + pintfn * const * const * p20 = (pintfn * const * const *) bar; + const constfn * const * const *p21 = (const constfn * const * const *) bar; + const pintfn * const * const *p22 = (const pintfn * const * const *) bar; +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 346887b..eb47d99 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1,6 +1,6 @@ /* Top level of GCC compilers (cc1, cc1plus, etc.) Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -2349,14 +2349,14 @@ toplev_main (int argc, char **argv) { expandargv (&argc, &argv); - save_argv = (const char **) argv; + save_argv = CONST_CAST2 (const char **, char **, argv); /* Initialization of GCC's environment, and diagnostics. */ general_init (argv[0]); /* Parse the options and do minimal processing; basically just enough to default flags appropriately. */ - decode_options (argc, (const char **) argv); + decode_options (argc, CONST_CAST2 (const char **, char **, argv)); init_local_tick ();