From 8a8211dffda1aa4fdb76b75a7c70bc8b5b18c719 Mon Sep 17 00:00:00 2001 From: jsm28 Date: Sat, 20 Dec 2014 00:29:16 +0000 Subject: [PATCH] 2014-12-20 Martin Uecker * doc/invoke.texi: Document -Wdiscarded-array-qualifiers. * doc/extend.texi: Document new behavior for pointers to arrays with qualifiers. c/ * c-typeck.c: New behavious for pointers to arrays with qualifiers (common-pointer-type): For pointers to arrays take qualifiers from element type. (build_conditional_expr): Add warnings for lost qualifiers. (comp-target-types): Allow pointers to arrays with different qualifiers. (convert-for-assignment): Adapt warnings for discarded qualifiers. Add WARNING_FOR_QUALIFIERS macro and rename WARN_FOR_QUALIFIERS to PEDWARN_FOR_QUALIFIERS. c-family/ * c.opt (Wdiscarded-array-qualifiers): New option. testsuite/ * gcc.dg/Wwrite-strings-1.c: Change dg-warning. * gcc.dg/array-quals-1.c: Use -Wno-discarded-array-qualifiers. * gcc.dg/array-quals-2.c: Change dg-options, dg-warning. * gcc.dg/pointer-array-atomic.c: New test. * gcc.dg/pointer-array-quals-1.c: New test. * gcc.dg/pointer-array-quals-2.c: New test (-pedantic-errors). * gcc.dg/qual-component-1.c: Change dg-options, dg-warnings. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218985 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 + gcc/c-family/ChangeLog | 4 + gcc/c-family/c.opt | 4 + gcc/c/ChangeLog | 11 + gcc/c/c-typeck.c | 328 +++++++++++++++++---------- gcc/doc/extend.texi | 22 ++ gcc/doc/invoke.texi | 14 +- gcc/testsuite/ChangeLog | 10 + gcc/testsuite/gcc.dg/Wwrite-strings-1.c | 2 +- gcc/testsuite/gcc.dg/array-quals-1.c | 1 + gcc/testsuite/gcc.dg/array-quals-2.c | 4 +- gcc/testsuite/gcc.dg/pointer-array-atomic.c | 60 +++++ gcc/testsuite/gcc.dg/pointer-array-quals-1.c | 106 +++++++++ gcc/testsuite/gcc.dg/pointer-array-quals-2.c | 102 +++++++++ gcc/testsuite/gcc.dg/qual-component-1.c | 42 ++-- 15 files changed, 568 insertions(+), 148 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pointer-array-atomic.c create mode 100644 gcc/testsuite/gcc.dg/pointer-array-quals-1.c create mode 100644 gcc/testsuite/gcc.dg/pointer-array-quals-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c5841f91c8..bddb9a8b6fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-12-20 Martin Uecker + + * doc/invoke.texi: Document -Wdiscarded-array-qualifiers. + * doc/extend.texi: Document new behavior for pointers to arrays + with qualifiers. + 2014-12-19 Jan Hubicka * hash-table.h (struct pointer_hash): Fix formating. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 94e6c34e9e6..7c0538d5da4 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2014-12-20 Martin Uecker + + * c.opt (Wdiscarded-array-qualifiers): New option. + 2014-12-19 Jakub Jelinek PR preprocessor/63831 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 1676f65bcd2..f86718b26f4 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -387,6 +387,10 @@ Wdesignated-init C ObjC Var(warn_designated_init) Init(1) Warning Warn about positional initialization of structs requiring designated initializers +Wdiscarded-array-qualifiers +C ObjC Var(warn_discarded_array_qualifiers) Init(1) Warning +Warn if qualifiers on arrays which are pointer targets are discarded + Wdiscarded-qualifiers C ObjC Var(warn_discarded_qualifiers) Init(1) Warning Warn if type qualifiers on pointers are discarded diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index ad9b8bc156f..1661747d604 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,14 @@ +2014-12-20 Martin Uecker + + * c-typeck.c: New behavious for pointers to arrays with qualifiers + (common-pointer-type): For pointers to arrays take qualifiers from + element type. + (build_conditional_expr): Add warnings for lost qualifiers. + (comp-target-types): Allow pointers to arrays with different qualifiers. + (convert-for-assignment): Adapt warnings for discarded qualifiers. Add + WARNING_FOR_QUALIFIERS macro and rename WARN_FOR_QUALIFIERS + to PEDWARN_FOR_QUALIFIERS. + 2014-12-17 Jakub Jelinek PR sanitizer/64289 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index ca9d512adf8..abd452aed39 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -673,12 +673,13 @@ common_pointer_type (tree t1, tree t2) mv2 = TYPE_MAIN_VARIANT (pointed_to_2); target = composite_type (mv1, mv2); + /* Strip array types to get correct qualifier for pointers to arrays */ + quals1 = TYPE_QUALS_NO_ADDR_SPACE (strip_array_types (pointed_to_1)); + quals2 = TYPE_QUALS_NO_ADDR_SPACE (strip_array_types (pointed_to_2)); + /* For function types do not merge const qualifiers, but drop them if used inconsistently. The middle-end uses these to mark const and noreturn functions. */ - quals1 = TYPE_QUALS_NO_ADDR_SPACE (pointed_to_1); - quals2 = TYPE_QUALS_NO_ADDR_SPACE (pointed_to_2); - if (TREE_CODE (pointed_to_1) == FUNCTION_TYPE) target_quals = (quals1 & quals2); else @@ -1224,6 +1225,7 @@ static int comp_target_types (location_t location, tree ttl, tree ttr) { int val; + int val_ped; tree mvl = TREE_TYPE (ttl); tree mvr = TREE_TYPE (ttr); addr_space_t asl = TYPE_ADDR_SPACE (mvl); @@ -1235,19 +1237,32 @@ comp_target_types (location_t location, tree ttl, tree ttr) if (!addr_space_superset (asl, asr, &as_common)) return 0; - /* Do not lose qualifiers on element types of array types that are - pointer targets by taking their TYPE_MAIN_VARIANT. */ - if (TREE_CODE (mvl) != ARRAY_TYPE) - mvl = (TYPE_ATOMIC (mvl) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvl), TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mvl)); - if (TREE_CODE (mvr) != ARRAY_TYPE) - mvr = (TYPE_ATOMIC (mvr) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvr), TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mvr)); + /* For pedantic record result of comptypes on arrays before losing + qualifiers on the element type below. */ + val_ped = 1; + + if (TREE_CODE (mvl) == ARRAY_TYPE + && TREE_CODE (mvr) == ARRAY_TYPE) + val_ped = comptypes (mvl, mvr); + + /* Qualifiers on element types of array types that are + pointer targets are lost by taking their TYPE_MAIN_VARIANT. */ + + mvl = (TYPE_ATOMIC (strip_array_types (mvl)) + ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvl), TYPE_QUAL_ATOMIC) + : TYPE_MAIN_VARIANT (mvl)); + + mvr = (TYPE_ATOMIC (strip_array_types (mvr)) + ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvr), TYPE_QUAL_ATOMIC) + : TYPE_MAIN_VARIANT (mvr)); + enum_and_int_p = false; val = comptypes_check_enum_int (mvl, mvr, &enum_and_int_p); + if (val == 1 && val_ped != 1) + pedwarn (location, OPT_Wpedantic, "pointers to arrays with different qualifiers " + "are incompatible in ISO C"); + if (val == 2) pedwarn (location, OPT_Wpedantic, "types are not quite compatible"); @@ -4609,6 +4624,13 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, else if (VOID_TYPE_P (TREE_TYPE (type1)) && !TYPE_ATOMIC (TREE_TYPE (type1))) { + if ((TREE_CODE (TREE_TYPE (type2)) == ARRAY_TYPE) + && (TYPE_QUALS (strip_array_types (TREE_TYPE (type2))) + & ~TYPE_QUALS (TREE_TYPE (type1)))) + warning_at (colon_loc, OPT_Wdiscarded_array_qualifiers, + "pointer to array loses qualifier " + "in conditional expression"); + if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) pedwarn (colon_loc, OPT_Wpedantic, "ISO C forbids conditional expr between " @@ -4619,6 +4641,13 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, else if (VOID_TYPE_P (TREE_TYPE (type2)) && !TYPE_ATOMIC (TREE_TYPE (type2))) { + if ((TREE_CODE (TREE_TYPE (type1)) == ARRAY_TYPE) + && (TYPE_QUALS (strip_array_types (TREE_TYPE (type1))) + & ~TYPE_QUALS (TREE_TYPE (type2)))) + warning_at (colon_loc, OPT_Wdiscarded_array_qualifiers, + "pointer to array loses qualifier " + "in conditional expression"); + if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) pedwarn (colon_loc, OPT_Wpedantic, "ISO C forbids conditional expr between " @@ -5661,7 +5690,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, /* This macro is used to emit diagnostics to ensure that all format strings are complete sentences, visible to gettext and checked at compile time. */ -#define WARN_FOR_ASSIGNMENT(LOCATION, PLOC, OPT, AR, AS, IN, RE) \ +#define PEDWARN_FOR_ASSIGNMENT(LOCATION, PLOC, OPT, AR, AS, IN, RE) \ do { \ switch (errtype) \ { \ @@ -5688,10 +5717,9 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, /* This macro is used to emit diagnostics to ensure that all format strings are complete sentences, visible to gettext and checked at - compile time. It is the same as WARN_FOR_ASSIGNMENT but with an + compile time. It is the same as PEDWARN_FOR_ASSIGNMENT but with an extra parameter to enumerate qualifiers. */ - -#define WARN_FOR_QUALIFIERS(LOCATION, PLOC, OPT, AR, AS, IN, RE, QUALS) \ +#define PEDWARN_FOR_QUALIFIERS(LOCATION, PLOC, OPT, AR, AS, IN, RE, QUALS) \ do { \ switch (errtype) \ { \ @@ -5716,6 +5744,35 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, } \ } while (0) + /* This macro is used to emit diagnostics to ensure that all format + strings are complete sentences, visible to gettext and checked at + compile time. It is the same as PEDWARN_FOR_QUALIFIERS but uses + warning_at instead of pedwarn. */ +#define WARNING_FOR_QUALIFIERS(LOCATION, PLOC, OPT, AR, AS, IN, RE, QUALS) \ + do { \ + switch (errtype) \ + { \ + case ic_argpass: \ + if (warning_at (PLOC, OPT, AR, parmnum, rname, QUALS)) \ + inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \ + ? DECL_SOURCE_LOCATION (fundecl) : PLOC, \ + "expected %qT but argument is of type %qT", \ + type, rhstype); \ + break; \ + case ic_assign: \ + warning_at (LOCATION, OPT, AS, QUALS); \ + break; \ + case ic_init: \ + warning_at (LOCATION, OPT, IN, QUALS); \ + break; \ + case ic_return: \ + warning_at (LOCATION, OPT, RE, QUALS); \ + break; \ + default: \ + gcc_unreachable (); \ + } \ + } while (0) + if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR) rhs = TREE_OPERAND (rhs, 0); @@ -5758,15 +5815,15 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, && TREE_CODE (type) == ENUMERAL_TYPE && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type)) { - WARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wc___compat, - G_("enum conversion when passing argument " - "%d of %qE is invalid in C++"), - G_("enum conversion in assignment is " - "invalid in C++"), - G_("enum conversion in initialization is " - "invalid in C++"), - G_("enum conversion in return is " - "invalid in C++")); + PEDWARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wc___compat, + G_("enum conversion when passing argument " + "%d of %qE is invalid in C++"), + G_("enum conversion in assignment is " + "invalid in C++"), + G_("enum conversion in initialization is " + "invalid in C++"), + G_("enum conversion in return is " + "invalid in C++")); } } @@ -5921,34 +5978,34 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, vice-versa. */ if (TYPE_QUALS_NO_ADDR_SPACE (ttl) & ~TYPE_QUALS_NO_ADDR_SPACE (ttr)) - WARN_FOR_QUALIFIERS (location, expr_loc, - OPT_Wdiscarded_qualifiers, - G_("passing argument %d of %qE " - "makes %q#v qualified function " - "pointer from unqualified"), - G_("assignment makes %q#v qualified " - "function pointer from " - "unqualified"), - G_("initialization makes %q#v qualified " - "function pointer from " - "unqualified"), - G_("return makes %q#v qualified function " - "pointer from unqualified"), - TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)); + PEDWARN_FOR_QUALIFIERS (location, expr_loc, + OPT_Wdiscarded_qualifiers, + G_("passing argument %d of %qE " + "makes %q#v qualified function " + "pointer from unqualified"), + G_("assignment makes %q#v qualified " + "function pointer from " + "unqualified"), + G_("initialization makes %q#v qualified " + "function pointer from " + "unqualified"), + G_("return makes %q#v qualified function " + "pointer from unqualified"), + TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)); } else if (TYPE_QUALS_NO_ADDR_SPACE (ttr) & ~TYPE_QUALS_NO_ADDR_SPACE (ttl)) - WARN_FOR_QUALIFIERS (location, expr_loc, - OPT_Wdiscarded_qualifiers, - G_("passing argument %d of %qE discards " - "%qv qualifier from pointer target type"), - G_("assignment discards %qv qualifier " - "from pointer target type"), - G_("initialization discards %qv qualifier " - "from pointer target type"), - G_("return discards %qv qualifier from " - "pointer target type"), - TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)); + PEDWARN_FOR_QUALIFIERS (location, expr_loc, + OPT_Wdiscarded_qualifiers, + G_("passing argument %d of %qE discards " + "%qv qualifier from pointer target type"), + G_("assignment discards %qv qualifier " + "from pointer target type"), + G_("initialization discards %qv qualifier " + "from pointer target type"), + G_("return discards %qv qualifier from " + "pointer target type"), + TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)); memb = marginal_memb; } @@ -6096,42 +6153,69 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, == c_common_signed_type (mvr)) && TYPE_ATOMIC (mvl) == TYPE_ATOMIC (mvr))) { - if (pedantic + /* Warn about loss of qualifers from pointers to arrays with + qualifiers on the element type. */ + if (TREE_CODE (ttr) == ARRAY_TYPE) + { + ttr = strip_array_types (ttr); + ttl = strip_array_types (ttl); + + if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr) + & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl)) + WARNING_FOR_QUALIFIERS (location, expr_loc, + OPT_Wdiscarded_array_qualifiers, + G_("passing argument %d of %qE discards " + "%qv qualifier from pointer target type"), + G_("assignment discards %qv qualifier " + "from pointer target type"), + G_("initialization discards %qv qualifier " + "from pointer target type"), + G_("return discards %qv qualifier from " + "pointer target type"), + TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)); + } + else if (pedantic && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE) || (VOID_TYPE_P (ttr) && !null_pointer_constant && TREE_CODE (ttl) == FUNCTION_TYPE))) - WARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpedantic, - G_("ISO C forbids passing argument %d of " - "%qE between function pointer " - "and %"), - G_("ISO C forbids assignment between " - "function pointer and %"), - G_("ISO C forbids initialization between " - "function pointer and %"), - G_("ISO C forbids return between function " - "pointer and %")); + PEDWARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpedantic, + G_("ISO C forbids passing argument %d of " + "%qE between function pointer " + "and %"), + G_("ISO C forbids assignment between " + "function pointer and %"), + G_("ISO C forbids initialization between " + "function pointer and %"), + G_("ISO C forbids return between function " + "pointer and %")); /* Const and volatile mean something different for function types, so the usual warnings are not appropriate. */ else if (TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttl) != FUNCTION_TYPE) { + /* Don't warn about loss of qualifier for conversions from + qualified void* to pointers to arrays with corresponding + qualifier on the element type. */ + if (!pedantic) + ttl = strip_array_types (ttl); + /* Assignments between atomic and non-atomic objects are OK. */ if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr) & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl)) { - WARN_FOR_QUALIFIERS (location, expr_loc, - OPT_Wdiscarded_qualifiers, - G_("passing argument %d of %qE discards " - "%qv qualifier from pointer target type"), - G_("assignment discards %qv qualifier " - "from pointer target type"), - G_("initialization discards %qv qualifier " - "from pointer target type"), - G_("return discards %qv qualifier from " - "pointer target type"), - TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)); + PEDWARN_FOR_QUALIFIERS (location, expr_loc, + OPT_Wdiscarded_qualifiers, + G_("passing argument %d of %qE discards " + "%qv qualifier from pointer target type"), + G_("assignment discards %qv qualifier " + "from pointer target type"), + G_("initialization discards %qv qualifier " + "from pointer target type"), + G_("return discards %qv qualifier from " + "pointer target type"), + TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)); } /* If this is not a case of ignoring a mismatch in signedness, no warning. */ @@ -6140,15 +6224,15 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, ; /* If there is a mismatch, do warn. */ else if (warn_pointer_sign) - WARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpointer_sign, - G_("pointer targets in passing argument " - "%d of %qE differ in signedness"), - G_("pointer targets in assignment " - "differ in signedness"), - G_("pointer targets in initialization " - "differ in signedness"), - G_("pointer targets in return differ " - "in signedness")); + PEDWARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpointer_sign, + G_("pointer targets in passing argument " + "%d of %qE differ in signedness"), + G_("pointer targets in assignment " + "differ in signedness"), + G_("pointer targets in initialization " + "differ in signedness"), + G_("pointer targets in return differ " + "in signedness")); } else if (TREE_CODE (ttl) == FUNCTION_TYPE && TREE_CODE (ttr) == FUNCTION_TYPE) @@ -6159,31 +6243,31 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS_NO_ADDR_SPACE (ttl) & ~TYPE_QUALS_NO_ADDR_SPACE (ttr)) - WARN_FOR_QUALIFIERS (location, expr_loc, - OPT_Wdiscarded_qualifiers, - G_("passing argument %d of %qE makes " - "%q#v qualified function pointer " - "from unqualified"), - G_("assignment makes %q#v qualified function " - "pointer from unqualified"), - G_("initialization makes %q#v qualified " - "function pointer from unqualified"), - G_("return makes %q#v qualified function " - "pointer from unqualified"), - TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)); + PEDWARN_FOR_QUALIFIERS (location, expr_loc, + OPT_Wdiscarded_qualifiers, + G_("passing argument %d of %qE makes " + "%q#v qualified function pointer " + "from unqualified"), + G_("assignment makes %q#v qualified function " + "pointer from unqualified"), + G_("initialization makes %q#v qualified " + "function pointer from unqualified"), + G_("return makes %q#v qualified function " + "pointer from unqualified"), + TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)); } } else /* Avoid warning about the volatile ObjC EH puts on decls. */ if (!objc_ok) - WARN_FOR_ASSIGNMENT (location, expr_loc, - OPT_Wincompatible_pointer_types, - G_("passing argument %d of %qE from " - "incompatible pointer type"), - G_("assignment from incompatible pointer type"), - G_("initialization from incompatible " - "pointer type"), - G_("return from incompatible pointer type")); + PEDWARN_FOR_ASSIGNMENT (location, expr_loc, + OPT_Wincompatible_pointer_types, + G_("passing argument %d of %qE from " + "incompatible pointer type"), + G_("assignment from incompatible pointer type"), + G_("initialization from incompatible " + "pointer type"), + G_("return from incompatible pointer type")); return convert (type, rhs); } @@ -6200,31 +6284,31 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, or one that results from arithmetic, even including a cast to integer type. */ if (!null_pointer_constant) - WARN_FOR_ASSIGNMENT (location, expr_loc, - OPT_Wint_conversion, - G_("passing argument %d of %qE makes " - "pointer from integer without a cast"), - G_("assignment makes pointer from integer " - "without a cast"), - G_("initialization makes pointer from " - "integer without a cast"), - G_("return makes pointer from integer " - "without a cast")); + PEDWARN_FOR_ASSIGNMENT (location, expr_loc, + OPT_Wint_conversion, + G_("passing argument %d of %qE makes " + "pointer from integer without a cast"), + G_("assignment makes pointer from integer " + "without a cast"), + G_("initialization makes pointer from " + "integer without a cast"), + G_("return makes pointer from integer " + "without a cast")); return convert (type, rhs); } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { - WARN_FOR_ASSIGNMENT (location, expr_loc, - OPT_Wint_conversion, - G_("passing argument %d of %qE makes integer " - "from pointer without a cast"), - G_("assignment makes integer from pointer " - "without a cast"), - G_("initialization makes integer from pointer " - "without a cast"), - G_("return makes integer from pointer " - "without a cast")); + PEDWARN_FOR_ASSIGNMENT (location, expr_loc, + OPT_Wint_conversion, + G_("passing argument %d of %qE makes integer " + "from pointer without a cast"), + G_("assignment makes integer from pointer " + "without a cast"), + G_("initialization makes integer from pointer " + "without a cast"), + G_("return makes integer from pointer " + "without a cast")); return convert (type, rhs); } else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index aaace534387..ffefb673efe 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -46,6 +46,7 @@ extensions, accepted by GCC in C90 mode and in C++. * Escaped Newlines:: Slightly looser rules for escaped newlines. * Subscripting:: Any array can be subscripted, even if not an lvalue. * Pointer Arith:: Arithmetic on @code{void}-pointers and function pointers. +* Pointers to Arrays:: Pointers to arrays with qualifiers work as expected. * Initializers:: Non-constant initializers. * Compound Literals:: Compound literals give structures, unions or arrays as values. @@ -1784,6 +1785,27 @@ and on function types, and returns 1. The option @option{-Wpointer-arith} requests a warning if these extensions are used. +@node Pointers to Arrays +@section Pointers to arrays with qualifiers work as expected +@cindex pointers to arrays +@cindex const qualifier + +In GNU C, pointers to arrays with qualifiers work similar to pointers +to other qualified types. For example, a value of type @code{int (*)[5]} +can be used to initialize a variable of type @code{const int (*)[5]}. +These types are incompatible in ISO C because the @code{const} qualifier +is formally attached to the element type of the array and not the +array itself. + +@smallexample +extern void +transpose (int N, int M, double out[M][N], const double in[N][M]); +double x[3][2]; +double y[2][3]; +@r{@dots{}} +transpose(3, 2, y, x); +@end smallexample + @node Initializers @section Non-Constant Initializers @cindex initializers, non-constant diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e37c777e895..9f56f42218d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -248,7 +248,8 @@ Objective-C and Objective-C++ Dialects}. -Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol -Wconversion -Wcoverage-mismatch -Wdate-time -Wdelete-incomplete -Wno-cpp @gol -Wno-deprecated -Wno-deprecated-declarations -Wno-designated-init @gol --Wdisabled-optimization -Wno-discarded-qualifiers @gol +-Wdisabled-optimization @gol +-Wno-discarded-qualifiers -Wno-discarded-array-qualifiers @gol -Wno-div-by-zero -Wdouble-promotion -Wempty-body -Wenum-compare @gol -Wno-endif-labels -Werror -Werror=* @gol -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol @@ -4300,9 +4301,18 @@ This warning is enabled by @option{-Wall}. @opindex Wdiscarded-qualifiers Do not warn if type qualifiers on pointers are being discarded. Typically, the compiler will warn if a @code{const char *} variable is -passed to a function that takes @code{char *} parameter. This option +passed to a function that takes a @code{char *} parameter. This option can be used to suppress such a warning. +@item -Wno-discarded-array-qualifiers @r{(C and Objective-C only)} +@opindex Wno-discarded-array-qualifiers +@opindex Wdiscarded-array-qualifiers +Do not warn if type qualifiers on arrays which are pointer targets +are being discarded. Typically, the compiler will warn if a +@code{const int (*)[]} variable is passed to a function that +takes a @code{int (*)[]} parameter. This option can be used to +suppress such a warning. + @item -Wno-incompatible-pointer-types @r{(C and Objective-C only)} @opindex Wno-incompatible-pointer-types @opindex Wincompatible-pointer-types diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad7acfba947..fd6c398ef88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2014-12-20 Martin Uecker + + * gcc.dg/Wwrite-strings-1.c: Change dg-warning. + * gcc.dg/array-quals-1.c: Use -Wno-discarded-array-qualifiers. + * gcc.dg/array-quals-2.c: Change dg-options, dg-warning. + * gcc.dg/pointer-array-atomic.c: New test. + * gcc.dg/pointer-array-quals-1.c: New test. + * gcc.dg/pointer-array-quals-2.c: New test (-pedantic-errors). + * gcc.dg/qual-component-1.c: Change dg-options, dg-warnings. + 2014-12-19 David Malcolm * jit.dg/test-expressions.c (make_tests_of_casts): Add tests of diff --git a/gcc/testsuite/gcc.dg/Wwrite-strings-1.c b/gcc/testsuite/gcc.dg/Wwrite-strings-1.c index 03bb4094104..24547d02bd8 100644 --- a/gcc/testsuite/gcc.dg/Wwrite-strings-1.c +++ b/gcc/testsuite/gcc.dg/Wwrite-strings-1.c @@ -5,4 +5,4 @@ /* { dg-do compile } */ /* { dg-options "-Wwrite-strings" } */ typedef char T[1]; -T *p = &""; /* { dg-warning "initialization from incompatible pointer type" } */ +T *p = &""; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ diff --git a/gcc/testsuite/gcc.dg/array-quals-1.c b/gcc/testsuite/gcc.dg/array-quals-1.c index 514daf8bc55..3981c916021 100644 --- a/gcc/testsuite/gcc.dg/array-quals-1.c +++ b/gcc/testsuite/gcc.dg/array-quals-1.c @@ -3,6 +3,7 @@ all should end up in a read-only section. PR c/12165. */ /* Origin: Joseph Myers */ /* { dg-do compile } */ +/* { dg-options "-Wno-discarded-array-qualifiers" } */ /* The MMIX port always switches to the .data section at the end of a file. */ /* { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail powerpc*-*-aix* mmix-*-* x86_64-*-mingw* } } } */ static const int a[2] = { 1, 2 }; diff --git a/gcc/testsuite/gcc.dg/array-quals-2.c b/gcc/testsuite/gcc.dg/array-quals-2.c index 2f1304e2a64..7f33e3fb2ce 100644 --- a/gcc/testsuite/gcc.dg/array-quals-2.c +++ b/gcc/testsuite/gcc.dg/array-quals-2.c @@ -3,12 +3,12 @@ lost in forming composite types. */ /* Origin: Joseph Myers */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-pedantic -Wno-discarded-array-qualifiers" } */ 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 "pointer type mismatch in conditional expression" } */ +void *f(void) { return 1 ? p : q; } /* { dg-warning "pointers to arrays with different qualifiers" } */ T *g(void) { return 1 ? p : p2; } diff --git a/gcc/testsuite/gcc.dg/pointer-array-atomic.c b/gcc/testsuite/gcc.dg/pointer-array-atomic.c new file mode 100644 index 00000000000..55b58e84e35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-array-atomic.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c11" } */ +/* Origin: Martin Uecker */ +void tvoid(void* x); +void transpose0(double* out, _Atomic double* in) { } +void transpose1(double out[2][2], _Atomic double in[2][2]) { } +void transpose2(double out[2][2][2], _Atomic double in[2][2][2]) { } +// return +int (*x2(_Atomic int x[3][3]))[3] { return x; } /* { dg-warning "return from incompatible pointer type" } */ +_Atomic int (*x3(int x[3][3]))[3] { return x; } /* { dg-warning "return from incompatible pointer type" } */ +void test(void) +{ + double x0[2]; + double y0[2]; + _Atomic double z0[4]; + double x1[2][2]; + double y1[2][2]; + double o1[2][3]; + _Atomic double z1[2][2]; + double x2[2][2][2]; + double y2[2][2][2]; + double o2[2][2][3]; + _Atomic double z2[2][2][2]; + tvoid(z0); + tvoid(z1); + tvoid(z2); + // passing as arguments + transpose0(y0, x0); /* { dg-warning "passing argument 2 of 'transpose0' from incompatible pointer type" } */ + transpose1(y1, o1); /* { dg-warning "passing argument 2 of 'transpose1' from incompatible pointer type" } */ + transpose1(y1, x1); /* { dg-warning "passing argument 2 of 'transpose1' from incompatible pointer type" } */ + transpose2(y2, o2); /* { dg-warning "passing argument 2 of 'transpose2' from incompatible pointer type" } */ + transpose2(y2, x2); /* { dg-warning "passing argument 2 of 'transpose2' from incompatible pointer type" } */ + // initialization + _Atomic double (*x0p) = x0; /* { dg-warning "initialization from incompatible pointer type" } */ + _Atomic double (*x1p)[2] = x1; /* { dg-warning "initialization from incompatible pointer type" } */ + _Atomic double (*x2p)[2][2] = x2; /* { dg-warning "initialization from incompatible pointer type" } */ + // assignment + x0p = x0; /* { dg-warning "assignment from incompatible pointer type" } */ + x1p = x1; /* { dg-warning "assignment from incompatible pointer type" } */ + x2p = x2; /* { dg-warning "assignment from incompatible pointer type" } */ + // subtraction + &(x0[1]) - &(z0[0]); /* { dg-error "invalid operands to binary" } */ + &(x1[1]) - &(z1[0]); /* { dg-error "invalid operands to binary" } */ + &(x2[1]) - &(z2[0]); /* { dg-error "invalid operands to binary" } */ + // comparison + x0 == z0; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x1 == z1; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x2 == z2; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x0 > z0; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x1 > z1; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x2 > z2; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x0 < z0; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x1 < z1; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + x2 < z2; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */ + // conditional expressions + (void)(1 ? x0 : z0); /* { dg-warning "pointer type mismatch in conditional expression" } */ + (void)(1 ? x1 : z1); /* { dg-warning "pointer type mismatch in conditional expression" } */ + (void)(1 ? x2 : z2); /* { dg-warning "pointer type mismatch in conditional expression" } */ +} + diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c new file mode 100644 index 00000000000..921a37e9e0d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c @@ -0,0 +1,106 @@ +/* { dg-do compile } */ +/* Origin: Martin Uecker */ +/* { dg-options "-Wdiscarded-array-qualifiers" } */ +void tvoid(void* x); +void transpose0(double* out, const double* in) { } +void transpose1(double out[2][2], const double in[2][2]) { } +void transpose2(double out[2][2][2], const double in[2][2][2]) { } +// return +int (*y2(const int x[3][3]))[3] { return x; } /* { dg-warning "return discards 'const' qualifier from pointer target type" } */ +const int (*y3(int x[3][3]))[3] { return x; } +void test(void) +{ + double x0[2]; + double y0[2]; + const double z0[4]; + double x1[2][2]; + double y1[2][2]; + double o1[2][3]; + const double z1[2][2]; + double x2[2][2][2]; + double y2[2][2][2]; + double o2[2][2][3]; + const double z2[2][2][2]; + // void pointers + tvoid(x0); + tvoid(x1); + tvoid(x2); + tvoid(z0); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z1); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z2); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + void* p; + const void* pc; + p = x0; + p = x1; + p = x2; + p = z0; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + p = z1; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + p = z2; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + pc = x0; + pc = x1; + pc = x2; + pc = z0; + pc = z1; + pc = z2; + transpose0(pc, p); /* { dg-warning "passing argument 1 of 'transpose0' discards 'const' qualifier from pointer target type" } */ + transpose1(pc, p); /* { dg-warning "passing argument 1 of 'transpose1' discards 'const' qualifier from pointer target type" } */ + transpose2(pc, p); /* { dg-warning "passing argument 1 of 'transpose2' discards 'const' qualifier from pointer target type" } */ + transpose0(p, pc); + transpose1(p, pc); + transpose2(p, pc); + // passing as arguments + transpose0(y0, x0); + transpose1(y1, x1); + transpose2(y2, x2); + // initialization + const double (*u0p) = x0; + const double (*u1p)[2] = x1; + const double (*u2p)[2][2] = x2; + double (*v0p) = z0; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ + double (*v1p)[2] = z1; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ + double (*v2p)[2][2] = z2; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ + // subtraction + &(x0[1]) - &(z0[0]); + &(x1[1]) - &(z1[0]); + &(x2[1]) - &(z2[0]); + // comparison + x0 == z0; + x1 == z1; + x2 == z2; + x0 < z0; + x1 < z1; + x2 < z2; + x0 > z0; + x1 > z1; + x2 > z2; + // assignment + u0p = x0; + u1p = x1; + u2p = x2; + v0p = z0; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = z1; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = z2; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + // conditional expressions + (void)(1 ? x0 : z0); + (void)(1 ? x1 : z1); + (void)(1 ? x2 : z2); + (void)(1 ? x0 : x1); /* { dg-warning "pointer type mismatch in conditional expression" } */ + (void)(1 ? x1 : x2); /* { dg-warning "pointer type mismatch in conditional expression" } */ + (void)(1 ? x2 : x0); /* { dg-warning "pointer type mismatch in conditional expression" } */ + v0p = (1 ? z0 : v0p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? z1 : v1p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? z2 : v2p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v0p = (1 ? x0 : u0p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? x1 : u1p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? x2 : u2p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + (1 ? x0 : z0)[0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x1 : z1)[0][0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x2 : z2)[0][0][0] = 1; /* { dg-error "assignment of read-only location" } */ + v0p = (1 ? p : z0); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? p : z1); /* { dg-warning "pointer to array loses qualifier in conditional expression" } */ + v2p = (1 ? p : z2); /* { dg-warning "pointer to array loses qualifier in conditional expression" } */ + v0p = (1 ? pc : x0); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? pc : x1); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? pc : x2); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ +} + diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-2.c b/gcc/testsuite/gcc.dg/pointer-array-quals-2.c new file mode 100644 index 00000000000..30689c7312d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-array-quals-2.c @@ -0,0 +1,102 @@ +/* { dg-do compile } */ +/* { dg-options "-Wdiscarded-array-qualifiers -pedantic-errors" } */ +/* Origin: Martin Uecker */ +void tvoid(void* x); +void transpose0(double* out, const double* in) { } +void transpose1(double out[2][2], const double in[2][2]) { } +void transpose2(double out[2][2][2], const double in[2][2][2]) { } +// return +int (*x2(const int x[3][3]))[3] { return x; } /* { dg-error "pointers to arrays with different qualifiers|return discards" } */ +const int (*x3(int x[3][3]))[3] { return x; } /* { dg-error "pointers to arrays with different qualifiers" } */ +void test(void) +{ + double x0[2]; + double y0[2]; + const double z0[4]; + double x1[2][2]; + double y1[2][2]; + double o1[2][3]; + const double z1[2][2]; + double x2[2][2][2]; + double y2[2][2][2]; + double o2[2][2][3]; + const double z2[2][2][2]; + // void pointers + tvoid(z0); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z1); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z2); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + void* p; + const void* pc; + p = x0; + p = x1; + p = x2; + p = z0; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + p = z1; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + p = z2; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + pc = x0; + pc = x1; + pc = x2; + pc = z0; + pc = z1; + pc = z2; + transpose0(pc, p); /* { dg-error "passing argument 1 of 'transpose0' discards 'const' qualifier from pointer target type" } */ + transpose1(pc, p); /* { dg-error "passing argument 1 of 'transpose1' discards 'const' qualifier from pointer target type" } */ + transpose2(pc, p); /* { dg-error "passing argument 1 of 'transpose2' discards 'const' qualifier from pointer target type" } */ + transpose0(p, pc); + transpose1(p, pc); /* { dg-error "passing argument 2 of 'transpose1' discards 'const' qualifier from pointer target type" } */ + transpose2(p, pc); /* { dg-error "passing argument 2 of 'transpose2' discards 'const' qualifier from pointer target type" } */ + // passing as arguments + transpose0(y0, x0); + transpose1(y1, o1); /* { dg-error "passing argument 2 of 'transpose1' from incompatible pointer type" } */ + transpose1(y1, x1); /* { dg-error "pointers to arrays with different qualifiers" } */ + transpose2(y2, o2); /* { dg-error "passing argument 2 of 'transpose2' from incompatible pointer type" } */ + transpose2(y2, x2); /* { dg-error "pointers to arrays with different qualifiers" } */ + // initialization + const double (*x0p) = x0; + const double (*x1p)[2] = x1; /* { dg-error "pointers to arrays with different qualifiers" } */ + const double (*x2p)[2][2] = x2; /* { dg-error "pointers to arrays with different qualifiers" } */ + double (*v0p) = z0; /* { dg-error "initialization discards 'const' qualifier from pointer target type" } */ + double (*v1p)[2] = z1; /* { dg-error "pointers to arrays with different qualifiers|initialization discards" } */ + double (*v2p)[2][2] = z2; /* { dg-error "pointers to arrays with different qualifiers|initialization discards" } */ + // assignment + x0p = x0; + x1p = x1; /* { dg-error "pointers to arrays with different qualifiers" } */ + x2p = x2; /* { dg-error "pointers to arrays with different qualifiers" } */ + // subtraction + &(x0[1]) - &(z0[0]); + &(x1[1]) - &(z1[0]); /* { dg-error "pointers to arrays with different qualifiers" } */ + &(x2[1]) - &(z2[0]); /* { dg-error "pointers to arrays with different qualifiers" } */ + // comparison + x0 == z0; + x1 == z1; /* { dg-error "pointers to arrays with different qualifiers" } */ + x2 == z2; /* { dg-error "pointers to arrays with different qualifiers" } */ + x0 < z0; + x1 < z1; /* { dg-error "pointers to arrays with different qualifiers" } */ + x2 < z2; /* { dg-error "pointers to arrays with different qualifiers" } */ + x0 > z0; + x1 > z1; /* { dg-error "pointers to arrays with different qualifiers" } */ + x2 > z2; /* { dg-error "pointers to arrays with different qualifiers" } */ + // conditional expressions + (void)(1 ? x0 : z0); + (void)(1 ? x1 : z1); /* { dg-error "pointers to arrays with different qualifiers" } */ + (void)(1 ? x2 : z2); /* { dg-error "pointers to arrays with different qualifiers" } */ + (void)(1 ? x0 : x1); /* { dg-error "pointer type mismatch in conditional expression" } */ + (void)(1 ? x1 : x2); /* { dg-error "pointer type mismatch in conditional expression" } */ + (void)(1 ? x2 : x0); /* { dg-error "pointer type mismatch in conditional expression" } */ + v0p = (1 ? z0 : v0p); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? z1 : v1p); /* { dg-error "pointers to arrays with different qualifiers|assignment discards" } */ + v2p = (1 ? z2 : v2p); /* { dg-error "pointers to arrays with different qualifiers|assignment discards" } */ + v0p = (1 ? x0 : x0p); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? x1 : x1p); /* { dg-error "pointers to arrays with different qualifiers|assignment discards" } */ + v2p = (1 ? x2 : x2p); /* { dg-error "pointers to arrays with different qualifiers|assignment discards" } */ + (1 ? x0 : z0)[0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x1 : z1)[0][0] = 1; /* { dg-error "assignment of read-only location|pointers to arrays" } */ + (1 ? x2 : z2)[0][0][0] = 1; /* { dg-error "assignment of read-only location|pointers to arrays" } */ + v0p = (1 ? p : z0); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? p : z1); /* { dg-warning "pointer to array loses qualifier in conditional expression" } */ + v2p = (1 ? p : z2); /* { dg-warning "pointer to array loses qualifier in conditional expression" } */ + v0p = (1 ? pc : x0); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? pc : x1); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? pc : x2); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ +} + diff --git a/gcc/testsuite/gcc.dg/qual-component-1.c b/gcc/testsuite/gcc.dg/qual-component-1.c index dedc63f39b2..4eaa71a2d19 100644 --- a/gcc/testsuite/gcc.dg/qual-component-1.c +++ b/gcc/testsuite/gcc.dg/qual-component-1.c @@ -3,7 +3,7 @@ union. Bug 27697 from Frank Victor Fischer. */ /* Origin: Joseph Myers */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-pedantic -Wdiscarded-array-qualifiers" } */ struct s { int a; @@ -110,24 +110,24 @@ g (void) int (*b)[1] = &v1.b; int (*c)[2][3] = &v1.c; int (*cc)[3] = v1.c; - const int (*ff)[3] = v1.c; /* { dg-warning "initialization from incompatible pointer type" } */ + const int (*ff)[3] = v1.c; /* { dg-warning "pointers to arrays with different qualifiers" } */ a = &v1.a; b = &v1.b; c = &v1.c; cc = v1.c; - ff = v1.c; /* { dg-warning "assignment from incompatible pointer type" } */ + ff = v1.c; /* { dg-warning "pointers to arrays with different qualifiers" } */ } { const int *d = &v1.d; const int (*e)[1] = &v1.e; const int (*f)[2][3] = &v1.f; const int (*ff)[3] = v1.f; - int (*cc)[3] = v1.f; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v1.f; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v1.d; e = &v1.e; f = &v1.f; ff = v1.f; - cc = v1.f; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v1.f; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { @@ -135,24 +135,24 @@ g (void) int (*b)[1] = &v2->b; int (*c)[2][3] = &v2->c; int (*cc)[3] = v2->c; - const int (*ff)[3] = v2->c; /* { dg-warning "initialization from incompatible pointer type" } */ + const int (*ff)[3] = v2->c; /* { dg-warning "pointers to arrays with different qualifiers" } */ a = &v2->a; b = &v2->b; c = &v2->c; cc = v2->c; - ff = v2->c; /* { dg-warning "assignment from incompatible pointer type" } */ + ff = v2->c; /* { dg-warning "pointers to arrays with different qualifiers" } */ } { const int *d = &v2->d; const int (*e)[1] = &v2->e; const int (*f)[2][3] = &v2->f; const int (*ff)[3] = v2->f; - int (*cc)[3] = v2->f; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v2->f; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v2->d; e = &v2->e; f = &v2->f; ff = v2->f; - cc = v2->f; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v2->f; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { @@ -160,24 +160,24 @@ g (void) const int (*e)[1] = &v3->b; const int (*f)[2][3] = &v3->c; const int (*ff)[3] = v3->c; - int (*cc)[3] = v3->c; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v3->c; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v3->a; e = &v3->b; f = &v3->c; ff = v3->c; - cc = v3->c; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v3->c; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { const int *d = &v3->d; const int (*e)[1] = &v3->e; const int (*f)[2][3] = &v3->f; const int (*ff)[3] = v3->f; - int (*cc)[3] = v3->f; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v3->f; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v3->d; e = &v3->e; f = &v3->f; ff = v3->f; - cc = v3->f; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v3->f; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { @@ -185,24 +185,24 @@ g (void) const int (*e)[1] = &v4.b; const int (*f)[2][3] = &v4.c; const int (*ff)[3] = v4.c; - int (*cc)[3] = v4.c; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v4.c; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v4.a; e = &v4.b; f = &v4.c; ff = v4.c; - cc = v4.c; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v4.c; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { const int *d = &v4.d; const int (*e)[1] = &v4.e; const int (*f)[2][3] = &v4.f; const int (*ff)[3] = v4.f; - int (*cc)[3] = v4.f; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v4.f; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v4.d; e = &v4.e; f = &v4.f; ff = v4.f; - cc = v4.f; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v4.f; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { @@ -210,23 +210,23 @@ g (void) const int (*e)[1] = &v5.x.b; const int (*f)[2][3] = &v5.x.c; const int (*ff)[3] = v5.x.c; - int (*cc)[3] = v5.x.c; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v5.x.c; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v5.x.a; e = &v5.x.b; f = &v5.x.c; ff = v5.x.c; - cc = v5.x.c; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v5.x.c; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } { const int *d = &v5.x.d; const int (*e)[1] = &v5.x.e; const int (*f)[2][3] = &v5.x.f; const int (*ff)[3] = v5.x.f; - int (*cc)[3] = v5.x.f; /* { dg-warning "initialization from incompatible pointer type" } */ + int (*cc)[3] = v5.x.f; /* { dg-warning "pointers to arrays with different qualifiers|initialization discards" } */ d = &v5.x.d; e = &v5.x.e; f = &v5.x.f; ff = v5.x.f; - cc = v5.x.f; /* { dg-warning "assignment from incompatible pointer type" } */ + cc = v5.x.f; /* { dg-warning "pointers to arrays with different qualifiers|assignment discards" } */ } } -- 2.11.4.GIT