This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v4] warning about const multidimensional array as function parameter


For completeness, this version adds the missing warning if the 
'const' is lost in a conditional expression with a void* on the
other branch. The only code change relative to the previous
version is in c/c-typeck.c in build_conditional_expr (otherwise 
I added the warnings to the testsuite and fixed some typos and 
trailing whitespace errors).

I would rather have the 'const' propagate to the result
of the conditional expression as with regular pointers to
const, but I do not see an easy way to make the warnings
(or errors) which could result from this be dependent on 
-Wdiscarded-array-qualifiers.

Joseph Myers <joseph@codesourcery.com>:

> On Thu, 6 Nov 2014, Martin Uecker wrote:
> > This patch implements a new proposed behaviour for 
> > pointers to arrays with qualifiers in C.
> > 
> > I found some time to work on this again, so here is another 
> > revision. Main changes to the previous version of the patch:
> > 
> > - add more test cases for cast from/to (const) void*
> > - correctly uses pedwarn/warning_at
> 
> Thanks.  I'll review this in more detail later, but I suspect it's quite 
> close to being ready to go in once the paperwork has been processed.

Thank you. I got the form and have sent it back, but did not get
a reply yet.
 
Martin


2014-11-10 Martin Uecker <uecker@eecs.berkeley.edu>

	* doc/invoke.texi: Document -Wdiscarded-array-qualifiers
	* doc/extend.texi: Document new behavior for pointers to arrays with qualifies
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)




Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(Revision 217273)
+++ gcc/c/c-typeck.c	(Arbeitskopie)
@@ -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,
   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");
 
@@ -4603,6 +4618,14 @@ build_conditional_expr (location_t colon_loc, tree
       else if (VOID_TYPE_P (TREE_TYPE (type1))
 	       && !TYPE_ATOMIC (TREE_TYPE (type1)))
 	{
+          if (OPT_Wdiscarded_array_qualifiers
+              && (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 "
@@ -4613,6 +4636,14 @@ build_conditional_expr (location_t colon_loc, tree
       else if (VOID_TYPE_P (TREE_TYPE (type2))
 	       && !TYPE_ATOMIC (TREE_TYPE (type2)))
 	{
+          if (OPT_Wdiscarded_array_qualifiers
+              && (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 "
@@ -5655,7 +5686,7 @@ convert_for_assignment (location_t location, locat
   /* 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)                                                     \
       {                                                                  \
@@ -5682,10 +5713,9 @@ convert_for_assignment (location_t location, locat
 
   /* 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)                                                     \
       {                                                                  \
@@ -5710,6 +5740,35 @@ convert_for_assignment (location_t location, locat
       }                                                                  \
   } 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);
 
@@ -5752,15 +5811,15 @@ convert_for_assignment (location_t location, locat
 	  && 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++"));
 	}
     }
 
@@ -5915,34 +5974,34 @@ convert_for_assignment (location_t location, locat
 		     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;
 	    }
@@ -6090,42 +6149,70 @@ convert_for_assignment (location_t location, locat
 		  == 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 (OPT_Wdiscarded_array_qualifiers
+              && (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 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)
+              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.  */
@@ -6134,15 +6221,15 @@ convert_for_assignment (location_t location, locat
 		;
 	      /* 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)
@@ -6153,31 +6240,31 @@ convert_for_assignment (location_t location, locat
 		 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);
     }
@@ -6194,31 +6281,31 @@ convert_for_assignment (location_t location, locat
 	 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)
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(Revision 217273)
+++ gcc/c-family/c.opt	(Arbeitskopie)
@@ -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
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(Revision 217273)
+++ gcc/doc/extend.texi	(Arbeitskopie)
@@ -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.
@@ -1782,6 +1783,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
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(Revision 217273)
+++ gcc/doc/invoke.texi	(Arbeitskopie)
@@ -247,7 +247,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
@@ -4263,9 +4264,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
Index: gcc/testsuite/gcc.dg/Wwrite-strings-1.c
===================================================================
--- gcc/testsuite/gcc.dg/Wwrite-strings-1.c	(Revision 217273)
+++ gcc/testsuite/gcc.dg/Wwrite-strings-1.c	(Arbeitskopie)
@@ -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" } */
Index: gcc/testsuite/gcc.dg/array-quals-1.c
===================================================================
--- gcc/testsuite/gcc.dg/array-quals-1.c	(Revision 217273)
+++ gcc/testsuite/gcc.dg/array-quals-1.c	(Arbeitskopie)
@@ -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 };
Index: gcc/testsuite/gcc.dg/array-quals-2.c
===================================================================
--- gcc/testsuite/gcc.dg/array-quals-2.c	(Revision 217273)
+++ gcc/testsuite/gcc.dg/array-quals-2.c	(Arbeitskopie)
@@ -3,7 +3,7 @@
    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];
@@ -10,5 +10,5 @@ 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; }
Index: gcc/testsuite/gcc.dg/pointer-array-atomic.c
===================================================================
--- gcc/testsuite/gcc.dg/pointer-array-atomic.c	(Revision 0)
+++ gcc/testsuite/gcc.dg/pointer-array-atomic.c	(Arbeitskopie)
@@ -0,0 +1,59 @@
+/* { 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" } */
+}
Index: gcc/testsuite/gcc.dg/pointer-array-quals-1.c
===================================================================
--- gcc/testsuite/gcc.dg/pointer-array-quals-1.c	(Revision 0)
+++ gcc/testsuite/gcc.dg/pointer-array-quals-1.c	(Arbeitskopie)
@@ -0,0 +1,105 @@
+/* { 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" } */
+}
Index: gcc/testsuite/gcc.dg/pointer-array-quals-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pointer-array-quals-2.c	(Revision 0)
+++ gcc/testsuite/gcc.dg/pointer-array-quals-2.c	(Arbeitskopie)
@@ -0,0 +1,101 @@
+/* { 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);
+	v2p = (1 ? p : z2);
+	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" } */
+}



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