invoke.texi: Document -Wdiscarded-array-qualifiers.
2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu> * 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. From-SVN: r218985
This commit is contained in:
parent
189486b858
commit
768952be25
@ -1,3 +1,9 @@
|
||||
2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu>
|
||||
|
||||
* doc/invoke.texi: Document -Wdiscarded-array-qualifiers.
|
||||
* doc/extend.texi: Document new behavior for pointers to arrays
|
||||
with qualifiers.
|
||||
|
||||
2014-12-19 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* hash-table.h (struct pointer_hash): Fix formating.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu>
|
||||
|
||||
* c.opt (Wdiscarded-array-qualifiers): New option.
|
||||
|
||||
2014-12-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR preprocessor/63831
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,14 @@
|
||||
2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu>
|
||||
|
||||
* 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 <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/64289
|
||||
|
328
gcc/c/c-typeck.c
328
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 %<void *%>"),
|
||||
G_("ISO C forbids assignment between "
|
||||
"function pointer and %<void *%>"),
|
||||
G_("ISO C forbids initialization between "
|
||||
"function pointer and %<void *%>"),
|
||||
G_("ISO C forbids return between function "
|
||||
"pointer and %<void *%>"));
|
||||
PEDWARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpedantic,
|
||||
G_("ISO C forbids passing argument %d of "
|
||||
"%qE between function pointer "
|
||||
"and %<void *%>"),
|
||||
G_("ISO C forbids assignment between "
|
||||
"function pointer and %<void *%>"),
|
||||
G_("ISO C forbids initialization between "
|
||||
"function pointer and %<void *%>"),
|
||||
G_("ISO C forbids return between function "
|
||||
"pointer and %<void *%>"));
|
||||
/* 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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,13 @@
|
||||
2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu>
|
||||
|
||||
* 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 <dmalcolm@redhat.com>
|
||||
|
||||
* jit.dg/test-expressions.c (make_tests_of_casts): Add tests of
|
||||
|
@ -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" } */
|
||||
|
@ -3,6 +3,7 @@
|
||||
all should end up in a read-only section. PR c/12165. */
|
||||
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
|
||||
/* { 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 };
|
||||
|
@ -3,12 +3,12 @@
|
||||
lost in forming composite types. */
|
||||
/* Origin: Joseph Myers <joseph@codesourcery.com> */
|
||||
/* { 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; }
|
||||
|
60
gcc/testsuite/gcc.dg/pointer-array-atomic.c
Normal file
60
gcc/testsuite/gcc.dg/pointer-array-atomic.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c11" } */
|
||||
/* Origin: Martin Uecker <uecker@eecs.berkeley.edu> */
|
||||
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" } */
|
||||
}
|
||||
|
106
gcc/testsuite/gcc.dg/pointer-array-quals-1.c
Normal file
106
gcc/testsuite/gcc.dg/pointer-array-quals-1.c
Normal file
@ -0,0 +1,106 @@
|
||||
/* { dg-do compile } */
|
||||
/* Origin: Martin Uecker <uecker@eecs.berkeley.edu> */
|
||||
/* { 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" } */
|
||||
}
|
||||
|
102
gcc/testsuite/gcc.dg/pointer-array-quals-2.c
Normal file
102
gcc/testsuite/gcc.dg/pointer-array-quals-2.c
Normal file
@ -0,0 +1,102 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wdiscarded-array-qualifiers -pedantic-errors" } */
|
||||
/* Origin: Martin Uecker <uecker@eecs.berkeley.edu> */
|
||||
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" } */
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
union. Bug 27697 from Frank Victor Fischer. */
|
||||
/* Origin: Joseph Myers <joseph@codesourcery.com> */
|
||||
/* { 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" } */
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user