4.1.2-28
This commit is contained in:
		
							parent
							
								
									764e3b5c01
								
							
						
					
					
						commit
						e198454f27
					
				| @ -1 +1 @@ | |||||||
| gcc-4.1.2-20070821.tar.bz2 | gcc-4.1.2-20070925.tar.bz2 | ||||||
|  | |||||||
							
								
								
									
										4198
									
								
								gcc41-artificial-attrib.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4198
									
								
								gcc41-artificial-attrib.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,37 +0,0 @@ | |||||||
| 2007-09-06  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	PR c++/33289 |  | ||||||
| 	* decl.c (builtin_function_1): Set DECL_ANTICIPATED also |  | ||||||
| 	on __*_chk non-__builtin_* decls. |  | ||||||
| 
 |  | ||||||
| 	* g++.dg/eh/builtin4.C: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/cp/decl.c.jj	2007-08-31 14:28:19.000000000 +0200
 |  | ||||||
| +++ gcc/cp/decl.c	2007-09-04 21:28:06.000000000 +0200
 |  | ||||||
| @@ -3517,6 +3529,17 @@ builtin_function_1 (tree decl, tree cont
 |  | ||||||
|       anticipated but not actually declared.  */ |  | ||||||
|    if (name[0] != '_' || name[1] != '_') |  | ||||||
|      DECL_ANTICIPATED (decl) = 1; |  | ||||||
| +  else if (strncmp (name + 2, "builtin_", strlen ("builtin_")) != 0)
 |  | ||||||
| +    {
 |  | ||||||
| +      size_t len = strlen (name);
 |  | ||||||
| +
 |  | ||||||
| +      /* Treat __*_chk fortification functions as anticipated as well,
 |  | ||||||
| +	 unless they are __builtin_*.  */
 |  | ||||||
| +      if (len > strlen ("___chk")
 |  | ||||||
| +	  && memcmp (name + len - strlen ("_chk"),
 |  | ||||||
| +		     "_chk", strlen ("_chk") + 1) == 0)
 |  | ||||||
| +	DECL_ANTICIPATED (decl) = 1;
 |  | ||||||
| +    }
 |  | ||||||
|   |  | ||||||
|    return decl; |  | ||||||
|  } |  | ||||||
| --- gcc/testsuite/g++.dg/eh/builtin4.C.jj	2007-09-04 22:06:06.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/eh/builtin4.C	2007-09-04 22:07:03.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,6 @@
 |  | ||||||
| +// PR c++/33289
 |  | ||||||
| +// { dg-do compile }
 |  | ||||||
| +
 |  | ||||||
| +typedef __SIZE_TYPE__ size_t;
 |  | ||||||
| +extern "C" int __sprintf_chk (char *__restrict, int, size_t, const char *, ...) throw ();
 |  | ||||||
| +extern "C" int __sprintf_chk (char *__restrict, int, size_t, const char *, ...) throw ();
 |  | ||||||
| @ -1,134 +0,0 @@ | |||||||
| 2007-09-06  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* builtin-attrs.def (ATTR_NONNULL_3): New. |  | ||||||
| 	(DEF_FORMAT_ATTRIBUTE): Use just ATTR_NONNULL_##FA instead of |  | ||||||
| 	ATTR_NOTHROW_NONNULL_##FA. |  | ||||||
| 	(DEF_FORMAT_ATTRIBUTE_NOTHROW, DEF_FORMAT_ATTRIBUTE_BOTH): New macros. |  | ||||||
| 	(ATTR_FORMAT_PRINTF_NOTHROW_2_0, ATTR_PRINTF_NOTHROW_2_3, |  | ||||||
| 	ATTR_FORMAT_PRINTF_NOTHROW_3_0, ATTR_FORMAT_PRINTF_NOTHROW_3_4, |  | ||||||
| 	ATTR_FORMAT_PRINTF_NOTHROW_4_0, ATTR_PRINTF_NOTHROW_4_5, |  | ||||||
| 	ATTR_FORMAT_PRINTF_NOTHROW_5_0, ATTR_FORMAT_PRINTF_NOTHROW_5_6, |  | ||||||
| 	ATTR_FORMAT_SCANF_NOTHROW_2_0, ATTR_FORMAT_SCANF_NOTHROW_2_3, |  | ||||||
| 	ATTR_FORMAT_STRFTIME_NOTHROW_3_0, ATTR_FORMAT_STRFMON_NOTHROW_3_4): |  | ||||||
| 	New. |  | ||||||
| 	(ATTR_FORMAT_PRINTF_4_0, ATTR_PRINTF_4_5, ATTR_FORMAT_PRINTF_5_0, |  | ||||||
| 	ATTR_FORMAT_PRINTF_5_6, ATTR_FORMAT_STRFTIME_3_0, |  | ||||||
| 	ATTR_FORMAT_NOTHROW_3_4): Remove. |  | ||||||
| 	* builtins.def (snprintf, sprintf, sscanf, vsnprintf, vsprintf, |  | ||||||
| 	vsscanf, strfmon, strftime, __snprintf_chk, __sprintf_chk, |  | ||||||
| 	__vsnprintf_chk, __vsprintf_chk): Use ATTR_FORMAT_*_NOTHROW_* |  | ||||||
| 	instead of ATTR_FORMAT_*_*. |  | ||||||
| 
 |  | ||||||
| --- gcc/builtin-attrs.def.jj	2007-08-13 15:11:18.000000000 +0200
 |  | ||||||
| +++ gcc/builtin-attrs.def	2007-09-03 11:26:13.000000000 +0200
 |  | ||||||
| @@ -118,6 +118,8 @@ DEF_ATTR_TREE_LIST (ATTR_NONNULL_LIST, A
 |  | ||||||
|  DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, ATTR_NULL) |  | ||||||
|  /* Functions whose second parameter is a nonnull pointer.  */ |  | ||||||
|  DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, ATTR_NULL) |  | ||||||
| +/* Functions whose third parameter is a nonnull pointer.  */
 |  | ||||||
| +DEF_ATTR_TREE_LIST (ATTR_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, ATTR_NULL)
 |  | ||||||
|  /* Nothrow functions with the sentinel(1) attribute. */ |  | ||||||
|  DEF_ATTR_TREE_LIST (ATTR_NOTHROW_SENTINEL_1, ATTR_SENTINEL, ATTR_LIST_1, \ |  | ||||||
|  			ATTR_NOTHROW_LIST) |  | ||||||
| @@ -157,24 +159,38 @@ DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_
 |  | ||||||
|    DEF_ATTR_TREE_LIST (ATTR_##TYPE##_##VALUES, ATTR_NULL,		 \ |  | ||||||
|  		      ATTR_##TYPE, ATTR_LIST_##VALUES)			 \ |  | ||||||
|    DEF_ATTR_TREE_LIST (ATTR_FORMAT_##TYPE##_##VALUES, ATTR_FORMAT,	 \ |  | ||||||
| +		      ATTR_##TYPE##_##VALUES, ATTR_NONNULL_##FA)
 |  | ||||||
| +#define DEF_FORMAT_ATTRIBUTE_NOTHROW(TYPE, FA, VALUES)			 \
 |  | ||||||
| +  DEF_ATTR_TREE_LIST (ATTR_##TYPE##_##VALUES, ATTR_NULL,		 \
 |  | ||||||
| +		      ATTR_##TYPE, ATTR_LIST_##VALUES)			 \
 |  | ||||||
| +  DEF_ATTR_TREE_LIST (ATTR_FORMAT_##TYPE##_NOTHROW_##VALUES, ATTR_FORMAT,\
 |  | ||||||
| +		      ATTR_##TYPE##_##VALUES, ATTR_NOTHROW_NONNULL_##FA)
 |  | ||||||
| +#define DEF_FORMAT_ATTRIBUTE_BOTH(TYPE, FA, VALUES)			 \
 |  | ||||||
| +  DEF_ATTR_TREE_LIST (ATTR_##TYPE##_##VALUES, ATTR_NULL,		 \
 |  | ||||||
| +		      ATTR_##TYPE, ATTR_LIST_##VALUES)			 \
 |  | ||||||
| +  DEF_ATTR_TREE_LIST (ATTR_FORMAT_##TYPE##_##VALUES, ATTR_FORMAT,	 \
 |  | ||||||
| +		      ATTR_##TYPE##_##VALUES, ATTR_NONNULL_##FA)	 \
 |  | ||||||
| +  DEF_ATTR_TREE_LIST (ATTR_FORMAT_##TYPE##_NOTHROW_##VALUES, ATTR_FORMAT,\
 |  | ||||||
|  		      ATTR_##TYPE##_##VALUES, ATTR_NOTHROW_NONNULL_##FA) |  | ||||||
|  DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0) |  | ||||||
|  DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_2) |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_0)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_3)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,3,3_0)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,3,3_4)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,4,4_0)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,4,4_5)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,5,5_0)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(PRINTF,5,5_6)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_BOTH(PRINTF,2,2_0)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_BOTH(PRINTF,2,2_3)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_BOTH(PRINTF,3,3_0)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_BOTH(PRINTF,3,3_4)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_NOTHROW(PRINTF,4,4_0)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_NOTHROW(PRINTF,4,4_5)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_NOTHROW(PRINTF,5,5_0)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_NOTHROW(PRINTF,5,5_6)
 |  | ||||||
|  DEF_FORMAT_ATTRIBUTE(SCANF,1,1_0) |  | ||||||
|  DEF_FORMAT_ATTRIBUTE(SCANF,1,1_2) |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(SCANF,2,2_0)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(SCANF,2,2_3)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(STRFTIME,3,3_0)
 |  | ||||||
| -DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_BOTH(SCANF,2,2_0)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_BOTH(SCANF,2,2_3)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_NOTHROW(STRFTIME,3,3_0)
 |  | ||||||
| +DEF_FORMAT_ATTRIBUTE_NOTHROW(STRFMON,3,3_4)
 |  | ||||||
|  #undef DEF_FORMAT_ATTRIBUTE |  | ||||||
| +#undef DEF_FORMAT_ATTRIBUTE_NOTHROW
 |  | ||||||
| +#undef DEF_FORMAT_ATTRIBUTE_BOTH
 |  | ||||||
|   |  | ||||||
|  /* Construct a tree for a format_arg attribute.  */ |  | ||||||
|  #define DEF_FORMAT_ARG_ATTRIBUTE(FA)					\ |  | ||||||
| --- gcc/builtins.def.jj	2007-08-30 18:46:59.000000000 +0200
 |  | ||||||
| +++ gcc/builtins.def	2007-09-03 10:52:18.000000000 +0200
 |  | ||||||
| @@ -553,16 +553,16 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_PUTCHAR
 |  | ||||||
|  DEF_LIB_BUILTIN        (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST) |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST) |  | ||||||
|  DEF_LIB_BUILTIN        (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2) |  | ||||||
| -DEF_C99_BUILTIN        (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
 |  | ||||||
| -DEF_LIB_BUILTIN        (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
 |  | ||||||
| -DEF_LIB_BUILTIN        (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
 |  | ||||||
| +DEF_C99_BUILTIN        (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_3_4)
 |  | ||||||
| +DEF_LIB_BUILTIN        (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_2_3)
 |  | ||||||
| +DEF_LIB_BUILTIN        (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_NOTHROW_2_3)
 |  | ||||||
|  DEF_LIB_BUILTIN        (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0) |  | ||||||
|  DEF_C99_BUILTIN        (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0) |  | ||||||
|  DEF_LIB_BUILTIN        (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0) |  | ||||||
|  DEF_C99_BUILTIN        (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0) |  | ||||||
| -DEF_C99_BUILTIN        (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
 |  | ||||||
| -DEF_LIB_BUILTIN        (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
 |  | ||||||
| -DEF_C99_BUILTIN        (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
 |  | ||||||
| +DEF_C99_BUILTIN        (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_3_0)
 |  | ||||||
| +DEF_LIB_BUILTIN        (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_2_0)
 |  | ||||||
| +DEF_C99_BUILTIN        (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_NOTHROW_2_0)
 |  | ||||||
|   |  | ||||||
|  /* Category: ctype builtins.  */ |  | ||||||
|  DEF_LIB_BUILTIN        (BUILT_IN_ISALNUM, "isalnum", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST) |  | ||||||
| @@ -693,8 +693,8 @@ DEF_GCC_BUILTIN        (BUILT_IN_RETURN_
 |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_STDARG_START, "stdarg_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL) |  | ||||||
| -DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_3_4)
 |  | ||||||
| -DEF_LIB_BUILTIN        (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_3_0)
 |  | ||||||
| +DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
 |  | ||||||
| +DEF_LIB_BUILTIN        (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
 |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL) |  | ||||||
| @@ -730,10 +730,10 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRCAT_
 |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL) |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL) |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL) |  | ||||||
| -DEF_EXT_LIB_BUILTIN    (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_5_6)
 |  | ||||||
| -DEF_EXT_LIB_BUILTIN    (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_4_5)
 |  | ||||||
| -DEF_EXT_LIB_BUILTIN    (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_5_0)
 |  | ||||||
| -DEF_EXT_LIB_BUILTIN    (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_4_0)
 |  | ||||||
| +DEF_EXT_LIB_BUILTIN    (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6)
 |  | ||||||
| +DEF_EXT_LIB_BUILTIN    (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5)
 |  | ||||||
| +DEF_EXT_LIB_BUILTIN    (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0)
 |  | ||||||
| +DEF_EXT_LIB_BUILTIN    (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_4_0)
 |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_FPRINTF_CHK, "__fprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4) |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_PRINTF_CHK, "__printf_chk", BT_FN_INT_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3) |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0) |  | ||||||
| @ -1,368 +0,0 @@ | |||||||
| 2007-09-11  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* builtins.def (BUILT_IN_VA_ARG_PACK_LEN): New builtin. |  | ||||||
| 	* builtins.c (expand_builtin) <case BUILT_IN_VA_ARG_PACK_LEN>: Issue |  | ||||||
| 	error if __builtin_va_arg_pack_len () wasn't optimized out during |  | ||||||
| 	inlining. |  | ||||||
| 	* tree-inline.c (copy_bb): Replace __builtin_va_arg_pack_len () |  | ||||||
| 	with the number of inline's anonymous arguments. |  | ||||||
| 	* doc/extend.texi: Document __builtin_va_arg_pack_len (). |  | ||||||
| 
 |  | ||||||
| 	* gcc.dg/va-arg-pack-len-1.c: New test. |  | ||||||
| 	* g++.dg/va-arg-pack-len-1.C: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/builtins.def.jj	2007-09-06 10:19:24.000000000 +0200
 |  | ||||||
| +++ gcc/builtins.def	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| @@ -666,6 +666,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_VA_COPY
 |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LIST) |  | ||||||
| +DEF_GCC_BUILTIN        (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LIST)
 |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) |  | ||||||
|  DEF_C99_BUILTIN        (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) |  | ||||||
|   |  | ||||||
| --- gcc/builtins.c.jj	2007-09-06 11:04:56.000000000 +0200
 |  | ||||||
| +++ gcc/builtins.c	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| @@ -5985,6 +5985,12 @@ expand_builtin (tree exp, rtx target, rt
 |  | ||||||
|        error ("invalid use of %<__builtin_va_arg_pack ()%>"); |  | ||||||
|        return const0_rtx; |  | ||||||
|   |  | ||||||
| +    case BUILT_IN_VA_ARG_PACK_LEN:
 |  | ||||||
| +      /* All valid uses of __builtin_va_arg_pack_len () are removed during
 |  | ||||||
| +	 inlining.  */
 |  | ||||||
| +      error ("invalid use of %<__builtin_va_arg_pack_len ()%>");
 |  | ||||||
| +      return const0_rtx;
 |  | ||||||
| +
 |  | ||||||
|        /* Return the address of the first anonymous stack arg.  */ |  | ||||||
|      case BUILT_IN_NEXT_ARG: |  | ||||||
|        if (fold_builtin_next_arg (arglist)) |  | ||||||
| --- gcc/tree-inline.c.jj	2007-09-06 12:35:57.000000000 +0200
 |  | ||||||
| +++ gcc/tree-inline.c	2007-09-14 21:22:48.000000000 +0200
 |  | ||||||
| @@ -741,6 +741,37 @@ copy_bb (copy_body_data *id, basic_block
 |  | ||||||
|  	      *a = copy_list (arglist); |  | ||||||
|  	      CALL_EXPR_VA_ARG_PACK (call) = 0; |  | ||||||
|  	    } |  | ||||||
| +	  else if (call
 |  | ||||||
| +		   && id->call_expr
 |  | ||||||
| +		   && (decl = get_callee_fndecl (call))
 |  | ||||||
| +		   && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
 |  | ||||||
| +		   && DECL_FUNCTION_CODE (decl)
 |  | ||||||
| +		      == BUILT_IN_VA_ARG_PACK_LEN)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      /* __builtin_va_arg_pack_len () should be replaced by
 |  | ||||||
| +		 the number of anonymous arguments.  */
 |  | ||||||
| +	      int nargs;
 |  | ||||||
| +	      tree count, *call_ptr, p, a;
 |  | ||||||
| +
 |  | ||||||
| +	      a = TREE_OPERAND (id->call_expr, 1);
 |  | ||||||
| +	      for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
 |  | ||||||
| +		a = TREE_CHAIN (a);
 |  | ||||||
| +
 |  | ||||||
| +              for (nargs = 0; a; a = TREE_CHAIN (a))
 |  | ||||||
| +		nargs++;
 |  | ||||||
| +
 |  | ||||||
| +	      count = build_int_cst (integer_type_node, nargs);
 |  | ||||||
| +	      call_ptr = &stmt;
 |  | ||||||
| +	      if (TREE_CODE (*call_ptr) == MODIFY_EXPR)
 |  | ||||||
| +		call_ptr = &TREE_OPERAND (*call_ptr, 1);
 |  | ||||||
| +	      if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR)
 |  | ||||||
| +		call_ptr = &TREE_OPERAND (*call_ptr, 0);
 |  | ||||||
| +	      gcc_assert (*call_ptr == call && call_ptr != &stmt);
 |  | ||||||
| +	      *call_ptr = count;
 |  | ||||||
| +	      update_stmt (stmt);
 |  | ||||||
| +	      call = NULL_TREE;
 |  | ||||||
| +	    }
 |  | ||||||
| +
 |  | ||||||
|  	  /* We're duplicating a CALL_EXPR.  Find any corresponding |  | ||||||
|  	     callgraph edges and update or duplicate them.  */ |  | ||||||
|  	  if (call && (decl = get_callee_fndecl (call))) |  | ||||||
| --- gcc/doc/extend.texi.jj	2007-09-06 10:19:25.000000000 +0200
 |  | ||||||
| +++ gcc/doc/extend.texi	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| @@ -578,6 +578,41 @@ myprintf (FILE *f, const char *format, .
 |  | ||||||
|  @end smallexample |  | ||||||
|  @end deftypefn |  | ||||||
|   |  | ||||||
| +@deftypefn {Built-in Function} __builtin_va_arg_pack_len ()
 |  | ||||||
| +This built-in function returns the number of anonymous arguments of
 |  | ||||||
| +an inline function.  It can be used only in inline functions which
 |  | ||||||
| +will be always inlined, never compiled as a separate function, such
 |  | ||||||
| +as those using @code{__attribute__ ((__always_inline__))} or
 |  | ||||||
| +@code{__attribute__ ((__gnu_inline__))} extern inline functions.
 |  | ||||||
| +For example following will do link or runtime checking of open
 |  | ||||||
| +arguments for optimized code:
 |  | ||||||
| +@smallexample
 |  | ||||||
| +#ifdef __OPTIMIZE__
 |  | ||||||
| +extern inline __attribute__((__gnu_inline__)) int
 |  | ||||||
| +myopen (const char *path, int oflag, ...)
 |  | ||||||
| +@{
 |  | ||||||
| +  if (__builtin_va_arg_pack_len () > 1)
 |  | ||||||
| +    warn_open_too_many_arguments ();
 |  | ||||||
| +
 |  | ||||||
| +  if (__builtin_constant_p (oflag))
 |  | ||||||
| +    @{
 |  | ||||||
| +      if ((oflag & O_CREAT) != 0 && __builtin_va_arg_pack_len () < 1)
 |  | ||||||
| +        @{
 |  | ||||||
| +          warn_open_missing_mode ();
 |  | ||||||
| +          return __open_2 (path, oflag);
 |  | ||||||
| +        @}
 |  | ||||||
| +      return open (path, oflag, __builtin_va_arg_pack ());
 |  | ||||||
| +    @}
 |  | ||||||
| +    
 |  | ||||||
| +  if (__builtin_va_arg_pack_len () < 1)
 |  | ||||||
| +    return __open_2 (path, oflag);
 |  | ||||||
| +
 |  | ||||||
| +  return open (path, oflag, __builtin_va_arg_pack ());
 |  | ||||||
| +@}
 |  | ||||||
| +#endif
 |  | ||||||
| +@end smallexample
 |  | ||||||
| +@end deftypefn
 |  | ||||||
| +
 |  | ||||||
|  @node Typeof |  | ||||||
|  @section Referring to a Type with @code{typeof} |  | ||||||
|  @findex typeof |  | ||||||
| --- gcc/testsuite/gcc.dg/va-arg-pack-len-1.c.jj	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/va-arg-pack-len-1.c	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,120 @@
 |  | ||||||
| +/* { dg-do run } */
 |  | ||||||
| +/* { dg-options "-O2" } */
 |  | ||||||
| +
 |  | ||||||
| +#include <stdarg.h>
 |  | ||||||
| +
 |  | ||||||
| +extern int warn_open_missing_mode (void);
 |  | ||||||
| +extern int warn_open_too_many_arguments (void);
 |  | ||||||
| +extern void abort (void);
 |  | ||||||
| +
 |  | ||||||
| +char expected_char;
 |  | ||||||
| +
 |  | ||||||
| +__attribute__((noinline)) int
 |  | ||||||
| +myopen2 (const char *path, int oflag)
 |  | ||||||
| +{
 |  | ||||||
| +  if (expected_char++ != path[0] || path[1] != '\0')
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (path[0])
 |  | ||||||
| +    {
 |  | ||||||
| +    case 'f':
 |  | ||||||
| +      if (oflag != 0x2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'g':
 |  | ||||||
| +      if (oflag != 0x43)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      /* In real __open_2 this would terminate the program:
 |  | ||||||
| +	 open with O_CREAT without third argument.  */
 |  | ||||||
| +      return -6;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__attribute__((noinline)) int
 |  | ||||||
| +myopenva (const char *path, int oflag, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  int mode = 0;
 |  | ||||||
| +  va_list ap;
 |  | ||||||
| +  if ((oflag & 0x40) != 0)
 |  | ||||||
| +    {
 |  | ||||||
| +      va_start (ap, oflag);
 |  | ||||||
| +      mode = va_arg (ap, int);
 |  | ||||||
| +      va_end (ap);
 |  | ||||||
| +    }
 |  | ||||||
| +  if (expected_char++ != path[0] || path[1] != '\0')
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (path[0])
 |  | ||||||
| +    {
 |  | ||||||
| +    case 'a':
 |  | ||||||
| +      if (oflag != 0x43 || mode != 0644)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'b':
 |  | ||||||
| +      if (oflag != 0x3)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'c':
 |  | ||||||
| +      if (oflag != 0x2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'd':
 |  | ||||||
| +      if (oflag != 0x43 || mode != 0600)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'e':
 |  | ||||||
| +      if (oflag != 0x3)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline, gnu_inline)) int
 |  | ||||||
| +myopen (const char *path, int oflag, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  if (__builtin_va_arg_pack_len () > 1)
 |  | ||||||
| +    warn_open_too_many_arguments ();
 |  | ||||||
| +
 |  | ||||||
| +  if (__builtin_constant_p (oflag))
 |  | ||||||
| +    {
 |  | ||||||
| +      if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1)
 |  | ||||||
| +	{
 |  | ||||||
| +	  warn_open_missing_mode ();
 |  | ||||||
| +	  return myopen2 (path, oflag);
 |  | ||||||
| +	}
 |  | ||||||
| +      return myopenva (path, oflag, __builtin_va_arg_pack ());
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +  if (__builtin_va_arg_pack_len () < 1)
 |  | ||||||
| +    return myopen2 (path, oflag);
 |  | ||||||
| +
 |  | ||||||
| +  return myopenva (path, oflag, __builtin_va_arg_pack ());
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +volatile int l0;
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  expected_char = 'a';
 |  | ||||||
| +  if (myopen ("a", 0x43, 0644))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("b", 0x3, 0755))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("c", 0x2))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("d", l0 + 0x43, 0600))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("e", l0 + 0x3, 0700))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("f", l0 + 0x2))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  /* Invalid use of myopen, but only detectable at runtime.  */
 |  | ||||||
| +  if (myopen ("g", l0 + 0x43) != -6)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C.jj	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,120 @@
 |  | ||||||
| +// { dg-do run }
 |  | ||||||
| +// { dg-options "-O2" }
 |  | ||||||
| +
 |  | ||||||
| +#include <stdarg.h>
 |  | ||||||
| +
 |  | ||||||
| +extern "C" int warn_open_missing_mode (void);
 |  | ||||||
| +extern "C" int warn_open_too_many_arguments (void);
 |  | ||||||
| +extern "C" void abort (void);
 |  | ||||||
| +
 |  | ||||||
| +char expected_char;
 |  | ||||||
| +
 |  | ||||||
| +__attribute__((noinline)) int
 |  | ||||||
| +myopen2 (const char *path, int oflag)
 |  | ||||||
| +{
 |  | ||||||
| +  if (expected_char++ != path[0] || path[1] != '\0')
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (path[0])
 |  | ||||||
| +    {
 |  | ||||||
| +    case 'f':
 |  | ||||||
| +      if (oflag != 0x2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'g':
 |  | ||||||
| +      if (oflag != 0x43)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      // In real __open_2 this would terminate the program:
 |  | ||||||
| +      // open with O_CREAT without third argument.
 |  | ||||||
| +      return -6;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__attribute__((noinline)) int
 |  | ||||||
| +myopenva (const char *path, int oflag, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  int mode = 0;
 |  | ||||||
| +  va_list ap;
 |  | ||||||
| +  if ((oflag & 0x40) != 0)
 |  | ||||||
| +    {
 |  | ||||||
| +      va_start (ap, oflag);
 |  | ||||||
| +      mode = va_arg (ap, int);
 |  | ||||||
| +      va_end (ap);
 |  | ||||||
| +    }
 |  | ||||||
| +  if (expected_char++ != path[0] || path[1] != '\0')
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (path[0])
 |  | ||||||
| +    {
 |  | ||||||
| +    case 'a':
 |  | ||||||
| +      if (oflag != 0x43 || mode != 0644)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'b':
 |  | ||||||
| +      if (oflag != 0x3)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'c':
 |  | ||||||
| +      if (oflag != 0x2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'd':
 |  | ||||||
| +      if (oflag != 0x43 || mode != 0600)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 'e':
 |  | ||||||
| +      if (oflag != 0x3)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline, gnu_inline)) int
 |  | ||||||
| +myopen (const char *path, int oflag, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  if (__builtin_va_arg_pack_len () > 1)
 |  | ||||||
| +    warn_open_too_many_arguments ();
 |  | ||||||
| +
 |  | ||||||
| +  if (__builtin_constant_p (oflag))
 |  | ||||||
| +    {
 |  | ||||||
| +      if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1)
 |  | ||||||
| +	{
 |  | ||||||
| +	  warn_open_missing_mode ();
 |  | ||||||
| +	  return myopen2 (path, oflag);
 |  | ||||||
| +	}
 |  | ||||||
| +      return myopenva (path, oflag, __builtin_va_arg_pack ());
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +  if (__builtin_va_arg_pack_len () < 1)
 |  | ||||||
| +    return myopen2 (path, oflag);
 |  | ||||||
| +
 |  | ||||||
| +  return myopenva (path, oflag, __builtin_va_arg_pack ());
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +volatile int l0;
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  expected_char = 'a';
 |  | ||||||
| +  if (myopen ("a", 0x43, 0644))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("b", 0x3, 0755))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("c", 0x2))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("d", l0 + 0x43, 0600))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("e", l0 + 0x3, 0700))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (myopen ("f", l0 + 0x2))
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  // Invalid use of myopen, but only detectable at runtime.
 |  | ||||||
| +  if (myopen ("g", l0 + 0x43) != -6)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| @ -1,722 +0,0 @@ | |||||||
| 2007-09-07  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* tree.c (cp_cannot_inline_tree_fn): Don't mark varargs_function_p |  | ||||||
| 	as uninlinable. |  | ||||||
| 
 |  | ||||||
| 	* g++.dg/ext/va-arg-pack-1.C: New test. |  | ||||||
| 	* g++.dg/ext/va-arg-pack-2.C: New test. |  | ||||||
| 
 |  | ||||||
| 2007-09-05  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* builtins.def (BUILT_IN_VA_ARG_PACK): New built-in. |  | ||||||
| 	* tree.h (CALL_EXPR_VA_ARG_PACK): Define. |  | ||||||
| 	* tree-inline.h (copy_body_data): Add call_expr field. |  | ||||||
| 	* tree-inline.c (expand_call_inline): Initialize call_expr. |  | ||||||
| 	(copy_bb): Append anonymous inline fn arguments to arguments |  | ||||||
| 	when inlining a CALL_EXPR_VA_ARG_PACK call. |  | ||||||
| 	* builtins.c (expand_builtin): Issue an error if |  | ||||||
| 	BUILT_IN_VA_ARG_PACK is seen during expand. |  | ||||||
| 	(fold_builtin_1): Don't fold calls with |  | ||||||
| 	__builtin_va_arg_pack () call as last argument. |  | ||||||
| 	* gimplify.c (gimplify_call_expr): If last argument to a vararg |  | ||||||
| 	function is __builtin_va_arg_pack (), decrease number of call |  | ||||||
| 	arguments and instead set CALL_EXPR_VA_ARG_PACK on the CALL_EXPR. |  | ||||||
| 	* fold-const.c (fold): Don't fold CALL_EXPRs with |  | ||||||
| 	CALL_EXPR_VA_ARG_PACK bit set. |  | ||||||
| 	* expr.c (expand_expr_real_1): Issue an error if |  | ||||||
| 	CALL_EXPR_VA_ARG_PACK CALL_EXPR is seen during expand. |  | ||||||
| 	* tree-pretty-print.c (dump_generic_node): Handle printing |  | ||||||
| 	CALL_EXPR_VA_ARG_PACK bit on CALL_EXPRs. |  | ||||||
| 	* doc/extend.texi (__builtin_va_arg_pack): Document. |  | ||||||
| 
 |  | ||||||
| 	* gcc.c-torture/execute/va-arg-pack-1.c: New test. |  | ||||||
| 	* gcc.dg/va-arg-pack-1.c: New test. |  | ||||||
| 	* gcc.dg/va-arg-pack-1a.c: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/builtins.def.jj	2007-09-06 10:19:09.000000000 +0200
 |  | ||||||
| +++ gcc/builtins.def	2007-09-06 10:19:24.000000000 +0200
 |  | ||||||
| @@ -665,6 +665,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_UPDATE_
 |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL) |  | ||||||
|  DEF_GCC_BUILTIN        (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL) |  | ||||||
| +DEF_GCC_BUILTIN        (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LIST)
 |  | ||||||
|  DEF_EXT_LIB_BUILTIN    (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) |  | ||||||
|  DEF_C99_BUILTIN        (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) |  | ||||||
|   |  | ||||||
| --- gcc/tree.h.jj	2007-02-20 22:39:12.000000000 +0100
 |  | ||||||
| +++ gcc/tree.h	2007-09-06 11:50:56.000000000 +0200
 |  | ||||||
| @@ -411,6 +411,8 @@ struct tree_common GTY(())
 |  | ||||||
|             VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE |  | ||||||
|         ASM_VOLATILE_P in |  | ||||||
|             ASM_EXPR |  | ||||||
| +       CALL_EXPR_VA_ARG_PACK in
 |  | ||||||
| +	  CALL_EXPR
 |  | ||||||
|         TYPE_CACHED_VALUES_P in |  | ||||||
|            ..._TYPE |  | ||||||
|         SAVE_EXPR_RESOLVED_P in |  | ||||||
| @@ -1066,6 +1068,11 @@ extern void omp_clause_range_check_faile
 |  | ||||||
|  #define SAVE_EXPR_RESOLVED_P(NODE) \ |  | ||||||
|    (TREE_CHECK (NODE, SAVE_EXPR)->common.public_flag) |  | ||||||
|   |  | ||||||
| +/* Set on a CALL_EXPR if this stdarg call should be passed the argument
 |  | ||||||
| +   pack.  */
 |  | ||||||
| +#define CALL_EXPR_VA_ARG_PACK(NODE) \
 |  | ||||||
| +  (CALL_EXPR_CHECK(NODE)->common.public_flag)
 |  | ||||||
| +
 |  | ||||||
|  /* In any expression, decl, or constant, nonzero means it has side effects or |  | ||||||
|     reevaluation of the whole expression could produce a different value. |  | ||||||
|     This is set if any subexpression is a function call, a side effect or a |  | ||||||
| --- gcc/tree-inline.h.jj	2007-02-20 22:39:13.000000000 +0100
 |  | ||||||
| +++ gcc/tree-inline.h	2007-09-06 10:19:24.000000000 +0200
 |  | ||||||
| @@ -57,6 +57,10 @@ typedef struct copy_body_data
 |  | ||||||
|    /* Current BLOCK.  */ |  | ||||||
|    tree block; |  | ||||||
|   |  | ||||||
| +  /* CALL_EXPR if va arg parameter packs should be expanded or NULL
 |  | ||||||
| +     is not.  */
 |  | ||||||
| +  tree call_expr;
 |  | ||||||
| +
 |  | ||||||
|    /* Exception region the inlined call lie in.  */ |  | ||||||
|    int eh_region; |  | ||||||
|    /* Take region number in the function being copied, add this value and |  | ||||||
| --- gcc/tree-inline.c.jj	2007-04-26 09:41:49.000000000 +0200
 |  | ||||||
| +++ gcc/tree-inline.c	2007-09-06 12:35:57.000000000 +0200
 |  | ||||||
| @@ -725,6 +725,22 @@ copy_bb (copy_body_data *id, basic_block
 |  | ||||||
|   |  | ||||||
|            bsi_insert_after (©_bsi, stmt, BSI_NEW_STMT); |  | ||||||
|  	  call = get_call_expr_in (stmt); |  | ||||||
| +	  if (call && CALL_EXPR_VA_ARG_PACK (call) && id->call_expr)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      tree arglist, *a, p;
 |  | ||||||
| +	      TREE_OPERAND (call, 1) = copy_list (TREE_OPERAND (call, 1));
 |  | ||||||
| +
 |  | ||||||
| +	      for (a = &TREE_OPERAND (call, 1); *a; a = &TREE_CHAIN (*a))
 |  | ||||||
| +		;
 |  | ||||||
| +
 |  | ||||||
| +	      p = DECL_ARGUMENTS (id->src_fn);
 |  | ||||||
| +	      for (arglist = TREE_OPERAND (id->call_expr, 1);
 |  | ||||||
| +		   p; p = TREE_CHAIN (p), arglist = TREE_CHAIN (arglist))
 |  | ||||||
| +		;
 |  | ||||||
| +
 |  | ||||||
| +	      *a = copy_list (arglist);
 |  | ||||||
| +	      CALL_EXPR_VA_ARG_PACK (call) = 0;
 |  | ||||||
| +	    }
 |  | ||||||
|  	  /* We're duplicating a CALL_EXPR.  Find any corresponding |  | ||||||
|  	     callgraph edges and update or duplicate them.  */ |  | ||||||
|  	  if (call && (decl = get_callee_fndecl (call))) |  | ||||||
| @@ -2085,6 +2101,7 @@ expand_call_inline (basic_block bb, tree
 |  | ||||||
|    /* Record the function we are about to inline.  */ |  | ||||||
|    id->src_fn = fn; |  | ||||||
|    id->src_node = cg_edge->callee; |  | ||||||
| +  id->call_expr = t;
 |  | ||||||
|   |  | ||||||
|    initialize_inlined_parameters (id, args, TREE_OPERAND (t, 2), fn, bb); |  | ||||||
|   |  | ||||||
| --- gcc/builtins.c.jj	2007-08-31 09:47:46.000000000 +0200
 |  | ||||||
| +++ gcc/builtins.c	2007-09-06 11:04:56.000000000 +0200
 |  | ||||||
| @@ -5979,6 +5979,12 @@ expand_builtin (tree exp, rtx target, rt
 |  | ||||||
|      case BUILT_IN_ARGS_INFO: |  | ||||||
|        return expand_builtin_args_info (arglist); |  | ||||||
|   |  | ||||||
| +    case BUILT_IN_VA_ARG_PACK:
 |  | ||||||
| +      /* All valid uses of __builtin_va_arg_pack () are removed during
 |  | ||||||
| +	 inlining.  */
 |  | ||||||
| +      error ("invalid use of %<__builtin_va_arg_pack ()%>");
 |  | ||||||
| +      return const0_rtx;
 |  | ||||||
| +
 |  | ||||||
|        /* Return the address of the first anonymous stack arg.  */ |  | ||||||
|      case BUILT_IN_NEXT_ARG: |  | ||||||
|        if (fold_builtin_next_arg (arglist)) |  | ||||||
| @@ -9017,7 +9023,27 @@ fold_builtin_1 (tree fndecl, tree arglis
 |  | ||||||
|  { |  | ||||||
|    tree type = TREE_TYPE (TREE_TYPE (fndecl)); |  | ||||||
|    enum built_in_function fcode; |  | ||||||
| +  tree a;
 |  | ||||||
| +
 |  | ||||||
| +  if (arglist)
 |  | ||||||
| +    {
 |  | ||||||
| +      for (a = arglist; TREE_CHAIN (a); a = TREE_CHAIN (a))
 |  | ||||||
| +	;
 |  | ||||||
|   |  | ||||||
| +      /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
 |  | ||||||
| +	 instead last argument is __builtin_va_arg_pack ().  Defer folding
 |  | ||||||
| +	 even in that case, until arguments are finalized.  */
 |  | ||||||
| +      if (TREE_CODE (TREE_VALUE (a)) == CALL_EXPR)
 |  | ||||||
| +	{
 |  | ||||||
| +	  tree fndecl2 = get_callee_fndecl (TREE_VALUE (a));
 |  | ||||||
| +	  if (fndecl2
 |  | ||||||
| +	      && TREE_CODE (fndecl2) == FUNCTION_DECL
 |  | ||||||
| +	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
 |  | ||||||
| +	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
 |  | ||||||
| +	    return NULL_TREE;
 |  | ||||||
| +	}
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|    if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) |  | ||||||
|      return targetm.fold_builtin (fndecl, arglist, ignore); |  | ||||||
|   |  | ||||||
| --- gcc/gimplify.c.jj	2007-08-31 09:47:46.000000000 +0200
 |  | ||||||
| +++ gcc/gimplify.c	2007-09-06 11:42:01.000000000 +0200
 |  | ||||||
| @@ -2018,6 +2018,55 @@ gimplify_call_expr (tree *expr_p, tree *
 |  | ||||||
|    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL, |  | ||||||
|  		       is_gimple_call_addr, fb_rvalue); |  | ||||||
|   |  | ||||||
| +  if (ret != GS_ERROR && TREE_OPERAND (*expr_p, 1))
 |  | ||||||
| +    {
 |  | ||||||
| +      int nargs;
 |  | ||||||
| +
 |  | ||||||
| +      for (nargs = 1, arglist = TREE_OPERAND (*expr_p, 1);
 |  | ||||||
| +	   TREE_CHAIN (arglist);
 |  | ||||||
| +	   arglist = TREE_CHAIN (arglist))
 |  | ||||||
| +	nargs++;
 |  | ||||||
| +
 |  | ||||||
| +      if (TREE_CODE (TREE_VALUE (arglist)) == CALL_EXPR)
 |  | ||||||
| +	{
 |  | ||||||
| +	  tree last_arg = TREE_VALUE (arglist);
 |  | ||||||
| +	  tree last_arg_fndecl = get_callee_fndecl (last_arg);
 |  | ||||||
| +
 |  | ||||||
| +	  if (last_arg_fndecl
 |  | ||||||
| +	      && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
 |  | ||||||
| +	      && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
 |  | ||||||
| +	      && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      tree p = NULL_TREE, *aptr;
 |  | ||||||
| +	      int i;
 |  | ||||||
| +
 |  | ||||||
| +	      if (decl && DECL_ARGUMENTS (decl))
 |  | ||||||
| +		p = DECL_ARGUMENTS (decl);
 |  | ||||||
| +	      else if (decl)
 |  | ||||||
| +		p = TYPE_ARG_TYPES (TREE_TYPE (decl));
 |  | ||||||
| +	      else if (POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
 |  | ||||||
| +		p = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE
 |  | ||||||
| +						(TREE_OPERAND (*expr_p, 0))));
 |  | ||||||
| +	      for (i = 0; p; p = TREE_CHAIN (p))
 |  | ||||||
| +		i++;
 |  | ||||||
| +
 |  | ||||||
| +	      if (i < nargs)
 |  | ||||||
| +		{
 |  | ||||||
| +		  TREE_OPERAND (*expr_p, 1)
 |  | ||||||
| +		    = copy_list (TREE_OPERAND (*expr_p, 1));
 |  | ||||||
| +
 |  | ||||||
| +		  for (aptr = &TREE_OPERAND (*expr_p, 1);
 |  | ||||||
| +		       TREE_CHAIN (*aptr);
 |  | ||||||
| +		       aptr = &TREE_CHAIN (*aptr))
 |  | ||||||
| +		    ;
 |  | ||||||
| +
 |  | ||||||
| +		  *aptr = NULL_TREE;
 |  | ||||||
| +		  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
 |  | ||||||
| +		}
 |  | ||||||
| +	    }
 |  | ||||||
| +	}
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|    if (PUSH_ARGS_REVERSED) |  | ||||||
|      TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1)); |  | ||||||
|    for (arglist = TREE_OPERAND (*expr_p, 1); arglist; |  | ||||||
| @@ -2037,7 +2086,7 @@ gimplify_call_expr (tree *expr_p, tree *
 |  | ||||||
|    if (ret != GS_ERROR) |  | ||||||
|      { |  | ||||||
|        decl = get_callee_fndecl (*expr_p); |  | ||||||
| -      if (decl && DECL_BUILT_IN (decl))
 |  | ||||||
| +      if (decl && DECL_BUILT_IN (decl) && !CALL_EXPR_VA_ARG_PACK (*expr_p))
 |  | ||||||
|  	{ |  | ||||||
|  	  tree arglist = TREE_OPERAND (*expr_p, 1); |  | ||||||
|  	  tree new = fold_builtin (decl, arglist, !want_value); |  | ||||||
| --- gcc/fold-const.c.jj	2007-08-31 09:47:39.000000000 +0200
 |  | ||||||
| +++ gcc/fold-const.c	2007-09-06 11:40:55.000000000 +0200
 |  | ||||||
| @@ -10409,6 +10409,8 @@ fold (tree expr)
 |  | ||||||
|  	  op0 = TREE_OPERAND (t, 0); |  | ||||||
|  	  op1 = TREE_OPERAND (t, 1); |  | ||||||
|  	  op2 = TREE_OPERAND (t, 2); |  | ||||||
| +	  if (code == CALL_EXPR && CALL_EXPR_VA_ARG_PACK (t))
 |  | ||||||
| +	    return expr;
 |  | ||||||
|  	  tem = fold_ternary (code, type, op0, op1, op2); |  | ||||||
|  	  return tem ? tem : expr; |  | ||||||
|  	default: |  | ||||||
| --- gcc/expr.c.jj	2007-04-24 22:58:53.000000000 +0200
 |  | ||||||
| +++ gcc/expr.c	2007-09-06 10:19:24.000000000 +0200
 |  | ||||||
| @@ -7475,6 +7475,10 @@ expand_expr_real_1 (tree exp, rtx target
 |  | ||||||
|        return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier); |  | ||||||
|   |  | ||||||
|      case CALL_EXPR: |  | ||||||
| +      /* All valid uses of __builtin_va_arg_pack () are removed during
 |  | ||||||
| +	 inlining.  */
 |  | ||||||
| +      if (CALL_EXPR_VA_ARG_PACK (exp))
 |  | ||||||
| +	error ("invalid use of %<__builtin_va_arg_pack ()%>");
 |  | ||||||
|        /* Check for a built-in function.  */ |  | ||||||
|        if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR |  | ||||||
|  	  && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) |  | ||||||
| --- gcc/doc/extend.texi.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/doc/extend.texi	2007-09-06 10:19:25.000000000 +0200
 |  | ||||||
| @@ -552,6 +552,32 @@ the containing function.  You should spe
 |  | ||||||
|  returned by @code{__builtin_apply}. |  | ||||||
|  @end deftypefn |  | ||||||
|   |  | ||||||
| +@deftypefn {Built-in Function} __builtin_va_arg_pack ()
 |  | ||||||
| +This built-in function represents all anonymous arguments of an inline
 |  | ||||||
| +function.  It can be used only in inline functions which will be always
 |  | ||||||
| +inlined, never compiled as a separate function, such as those using
 |  | ||||||
| +@code{__attribute__ ((__always_inline__))} or
 |  | ||||||
| +@code{__attribute__ ((__gnu_inline__))} extern inline functions.
 |  | ||||||
| +It must be only passed as last argument to some other function
 |  | ||||||
| +with variable arguments.  This is useful for writing small wrapper
 |  | ||||||
| +inlines for variable argument functions, when using preprocessor
 |  | ||||||
| +macros is undesirable.  For example:
 |  | ||||||
| +@smallexample
 |  | ||||||
| +extern int myprintf (FILE *f, const char *format, ...);
 |  | ||||||
| +extern inline __attribute__ ((__gnu_inline__)) int
 |  | ||||||
| +myprintf (FILE *f, const char *format, ...)
 |  | ||||||
| +@{
 |  | ||||||
| +  int r = fprintf (f, "myprintf: ");
 |  | ||||||
| +  if (r < 0)
 |  | ||||||
| +    return r;
 |  | ||||||
| +  int s = fprintf (f, format, __builtin_va_arg_pack ());
 |  | ||||||
| +  if (s < 0)
 |  | ||||||
| +    return s;
 |  | ||||||
| +  return r + s;
 |  | ||||||
| +@}
 |  | ||||||
| +@end smallexample
 |  | ||||||
| +@end deftypefn
 |  | ||||||
| +
 |  | ||||||
|  @node Typeof |  | ||||||
|  @section Referring to a Type with @code{typeof} |  | ||||||
|  @findex typeof |  | ||||||
| --- gcc/tree-pretty-print.c.jj	2007-02-20 22:39:12.000000000 +0100
 |  | ||||||
| +++ gcc/tree-pretty-print.c	2007-09-06 10:24:51.000000000 +0200
 |  | ||||||
| @@ -1128,6 +1128,15 @@ dump_generic_node (pretty_printer *buffe
 |  | ||||||
|        op1 = TREE_OPERAND (node, 1); |  | ||||||
|        if (op1) |  | ||||||
|  	dump_generic_node (buffer, op1, spc, flags, false); |  | ||||||
| +      if (CALL_EXPR_VA_ARG_PACK (node))
 |  | ||||||
| +	{
 |  | ||||||
| +	  if (op1)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      pp_character (buffer, ',');
 |  | ||||||
| +	      pp_space (buffer);
 |  | ||||||
| +	    }
 |  | ||||||
| +	  pp_string (buffer, "__builtin_va_arg_pack ()");
 |  | ||||||
| +	}
 |  | ||||||
|        pp_character (buffer, ')'); |  | ||||||
|   |  | ||||||
|        op1 = TREE_OPERAND (node, 2); |  | ||||||
| --- gcc/cp/tree.c.jj	2007-03-12 08:28:01.000000000 +0100
 |  | ||||||
| +++ gcc/cp/tree.c	2007-09-07 09:03:07.000000000 +0200
 |  | ||||||
| @@ -2078,12 +2078,6 @@ cp_cannot_inline_tree_fn (tree* fnp)
 |  | ||||||
|        return 1; |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| -  if (varargs_function_p (fn))
 |  | ||||||
| -    {
 |  | ||||||
| -      DECL_UNINLINABLE (fn) = 1;
 |  | ||||||
| -      return 1;
 |  | ||||||
| -    }
 |  | ||||||
| -
 |  | ||||||
|    if (! function_attribute_inlinable_p (fn)) |  | ||||||
|      { |  | ||||||
|        DECL_UNINLINABLE (fn) = 1; |  | ||||||
| --- gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c.jj	2007-09-06 10:19:25.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c	2007-09-06 10:19:25.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,143 @@
 |  | ||||||
| +/* __builtin_va_arg_pack () builtin tests.  */
 |  | ||||||
| +
 |  | ||||||
| +#include <stdarg.h>
 |  | ||||||
| +
 |  | ||||||
| +extern void abort (void);
 |  | ||||||
| +
 |  | ||||||
| +int v1 = 8;
 |  | ||||||
| +long int v2 = 3;
 |  | ||||||
| +void *v3 = (void *) &v2;
 |  | ||||||
| +struct A { char c[16]; } v4 = { "foo" };
 |  | ||||||
| +long double v5 = 40;
 |  | ||||||
| +char seen[20];
 |  | ||||||
| +int cnt;
 |  | ||||||
| +
 |  | ||||||
| +__attribute__ ((noinline)) int
 |  | ||||||
| +foo1 (int x, int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  int i;
 |  | ||||||
| +  long int l;
 |  | ||||||
| +  void *v;
 |  | ||||||
| +  struct A a;
 |  | ||||||
| +  long double ld;
 |  | ||||||
| +  va_list ap;
 |  | ||||||
| +
 |  | ||||||
| +  va_start (ap, y);
 |  | ||||||
| +  if (x < 0 || x >= 20 || seen[x])
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  seen[x] = ++cnt;
 |  | ||||||
| +  if (y != 6)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  i = va_arg (ap, int);
 |  | ||||||
| +  if (i != 5)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (x)
 |  | ||||||
| +    {
 |  | ||||||
| +    case 0:
 |  | ||||||
| +      i = va_arg (ap, int);
 |  | ||||||
| +      if (i != 9 || v1 != 9)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      a = va_arg (ap, struct A);
 |  | ||||||
| +      if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      v = (void *) va_arg (ap, struct A *);
 |  | ||||||
| +      if (v != (void *) &v4)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      l = va_arg (ap, long int);
 |  | ||||||
| +      if (l != 3 || v2 != 4)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 1:
 |  | ||||||
| +      ld = va_arg (ap, long double);
 |  | ||||||
| +      if (ld != 41 || v5 != ld)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      i = va_arg (ap, int);
 |  | ||||||
| +      if (i != 8)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      v = va_arg (ap, void *);
 |  | ||||||
| +      if (v != &v2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 2:
 |  | ||||||
| +      break;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  va_end (ap);
 |  | ||||||
| +  return x;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__attribute__ ((noinline)) int
 |  | ||||||
| +foo2 (int x, int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  long long int ll;
 |  | ||||||
| +  void *v;
 |  | ||||||
| +  struct A a, b;
 |  | ||||||
| +  long double ld;
 |  | ||||||
| +  va_list ap;
 |  | ||||||
| +
 |  | ||||||
| +  va_start (ap, y);
 |  | ||||||
| +  if (x < 0 || x >= 20 || seen[x])
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  seen[x] = ++cnt | 64;
 |  | ||||||
| +  if (y != 10)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (x)
 |  | ||||||
| +    {
 |  | ||||||
| +    case 11:
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 12:
 |  | ||||||
| +      ld = va_arg (ap, long double);
 |  | ||||||
| +      if (ld != 41 || v5 != 40)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      a = va_arg (ap, struct A);
 |  | ||||||
| +      if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      b = va_arg (ap, struct A);
 |  | ||||||
| +      if (__builtin_memcmp (b.c, v4.c, sizeof (b.c)) != 0)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      v = va_arg (ap, void *);
 |  | ||||||
| +      if (v != &v2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      ll = va_arg (ap, long long int);
 |  | ||||||
| +      if (ll != 16LL)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 2:
 |  | ||||||
| +      break;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  va_end (ap);
 |  | ||||||
| +  return x + 8;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__attribute__ ((noinline)) int
 |  | ||||||
| +foo3 (void)
 |  | ||||||
| +{
 |  | ||||||
| +  return 6;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__ ((always_inline, gnu_inline)) int
 |  | ||||||
| +bar (int x, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  if (x < 10)
 |  | ||||||
| +    return foo1 (x, foo3 (), 5, __builtin_va_arg_pack ());
 |  | ||||||
| +  return foo2 (x, foo3 () + 4, __builtin_va_arg_pack ());
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  if (bar (0, ++v1, v4, &v4, v2++) != 0)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (1, ++v5, 8, v3) != 1)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (2) != 2)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (v1 + 2) != 19)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (v1 + 3, v5--, v4, v4, v3, 16LL) != 20)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/gcc.dg/va-arg-pack-1.c.jj	2007-09-06 10:19:25.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/va-arg-pack-1.c	2007-09-06 12:52:00.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,46 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O2" } */
 |  | ||||||
| +
 |  | ||||||
| +int bar (int, const char *, int, ...);
 |  | ||||||
| +int baz (int, const char *, long int);
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f2 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (y, "", __builtin_va_arg_pack ());		/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f3 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (y, "", 5, __builtin_va_arg_pack ());
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f4 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (y, "", 4, __builtin_va_arg_pack (), 6);	/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f5 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return baz (y, "", __builtin_va_arg_pack ());		/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f6 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return __builtin_va_arg_pack ();			/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +test (void)
 |  | ||||||
| +{
 |  | ||||||
| +  int a = f2 (5, "a", 6);
 |  | ||||||
| +  a += f3 (6, "ab", 17LL);
 |  | ||||||
| +  a += f4 (7, 1, 2, 3);
 |  | ||||||
| +  a += f5 (8, 7L);
 |  | ||||||
| +  a += f6 (9);
 |  | ||||||
| +  return a;
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/gcc.dg/va-arg-pack-1a.c.jj	2007-09-06 12:51:51.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/va-arg-pack-1a.c	2007-09-06 12:52:09.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,11 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O2" } */
 |  | ||||||
| +
 |  | ||||||
| +int bar (int, const char *, int, ...);
 |  | ||||||
| +int baz (int, const char *, long int);
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +f1 (int x, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (5, "", 6, __builtin_va_arg_pack ());	/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/va-arg-pack-1.C.jj	2007-09-07 08:52:55.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/va-arg-pack-1.C	2007-09-07 08:53:45.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,145 @@
 |  | ||||||
| +// __builtin_va_arg_pack () builtin tests.
 |  | ||||||
| +// { dg-do run }
 |  | ||||||
| +// { dg-options "-O2" }
 |  | ||||||
| +
 |  | ||||||
| +#include <stdarg.h>
 |  | ||||||
| +
 |  | ||||||
| +extern "C" void abort (void);
 |  | ||||||
| +
 |  | ||||||
| +int v1 = 8;
 |  | ||||||
| +long int v2 = 3;
 |  | ||||||
| +void *v3 = (void *) &v2;
 |  | ||||||
| +struct A { char c[16]; } v4 = { "foo" };
 |  | ||||||
| +long double v5 = 40;
 |  | ||||||
| +char seen[20];
 |  | ||||||
| +int cnt;
 |  | ||||||
| +
 |  | ||||||
| +__attribute__ ((noinline)) int
 |  | ||||||
| +foo1 (int x, int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  int i;
 |  | ||||||
| +  long int l;
 |  | ||||||
| +  void *v;
 |  | ||||||
| +  struct A a;
 |  | ||||||
| +  long double ld;
 |  | ||||||
| +  va_list ap;
 |  | ||||||
| +
 |  | ||||||
| +  va_start (ap, y);
 |  | ||||||
| +  if (x < 0 || x >= 20 || seen[x])
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  seen[x] = ++cnt;
 |  | ||||||
| +  if (y != 6)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  i = va_arg (ap, int);
 |  | ||||||
| +  if (i != 5)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (x)
 |  | ||||||
| +    {
 |  | ||||||
| +    case 0:
 |  | ||||||
| +      i = va_arg (ap, int);
 |  | ||||||
| +      if (i != 9 || v1 != 9)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      a = va_arg (ap, struct A);
 |  | ||||||
| +      if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      v = (void *) va_arg (ap, struct A *);
 |  | ||||||
| +      if (v != (void *) &v4)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      l = va_arg (ap, long int);
 |  | ||||||
| +      if (l != 3 || v2 != 4)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 1:
 |  | ||||||
| +      ld = va_arg (ap, long double);
 |  | ||||||
| +      if (ld != 41 || v5 != ld)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      i = va_arg (ap, int);
 |  | ||||||
| +      if (i != 8)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      v = va_arg (ap, void *);
 |  | ||||||
| +      if (v != &v2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 2:
 |  | ||||||
| +      break;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  va_end (ap);
 |  | ||||||
| +  return x;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__attribute__ ((noinline)) int
 |  | ||||||
| +foo2 (int x, int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  long long int ll;
 |  | ||||||
| +  void *v;
 |  | ||||||
| +  struct A a, b;
 |  | ||||||
| +  long double ld;
 |  | ||||||
| +  va_list ap;
 |  | ||||||
| +
 |  | ||||||
| +  va_start (ap, y);
 |  | ||||||
| +  if (x < 0 || x >= 20 || seen[x])
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  seen[x] = ++cnt | 64;
 |  | ||||||
| +  if (y != 10)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  switch (x)
 |  | ||||||
| +    {
 |  | ||||||
| +    case 11:
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 12:
 |  | ||||||
| +      ld = va_arg (ap, long double);
 |  | ||||||
| +      if (ld != 41 || v5 != 40)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      a = va_arg (ap, struct A);
 |  | ||||||
| +      if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      b = va_arg (ap, struct A);
 |  | ||||||
| +      if (__builtin_memcmp (b.c, v4.c, sizeof (b.c)) != 0)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      v = va_arg (ap, void *);
 |  | ||||||
| +      if (v != &v2)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      ll = va_arg (ap, long long int);
 |  | ||||||
| +      if (ll != 16LL)
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      break;
 |  | ||||||
| +    case 2:
 |  | ||||||
| +      break;
 |  | ||||||
| +    default:
 |  | ||||||
| +      abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  va_end (ap);
 |  | ||||||
| +  return x + 8;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__attribute__ ((noinline)) int
 |  | ||||||
| +foo3 (void)
 |  | ||||||
| +{
 |  | ||||||
| +  return 6;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__ ((always_inline, gnu_inline)) int
 |  | ||||||
| +bar (int x, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  if (x < 10)
 |  | ||||||
| +    return foo1 (x, foo3 (), 5, __builtin_va_arg_pack ());
 |  | ||||||
| +  return foo2 (x, foo3 () + 4, __builtin_va_arg_pack ());
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  if (bar (0, ++v1, v4, &v4, v2++) != 0)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (1, ++v5, 8, v3) != 1)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (2) != 2)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (v1 + 2) != 19)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  if (bar (v1 + 3, v5--, v4, v4, v3, 16LL) != 20)
 |  | ||||||
| +    abort ();
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/va-arg-pack-2.C.jj	2007-09-07 08:53:23.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/va-arg-pack-2.C	2007-09-07 08:54:25.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,46 @@
 |  | ||||||
| +// { dg-do compile }
 |  | ||||||
| +// { dg-options "-O2" }
 |  | ||||||
| +
 |  | ||||||
| +int bar (int, const char *, int, ...);
 |  | ||||||
| +int baz (int, const char *, long int);
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f2 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (y, "", __builtin_va_arg_pack ());		/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f3 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (y, "", 5, __builtin_va_arg_pack ());
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f4 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return bar (y, "", 4, __builtin_va_arg_pack (), 6);	/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f5 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return baz (y, "", __builtin_va_arg_pack ());		/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((always_inline)) int
 |  | ||||||
| +f6 (int y, ...)
 |  | ||||||
| +{
 |  | ||||||
| +  return __builtin_va_arg_pack ();			/* { dg-error "invalid use of" } */
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +test (void)
 |  | ||||||
| +{
 |  | ||||||
| +  int a = f2 (5, "a", 6);
 |  | ||||||
| +  a += f3 (6, "ab", 17LL);
 |  | ||||||
| +  a += f4 (7, 1, 2, 3);
 |  | ||||||
| +  a += f5 (8, 7L);
 |  | ||||||
| +  a += f6 (9);
 |  | ||||||
| +  return a;
 |  | ||||||
| +}
 |  | ||||||
| @ -1,608 +0,0 @@ | |||||||
| 2007-08-31  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* cp-tree.h (cp_disregard_inline_limits): New prototype. |  | ||||||
| 	* decl.c (cp_disregard_inline_limits): New function. |  | ||||||
| 	* cp-objcp-common.h |  | ||||||
| 	(LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS): Define. |  | ||||||
| 
 |  | ||||||
| 2007-08-30  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* gcc.dg/inline-24.c: New test. |  | ||||||
| 	* g++.dg/opt/inline11.C: New test. |  | ||||||
| 
 |  | ||||||
| 2007-08-27  Alexandre Oliva  <aoliva@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* doc/extend.texi (gnu_inline funtion attribute): Document C++ |  | ||||||
| 	behavior. |  | ||||||
| 
 |  | ||||||
| 	* decl.c (GNU_INLINE_P): New. |  | ||||||
| 	(duplicate_decls): Handle gnu_inline.  Merge attributes and |  | ||||||
| 	some flags in overriding definitions. |  | ||||||
| 	(redeclaration_error_message): Handle gnu_inline. |  | ||||||
| 	(start_preparsed_function): Likewise. |  | ||||||
| 
 |  | ||||||
| 	* g++.dg/ext/gnu-inline-common.h: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-global-reject.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-global.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-namespace.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-anon-namespace.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-class.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-class-static.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-template-class.C: New. |  | ||||||
| 	* g++.dg/ext/gnu-inline-template-func.C: New. |  | ||||||
| 
 |  | ||||||
| --- gcc/cp/cp-tree.h.jj	2007-08-31 09:47:43.000000000 +0200
 |  | ||||||
| +++ gcc/cp/cp-tree.h	2007-08-31 14:09:08.000000000 +0200
 |  | ||||||
| @@ -4417,6 +4417,7 @@ extern linkage_kind decl_linkage		(tree)
 |  | ||||||
|  extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn, |  | ||||||
|  			      void*, struct pointer_set_t*); |  | ||||||
|  extern int cp_cannot_inline_tree_fn		(tree*); |  | ||||||
| +extern int cp_disregard_inline_limits		(tree);
 |  | ||||||
|  extern tree cp_add_pending_fn_decls		(void*,tree); |  | ||||||
|  extern int cp_auto_var_in_fn_p			(tree,tree); |  | ||||||
|  extern tree fold_if_not_in_template		(tree); |  | ||||||
| --- gcc/cp/decl.c.jj	2007-08-31 09:47:43.000000000 +0200
 |  | ||||||
| +++ gcc/cp/decl.c	2007-08-31 14:27:12.000000000 +0200
 |  | ||||||
| @@ -1097,6 +1097,10 @@ check_redeclaration_exception_specificat
 |  | ||||||
|      } |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +#define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn)			\
 |  | ||||||
| +			  && lookup_attribute ("gnu_inline",		\
 |  | ||||||
| +					       DECL_ATTRIBUTES (fn)))
 |  | ||||||
| +
 |  | ||||||
|  /* If NEWDECL is a redeclaration of OLDDECL, merge the declarations. |  | ||||||
|     If the redeclaration is invalid, a diagnostic is issued, and the |  | ||||||
|     error_mark_node is returned.  Otherwise, OLDDECL is returned. |  | ||||||
| @@ -1626,19 +1630,45 @@ duplicate_decls (tree newdecl, tree oldd
 |  | ||||||
|  	= chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl), |  | ||||||
|  		   DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); |  | ||||||
|   |  | ||||||
| +      DECL_ATTRIBUTES (old_result)
 |  | ||||||
| +	= (*targetm.merge_decl_attributes) (old_result, new_result);
 |  | ||||||
| +
 |  | ||||||
|        if (DECL_FUNCTION_TEMPLATE_P (newdecl)) |  | ||||||
|  	{ |  | ||||||
| -	  DECL_INLINE (old_result)
 |  | ||||||
| -	    |= DECL_INLINE (new_result);
 |  | ||||||
| -	  DECL_DECLARED_INLINE_P (old_result)
 |  | ||||||
| -	    |= DECL_DECLARED_INLINE_P (new_result);
 |  | ||||||
| -	  check_redeclaration_exception_specification (newdecl, olddecl);
 |  | ||||||
| +	  if (GNU_INLINE_P (old_result) != GNU_INLINE_P (new_result)
 |  | ||||||
| +	      && DECL_INITIAL (new_result))
 |  | ||||||
| +	    {
 |  | ||||||
| +	      if (DECL_INITIAL (old_result))
 |  | ||||||
| +		{
 |  | ||||||
| +		  DECL_INLINE (old_result) = 0;
 |  | ||||||
| +		  DECL_UNINLINABLE (old_result) = 1;
 |  | ||||||
| +		}
 |  | ||||||
| +	      else
 |  | ||||||
| +		{
 |  | ||||||
| +		  DECL_INLINE (old_result) = DECL_INLINE (new_result);
 |  | ||||||
| +		  DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
 |  | ||||||
| +		}
 |  | ||||||
| +	      DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result);
 |  | ||||||
| +	      DECL_NOT_REALLY_EXTERN (old_result)
 |  | ||||||
| +		= DECL_NOT_REALLY_EXTERN (new_result);
 |  | ||||||
| +	      DECL_INTERFACE_KNOWN (old_result)
 |  | ||||||
| +		= DECL_INTERFACE_KNOWN (new_result);
 |  | ||||||
| +	      DECL_DECLARED_INLINE_P (old_result)
 |  | ||||||
| +		= DECL_DECLARED_INLINE_P (new_result);
 |  | ||||||
| +	    }
 |  | ||||||
| +	  else
 |  | ||||||
| +	    {
 |  | ||||||
| +	      DECL_INLINE (old_result)
 |  | ||||||
| +		|= DECL_INLINE (new_result);
 |  | ||||||
| +	      DECL_DECLARED_INLINE_P (old_result)
 |  | ||||||
| +		|= DECL_DECLARED_INLINE_P (new_result);
 |  | ||||||
| +	      check_redeclaration_exception_specification (newdecl, olddecl);
 |  | ||||||
| +	    }
 |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|        /* If the new declaration is a definition, update the file and |  | ||||||
|  	 line information on the declaration.  */ |  | ||||||
| -      if (DECL_INITIAL (old_result) == NULL_TREE
 |  | ||||||
| -	  && DECL_INITIAL (new_result) != NULL_TREE)
 |  | ||||||
| +      if (DECL_INITIAL (new_result) != NULL_TREE)
 |  | ||||||
|  	{ |  | ||||||
|  	  DECL_SOURCE_LOCATION (olddecl) |  | ||||||
|  	    = DECL_SOURCE_LOCATION (old_result) |  | ||||||
| @@ -1795,9 +1825,29 @@ duplicate_decls (tree newdecl, tree oldd
 |  | ||||||
|    new_template = NULL_TREE; |  | ||||||
|    if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) |  | ||||||
|      { |  | ||||||
| -      DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
 |  | ||||||
| -      DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
 |  | ||||||
| -      DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
 |  | ||||||
| +      bool old_decl_gnu_inline;
 |  | ||||||
| +
 |  | ||||||
| +      if ((DECL_INTERFACE_KNOWN (olddecl)
 |  | ||||||
| +	   && TREE_CODE (olddecl) == FUNCTION_DECL)
 |  | ||||||
| +	  || (TREE_CODE (olddecl) == TEMPLATE_DECL
 |  | ||||||
| +	      && TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL))
 |  | ||||||
| +	{
 |  | ||||||
| +	  tree fn = olddecl;
 |  | ||||||
| +
 |  | ||||||
| +	  if (TREE_CODE (fn) == TEMPLATE_DECL)
 |  | ||||||
| +	    fn = DECL_TEMPLATE_RESULT (olddecl);
 |  | ||||||
| +
 |  | ||||||
| +	  old_decl_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
 |  | ||||||
| +	}
 |  | ||||||
| +      else
 |  | ||||||
| +	old_decl_gnu_inline = false;
 |  | ||||||
| +
 |  | ||||||
| +      if (!old_decl_gnu_inline)
 |  | ||||||
| +	{
 |  | ||||||
| +	  DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
 |  | ||||||
| +	  DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
 |  | ||||||
| +	  DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
 |  | ||||||
| +	}
 |  | ||||||
|        DECL_TEMPLATE_INSTANTIATED (newdecl) |  | ||||||
|  	|= DECL_TEMPLATE_INSTANTIATED (olddecl); |  | ||||||
|   |  | ||||||
| @@ -1871,6 +1921,13 @@ duplicate_decls (tree newdecl, tree oldd
 |  | ||||||
|  	  /* [temp.expl.spec/14] We don't inline explicit specialization |  | ||||||
|  	     just because the primary template says so.  */ |  | ||||||
|  	} |  | ||||||
| +      else if (new_defines_function && DECL_INITIAL (olddecl))
 |  | ||||||
| +	{
 |  | ||||||
| +	  /* C++ is always in in unit-at-a-time mode, so we never
 |  | ||||||
| +	     inline re-defined extern inline functions.  */
 |  | ||||||
| +	  DECL_INLINE (newdecl) = 0;
 |  | ||||||
| +	  DECL_UNINLINABLE (newdecl) = 1;
 |  | ||||||
| +	}
 |  | ||||||
|        else |  | ||||||
|  	{ |  | ||||||
|  	  if (DECL_PENDING_INLINE_INFO (newdecl) == 0) |  | ||||||
| @@ -2113,9 +2170,25 @@ redeclaration_error_message (tree newdec
 |  | ||||||
|  	{ |  | ||||||
|  	  if (DECL_NAME (olddecl) == NULL_TREE) |  | ||||||
|  	    return "%q#D not declared in class"; |  | ||||||
| -	  else
 |  | ||||||
| +	  else if (!GNU_INLINE_P (olddecl)
 |  | ||||||
| +		   || GNU_INLINE_P (newdecl))
 |  | ||||||
|  	    return "redefinition of %q#D"; |  | ||||||
|  	} |  | ||||||
| +
 |  | ||||||
| +      if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl))
 |  | ||||||
| +	{
 |  | ||||||
| +	  bool olda = GNU_INLINE_P (olddecl);
 |  | ||||||
| +	  bool newa = GNU_INLINE_P (newdecl);
 |  | ||||||
| +
 |  | ||||||
| +	  if (olda != newa)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      if (newa)
 |  | ||||||
| +		return "%q+D redeclared inline with %<gnu_inline%> attribute";
 |  | ||||||
| +	      else
 |  | ||||||
| +		return "%q+D redeclared inline without %<gnu_inline%> attribute";
 |  | ||||||
| +	    }
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
|        return 0; |  | ||||||
|      } |  | ||||||
|    else if (TREE_CODE (newdecl) == TEMPLATE_DECL) |  | ||||||
| @@ -2141,9 +2214,24 @@ redeclaration_error_message (tree newdec
 |  | ||||||
|        ot = DECL_TEMPLATE_RESULT (olddecl); |  | ||||||
|        if (DECL_TEMPLATE_INFO (ot)) |  | ||||||
|  	ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot)); |  | ||||||
| -      if (DECL_INITIAL (nt) && DECL_INITIAL (ot))
 |  | ||||||
| +      if (DECL_INITIAL (nt) && DECL_INITIAL (ot)
 |  | ||||||
| +	  && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt)))
 |  | ||||||
|  	return "redefinition of %q#D"; |  | ||||||
|   |  | ||||||
| +      if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt))
 |  | ||||||
| +	{
 |  | ||||||
| +	  bool olda = GNU_INLINE_P (ot);
 |  | ||||||
| +	  bool newa = GNU_INLINE_P (nt);
 |  | ||||||
| +
 |  | ||||||
| +	  if (olda != newa)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      if (newa)
 |  | ||||||
| +		return "%q+D redeclared inline with %<gnu_inline%> attribute";
 |  | ||||||
| +	      else
 |  | ||||||
| +		return "%q+D redeclared inline without %<gnu_inline%> attribute";
 |  | ||||||
| +	    }
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
|        return NULL; |  | ||||||
|      } |  | ||||||
|    else if (TREE_CODE (newdecl) == VAR_DECL |  | ||||||
| @@ -10447,6 +10535,14 @@ start_preparsed_function (tree decl1, tr
 |  | ||||||
|        && lookup_attribute ("noinline", attrs)) |  | ||||||
|      warning (0, "inline function %q+D given attribute noinline", decl1); |  | ||||||
|   |  | ||||||
| +  /* Handle gnu_inline attribute.  */
 |  | ||||||
| +  if (GNU_INLINE_P (decl1))
 |  | ||||||
| +    {
 |  | ||||||
| +      DECL_EXTERNAL (decl1) = 1;
 |  | ||||||
| +      DECL_NOT_REALLY_EXTERN (decl1) = 0;
 |  | ||||||
| +      DECL_INTERFACE_KNOWN (decl1) = 1;
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|    if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1)) |  | ||||||
|      /* This is a constructor, we must ensure that any default args |  | ||||||
|         introduced by this definition are propagated to the clones |  | ||||||
| @@ -10702,8 +10798,9 @@ start_preparsed_function (tree decl1, tr
 |  | ||||||
|    else |  | ||||||
|      { |  | ||||||
|        /* This is a definition, not a reference. |  | ||||||
| -	 So clear DECL_EXTERNAL.  */
 |  | ||||||
| -      DECL_EXTERNAL (decl1) = 0;
 |  | ||||||
| +	 So clear DECL_EXTERNAL, unless this is a GNU extern inline.  */
 |  | ||||||
| +      if (!GNU_INLINE_P (decl1))
 |  | ||||||
| +	DECL_EXTERNAL (decl1) = 0;
 |  | ||||||
|   |  | ||||||
|        if ((DECL_DECLARED_INLINE_P (decl1) |  | ||||||
|  	   || DECL_TEMPLATE_INSTANTIATION (decl1)) |  | ||||||
| @@ -11698,4 +11795,17 @@ cxx_comdat_group (tree decl)
 |  | ||||||
|    return IDENTIFIER_POINTER (name); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +/* We want to inline __gnu_inline__ functions even if this would
 |  | ||||||
| +   violate inlining limits.  Some glibc and linux constructs depend on
 |  | ||||||
| +   such functions always being inlined when optimizing.  */
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +cp_disregard_inline_limits (tree fn)
 |  | ||||||
| +{
 |  | ||||||
| +  if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
 |  | ||||||
| +    return 1;
 |  | ||||||
| +
 |  | ||||||
| +  return (!flag_really_no_inline && GNU_INLINE_P (fn));
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  #include "gt-cp-decl.h" |  | ||||||
| --- gcc/cp/cp-objcp-common.h.jj	2007-02-20 22:37:34.000000000 +0100
 |  | ||||||
| +++ gcc/cp/cp-objcp-common.h	2007-08-31 13:58:32.000000000 +0200
 |  | ||||||
| @@ -107,6 +107,9 @@ extern tree objcp_tsubst_copy_and_build 
 |  | ||||||
|  #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN |  | ||||||
|  #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ |  | ||||||
|    cp_cannot_inline_tree_fn |  | ||||||
| +#undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
 |  | ||||||
| +#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
 |  | ||||||
| +  cp_disregard_inline_limits
 |  | ||||||
|  #undef LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS |  | ||||||
|  #define LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS \ |  | ||||||
|    cp_add_pending_fn_decls |  | ||||||
| --- gcc/doc/extend.texi.jj	2007-08-31 09:47:40.000000000 +0200
 |  | ||||||
| +++ gcc/doc/extend.texi	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -1587,8 +1587,8 @@ refer to the single copy in the library.
 |  | ||||||
|  definitions of the functions need not be precisely the same, although |  | ||||||
|  if they do not have the same effect your program may behave oddly. |  | ||||||
|   |  | ||||||
| -If the function is neither @code{extern} nor @code{static}, then the
 |  | ||||||
| -function is compiled as a standalone function, as well as being
 |  | ||||||
| +In C, if the function is neither @code{extern} nor @code{static}, then
 |  | ||||||
| +the function is compiled as a standalone function, as well as being
 |  | ||||||
|  inlined where possible. |  | ||||||
|   |  | ||||||
|  This is how GCC traditionally handled functions declared |  | ||||||
| @@ -1606,6 +1606,10 @@ assume that it is always present, whethe
 |  | ||||||
|  In versions prior to 4.3, the only effect of explicitly including it is |  | ||||||
|  to disable warnings about using inline functions in C99 mode. |  | ||||||
|   |  | ||||||
| +In C++, this attribute does not depend on @code{extern} in any way,
 |  | ||||||
| +but it still requires the @code{inline} keyword to enable its special
 |  | ||||||
| +behavior.
 |  | ||||||
| +
 |  | ||||||
|  @cindex @code{flatten} function attribute |  | ||||||
|  @item flatten |  | ||||||
|  Generally, inlining into a function is limited.  For a function marked with |  | ||||||
| --- gcc/testsuite/gcc.dg/inline-24.c.jj	2007-08-31 14:11:45.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/inline-24.c	2007-08-30 18:43:55.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,28 @@
 |  | ||||||
| +/* Verify that gnu_inline inlines disregard inlining limits.  */
 |  | ||||||
| +/* { dg-do link } */
 |  | ||||||
| +/* { dg-options "-O2" } */
 |  | ||||||
| +
 |  | ||||||
| +extern int foo (int);
 |  | ||||||
| +extern int baz (int);
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((gnu_inline))
 |  | ||||||
| +int foo (int x)
 |  | ||||||
| +{
 |  | ||||||
| +  int i;
 |  | ||||||
| +  if (!__builtin_constant_p (x))
 |  | ||||||
| +    {
 |  | ||||||
| +#define B(n) baz (1##n) + baz (2##n) + baz (3##n) \
 |  | ||||||
| +	     + baz (4##n) + baz (5##n) + baz (6##n)
 |  | ||||||
| +#define C(n) B(1##n) + B(2##n) + B(3##n) + B(4##n) + B(5##n) + B(6##n)
 |  | ||||||
| +#define D(n) C(1##n) + C(2##n) + C(3##n) + C(4##n) + C(5##n) + C(6##n)
 |  | ||||||
| +      return D(0) + D(1) + D(2) + D(3) + D(4)
 |  | ||||||
| +	     + D(5) + D(6) + D(7) + D(8) + D(9);
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  return foo (0);
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/opt/inline11.C.jj	2007-08-31 14:12:05.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/opt/inline11.C	2007-08-30 18:43:55.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,28 @@
 |  | ||||||
| +/* Verify that gnu_inline inlines disregard inlining limits.  */
 |  | ||||||
| +/* { dg-do link } */
 |  | ||||||
| +/* { dg-options "-O2" } */
 |  | ||||||
| +
 |  | ||||||
| +extern int foo (int);
 |  | ||||||
| +extern int baz (int);
 |  | ||||||
| +
 |  | ||||||
| +extern inline __attribute__((gnu_inline))
 |  | ||||||
| +int foo (int x)
 |  | ||||||
| +{
 |  | ||||||
| +  int i;
 |  | ||||||
| +  if (!__builtin_constant_p (x))
 |  | ||||||
| +    {
 |  | ||||||
| +#define B(n) baz (1##n) + baz (2##n) + baz (3##n) \
 |  | ||||||
| +	     + baz (4##n) + baz (5##n) + baz (6##n)
 |  | ||||||
| +#define C(n) B(1##n) + B(2##n) + B(3##n) + B(4##n) + B(5##n) + B(6##n)
 |  | ||||||
| +#define D(n) C(1##n) + C(2##n) + C(3##n) + C(4##n) + C(5##n) + C(6##n)
 |  | ||||||
| +      return D(0) + D(1) + D(2) + D(3) + D(4)
 |  | ||||||
| +	     + D(5) + D(6) + D(7) + D(8) + D(9);
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  return foo (0);
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,55 @@
 |  | ||||||
| +/* Test __attribute__((gnu_inline)).
 |  | ||||||
| +
 |  | ||||||
| +   Check that we reject various forms of duplicate definitions.
 |  | ||||||
| +*/
 |  | ||||||
| +
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +
 |  | ||||||
| +#include "gnu-inline-common.h"
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_decl_inline_before)
 |  | ||||||
| +decl(inline, fn) // { dg-error "previous" "" }
 |  | ||||||
| +gnuindef(fn, 0) // { dg-error "redeclared" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_decl_inline_after)
 |  | ||||||
| +gnuindef(fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +decl(inline, fn) // { dg-error "redeclared" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_def_gnuin_redef)
 |  | ||||||
| +gnuindef(fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +gnuindef(fn, 1) // { dg-error "redefinition" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_def_inline_redef)
 |  | ||||||
| +def(inline, fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +def(inline, fn, 1) // { dg-error "redefinition" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_def_inline_after)
 |  | ||||||
| +gnuindef(fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +def(inline, fn, 1) // { dg-error "redeclare" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_def_inline_before)
 |  | ||||||
| +def(inline, fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +gnuindef(fn, 1) // { dg-error "redefinition" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_def_before)
 |  | ||||||
| +def(, fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +gnuindef(fn, 1) // { dg-error "redefinition" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_decl_static_inline_before)
 |  | ||||||
| +decl(static inline, fn) // { dg-error "previous" "" }
 |  | ||||||
| +gnuindef(fn, 0) // { dg-error "redeclared" "" }
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func_def_static_inline_after)
 |  | ||||||
| +decl(static, fn)
 |  | ||||||
| +gnuindef(fn, 0) // { dg-error "previous" "" }
 |  | ||||||
| +decl(static, fn)
 |  | ||||||
| +def(static inline, fn, 1) // { dg-error "redeclare" "" }
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-template-func.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-template-func.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,17 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +#define defpfx template <typename T>
 |  | ||||||
| +
 |  | ||||||
| +#include "gnu-inline-global.C"
 |  | ||||||
| +
 |  | ||||||
| +template int func1<int>(void);
 |  | ||||||
| +template int func2<int>(void);
 |  | ||||||
| +template int func3<int>(void);
 |  | ||||||
| +template int func4<int>(void);
 |  | ||||||
| +template int func5<int>(void);
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-common.h.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-common.h	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,24 @@
 |  | ||||||
| +#ifndef gnu
 |  | ||||||
| +# define gnu_inline __attribute__((gnu_inline)) inline
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
| +#define declspec(spec, name) spec int name (void)
 |  | ||||||
| +#ifdef IN_CLASS
 |  | ||||||
| +# define decl(spec, name)
 |  | ||||||
| +#else
 |  | ||||||
| +# define decl(spec, name) defpfx declspec(spec, name);
 |  | ||||||
| +#endif
 |  | ||||||
| +#define def(spec, name, ret) defpfx declspec(spec, name) { return ret; }
 |  | ||||||
| +#define gnuindef(name, ret) def(gnu_inline, name, ret)
 |  | ||||||
| +
 |  | ||||||
| +#ifndef pfx
 |  | ||||||
| +# ifdef IN_CLASS
 |  | ||||||
| +#  define pfx(x) IN_CLASS::x
 |  | ||||||
| +# else
 |  | ||||||
| +#  define pfx(x) x
 |  | ||||||
| +# endif
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
| +#ifndef defpfx
 |  | ||||||
| +# define defpfx
 |  | ||||||
| +#endif
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-anon-namespace.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-anon-namespace.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,11 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +namespace {
 |  | ||||||
| +#include "gnu-inline-global.C"
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-class-static.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-class-static.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,20 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +#undef IN_CLASS
 |  | ||||||
| +#define IN_CLASS gnu_test_static
 |  | ||||||
| +
 |  | ||||||
| +struct IN_CLASS {
 |  | ||||||
| +  static int func1(void);
 |  | ||||||
| +  static int func2(void);
 |  | ||||||
| +  static int func3(void);
 |  | ||||||
| +  static int func4(void);
 |  | ||||||
| +  static int func5(void);
 |  | ||||||
| +};
 |  | ||||||
| +
 |  | ||||||
| +#include "gnu-inline-global.C"
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-global.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-global.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,50 @@
 |  | ||||||
| +/* Test __attribute__((gnu_inline)).
 |  | ||||||
| +
 |  | ||||||
| +   Check that __attribute__((gnu_inline)) has no effect, in the
 |  | ||||||
| +   absence of extern and/or inline.
 |  | ||||||
| +
 |  | ||||||
| +   Check that we don't get out-of-line definitions for extern inline
 |  | ||||||
| +   gnu_inline functions, regardless of declarations or definitions.
 |  | ||||||
| +
 |  | ||||||
| +   Check that such functions can be overridden by out-of-line
 |  | ||||||
| +   definitions.
 |  | ||||||
| +
 |  | ||||||
| + */
 |  | ||||||
| +
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +#include "gnu-inline-common.h"
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func1) // must be emitted out-of-line
 |  | ||||||
| +gnuindef(fn, 0)
 |  | ||||||
| +def(, fn, 2)
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func2) // must be emitted out-of-line
 |  | ||||||
| +decl(extern, fn)
 |  | ||||||
| +gnuindef(fn, 0)
 |  | ||||||
| +def(, fn, 2)
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func3) // must not be emitted
 |  | ||||||
| +decl(extern, fn)
 |  | ||||||
| +gnuindef(fn, 0)
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func4) // must be emitted out-of-line
 |  | ||||||
| +decl(extern, fn)
 |  | ||||||
| +gnuindef(fn, 0)
 |  | ||||||
| +def(, fn, 1)
 |  | ||||||
| +
 |  | ||||||
| +#undef fn
 |  | ||||||
| +#define fn pfx(func5) // must NOT be emitted, because it's static and unused
 |  | ||||||
| +decl(static, fn)
 |  | ||||||
| +gnuindef(fn, 0)
 |  | ||||||
| +def(, fn, 1)
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-template-class.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-template-class.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,22 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +template <typename T> struct gnu_test {
 |  | ||||||
| +  int func1(void);
 |  | ||||||
| +  int func2(void);
 |  | ||||||
| +  int func3(void);
 |  | ||||||
| +  int func4(void);
 |  | ||||||
| +  int func5(void);
 |  | ||||||
| +};
 |  | ||||||
| +
 |  | ||||||
| +#define defpfx template <typename T>
 |  | ||||||
| +#define IN_CLASS gnu_test<T>
 |  | ||||||
| +
 |  | ||||||
| +#include "gnu-inline-global.C"
 |  | ||||||
| +
 |  | ||||||
| +template struct gnu_test<int>;
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-namespace.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-namespace.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,11 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +namespace gnu_test {
 |  | ||||||
| +#include "gnu-inline-global.C"
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/g++.dg/ext/gnu-inline-class.C.jj	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/g++.dg/ext/gnu-inline-class.C	2007-08-31 13:00:28.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,19 @@
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-O" } */ // such that static functions are optimized out
 |  | ||||||
| +/* { dg-final { scan-assembler "func1" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func2" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler-not "func3" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func4" } } */
 |  | ||||||
| +/* { dg-final { scan-assembler "func5" } } */
 |  | ||||||
| +
 |  | ||||||
| +#define IN_CLASS gnu_test
 |  | ||||||
| +
 |  | ||||||
| +struct IN_CLASS {
 |  | ||||||
| +  int func1(void);
 |  | ||||||
| +  int func2(void);
 |  | ||||||
| +  int func3(void);
 |  | ||||||
| +  int func4(void);
 |  | ||||||
| +  int func5(void);
 |  | ||||||
| +};
 |  | ||||||
| +
 |  | ||||||
| +#include "gnu-inline-global.C"
 |  | ||||||
							
								
								
									
										295
									
								
								gcc41-error-attrib.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								gcc41-error-attrib.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,295 @@ | |||||||
|  | 2007-09-23  Jakub Jelinek  <jakub@redhat.com> | ||||||
|  | 
 | ||||||
|  | 	* expr.c (expand_expr_real_1) <case CALL_EXPR>: Use get_callee_fndecl | ||||||
|  | 	instead of checking CALL_EXPR_FN directly to test for builtins. | ||||||
|  | 	If error or warning attributes are present, print | ||||||
|  | 	error resp. warning. | ||||||
|  | 	* c-common.c (handle_error_attribute): New function. | ||||||
|  | 	(c_common_attribute_table): Add error and warning | ||||||
|  | 	attributes. | ||||||
|  | 	* doc/extend.texi: Document error and warning attributes. | ||||||
|  | 
 | ||||||
|  | 	* gcc.dg/va-arg-pack-len-1.c: Use error and warning | ||||||
|  | 	attributes. | ||||||
|  | 	* gcc.dg/va-arg-pack-len-2.c: New test. | ||||||
|  | 	* g++.dg/ext/va-arg-pack-len-1.C: Use error and warning | ||||||
|  | 	attributes. | ||||||
|  | 	* g++.dg/ext/va-arg-pack-len-2.C: New test. | ||||||
|  | 
 | ||||||
|  | --- gcc/doc/extend.texi.jj	2007-09-25 15:04:15.000000000 +0200
 | ||||||
|  | +++ gcc/doc/extend.texi	2007-09-25 15:32:22.000000000 +0200
 | ||||||
|  | @@ -1589,8 +1589,8 @@ attributes are currently defined for fun
 | ||||||
|  |  @code{section}, @code{constructor}, @code{destructor}, @code{used}, | ||||||
|  |  @code{unused}, @code{deprecated}, @code{weak}, @code{malloc}, | ||||||
|  |  @code{alias}, @code{warn_unused_result}, @code{nonnull}, | ||||||
|  | -@code{gnu_inline}, @code{externally_visible} and @code{artificial}.
 | ||||||
|  | -Several other
 | ||||||
|  | +@code{gnu_inline}, @code{externally_visible}, @code{artificial},
 | ||||||
|  | +@code{error} and @code{warning}.  Several other
 | ||||||
|  |  attributes are defined for functions on particular target systems.  Other | ||||||
|  |  attributes, including @code{section} are supported for variables declarations | ||||||
|  |  (@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}). | ||||||
|  | @@ -1688,6 +1688,30 @@ Whether the function itself is considere
 | ||||||
|  |  the current inlining parameters.  The @code{flatten} attribute only works | ||||||
|  |  reliably in unit-at-a-time mode. | ||||||
|  |   | ||||||
|  | +@item error ("@var{message}")
 | ||||||
|  | +@cindex @code{error} function attribute
 | ||||||
|  | +If this attribute is used on a function declaration and a call to such a function
 | ||||||
|  | +is not eliminated through dead code elimination or other optimizations, an error
 | ||||||
|  | +which will include @var{message} will be diagnosed.  This is useful
 | ||||||
|  | +for compile time checking, especially together with @code{__builtin_constant_p}
 | ||||||
|  | +and inline functions where checking the inline function arguments is not
 | ||||||
|  | +possible through @code{extern char [(condition) ? 1 : -1];} tricks.
 | ||||||
|  | +While it is possible to leave the function undefined and thus invoke
 | ||||||
|  | +a link failure, when using this attribute the problem will be diagnosed
 | ||||||
|  | +earlier and with exact location of the call even in presence of inline
 | ||||||
|  | +functions or when not emitting debugging information.
 | ||||||
|  | +
 | ||||||
|  | +@item warning ("@var{message}")
 | ||||||
|  | +@cindex @code{warning} function attribute
 | ||||||
|  | +If this attribute is used on a function declaration and a call to such a function
 | ||||||
|  | +is not eliminated through dead code elimination or other optimizations, a warning
 | ||||||
|  | +which will include @var{message} will be diagnosed.  This is useful
 | ||||||
|  | +for compile time checking, especially together with @code{__builtin_constant_p}
 | ||||||
|  | +and inline functions.  While it is possible to define the function with
 | ||||||
|  | +a message in @code{.gnu.warning*} section, when using this attribute the problem
 | ||||||
|  | +will be diagnosed earlier and with exact location of the call even in presence
 | ||||||
|  | +of inline functions or when not emitting debugging information.
 | ||||||
|  | +
 | ||||||
|  |  @item cdecl | ||||||
|  |  @cindex functions that do pop the argument stack on the 386 | ||||||
|  |  @opindex mrtd | ||||||
|  | --- gcc/expr.c.jj	2007-09-25 14:58:40.000000000 +0200
 | ||||||
|  | +++ gcc/expr.c	2007-09-25 15:19:15.000000000 +0200
 | ||||||
|  | @@ -7513,19 +7513,31 @@ expand_expr_real_1 (tree exp, rtx target
 | ||||||
|  |  	 inlining.  */ | ||||||
|  |        if (CALL_EXPR_VA_ARG_PACK (exp)) | ||||||
|  |  	error ("invalid use of %<__builtin_va_arg_pack ()%>"); | ||||||
|  | -      /* Check for a built-in function.  */
 | ||||||
|  | -      if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
 | ||||||
|  | -	  && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
 | ||||||
|  | -	      == FUNCTION_DECL)
 | ||||||
|  | -	  && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
 | ||||||
|  | -	{
 | ||||||
|  | -	  if (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
 | ||||||
|  | -	      == BUILT_IN_FRONTEND)
 | ||||||
|  | -	    return lang_hooks.expand_expr (exp, original_target,
 | ||||||
|  | -					   tmode, modifier,
 | ||||||
|  | -					   alt_rtl);
 | ||||||
|  | -	  else
 | ||||||
|  | -	    return expand_builtin (exp, target, subtarget, tmode, ignore);
 | ||||||
|  | +      {
 | ||||||
|  | +	tree fndecl = get_callee_fndecl (exp), attr;
 | ||||||
|  | +
 | ||||||
|  | +	if (fndecl
 | ||||||
|  | +	    && (attr = lookup_attribute ("error",
 | ||||||
|  | +					 DECL_ATTRIBUTES (fndecl))) != NULL)
 | ||||||
|  | +	  error ("call to %qs declared with attribute error: %s",
 | ||||||
|  | +		 lang_hooks.decl_printable_name (fndecl, 1),
 | ||||||
|  | +		 TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
 | ||||||
|  | +	if (fndecl
 | ||||||
|  | +	    && (attr = lookup_attribute ("warning",
 | ||||||
|  | +					 DECL_ATTRIBUTES (fndecl))) != NULL)
 | ||||||
|  | +	  warning (0, "call to %qs declared with attribute warning: %s",
 | ||||||
|  | +		   lang_hooks.decl_printable_name (fndecl, 1),
 | ||||||
|  | +		   TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
 | ||||||
|  | +
 | ||||||
|  | +	/* Check for a built-in function.  */
 | ||||||
|  | +	if (fndecl && DECL_BUILT_IN (fndecl))
 | ||||||
|  | +	  {
 | ||||||
|  | +	    if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_FRONTEND)
 | ||||||
|  | +	      return lang_hooks.expand_expr (exp, original_target,
 | ||||||
|  | +					     tmode, modifier, alt_rtl);
 | ||||||
|  | +	    else
 | ||||||
|  | +	      return expand_builtin (exp, target, subtarget, tmode, ignore);
 | ||||||
|  | +	  }
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |        return expand_call (exp, target, ignore); | ||||||
|  | --- gcc/c-common.c.jj	2007-09-25 15:01:49.000000000 +0200
 | ||||||
|  | +++ gcc/c-common.c	2007-09-25 15:24:34.000000000 +0200
 | ||||||
|  | @@ -508,6 +508,7 @@ static tree handle_always_inline_attribu
 | ||||||
|  |  static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *); | ||||||
|  |  static tree handle_artificial_attribute (tree *, tree, tree, int, bool *); | ||||||
|  |  static tree handle_flatten_attribute (tree *, tree, tree, int, bool *); | ||||||
|  | +static tree handle_error_attribute (tree *, tree, tree, int, bool *);
 | ||||||
|  |  static tree handle_used_attribute (tree *, tree, tree, int, bool *); | ||||||
|  |  static tree handle_unused_attribute (tree *, tree, tree, int, bool *); | ||||||
|  |  static tree handle_externally_visible_attribute (tree *, tree, tree, int, | ||||||
|  | @@ -641,6 +642,10 @@ const struct attribute_spec c_common_att
 | ||||||
|  |  			      handle_warn_unused_result_attribute }, | ||||||
|  |    { "sentinel",               0, 1, false, true, true, | ||||||
|  |  			      handle_sentinel_attribute }, | ||||||
|  | +  { "warning",		      1, 1, true,  false, false,
 | ||||||
|  | +			      handle_error_attribute },
 | ||||||
|  | +  { "error",		      1, 1, true,  false, false,
 | ||||||
|  | +			      handle_error_attribute },
 | ||||||
|  |    { NULL,                     0, 0, false, false, false, NULL } | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -4226,6 +4231,26 @@ handle_flatten_attribute (tree *node, tr
 | ||||||
|  |    return NULL_TREE; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* Handle a "warning" or "error" attribute; arguments as in
 | ||||||
|  | +   struct attribute_spec.handler.  */
 | ||||||
|  | +
 | ||||||
|  | +static tree
 | ||||||
|  | +handle_error_attribute (tree *node, tree name, tree args,
 | ||||||
|  | +			int ARG_UNUSED (flags), bool *no_add_attrs)
 | ||||||
|  | +{
 | ||||||
|  | +  if (TREE_CODE (*node) == FUNCTION_DECL
 | ||||||
|  | +      || TREE_CODE (TREE_VALUE (args)) == STRING_CST)
 | ||||||
|  | +    /* Do nothing else, just set the attribute.  We'll get at
 | ||||||
|  | +       it later with lookup_attribute.  */
 | ||||||
|  | +    ;
 | ||||||
|  | +  else
 | ||||||
|  | +    {
 | ||||||
|  | +      warning (OPT_Wattributes, "%qE attribute ignored", name);
 | ||||||
|  | +      *no_add_attrs = true;
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +  return NULL_TREE;
 | ||||||
|  | +}
 | ||||||
|  |   | ||||||
|  |  /* Handle a "used" attribute; arguments as in | ||||||
|  |     struct attribute_spec.handler.  */ | ||||||
|  | --- gcc/testsuite/gcc.dg/va-arg-pack-len-1.c.jj	2007-09-25 12:23:05.000000000 +0200
 | ||||||
|  | +++ gcc/testsuite/gcc.dg/va-arg-pack-len-1.c	2007-09-25 15:16:03.000000000 +0200
 | ||||||
|  | @@ -3,8 +3,10 @@
 | ||||||
|  |   | ||||||
|  |  #include <stdarg.h> | ||||||
|  |   | ||||||
|  | -extern int warn_open_missing_mode (void);
 | ||||||
|  | -extern int warn_open_too_many_arguments (void);
 | ||||||
|  | +extern int error_open_missing_mode (void)
 | ||||||
|  | +  __attribute__((__error__ ("open with O_CREAT needs 3 arguments, only 2 were given")));
 | ||||||
|  | +extern int warn_open_too_many_arguments (void)
 | ||||||
|  | +  __attribute__((__warning__ ("open called with more than 3 arguments")));
 | ||||||
|  |  extern void abort (void); | ||||||
|  |   | ||||||
|  |  char expected_char; | ||||||
|  | @@ -83,7 +85,7 @@ myopen (const char *path, int oflag, ...
 | ||||||
|  |      { | ||||||
|  |        if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1) | ||||||
|  |  	{ | ||||||
|  | -	  warn_open_missing_mode ();
 | ||||||
|  | +	  error_open_missing_mode ();
 | ||||||
|  |  	  return myopen2 (path, oflag); | ||||||
|  |  	} | ||||||
|  |        return myopenva (path, oflag, __builtin_va_arg_pack ()); | ||||||
|  | --- gcc/testsuite/gcc.dg/va-arg-pack-len-2.c.jj	2007-09-25 15:16:03.000000000 +0200
 | ||||||
|  | +++ gcc/testsuite/gcc.dg/va-arg-pack-len-2.c	2007-09-25 15:16:03.000000000 +0200
 | ||||||
|  | @@ -0,0 +1,42 @@
 | ||||||
|  | +/* { dg-do compile } */
 | ||||||
|  | +/* { dg-options "-O2" } */
 | ||||||
|  | +
 | ||||||
|  | +#include <stdarg.h>
 | ||||||
|  | +
 | ||||||
|  | +extern int error_open_missing_mode (void)
 | ||||||
|  | +  __attribute__((__error__ ("open with O_CREAT needs 3 arguments, only 2 were given")));
 | ||||||
|  | +extern int warn_open_too_many_arguments (void)
 | ||||||
|  | +  __attribute__((__warning__ ("open called with more than 3 arguments")));
 | ||||||
|  | +
 | ||||||
|  | +extern int myopen2 (const char *path, int oflag);
 | ||||||
|  | +extern int myopenva (const char *path, int oflag, ...);
 | ||||||
|  | +
 | ||||||
|  | +extern inline __attribute__((always_inline, gnu_inline)) int
 | ||||||
|  | +myopen (const char *path, int oflag, ...)
 | ||||||
|  | +{
 | ||||||
|  | +  if (__builtin_va_arg_pack_len () > 1)
 | ||||||
|  | +    warn_open_too_many_arguments ();	/* { dg-warning "called with more than 3" } */
 | ||||||
|  | +
 | ||||||
|  | +  if (__builtin_constant_p (oflag))
 | ||||||
|  | +    {
 | ||||||
|  | +      if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1)
 | ||||||
|  | +	{
 | ||||||
|  | +	  error_open_missing_mode ();	/* { dg-error "needs 3 arguments, only 2 were given" } */
 | ||||||
|  | +	  return myopen2 (path, oflag);
 | ||||||
|  | +	}
 | ||||||
|  | +      return myopenva (path, oflag, __builtin_va_arg_pack ());
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +  if (__builtin_va_arg_pack_len () < 1)
 | ||||||
|  | +    return myopen2 (path, oflag);
 | ||||||
|  | +
 | ||||||
|  | +  return myopenva (path, oflag, __builtin_va_arg_pack ());
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +main (void)
 | ||||||
|  | +{
 | ||||||
|  | +  myopen ("h", 0x43);
 | ||||||
|  | +  myopen ("i", 0x43, 0644, 0655);
 | ||||||
|  | +  return 0;
 | ||||||
|  | +}
 | ||||||
|  | --- gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C.jj	2007-09-25 12:23:05.000000000 +0200
 | ||||||
|  | +++ gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C	2007-09-25 15:16:03.000000000 +0200
 | ||||||
|  | @@ -3,8 +3,10 @@
 | ||||||
|  |   | ||||||
|  |  #include <stdarg.h> | ||||||
|  |   | ||||||
|  | -extern "C" int warn_open_missing_mode (void);
 | ||||||
|  | -extern "C" int warn_open_too_many_arguments (void);
 | ||||||
|  | +extern "C" int error_open_missing_mode (void)
 | ||||||
|  | +  __attribute__((__error__ ("open with O_CREAT needs 3 arguments, only 2 were given")));
 | ||||||
|  | +extern "C" int warn_open_too_many_arguments (void)
 | ||||||
|  | +  __attribute__((__warning__ ("open called with more than 3 arguments")));
 | ||||||
|  |  extern "C" void abort (void); | ||||||
|  |   | ||||||
|  |  char expected_char; | ||||||
|  | @@ -83,7 +85,7 @@ myopen (const char *path, int oflag, ...
 | ||||||
|  |      { | ||||||
|  |        if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1) | ||||||
|  |  	{ | ||||||
|  | -	  warn_open_missing_mode ();
 | ||||||
|  | +	  error_open_missing_mode ();
 | ||||||
|  |  	  return myopen2 (path, oflag); | ||||||
|  |  	} | ||||||
|  |        return myopenva (path, oflag, __builtin_va_arg_pack ()); | ||||||
|  | --- gcc/testsuite/g++.dg/ext/va-arg-pack-len-2.C.jj	2007-09-25 15:16:03.000000000 +0200
 | ||||||
|  | +++ gcc/testsuite/g++.dg/ext/va-arg-pack-len-2.C	2007-09-25 15:16:03.000000000 +0200
 | ||||||
|  | @@ -0,0 +1,42 @@
 | ||||||
|  | +// { dg-do compile }
 | ||||||
|  | +// { dg-options "-O2" }
 | ||||||
|  | +
 | ||||||
|  | +#include <stdarg.h>
 | ||||||
|  | +
 | ||||||
|  | +extern int error_open_missing_mode (void)
 | ||||||
|  | +  __attribute__((__error__ ("open with O_CREAT needs 3 arguments, only 2 were given")));
 | ||||||
|  | +extern int warn_open_too_many_arguments (void)
 | ||||||
|  | +  __attribute__((__warning__ ("open called with more than 3 arguments")));
 | ||||||
|  | +
 | ||||||
|  | +extern int myopen2 (const char *path, int oflag);
 | ||||||
|  | +extern int myopenva (const char *path, int oflag, ...);
 | ||||||
|  | +
 | ||||||
|  | +extern inline __attribute__((always_inline, gnu_inline)) int
 | ||||||
|  | +myopen (const char *path, int oflag, ...)
 | ||||||
|  | +{
 | ||||||
|  | +  if (__builtin_va_arg_pack_len () > 1)
 | ||||||
|  | +    warn_open_too_many_arguments ();	// { dg-warning "called with more than 3" }
 | ||||||
|  | +
 | ||||||
|  | +  if (__builtin_constant_p (oflag))
 | ||||||
|  | +    {
 | ||||||
|  | +      if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1)
 | ||||||
|  | +	{
 | ||||||
|  | +	  error_open_missing_mode ();	// { dg-error "needs 3 arguments, only 2 were given" }
 | ||||||
|  | +	  return myopen2 (path, oflag);
 | ||||||
|  | +	}
 | ||||||
|  | +      return myopenva (path, oflag, __builtin_va_arg_pack ());
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +  if (__builtin_va_arg_pack_len () < 1)
 | ||||||
|  | +    return myopen2 (path, oflag);
 | ||||||
|  | +
 | ||||||
|  | +  return myopenva (path, oflag, __builtin_va_arg_pack ());
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +main (void)
 | ||||||
|  | +{
 | ||||||
|  | +  myopen ("h", 0x43);
 | ||||||
|  | +  myopen ("i", 0x43, 0644, 0655);
 | ||||||
|  | +  return 0;
 | ||||||
|  | +}
 | ||||||
							
								
								
									
										242
									
								
								gcc41-jdwp.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								gcc41-jdwp.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,242 @@ | |||||||
|  | 2007-09-24  Keith Seitz  <keiths@redhat.com> | ||||||
|  | 
 | ||||||
|  | 	* include/jvm.h (struct natThread): Add new field 'frame'. | ||||||
|  | 	* include/java-interp.h (_Jv_Frame): Use _Jv_ThreadStackPeek, | ||||||
|  | 	_Jv_ThreadStackPop, and _Jv_ThreadStackPush instead of | ||||||
|  | 	java.lang.Thread.frame. | ||||||
|  | 	(~_Jv_Frame): Use _Jv_ThreadStackPop. | ||||||
|  | 	* java/lang/natThread.cc (_Jv_ThreadStackPeek): New function. | ||||||
|  | 	(_Jv_ThreadStackPush): New function. | ||||||
|  | 	(_Jv_ThreadStackPop): New function. | ||||||
|  | 	* java/lang/Thread.java (frame): Remove field to restore | ||||||
|  | 	C++ ABI compatibility. | ||||||
|  | 	* gnu/classpath/jdwp/natVMVirtualMachine.cc (getFrames): Use | ||||||
|  | 	_Jv_ThreadStackPeek. | ||||||
|  | 	(getFrame): Likewise. | ||||||
|  | 	* gnu/classpath/jdwp/natVMFrame.cc (getFrameDepth): Likewise. | ||||||
|  | 	* jvmti.cc (getLocalFrame): Likewise. | ||||||
|  | 	(_Jv_JVMTI_GetFrameCount): Likewise. | ||||||
|  | 	(_Jv_JVMTI_GetThreadState): Likewise. | ||||||
|  | 	(_Jv_JVMTI_GetStackTrace): Likewise. | ||||||
|  | 	* interpret.cc (_Jv_ReportJVMTIExceptionThrow): Likewise. | ||||||
|  | 	* headers.txt (java/lang/Thread.h): Prepend declarations | ||||||
|  | 	for _Jv_ThreadStackPeek, _Jv_ThreadStackPush, and _Jv_ThreadStackPop. | ||||||
|  | 	Add as friend functions. | ||||||
|  | 	* jni.cc (_Jv_JNIMethod::call): Push a frame onto the stack when | ||||||
|  | 	calling a JNI method. | ||||||
|  | 
 | ||||||
|  | --- libjava/interpret.cc	(revision 128603)
 | ||||||
|  | +++ libjava/interpret.cc	(working copy)
 | ||||||
|  | @@ -1709,7 +1709,7 @@
 | ||||||
|  |  _Jv_ReportJVMTIExceptionThrow (jthrowable ex) | ||||||
|  |  { | ||||||
|  |    jthread thread = ::java::lang::Thread::currentThread (); | ||||||
|  | -  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
 | ||||||
|  | +  _Jv_Frame *frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |    jmethodID throw_meth = frame->self->get_method (); | ||||||
|  |    jlocation throw_loc = -1; | ||||||
|  |    if (frame->frame_type == frame_interpreter) | ||||||
|  | --- libjava/include/java-interp.h	(revision 128603)
 | ||||||
|  | +++ libjava/include/java-interp.h	(working copy)
 | ||||||
|  | @@ -391,14 +391,14 @@
 | ||||||
|  |    { | ||||||
|  |      self = s; | ||||||
|  |      frame_type = type; | ||||||
|  | -    next = (_Jv_Frame *) thr->frame;
 | ||||||
|  | -    thr->frame = (gnu::gcj::RawData *) this;
 | ||||||
|  | +    next = _Jv_ThreadStackPeek (thr);
 | ||||||
|  | +    _Jv_ThreadStackPush (thr, this);
 | ||||||
|  |      thread = thr; | ||||||
|  |    } | ||||||
|  |   | ||||||
|  |    ~_Jv_Frame () | ||||||
|  |    { | ||||||
|  | -    thread->frame = (gnu::gcj::RawData *) next;
 | ||||||
|  | +    _Jv_ThreadStackPop (thread);
 | ||||||
|  |    } | ||||||
|  |   | ||||||
|  |    int depth () | ||||||
|  | --- libjava/include/jvm.h	(revision 128603)
 | ||||||
|  | +++ libjava/include/jvm.h	(working copy)
 | ||||||
|  | @@ -34,6 +34,8 @@
 | ||||||
|  |   | ||||||
|  |  #include <sysdep/locks.h> | ||||||
|  |   | ||||||
|  | +class _Jv_Frame;
 | ||||||
|  | +
 | ||||||
|  |  /* Macro for possible unused arguments.  */ | ||||||
|  |  #define MAYBE_UNUSED __attribute__((__unused__)) | ||||||
|  |   | ||||||
|  | @@ -767,6 +769,12 @@
 | ||||||
|  |   | ||||||
|  |    // Each thread has its own JNI object. | ||||||
|  |    _Jv_JNIEnv *jni_env; | ||||||
|  | +
 | ||||||
|  | +  // Describes the topmost frame in the thread's composite
 | ||||||
|  | +  // (interp + JNI) stack. Added here to maintain C++ ABI
 | ||||||
|  | +  // compatibility with previous versions. Newer versions
 | ||||||
|  | +  // of gcj put this in java/lang/Thread.java.
 | ||||||
|  | +  _Jv_Frame *frame;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  #endif /* __JAVA_JVM_H__ */ | ||||||
|  | --- libjava/jni.cc	(revision 128603)
 | ||||||
|  | +++ libjava/jni.cc	(working copy)
 | ||||||
|  | @@ -2343,6 +2343,10 @@
 | ||||||
|  |    // Copy over passed-in arguments. | ||||||
|  |    memcpy (&real_args[offset], args, _this->args_raw_size); | ||||||
|  |   | ||||||
|  | +  // Add a frame to the composite (interpreted + JNI) call stack
 | ||||||
|  | +  java::lang::Thread *thread = java::lang::Thread::currentThread ();
 | ||||||
|  | +  _Jv_NativeFrame nat_frame (_this, thread);
 | ||||||
|  | +
 | ||||||
|  |    // The actual call to the JNI function. | ||||||
|  |  #if FFI_NATIVE_RAW_API | ||||||
|  |    ffi_raw_call (&_this->jni_cif, (void (*)()) _this->function, | ||||||
|  | --- libjava/jvmti.cc	(revision 128603)
 | ||||||
|  | +++ libjava/jvmti.cc	(working copy)
 | ||||||
|  | @@ -228,7 +228,7 @@
 | ||||||
|  |    THREAD_CHECK_VALID (thread); | ||||||
|  |    THREAD_CHECK_IS_ALIVE (thread); | ||||||
|  |     | ||||||
|  | -  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
 | ||||||
|  | +  _Jv_Frame *frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |     | ||||||
|  |    for (int i = 0; i < depth; i++) | ||||||
|  |      {     | ||||||
|  | @@ -516,7 +516,7 @@
 | ||||||
|  |    THREAD_CHECK_VALID (thread); | ||||||
|  |    THREAD_CHECK_IS_ALIVE (thread); | ||||||
|  |      | ||||||
|  | -  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
 | ||||||
|  | +  _Jv_Frame *frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |    (*frame_count) = frame->depth (); | ||||||
|  |    return JVMTI_ERROR_NONE; | ||||||
|  |  } | ||||||
|  | @@ -543,7 +543,7 @@
 | ||||||
|  |        if (thread->isInterrupted ()) | ||||||
|  |  	state |= JVMTI_THREAD_STATE_INTERRUPTED; | ||||||
|  |   | ||||||
|  | -      _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
 | ||||||
|  | +      _Jv_Frame *frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |        if (frame != NULL && frame->frame_type == frame_native) | ||||||
|  |  	state |= JVMTI_THREAD_STATE_IN_NATIVE; | ||||||
|  |   | ||||||
|  | @@ -1273,7 +1273,7 @@
 | ||||||
|  |    ILLEGAL_ARGUMENT (start_depth >= (*frame_count)); | ||||||
|  |    ILLEGAL_ARGUMENT (start_depth < (-(*frame_count))); | ||||||
|  |     | ||||||
|  | -  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
 | ||||||
|  | +  _Jv_Frame *frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |   | ||||||
|  |    // If start_depth is negative use this to determine at what depth to start | ||||||
|  |    // the trace by adding it to the length of the call stack.  This allows the | ||||||
|  | --- libjava/headers.txt	(revision 128603)
 | ||||||
|  | +++ libjava/headers.txt	(working copy)
 | ||||||
|  | @@ -6,6 +6,7 @@
 | ||||||
|  |   | ||||||
|  |  class java/lang/Thread | ||||||
|  |  prepend class _Jv_JNIEnv; | ||||||
|  | +prepend class _Jv_Frame;
 | ||||||
|  |  prepend #define _JV_NOT_OWNER 1 | ||||||
|  |  prepend #define _JV_INTERRUPTED 2 | ||||||
|  |  prepend _Jv_JNIEnv * _Jv_GetCurrentJNIEnv (); | ||||||
|  | @@ -17,6 +18,9 @@
 | ||||||
|  |  prepend jint _Jv_DetachCurrentThread (); | ||||||
|  |  prepend struct _Jv_Thread_t; | ||||||
|  |  prepend _Jv_Thread_t* _Jv_ThreadGetData (java::lang::Thread* thread); | ||||||
|  | +prepend _Jv_Frame *_Jv_ThreadStackPeek (java::lang::Thread *thread);
 | ||||||
|  | +prepend void _Jv_ThreadStackPush (java::lang::Thread *thread, _Jv_Frame *frame);
 | ||||||
|  | +prepend void _Jv_ThreadStackPop (java::lang::Thread *thread);
 | ||||||
|  |  friend _Jv_JNIEnv * ::_Jv_GetCurrentJNIEnv (); | ||||||
|  |  friend void ::_Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env); | ||||||
|  |  friend void ::_Jv_ThreadRun (java::lang::Thread* thread); | ||||||
|  | @@ -24,6 +28,9 @@
 | ||||||
|  |  friend java::lang::Thread* ::_Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group); | ||||||
|  |  friend java::lang::Thread* ::_Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group); | ||||||
|  |  friend jint (::_Jv_DetachCurrentThread) (); | ||||||
|  | +friend _Jv_Frame *::_Jv_ThreadStackPeek (java::lang::Thread *thread);
 | ||||||
|  | +friend void ::_Jv_ThreadStackPush (java::lang::Thread *thread, _Jv_Frame *frame);
 | ||||||
|  | +friend void ::_Jv_ThreadStackPop (java::lang::Thread *thread);
 | ||||||
|  |   | ||||||
|  |  class java/lang/String | ||||||
|  |  prepend jchar* _Jv_GetStringChars (jstring str); | ||||||
|  | --- libjava/gnu/classpath/jdwp/natVMFrame.cc	(revision 128603)
 | ||||||
|  | +++ libjava/gnu/classpath/jdwp/natVMFrame.cc	(working copy)
 | ||||||
|  | @@ -181,7 +181,7 @@
 | ||||||
|  |  getFrameDepth (_Jv_Frame *frame) | ||||||
|  |  { | ||||||
|  |    jint depth = 0; | ||||||
|  | -  _Jv_Frame *top_frame = (_Jv_Frame *) frame->thread->frame;
 | ||||||
|  | +  _Jv_Frame *top_frame = _Jv_ThreadStackPeek (frame->thread);
 | ||||||
|  |    jint num_frames = VMVirtualMachine::getFrameCount (frame->thread); | ||||||
|  |     | ||||||
|  |    while (frame != top_frame) | ||||||
|  | --- libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc	(revision 128603)
 | ||||||
|  | +++ libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc	(working copy)
 | ||||||
|  | @@ -553,7 +553,7 @@
 | ||||||
|  |        | ||||||
|  |    frame_list = new ::java::util::ArrayList (num_frames); | ||||||
|  |     | ||||||
|  | -  _Jv_Frame *vm_frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
 | ||||||
|  | +  _Jv_Frame *vm_frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |     | ||||||
|  |    // Take start frames off the top of the stack | ||||||
|  |    while (vm_frame != NULL && start > 0) | ||||||
|  | @@ -584,7 +584,7 @@
 | ||||||
|  |  { | ||||||
|  |    using namespace gnu::classpath::jdwp::exception; | ||||||
|  |     | ||||||
|  | -  _Jv_Frame *vm_frame = (_Jv_Frame *) thread->frame;
 | ||||||
|  | +  _Jv_Frame *vm_frame = _Jv_ThreadStackPeek (thread);
 | ||||||
|  |    jint depth = 0; | ||||||
|  |    _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (frameID);  | ||||||
|  |     | ||||||
|  | --- libjava/java/lang/Thread.java	(revision 128603)
 | ||||||
|  | +++ libjava/java/lang/Thread.java	(working copy)
 | ||||||
|  | @@ -186,9 +186,6 @@
 | ||||||
|  |    // This describes the top-most interpreter frame for this thread. | ||||||
|  |    RawData interp_frame; | ||||||
|  |     | ||||||
|  | -  // This describes the top most frame in the composite (interp + JNI) stack
 | ||||||
|  | -  RawData frame;
 | ||||||
|  | -
 | ||||||
|  |    // Current state. | ||||||
|  |    volatile int state; | ||||||
|  |   | ||||||
|  | --- libjava/java/lang/natThread.cc	(revision 128603)
 | ||||||
|  | +++ libjava/java/lang/natThread.cc	(working copy)
 | ||||||
|  | @@ -15,6 +15,7 @@
 | ||||||
|  |  #include <gcj/cni.h> | ||||||
|  |  #include <jvm.h> | ||||||
|  |  #include <java-threads.h> | ||||||
|  | +#include <java-interp.h>
 | ||||||
|  |   | ||||||
|  |  #include <gnu/gcj/RawDataManaged.h> | ||||||
|  |  #include <java/lang/Thread.h> | ||||||
|  | @@ -525,3 +526,25 @@
 | ||||||
|  |   | ||||||
|  |    return 0; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +_Jv_Frame *
 | ||||||
|  | +_Jv_ThreadStackPeek (java::lang::Thread *thread)
 | ||||||
|  | +{
 | ||||||
|  | +  struct natThread *nt = (natThread *) thread->data;
 | ||||||
|  | +  return nt->frame;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +_Jv_ThreadStackPush (java::lang::Thread *thread, _Jv_Frame *frame)
 | ||||||
|  | +{
 | ||||||
|  | +  struct natThread *nt = (natThread *) thread->data;
 | ||||||
|  | +  nt->frame = frame;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +_Jv_ThreadStackPop (java::lang::Thread *thread)
 | ||||||
|  | +{
 | ||||||
|  | +  struct natThread *nt = (natThread *) thread->data;
 | ||||||
|  | +  _Jv_Frame *next = nt->frame->next;
 | ||||||
|  | +  nt->frame = next;
 | ||||||
|  | +}
 | ||||||
| @ -1,54 +0,0 @@ | |||||||
| 2007-09-22  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* configure.ac (MAKEINFO): Handle makeinfo version 4.10 and above. |  | ||||||
| 	* configure: Regenerated. |  | ||||||
| 
 |  | ||||||
| 2007-09-15  Alan Modra  <amodra@bigpond.net.au> |  | ||||||
| 
 |  | ||||||
| 	* configure.in: Correct makeinfo version check. |  | ||||||
| 	* configure: Regenerate. |  | ||||||
| 
 |  | ||||||
| --- configure.in.jj	2007-02-20 16:41:55.000000000 -0500
 |  | ||||||
| +++ configure.in	2007-09-22 09:36:04.000000000 -0400
 |  | ||||||
| @@ -2159,7 +2159,7 @@ changequote(,)
 |  | ||||||
|      # For an installed makeinfo, we require it to be from texinfo 4.2 or |  | ||||||
|      # higher, else we use the "missing" dummy. |  | ||||||
|      if ${MAKEINFO} --version \ |  | ||||||
| -       | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|[5-9])' >/dev/null 2>&1; then
 |  | ||||||
| +       | egrep 'texinfo[^0-9]*(4\.([2-9]|[1-9][0-9])|[5-9]|[1-9][0-9])' >/dev/null 2>&1; then
 |  | ||||||
|        : |  | ||||||
|      else |  | ||||||
|        MAKEINFO="$MISSING makeinfo" |  | ||||||
| --- configure.jj	2007-02-20 16:41:55.000000000 -0500
 |  | ||||||
| +++ configure	2007-09-22 09:36:25.000000000 -0400
 |  | ||||||
| @@ -3574,7 +3574,7 @@ case " $build_configdirs " in
 |  | ||||||
|      # For an installed makeinfo, we require it to be from texinfo 4.2 or |  | ||||||
|      # higher, else we use the "missing" dummy. |  | ||||||
|      if ${MAKEINFO} --version \ |  | ||||||
| -       | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|[5-9])' >/dev/null 2>&1; then
 |  | ||||||
| +       | egrep 'texinfo[^0-9]*(4\.([2-9]|[1-9][0-9])|[5-9]|[1-9][0-9])' >/dev/null 2>&1; then
 |  | ||||||
|        : |  | ||||||
|      else |  | ||||||
|        MAKEINFO="$MISSING makeinfo" |  | ||||||
| --- gcc/configure.ac.jj	2007-02-20 16:39:12.000000000 -0500
 |  | ||||||
| +++ gcc/configure.ac	2007-09-22 08:38:07.000000000 -0400
 |  | ||||||
| @@ -833,7 +833,7 @@ MISSING="${CONFIG_SHELL-/bin/sh} $srcdir
 |  | ||||||
|  # that we can use it. |  | ||||||
|  gcc_AC_CHECK_PROG_VER(MAKEINFO, makeinfo, --version, |  | ||||||
|    [GNU texinfo.* \([0-9][0-9.]*\)], |  | ||||||
| -  [4.[2-9]*])
 |  | ||||||
| +  [4.[2-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
 |  | ||||||
|  if test $gcc_cv_prog_makeinfo_modern = no; then |  | ||||||
|    MAKEINFO="$MISSING makeinfo" |  | ||||||
|    AC_MSG_WARN([ |  | ||||||
| --- gcc/configure.jj	2007-02-20 16:39:12.000000000 -0500
 |  | ||||||
| +++ gcc/configure	2007-09-22 08:38:30.000000000 -0400
 |  | ||||||
| @@ -7496,7 +7496,7 @@ else
 |  | ||||||
|    echo "configure:7496: version of makeinfo is $ac_prog_version" >&5 |  | ||||||
|    case $ac_prog_version in |  | ||||||
|      '')     gcc_cv_prog_makeinfo_modern=no;; |  | ||||||
| -    4.[2-9]*)
 |  | ||||||
| +    4.[2-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*)
 |  | ||||||
|              gcc_cv_prog_makeinfo_modern=yes;; |  | ||||||
|      *)      gcc_cv_prog_makeinfo_modern=no;; |  | ||||||
|    esac |  | ||||||
| @ -1,82 +0,0 @@ | |||||||
| 2007-08-29  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* config/rs6000/rs6000.c (rs6000_emit_sync): For QI or HI mode |  | ||||||
| 	used_m, even if it is 32-bit aligned, adjust used_m MEM to have |  | ||||||
| 	SImode and update m.  Don't run gen_lowpart_common on arbitrary |  | ||||||
| 	memory address, force it to register first. |  | ||||||
| 
 |  | ||||||
| 	* gcc.dg/sync-2.c (AI_ALIGN): Define if not defined. |  | ||||||
| 	(AI): Add AI_ALIGN. |  | ||||||
| 	* gcc.dg/sync-3.c: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/config/rs6000/rs6000.c.jj	2007-08-27 14:56:36.000000000 +0200
 |  | ||||||
| +++ gcc/config/rs6000/rs6000.c	2007-08-29 22:15:41.000000000 +0200
 |  | ||||||
| @@ -12757,14 +12757,16 @@ rs6000_emit_sync (enum rtx_code code, en
 |  | ||||||
|  	    ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode); |  | ||||||
|   |  | ||||||
|  	  shift = GEN_INT (ishift); |  | ||||||
| +	  used_m = change_address (used_m, SImode, 0);
 |  | ||||||
|  	} |  | ||||||
|        else |  | ||||||
|  	{ |  | ||||||
|  	  rtx addrSI, aligned_addr; |  | ||||||
|  	  int shift_mask = mode == QImode ? 0x18 : 0x10; |  | ||||||
|   |  | ||||||
| -	  addrSI = force_reg (SImode, gen_lowpart_common (SImode,
 |  | ||||||
| -							  XEXP (used_m, 0)));
 |  | ||||||
| +	  addrSI = gen_lowpart_common (SImode,
 |  | ||||||
| +				       force_reg (Pmode, XEXP (used_m, 0)));
 |  | ||||||
| +	  addrSI = force_reg (SImode, addrSI);
 |  | ||||||
|  	  shift = gen_reg_rtx (SImode); |  | ||||||
|   |  | ||||||
|  	  emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3), |  | ||||||
| @@ -12777,14 +12779,14 @@ rs6000_emit_sync (enum rtx_code code, en
 |  | ||||||
|  				       1, OPTAB_LIB_WIDEN); |  | ||||||
|  	  used_m = change_address (used_m, SImode, aligned_addr); |  | ||||||
|  	  set_mem_align (used_m, 32); |  | ||||||
| -	  /* It's safe to keep the old alias set of USED_M, because
 |  | ||||||
| -	     the operation is atomic and only affects the original
 |  | ||||||
| -	     USED_M.  */
 |  | ||||||
| -	  if (GET_CODE (m) == NOT)
 |  | ||||||
| -	    m = gen_rtx_NOT (SImode, used_m);
 |  | ||||||
| -	  else
 |  | ||||||
| -	    m = used_m;
 |  | ||||||
|  	} |  | ||||||
| +      /* It's safe to keep the old alias set of USED_M, because
 |  | ||||||
| +	 the operation is atomic and only affects the original
 |  | ||||||
| +	 USED_M.  */
 |  | ||||||
| +      if (GET_CODE (m) == NOT)
 |  | ||||||
| +	m = gen_rtx_NOT (SImode, used_m);
 |  | ||||||
| +      else
 |  | ||||||
| +	m = used_m;
 |  | ||||||
|   |  | ||||||
|        if (GET_CODE (op) == NOT) |  | ||||||
|  	{ |  | ||||||
| --- gcc/testsuite/gcc.dg/sync-2.c.jj	2006-10-05 00:25:32.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/sync-2.c	2007-08-29 21:49:47.000000000 +0200
 |  | ||||||
| @@ -8,7 +8,11 @@
 |  | ||||||
|  extern void abort (void); |  | ||||||
|  extern void *memcpy (void *, const void *, __SIZE_TYPE__); |  | ||||||
|   |  | ||||||
| -static char AI[18];
 |  | ||||||
| +#ifndef AI_ALIGN
 |  | ||||||
| +#define AI_ALIGN
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
| +static char AI[18] AI_ALIGN;
 |  | ||||||
|  static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; |  | ||||||
|  static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; |  | ||||||
|   |  | ||||||
| --- gcc/testsuite/gcc.dg/sync-3.c.jj	2007-08-29 21:49:59.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/sync-3.c	2007-08-29 22:00:31.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,10 @@
 |  | ||||||
| +/* { dg-do run } */
 |  | ||||||
| +/* { dg-require-effective-target sync_char_short } */
 |  | ||||||
| +/* { dg-options "-O2" } */
 |  | ||||||
| +/* { dg-options "-march=i486 -O2" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 |  | ||||||
| +/* { dg-options "-mcpu=v9 -O2" { target sparc*-*-* } } */
 |  | ||||||
| +
 |  | ||||||
| +/* Test functionality of the intrinsics for 'short' and 'char'.  */
 |  | ||||||
| +
 |  | ||||||
| +#define AI_ALIGN __attribute__((__aligned__ (4)))
 |  | ||||||
| +#include "sync-2.c"
 |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| 2007-08-20  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* config/rs6000/tramp.asm: Include config.h. |  | ||||||
| 	Check __PIC__ or __pic__ macro instead of SHARED. |  | ||||||
| 
 |  | ||||||
| --- gcc/config/rs6000/tramp.asm.jj	2006-10-05 00:28:33.000000000 +0200
 |  | ||||||
| +++ gcc/config/rs6000/tramp.asm	2007-08-20 23:20:52.000000000 +0200
 |  | ||||||
| @@ -1,6 +1,6 @@
 |  | ||||||
|  /*  Special support for trampolines |  | ||||||
|   * |  | ||||||
| - *   Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
 |  | ||||||
| + *   Copyright (C) 1996, 1997, 2000, 2007 Free Software Foundation, Inc.
 |  | ||||||
|   *   Written By Michael Meissner |  | ||||||
|   *  |  | ||||||
|   * This file is free software; you can redistribute it and/or modify it |  | ||||||
| @@ -37,7 +37,8 @@
 |  | ||||||
|   |  | ||||||
|  	.file	"tramp.asm" |  | ||||||
|  	.section ".text" |  | ||||||
| -	#include "ppc-asm.h"
 |  | ||||||
| +#include "ppc-asm.h"
 |  | ||||||
| +#include "config.h"
 |  | ||||||
|   |  | ||||||
|  #ifndef __powerpc64__ |  | ||||||
|  	.type	trampoline_initial,@object |  | ||||||
| @@ -105,7 +106,7 @@ FUNC_START(__trampoline_setup)
 |  | ||||||
|  	blr |  | ||||||
|   |  | ||||||
|  .Labort: |  | ||||||
| -#if defined SHARED && defined HAVE_AS_REL16
 |  | ||||||
| +#if (defined __PIC__ || defined __pic__) && defined HAVE_AS_REL16
 |  | ||||||
|  	bcl	20,31,1f |  | ||||||
|  1:	mflr	r30 |  | ||||||
|  	addis	r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha |  | ||||||
							
								
								
									
										59
									
								
								gcc41-pr20880.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								gcc41-pr20880.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | 2006-11-24  Paul Thomas  <pault@gcc.gnu.org> | ||||||
|  | 
 | ||||||
|  | 	PR fortran/20880 | ||||||
|  | 	* parse.c (parse_interface): Error if procedure name is that of | ||||||
|  | 	encompassing scope. | ||||||
|  | 
 | ||||||
|  | 	* gfortran.dg/interface_3a.f90: New test. | ||||||
|  | 
 | ||||||
|  | --- gcc/fortran/parse.c	(revision 119172)
 | ||||||
|  | +++ gcc/fortran/parse.c	(revision 119173)
 | ||||||
|  | @@ -1694,6 +1694,7 @@ parse_interface (void)
 | ||||||
|  |    gfc_interface_info save; | ||||||
|  |    gfc_state_data s1, s2; | ||||||
|  |    gfc_statement st; | ||||||
|  | +  locus proc_locus;
 | ||||||
|  |   | ||||||
|  |    accept_statement (ST_INTERFACE); | ||||||
|  |   | ||||||
|  | @@ -1781,6 +1782,7 @@ loop:
 | ||||||
|  |    accept_statement (st); | ||||||
|  |    prog_unit = gfc_new_block; | ||||||
|  |    prog_unit->formal_ns = gfc_current_ns; | ||||||
|  | +  proc_locus = gfc_current_locus;
 | ||||||
|  |   | ||||||
|  |  decl: | ||||||
|  |    /* Read data declaration statements.  */ | ||||||
|  | @@ -1796,8 +1798,15 @@ decl:
 | ||||||
|  |   | ||||||
|  |    current_interface = save; | ||||||
|  |    gfc_add_interface (prog_unit); | ||||||
|  | -
 | ||||||
|  |    pop_state (); | ||||||
|  | +
 | ||||||
|  | +  if (current_interface.ns
 | ||||||
|  | +	&& current_interface.ns->proc_name
 | ||||||
|  | +	&& strcmp (current_interface.ns->proc_name->name,
 | ||||||
|  | +		   prog_unit->name) == 0)
 | ||||||
|  | +    gfc_error ("INTERFACE procedure '%s' at %L has the same name as the "
 | ||||||
|  | +	       "enclosing procedure", prog_unit->name, &proc_locus);
 | ||||||
|  | +
 | ||||||
|  |    goto loop; | ||||||
|  |   | ||||||
|  |  done: | ||||||
|  | --- gcc/testsuite/gfortran.dg/interface_3a.f90
 | ||||||
|  | +++ gcc/testsuite/gfortran.dg/interface_3a.f90
 | ||||||
|  | @@ -0,0 +1,13 @@
 | ||||||
|  | +! { dg-do compile }
 | ||||||
|  | +! Contributed by Joost VandeVondele  <jv244@cam.ac.uk>
 | ||||||
|  | +!
 | ||||||
|  | +! This was found whilst investigating => segfault
 | ||||||
|  | +subroutine thy_sub (a)
 | ||||||
|  | +  interface 
 | ||||||
|  | +    subroutine thy_sub (a) ! { dg-error "enclosing procedure" }
 | ||||||
|  | +      real a
 | ||||||
|  | +    end subroutine
 | ||||||
|  | +  end interface
 | ||||||
|  | +  real a
 | ||||||
|  | +  print *, a
 | ||||||
|  | +end subroutine
 | ||||||
| @ -1,63 +0,0 @@ | |||||||
| 2007-08-14  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	PR fortran/22244 |  | ||||||
| 	* Make-lang.in (fortran/trans-types.o): Depend on $(FLAGS_H). |  | ||||||
| 	* trans-types.c: Include flags.h. |  | ||||||
| 	(gfc_get_nodesc_array_type): Add TYPE_DECL TYPE_NAME with |  | ||||||
| 	correct bounds and dimensions for packed arrays. |  | ||||||
| 
 |  | ||||||
| --- gcc/fortran/Make-lang.in	(revision 127395)
 |  | ||||||
| +++ gcc/fortran/Make-lang.in	(working copy)
 |  | ||||||
| @@ -292,7 +292,7 @@ fortran/trans-decl.o: $(GFORTRAN_TRANS_D
 |  | ||||||
|    cgraph.h $(TARGET_H) function.h $(FLAGS_H) $(RTL_H) tree-gimple.h \ |  | ||||||
|    tree-dump.h |  | ||||||
|  fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h \ |  | ||||||
| -  real.h toplev.h $(TARGET_H)
 |  | ||||||
| +  real.h toplev.h $(TARGET_H) $(FLAGS_H)
 |  | ||||||
|  fortran/trans-const.o: $(GFORTRAN_TRANS_DEPS) |  | ||||||
|  fortran/trans-expr.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h |  | ||||||
|  fortran/trans-stmt.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h |  | ||||||
| --- gcc/fortran/trans-types.c	(revision 127395)
 |  | ||||||
| +++ gcc/fortran/trans-types.c	(working copy)
 |  | ||||||
| @@ -35,6 +35,7 @@ Software Foundation, 51 Franklin Street,
 |  | ||||||
|  #include "trans-types.h" |  | ||||||
|  #include "trans-const.h" |  | ||||||
|  #include "real.h" |  | ||||||
| +#include "flags.h"
 |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  #if (GFC_MAX_DIMENSIONS < 10) |  | ||||||
| @@ -1005,7 +1006,7 @@ gfc_get_nodesc_array_type (tree etype, g
 |  | ||||||
|      { |  | ||||||
|        /* Fill in the stride and bound components of the type.  */ |  | ||||||
|        if (known_stride) |  | ||||||
| -	tmp =  gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
 |  | ||||||
| +	tmp = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
 |  | ||||||
|        else |  | ||||||
|          tmp = NULL_TREE; |  | ||||||
|        GFC_TYPE_ARRAY_STRIDE (type, n) = tmp; |  | ||||||
| @@ -1103,6 +1104,24 @@ gfc_get_nodesc_array_type (tree etype, g
 |  | ||||||
|    mpz_clear (stride); |  | ||||||
|    mpz_clear (delta); |  | ||||||
|   |  | ||||||
| +  /* In debug info represent packed arrays as multi-dimensional
 |  | ||||||
| +     if they have rank > 1 and with proper bounds, instead of flat
 |  | ||||||
| +     arrays.  */
 |  | ||||||
| +  if (known_stride && write_symbols != NO_DEBUG)
 |  | ||||||
| +    {
 |  | ||||||
| +      tree gtype = etype, rtype, type_decl;
 |  | ||||||
| +
 |  | ||||||
| +      for (n = as->rank - 1; n >= 0; n--)
 |  | ||||||
| +	{
 |  | ||||||
| +	  rtype = build_range_type (gfc_array_index_type,
 |  | ||||||
| +				    GFC_TYPE_ARRAY_LBOUND (type, n),
 |  | ||||||
| +				    GFC_TYPE_ARRAY_UBOUND (type, n));
 |  | ||||||
| +	  gtype = build_array_type (gtype, rtype);
 |  | ||||||
| +	}
 |  | ||||||
| +      TYPE_NAME (type) = type_decl = build_decl (TYPE_DECL, NULL, gtype);
 |  | ||||||
| +      DECL_ORIGINAL_TYPE (type_decl) = gtype;
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|    if (packed < 3 || !known_stride) |  | ||||||
|      { |  | ||||||
|        /* For dummy arrays and automatic (heap allocated) arrays we |  | ||||||
| @ -1,84 +0,0 @@ | |||||||
| 2006-10-27  Jerry DeLisle  <jvdelisle@gcc.gnu.org> |  | ||||||
| 
 |  | ||||||
| 	PR fortran/27954 |  | ||||||
| 	* decl.c (gfc_free_data_all): New function to free all data structures |  | ||||||
| 	after errors in DATA statements and declarations. |  | ||||||
| 	(top_var_list): Use new function.(top_val_list): Use new function. |  | ||||||
| 	(gfc_match_data_decl): Use new function. |  | ||||||
| 
 |  | ||||||
| 	PR libgfortran/27954 |  | ||||||
| 	* gfortran.dg/error_recovery_2.f90: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/fortran/decl.c	(revision 118083)
 |  | ||||||
| +++ gcc/fortran/decl.c	(revision 118086)
 |  | ||||||
| @@ -128,6 +128,21 @@ gfc_free_data (gfc_data * p)
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| +/* Free all data in a namespace.  */
 |  | ||||||
| +static void
 |  | ||||||
| +gfc_free_data_all (gfc_namespace * ns)
 |  | ||||||
| +{
 |  | ||||||
| +  gfc_data *d;
 |  | ||||||
| +
 |  | ||||||
| +  for (;ns->data;)
 |  | ||||||
| +    {
 |  | ||||||
| +      d = ns->data->next;
 |  | ||||||
| +      gfc_free (ns->data);
 |  | ||||||
| +      ns->data = d;
 |  | ||||||
| +    }
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +
 |  | ||||||
|  static match var_element (gfc_data_variable *); |  | ||||||
|   |  | ||||||
|  /* Match a list of variables terminated by an iterator and a right |  | ||||||
| @@ -262,6 +277,7 @@ top_var_list (gfc_data * d)
 |  | ||||||
|   |  | ||||||
|  syntax: |  | ||||||
|    gfc_syntax_error (ST_DATA); |  | ||||||
| +  gfc_free_data_all (gfc_current_ns);
 |  | ||||||
|    return MATCH_ERROR; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -374,6 +390,7 @@ top_val_list (gfc_data * data)
 |  | ||||||
|   |  | ||||||
|  syntax: |  | ||||||
|    gfc_syntax_error (ST_DATA); |  | ||||||
| +  gfc_free_data_all (gfc_current_ns);
 |  | ||||||
|    return MATCH_ERROR; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -2368,6 +2385,8 @@ ok:
 |  | ||||||
|    gfc_error ("Syntax error in data declaration at %C"); |  | ||||||
|    m = MATCH_ERROR; |  | ||||||
|   |  | ||||||
| +  gfc_free_data_all (gfc_current_ns);
 |  | ||||||
| +
 |  | ||||||
|  cleanup: |  | ||||||
|    gfc_free_array_spec (current_as); |  | ||||||
|    current_as = NULL; |  | ||||||
| --- gcc/testsuite/gfortran.dg/error_recovery_2.f90	(revision 0)
 |  | ||||||
| +++ gcc/testsuite/gfortran.dg/error_recovery_2.f90	(revision 118086)
 |  | ||||||
| @@ -0,0 +1,21 @@
 |  | ||||||
| +! { dg-do compile }
 |  | ||||||
| +! PR27954 Internal compiler error on bad statements
 |  | ||||||
| +! Derived from test case submitted in PR.
 |  | ||||||
| +subroutine bad1
 |  | ||||||
| +  character*20 :: y, x 00  ! { dg-error "Syntax error" }
 |  | ||||||
| +  data  y /'abcdef'/, x /'jbnhjk'/ pp  ! { dg-error "Syntax error" }
 |  | ||||||
| +end subroutine bad1
 |  | ||||||
| +
 |  | ||||||
| +subroutine bad2
 |  | ||||||
| +  character*20 :: y, x 00  ! { dg-error "Syntax error" }
 |  | ||||||
| +  data  y /'abcdef'/, x /'jbnhjk'/ pp  ! { dg-error "Syntax error" }
 |  | ||||||
| +  print *, "basket case."
 |  | ||||||
| +end subroutine bad2
 |  | ||||||
| +
 |  | ||||||
| +subroutine bad3
 |  | ||||||
| +  implicit none
 |  | ||||||
| +  character*20 :: y, x 00  ! { dg-error "Syntax error" }
 |  | ||||||
| +  data  y /'abcdef'/, x /'jbnhjk'/ pp  ! { dg-error "Syntax error" }
 |  | ||||||
| +  print *, "basket case that segfaults without patch."
 |  | ||||||
| +end subroutine bad3
 |  | ||||||
| +
 |  | ||||||
| @ -1,44 +1,210 @@ | |||||||
| 2006-08-17  Jakub Jelinek  <jakub@redhat.com> | 2007-09-23  Jakub Jelinek  <jakub@redhat.com> | ||||||
| 
 | 
 | ||||||
| 	PR middle-end/28755 | 	PR middle-end/28755 | ||||||
| 	* expr.c (expand_expr_real_1) <case ARRAY_REF>: Make sure | 	* expr.c (expand_constructor): New function. | ||||||
| 	the const array field optimization doesn't create an extra constant | 	(expand_expr_real_1) <case CONSTRUCTOR>: Call it. | ||||||
| 	MEM. | 	(expand_expr_real_1) <case ARRAY_REF>: Call it if VALUE is | ||||||
|  | 	CONSTRUCTOR. | ||||||
| 
 | 
 | ||||||
| 	* gcc.dg/pr28755.c: New test. | 	* gcc.dg/pr28755.c: New test. | ||||||
| 
 | 
 | ||||||
| --- gcc/expr.c.jj	2006-08-09 17:54:03.000000000 +0200
 | --- gcc/expr.c	(revision 128684)
 | ||||||
| +++ gcc/expr.c	2006-08-17 13:00:33.000000000 +0200
 | +++ gcc/expr.c	(revision 128685)
 | ||||||
| @@ -7105,13 +7105,25 @@ expand_expr_real_1 (tree exp, rtx target
 | @@ -6435,6 +6435,89 @@ expand_expr_addr_expr (tree exp, rtx tar
 | ||||||
|  |    return result; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* Generate code for computing CONSTRUCTOR EXP.
 | ||||||
|  | +   An rtx for the computed value is returned.  If AVOID_TEMP_MEM
 | ||||||
|  | +   is TRUE, instead of creating a temporary variable in memory
 | ||||||
|  | +   NULL is returned and the caller needs to handle it differently.  */
 | ||||||
|  | +
 | ||||||
|  | +static rtx
 | ||||||
|  | +expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
 | ||||||
|  | +		    bool avoid_temp_mem)
 | ||||||
|  | +{
 | ||||||
|  | +  tree type = TREE_TYPE (exp);
 | ||||||
|  | +  enum machine_mode mode = TYPE_MODE (type);
 | ||||||
|  | +
 | ||||||
|  | +  /* Try to avoid creating a temporary at all.  This is possible
 | ||||||
|  | +     if all of the initializer is zero.
 | ||||||
|  | +     FIXME: try to handle all [0..255] initializers we can handle
 | ||||||
|  | +     with memset.  */
 | ||||||
|  | +  if (TREE_STATIC (exp)
 | ||||||
|  | +      && !TREE_ADDRESSABLE (exp)
 | ||||||
|  | +      && target != 0 && mode == BLKmode
 | ||||||
|  | +      && all_zeros_p (exp))
 | ||||||
|  | +    {
 | ||||||
|  | +      clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
 | ||||||
|  | +      return target;
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +  /* All elts simple constants => refer to a constant in memory.  But
 | ||||||
|  | +     if this is a non-BLKmode mode, let it store a field at a time
 | ||||||
|  | +     since that should make a CONST_INT or CONST_DOUBLE when we
 | ||||||
|  | +     fold.  Likewise, if we have a target we can use, it is best to
 | ||||||
|  | +     store directly into the target unless the type is large enough
 | ||||||
|  | +     that memcpy will be used.  If we are making an initializer and
 | ||||||
|  | +     all operands are constant, put it in memory as well.
 | ||||||
|  | +
 | ||||||
|  | +     FIXME: Avoid trying to fill vector constructors piece-meal.
 | ||||||
|  | +     Output them with output_constant_def below unless we're sure
 | ||||||
|  | +     they're zeros.  This should go away when vector initializers
 | ||||||
|  | +     are treated like VECTOR_CST instead of arrays.  */
 | ||||||
|  | +  if ((TREE_STATIC (exp)
 | ||||||
|  | +       && ((mode == BLKmode
 | ||||||
|  | +	    && ! (target != 0 && safe_from_p (target, exp, 1)))
 | ||||||
|  | +		  || TREE_ADDRESSABLE (exp)
 | ||||||
|  | +		  || (host_integerp (TYPE_SIZE_UNIT (type), 1)
 | ||||||
|  | +		      && (! MOVE_BY_PIECES_P
 | ||||||
|  | +				     (tree_low_cst (TYPE_SIZE_UNIT (type), 1),
 | ||||||
|  | +				      TYPE_ALIGN (type)))
 | ||||||
|  | +		      && ! mostly_zeros_p (exp))))
 | ||||||
|  | +      || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
 | ||||||
|  | +	  && TREE_CONSTANT (exp)))
 | ||||||
|  | +    {
 | ||||||
|  | +      rtx constructor;
 | ||||||
|  | +
 | ||||||
|  | +      if (avoid_temp_mem)
 | ||||||
|  | +	return NULL_RTX;
 | ||||||
|  | +
 | ||||||
|  | +      constructor = output_constant_def (exp, 1);
 | ||||||
|  | +
 | ||||||
|  | +      if (modifier != EXPAND_CONST_ADDRESS
 | ||||||
|  | +	  && modifier != EXPAND_INITIALIZER
 | ||||||
|  | +	  && modifier != EXPAND_SUM)
 | ||||||
|  | +	constructor = validize_mem (constructor);
 | ||||||
|  | +
 | ||||||
|  | +      return constructor;
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +  /* Handle calls that pass values in multiple non-contiguous
 | ||||||
|  | +     locations.  The Irix 6 ABI has examples of this.  */
 | ||||||
|  | +  if (target == 0 || ! safe_from_p (target, exp, 1)
 | ||||||
|  | +      || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM)
 | ||||||
|  | +    {
 | ||||||
|  | +      if (avoid_temp_mem)
 | ||||||
|  | +	return NULL_RTX;
 | ||||||
|  | +
 | ||||||
|  | +      target
 | ||||||
|  | +	= assign_temp (build_qualified_type (type, (TYPE_QUALS (type)
 | ||||||
|  | +						    | (TREE_READONLY (exp)
 | ||||||
|  | +						       * TYPE_QUAL_CONST))),
 | ||||||
|  | +		       0, TREE_ADDRESSABLE (exp), 1);
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +  store_constructor (exp, target, 0, int_expr_size (exp));
 | ||||||
|  | +  return target;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |   | ||||||
|  |  /* expand_expr: generate code for computing expression EXP. | ||||||
|  |     An rtx for the computed value is returned.  The value is never null. | ||||||
|  | @@ -6899,71 +6982,7 @@ expand_expr_real_1 (tree exp, rtx target
 | ||||||
|  |  	  return const0_rtx; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -      /* Try to avoid creating a temporary at all.  This is possible
 | ||||||
|  | -	 if all of the initializer is zero.
 | ||||||
|  | -	 FIXME: try to handle all [0..255] initializers we can handle
 | ||||||
|  | -	 with memset.  */
 | ||||||
|  | -      else if (TREE_STATIC (exp)
 | ||||||
|  | -	       && !TREE_ADDRESSABLE (exp)
 | ||||||
|  | -	       && target != 0 && mode == BLKmode
 | ||||||
|  | -	       && all_zeros_p (exp))
 | ||||||
|  | -	{
 | ||||||
|  | -	  clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
 | ||||||
|  | -	  return target;
 | ||||||
|  | -	}
 | ||||||
|  | -
 | ||||||
|  | -      /* All elts simple constants => refer to a constant in memory.  But
 | ||||||
|  | -	 if this is a non-BLKmode mode, let it store a field at a time
 | ||||||
|  | -	 since that should make a CONST_INT or CONST_DOUBLE when we
 | ||||||
|  | -	 fold.  Likewise, if we have a target we can use, it is best to
 | ||||||
|  | -	 store directly into the target unless the type is large enough
 | ||||||
|  | -	 that memcpy will be used.  If we are making an initializer and
 | ||||||
|  | -	 all operands are constant, put it in memory as well.
 | ||||||
|  | -
 | ||||||
|  | -	FIXME: Avoid trying to fill vector constructors piece-meal.
 | ||||||
|  | -	Output them with output_constant_def below unless we're sure
 | ||||||
|  | -	they're zeros.  This should go away when vector initializers
 | ||||||
|  | -	are treated like VECTOR_CST instead of arrays.
 | ||||||
|  | -      */
 | ||||||
|  | -      else if ((TREE_STATIC (exp)
 | ||||||
|  | -		&& ((mode == BLKmode
 | ||||||
|  | -		     && ! (target != 0 && safe_from_p (target, exp, 1)))
 | ||||||
|  | -		    || TREE_ADDRESSABLE (exp)
 | ||||||
|  | -		    || (host_integerp (TYPE_SIZE_UNIT (type), 1)
 | ||||||
|  | -			&& (! MOVE_BY_PIECES_P
 | ||||||
|  | -			    (tree_low_cst (TYPE_SIZE_UNIT (type), 1),
 | ||||||
|  | -			     TYPE_ALIGN (type)))
 | ||||||
|  | -			&& ! mostly_zeros_p (exp))))
 | ||||||
|  | -	       || ((modifier == EXPAND_INITIALIZER
 | ||||||
|  | -		    || modifier == EXPAND_CONST_ADDRESS)
 | ||||||
|  | -		   && TREE_CONSTANT (exp)))
 | ||||||
|  | -	{
 | ||||||
|  | -	  rtx constructor = output_constant_def (exp, 1);
 | ||||||
|  | -
 | ||||||
|  | -	  if (modifier != EXPAND_CONST_ADDRESS
 | ||||||
|  | -	      && modifier != EXPAND_INITIALIZER
 | ||||||
|  | -	      && modifier != EXPAND_SUM)
 | ||||||
|  | -	    constructor = validize_mem (constructor);
 | ||||||
|  | -
 | ||||||
|  | -	  return constructor;
 | ||||||
|  | -	}
 | ||||||
|  | -      else
 | ||||||
|  | -	{
 | ||||||
|  | -	  /* Handle calls that pass values in multiple non-contiguous
 | ||||||
|  | -	     locations.  The Irix 6 ABI has examples of this.  */
 | ||||||
|  | -	  if (target == 0 || ! safe_from_p (target, exp, 1)
 | ||||||
|  | -	      || GET_CODE (target) == PARALLEL
 | ||||||
|  | -	      || modifier == EXPAND_STACK_PARM)
 | ||||||
|  | -	    target
 | ||||||
|  | -	      = assign_temp (build_qualified_type (type,
 | ||||||
|  | -						   (TYPE_QUALS (type)
 | ||||||
|  | -						    | (TREE_READONLY (exp)
 | ||||||
|  | -						       * TYPE_QUAL_CONST))),
 | ||||||
|  | -			     0, TREE_ADDRESSABLE (exp), 1);
 | ||||||
|  | -
 | ||||||
|  | -	  store_constructor (exp, target, 0, int_expr_size (exp));
 | ||||||
|  | -	  return target;
 | ||||||
|  | -	}
 | ||||||
|  | +      return expand_constructor (exp, target, modifier, false);
 | ||||||
|  |   | ||||||
|  |      case MISALIGNED_INDIRECT_REF: | ||||||
|  |      case ALIGN_INDIRECT_REF: | ||||||
|  | @@ -7105,10 +7124,25 @@ expand_expr_real_1 (tree exp, rtx target
 | ||||||
|  					      field, value) |  					      field, value) | ||||||
|  		      if (tree_int_cst_equal (field, index)) |  		      if (tree_int_cst_equal (field, index)) | ||||||
|  			{ |  			{ | ||||||
| -			  if (!TREE_SIDE_EFFECTS (value))
 | -			  if (!TREE_SIDE_EFFECTS (value))
 | ||||||
|  | -			    return expand_expr (fold (value), target, tmode,
 | ||||||
|  | -						modifier);
 | ||||||
|  | -			  break;
 | ||||||
| +			  if (TREE_SIDE_EFFECTS (value))
 | +			  if (TREE_SIDE_EFFECTS (value))
 | ||||||
| +			    break;
 | +			    break;
 | ||||||
| +
 | +
 | ||||||
| +			  if (TREE_CODE (value) != CONSTRUCTOR)
 | +			  if (TREE_CODE (value) == CONSTRUCTOR)
 | ||||||
|  			    return expand_expr (fold (value), target, tmode, | +			    {
 | ||||||
|  						modifier); | +			      /* If VALUE is a CONSTRUCTOR, this
 | ||||||
|  | +				 optimization is only useful if
 | ||||||
|  | +				 this doesn't store the CONSTRUCTOR
 | ||||||
|  | +				 into memory.  If it does, it is more
 | ||||||
|  | +				 efficient to just load the data from
 | ||||||
|  | +				 the array directly.  */
 | ||||||
|  | +			      rtx ret = expand_constructor (value, target,
 | ||||||
|  | +							    modifier, true);
 | ||||||
|  | +			      if (ret == NULL_RTX)
 | ||||||
|  | +				break;
 | ||||||
|  | +			    }
 | ||||||
| +
 | +
 | ||||||
| +			  /* For CONSTRUCTOR this optimization is not always
 | +			  return expand_expr (fold (value), target, tmode,
 | ||||||
| +			     a win - if expand_expr creates a temporary
 | +					      modifier);
 | ||||||
| +			     constant, we just waste unnecessarily rodata
 |  | ||||||
| +			     space.  */
 |  | ||||||
| +			  temp = expand_expr (value, target, tmode, modifier);
 |  | ||||||
| +			  if (temp == target
 |  | ||||||
| +			      || (temp && GET_CODE (temp) != MEM))
 |  | ||||||
| +			    return temp;
 |  | ||||||
|  			  break; |  | ||||||
|  			} |  			} | ||||||
|  		  } |  		  } | ||||||
| -		else if(TREE_CODE (init) == STRING_CST)
 |  		else if(TREE_CODE (init) == STRING_CST) | ||||||
| +		else if (TREE_CODE (init) == STRING_CST)
 | --- gcc/testsuite/gcc.dg/pr28755.c	(revision 0)
 | ||||||
|  		  { | +++ gcc/testsuite/gcc.dg/pr28755.c	(revision 128685)
 | ||||||
|  		    tree index1 = index; |  | ||||||
|  		    tree low_bound = array_ref_low_bound (exp); |  | ||||||
| --- gcc/testsuite/gcc.dg/pr28755.c.jj	2006-08-17 12:59:57.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/pr28755.c	2006-08-17 12:59:57.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,22 @@
 | @@ -0,0 +1,22 @@
 | ||||||
| +/* PR middle-end/28755 */
 | +/* PR middle-end/28755 */
 | ||||||
| +/* { dg-do compile } */
 | +/* { dg-do compile } */
 | ||||||
|  | |||||||
| @ -1,63 +0,0 @@ | |||||||
| 2007-07-21  Jerry DeLisle  <jvdelisle@gcc.gnu.org> |  | ||||||
| 
 |  | ||||||
| 	PR libgfortran/32678 |  | ||||||
| 	* io/transfer.c (formatted_transfer_scalar): Fix off by one error in |  | ||||||
| 	calculation of pos and skips. Don't allow pending_spaces to go |  | ||||||
| 	negative. |  | ||||||
| 
 |  | ||||||
| 	PR fortran/32678 |  | ||||||
| 	* gfortran.dg/fmt_t_5.f90: New test. |  | ||||||
| 
 |  | ||||||
| --- libgfortran/io/transfer.c	(revision 126821)
 |  | ||||||
| +++ libgfortran/io/transfer.c	(revision 126823)
 |  | ||||||
| @@ -893,9 +893,9 @@ formatted_transfer_scalar (st_parameter_
 |  | ||||||
|  	case FMT_TR: |  | ||||||
|  	  consume_data_flag = 0 ; |  | ||||||
|   |  | ||||||
| -	  pos = bytes_used + f->u.n + dtp->u.p.skips;
 |  | ||||||
| -	  dtp->u.p.skips = f->u.n + dtp->u.p.skips;
 |  | ||||||
| -	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos;
 |  | ||||||
| +	  dtp->u.p.skips += f->u.n;
 |  | ||||||
| +	  pos = bytes_used + dtp->u.p.skips - 1;
 |  | ||||||
| +	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
 |  | ||||||
|   |  | ||||||
|  	  /* Writes occur just before the switch on f->format, above, so |  | ||||||
|  	     that trailing blanks are suppressed, unless we are doing a |  | ||||||
| @@ -922,8 +922,6 @@ formatted_transfer_scalar (st_parameter_
 |  | ||||||
|  	      if (bytes_used == 0) |  | ||||||
|  		{ |  | ||||||
|  		  dtp->u.p.pending_spaces -= f->u.n; |  | ||||||
| -		  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? 0
 |  | ||||||
| -					    : dtp->u.p.pending_spaces;
 |  | ||||||
|  		  dtp->u.p.skips -= f->u.n; |  | ||||||
|  		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips; |  | ||||||
|  		} |  | ||||||
| @@ -945,6 +943,8 @@ formatted_transfer_scalar (st_parameter_
 |  | ||||||
|  	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used; |  | ||||||
|  	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces |  | ||||||
|  				    + pos - dtp->u.p.max_pos; |  | ||||||
| +	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
 |  | ||||||
| +				    ? 0 : dtp->u.p.pending_spaces;
 |  | ||||||
|   |  | ||||||
|  	  if (dtp->u.p.skips == 0) |  | ||||||
|  	    break; |  | ||||||
| --- gcc/testsuite/gfortran.dg/fmt_t_5.f90	(revision 126821)
 |  | ||||||
| +++ gcc/testsuite/gfortran.dg/fmt_t_5.f90	(revision 126823)
 |  | ||||||
| @@ -0,0 +1,17 @@
 |  | ||||||
| +! { dg-do run }
 |  | ||||||
| +! PR32678 GFortan works incorrectly when writing with FORMAT Tx
 |  | ||||||
| +! Before patch, NULLs were inserted in output.
 |  | ||||||
| +! Test case from reporter enhanced to detect this problem.
 |  | ||||||
| +      character(25) :: output
 |  | ||||||
| +      character(1)  :: c
 |  | ||||||
| +      output = ""
 |  | ||||||
| +      open (unit=10, file="pr32678testfile", status="replace")
 |  | ||||||
| +      write (10,10) '12','a','b'
 |  | ||||||
| +      close (10, status="keep")
 |  | ||||||
| +      open (unit=10, file="pr32678testfile")
 |  | ||||||
| +      read(10,20) output(1:21)
 |  | ||||||
| +      if (output(1:21).ne."ab                  x") call abort
 |  | ||||||
| +      close (10, status="delete")
 |  | ||||||
| + 10   format (a2,t1,a1,t2,a1,t20,' x')
 |  | ||||||
| + 20   format (a21)
 |  | ||||||
| +      end
 |  | ||||||
							
								
								
									
										46
									
								
								gcc41-pr32694.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								gcc41-pr32694.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | 2007-09-25  Jakub Jelinek  <jakub@redhat.com> | ||||||
|  | 
 | ||||||
|  | 	PR tree-optimization/32694 | ||||||
|  | 	2006-11-08  Roger Sayle  <roger@eyesopen.com> | ||||||
|  | 	* tree-ssa-propagate.c (set_rhs): Verify tcc_comparison the same way | ||||||
|  | 	as tcc_binary. | ||||||
|  | 
 | ||||||
|  | 	* gcc.c-torture/compile/20070925-1.c: New test. | ||||||
|  | 
 | ||||||
|  | --- gcc/tree-ssa-propagate.c.jj	2007-09-23 19:43:36.000000000 +0200
 | ||||||
|  | +++ gcc/tree-ssa-propagate.c	2007-09-25 09:30:50.000000000 +0200
 | ||||||
|  | @@ -570,7 +570,8 @@ set_rhs (tree *stmt_p, tree expr)
 | ||||||
|  |    ssa_op_iter iter; | ||||||
|  |   | ||||||
|  |    /* Verify the constant folded result is valid gimple.  */ | ||||||
|  | -  if (TREE_CODE_CLASS (code) == tcc_binary)
 | ||||||
|  | +  if (TREE_CODE_CLASS (code) == tcc_binary
 | ||||||
|  | +      || TREE_CODE_CLASS (code) == tcc_comparison)
 | ||||||
|  |      { | ||||||
|  |        if (!is_gimple_val (TREE_OPERAND (expr, 0)) | ||||||
|  |  	  || !is_gimple_val (TREE_OPERAND (expr, 1))) | ||||||
|  | --- gcc/testsuite/gcc.c-torture/compile/20070925-1.c.jj	2007-09-25 09:28:37.000000000 +0200
 | ||||||
|  | +++ gcc/testsuite/gcc.c-torture/compile/20070925-1.c	2007-09-25 09:29:41.000000000 +0200
 | ||||||
|  | @@ -0,0 +1,22 @@
 | ||||||
|  | +/* PR tree-optimization/32694 */
 | ||||||
|  | +
 | ||||||
|  | +typedef signed long long int WordS64;
 | ||||||
|  | +typedef unsigned long long int Word64;
 | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +foo (Word64 * p)
 | ||||||
|  | +{
 | ||||||
|  | +  while (1)
 | ||||||
|  | +    {
 | ||||||
|  | +      WordS64 c = 0x1llu;
 | ||||||
|  | +      WordS64 x = *p;
 | ||||||
|  | +      if (c >= 0)
 | ||||||
|  | +	{
 | ||||||
|  | +	  if (x > (WordS64) 0x7FFFFFFFFFFFFFFFll - c)
 | ||||||
|  | +	    return 6;
 | ||||||
|  | +	}
 | ||||||
|  | +      else if (x < (WordS64) 0x8000000000000000ll - c)
 | ||||||
|  | +	return 7;
 | ||||||
|  | +      p++;
 | ||||||
|  | +    }
 | ||||||
|  | +}
 | ||||||
| @ -1,138 +0,0 @@ | |||||||
| 2007-08-20  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	PR middle-end/32912 |  | ||||||
| 	* fold-const.c (fold_binary): Only optimize X | ~X and X ^ ~X for |  | ||||||
| 	integral types. |  | ||||||
| 
 |  | ||||||
| 	* gcc.dg/pr32912-1.c: New test. |  | ||||||
| 	* gcc.dg/pr32912-2.c: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/fold-const.c.jj	2007-08-13 15:11:18.000000000 +0200
 |  | ||||||
| +++ gcc/fold-const.c	2007-08-20 15:49:05.000000000 +0200
 |  | ||||||
| @@ -8079,6 +8079,7 @@ fold_binary (enum tree_code code, tree t
 |  | ||||||
|   |  | ||||||
|        /* ~X | X is -1.  */ |  | ||||||
|        if (TREE_CODE (arg0) == BIT_NOT_EXPR |  | ||||||
| +	  && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
 |  | ||||||
|  	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) |  | ||||||
|  	{ |  | ||||||
|  	  t1 = build_int_cst (type, -1); |  | ||||||
| @@ -8088,6 +8089,7 @@ fold_binary (enum tree_code code, tree t
 |  | ||||||
|   |  | ||||||
|        /* X | ~X is -1.  */ |  | ||||||
|        if (TREE_CODE (arg1) == BIT_NOT_EXPR |  | ||||||
| +	  && INTEGRAL_TYPE_P (TREE_TYPE (arg0))
 |  | ||||||
|  	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) |  | ||||||
|  	{ |  | ||||||
|  	  t1 = build_int_cst (type, -1); |  | ||||||
| @@ -8175,6 +8177,7 @@ fold_binary (enum tree_code code, tree t
 |  | ||||||
|   |  | ||||||
|        /* ~X ^ X is -1.  */ |  | ||||||
|        if (TREE_CODE (arg0) == BIT_NOT_EXPR |  | ||||||
| +	  && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
 |  | ||||||
|  	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) |  | ||||||
|  	{ |  | ||||||
|  	  t1 = build_int_cst (type, -1); |  | ||||||
| @@ -8184,6 +8187,7 @@ fold_binary (enum tree_code code, tree t
 |  | ||||||
|   |  | ||||||
|        /* X ^ ~X is -1.  */ |  | ||||||
|        if (TREE_CODE (arg1) == BIT_NOT_EXPR |  | ||||||
| +	  && INTEGRAL_TYPE_P (TREE_TYPE (arg0))
 |  | ||||||
|  	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) |  | ||||||
|  	{ |  | ||||||
|  	  t1 = build_int_cst (type, -1); |  | ||||||
| --- gcc/testsuite/gcc.dg/pr32912-1.c.jj	2007-08-20 14:43:05.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/pr32912-1.c	2007-08-20 14:43:23.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,44 @@
 |  | ||||||
| +/* PR middle-end/32912 */
 |  | ||||||
| +/* { dg-do run } */
 |  | ||||||
| +/* { dg-options "-O2 -w" } */
 |  | ||||||
| +
 |  | ||||||
| +extern void abort (void);
 |  | ||||||
| +
 |  | ||||||
| +typedef int __m128i __attribute__ ((__vector_size__ (16)));
 |  | ||||||
| +
 |  | ||||||
| +__m128i a, b, c, d, e, f;
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +foo (__m128i x)
 |  | ||||||
| +{
 |  | ||||||
| +  a = x ^ ~x;
 |  | ||||||
| +  b = ~x ^ x;
 |  | ||||||
| +  c = x | ~x;
 |  | ||||||
| +  d = ~x | x;
 |  | ||||||
| +  e = x & ~x;
 |  | ||||||
| +  f = ~x & x;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  union { __m128i v; int i[sizeof (__m128i) / sizeof (int)]; } u;
 |  | ||||||
| +  int i;
 |  | ||||||
| +
 |  | ||||||
| +  for (i = 0; i < sizeof (u.i) / sizeof (u.i[0]); i++)
 |  | ||||||
| +    u.i[i] = i * 49 - 36;
 |  | ||||||
| +  foo (u.v);
 |  | ||||||
| +#define check(x, val) \
 |  | ||||||
| +  u.v = (x); \
 |  | ||||||
| +  for (i = 0; i < sizeof (u.i) / sizeof (u.i[0]); i++) \
 |  | ||||||
| +    if (u.i[i] != (val)) \
 |  | ||||||
| +      abort ()
 |  | ||||||
| +
 |  | ||||||
| +  check (a, ~0);
 |  | ||||||
| +  check (b, ~0);
 |  | ||||||
| +  check (c, ~0);
 |  | ||||||
| +  check (d, ~0);
 |  | ||||||
| +  check (e, 0);
 |  | ||||||
| +  check (f, 0);
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/gcc.dg/pr32912-2.c.jj	2007-08-20 15:58:47.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/pr32912-2.c	2007-08-20 15:55:32.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,45 @@
 |  | ||||||
| +/* { dg-do run } */
 |  | ||||||
| +/* { dg-options "-O2 -w" } */
 |  | ||||||
| +
 |  | ||||||
| +extern void abort (void);
 |  | ||||||
| +
 |  | ||||||
| +typedef int __m128i __attribute__ ((__vector_size__ (16)));
 |  | ||||||
| +
 |  | ||||||
| +__m128i a, b, c, d, e, f;
 |  | ||||||
| +
 |  | ||||||
| +__m128i
 |  | ||||||
| +foo (void)
 |  | ||||||
| +{
 |  | ||||||
| +  __m128i x = { 0x11111111, 0x22222222, 0x44444444 };
 |  | ||||||
| +  return x;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +__m128i
 |  | ||||||
| +bar (void)
 |  | ||||||
| +{
 |  | ||||||
| +  __m128i x = { 0x11111111, 0x22222222, 0x44444444 };
 |  | ||||||
| +  return ~x;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +main (void)
 |  | ||||||
| +{
 |  | ||||||
| +  union { __m128i v; int i[sizeof (__m128i) / sizeof (int)]; } u, v;
 |  | ||||||
| +  int i;
 |  | ||||||
| +
 |  | ||||||
| +  u.v = foo ();
 |  | ||||||
| +  v.v = bar ();
 |  | ||||||
| +  for (i = 0; i < sizeof (u.i) / sizeof (u.i[0]); i++)
 |  | ||||||
| +    {
 |  | ||||||
| +      if (u.i[i] != ~v.i[i])
 |  | ||||||
| +	abort ();
 |  | ||||||
| +      if (i < 3)
 |  | ||||||
| +	{
 |  | ||||||
| +	  if (u.i[i] != (0x11111111 << i))
 |  | ||||||
| +	    abort ();
 |  | ||||||
| +	}
 |  | ||||||
| +      else if (u.i[i])
 |  | ||||||
| +	abort ();
 |  | ||||||
| +    }
 |  | ||||||
| +  return 0;
 |  | ||||||
| +}
 |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| 2007-09-15  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	PR middle-end/33423 |  | ||||||
| 	* builtins.c (expand_builtin_memory_chk): Handle COMPOUND_EXPRs |  | ||||||
| 	returned by build_call_expr. |  | ||||||
| 
 |  | ||||||
| 	* gcc.c-torture/compile/20070915-1.c: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/builtins.c.jj	2007-09-14 21:07:41.000000000 +0200
 |  | ||||||
| +++ gcc/builtins.c	2007-09-16 22:31:40.000000000 +0200
 |  | ||||||
| @@ -10383,6 +10383,13 @@ expand_builtin_memory_chk (tree exp, rtx
 |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
|        fn = build_function_call_expr (fn, arglist); |  | ||||||
| +      STRIP_TYPE_NOPS (fn);
 |  | ||||||
| +      while (TREE_CODE (fn) == COMPOUND_EXPR)
 |  | ||||||
| +	{
 |  | ||||||
| +	  expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
 |  | ||||||
| +		       EXPAND_NORMAL);
 |  | ||||||
| +	  fn = TREE_OPERAND (fn, 1);
 |  | ||||||
| +	}
 |  | ||||||
|        if (TREE_CODE (fn) == CALL_EXPR) |  | ||||||
|  	CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); |  | ||||||
|        return expand_expr (fn, target, mode, EXPAND_NORMAL); |  | ||||||
| @@ -10432,6 +10439,13 @@ expand_builtin_memory_chk (tree exp, rtx
 |  | ||||||
|  	      if (!fn) |  | ||||||
|  		return 0; |  | ||||||
|  	      fn = build_function_call_expr (fn, arglist); |  | ||||||
| +	      STRIP_TYPE_NOPS (fn);
 |  | ||||||
| +	      while (TREE_CODE (fn) == COMPOUND_EXPR)
 |  | ||||||
| +		{
 |  | ||||||
| +		  expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
 |  | ||||||
| +			       EXPAND_NORMAL);
 |  | ||||||
| +		  fn = TREE_OPERAND (fn, 1);
 |  | ||||||
| +		}
 |  | ||||||
|  	      if (TREE_CODE (fn) == CALL_EXPR) |  | ||||||
|  		CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); |  | ||||||
|  	      return expand_expr (fn, target, mode, EXPAND_NORMAL); |  | ||||||
| --- gcc/testsuite/gcc.c-torture/compile/20070915-1.c.jj	2007-09-16 22:29:37.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.c-torture/compile/20070915-1.c	2007-09-16 22:29:37.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,20 @@
 |  | ||||||
| +/* PR middle-end/33423 */
 |  | ||||||
| +
 |  | ||||||
| +static struct
 |  | ||||||
| +{
 |  | ||||||
| +  char buf[15];
 |  | ||||||
| +} u2;
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +test6 (void)
 |  | ||||||
| +{
 |  | ||||||
| +  int len;
 |  | ||||||
| +  char *p;
 |  | ||||||
| +
 |  | ||||||
| +  for (len = 0; len < 2; len++)
 |  | ||||||
| +    {
 |  | ||||||
| +      p = __builtin___memset_chk (u2.buf, '\0', len, 15);
 |  | ||||||
| +      if (p != u2.buf)
 |  | ||||||
| +	return;
 |  | ||||||
| +    }
 |  | ||||||
| +}
 |  | ||||||
| @ -1,89 +0,0 @@ | |||||||
| 2007-08-17  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* decl.c (variable_decl): Don't share charlen structs if |  | ||||||
| 	length == NULL. |  | ||||||
| 	* trans-decl.c (create_function_arglist): Assert |  | ||||||
| 	f->sym->ts.cl->backend_decl is NULL instead of unsharing |  | ||||||
| 	charlen struct here. |  | ||||||
| 
 |  | ||||||
| 	* gfortran.dg/assumed_charlen_sharing.f90: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/fortran/decl.c.jj	2007-02-20 22:38:20.000000000 +0100
 |  | ||||||
| +++ gcc/fortran/decl.c	2007-08-21 20:50:33.000000000 +0200
 |  | ||||||
| @@ -1086,10 +1086,11 @@ variable_decl (int elem)
 |  | ||||||
|  	  break; |  | ||||||
|   |  | ||||||
|  	/* Non-constant lengths need to be copied after the first |  | ||||||
| -	   element.  */
 |  | ||||||
| +	   element.  Also copy assumed lengths.  */
 |  | ||||||
|  	case MATCH_NO: |  | ||||||
| -	  if (elem > 1 && current_ts.cl->length
 |  | ||||||
| -		&& current_ts.cl->length->expr_type != EXPR_CONSTANT)
 |  | ||||||
| +	  if (elem > 1
 |  | ||||||
| +	      && (current_ts.cl->length == NULL
 |  | ||||||
| +		  || current_ts.cl->length->expr_type != EXPR_CONSTANT))
 |  | ||||||
|  	    { |  | ||||||
|  	      cl = gfc_get_charlen (); |  | ||||||
|  	      cl->next = gfc_current_ns->cl_list; |  | ||||||
| --- gcc/fortran/trans-decl.c.jj	2007-03-12 08:28:13.000000000 +0100
 |  | ||||||
| +++ gcc/fortran/trans-decl.c	2007-08-21 20:50:33.000000000 +0200
 |  | ||||||
| @@ -1417,25 +1417,8 @@ create_function_arglist (gfc_symbol * sy
 |  | ||||||
|  	  if (!f->sym->ts.cl->length) |  | ||||||
|  	    { |  | ||||||
|  	      TREE_USED (length) = 1; |  | ||||||
| -	      if (!f->sym->ts.cl->backend_decl)
 |  | ||||||
| -		f->sym->ts.cl->backend_decl = length;
 |  | ||||||
| -	      else
 |  | ||||||
| -		{
 |  | ||||||
| -		  /* there is already another variable using this
 |  | ||||||
| -		     gfc_charlen node, build a new one for this variable
 |  | ||||||
| -		     and chain it into the list of gfc_charlens.
 |  | ||||||
| -		     This happens for e.g. in the case
 |  | ||||||
| -		     CHARACTER(*)::c1,c2
 |  | ||||||
| -		     since CHARACTER declarations on the same line share
 |  | ||||||
| -		     the same gfc_charlen node.  */
 |  | ||||||
| -		  gfc_charlen *cl;
 |  | ||||||
| -	      
 |  | ||||||
| -		  cl = gfc_get_charlen ();
 |  | ||||||
| -		  cl->backend_decl = length;
 |  | ||||||
| -		  cl->next = f->sym->ts.cl->next;
 |  | ||||||
| -		  f->sym->ts.cl->next = cl;
 |  | ||||||
| -		  f->sym->ts.cl = cl;
 |  | ||||||
| -		}
 |  | ||||||
| +	      gcc_assert (!f->sym->ts.cl->backend_decl);
 |  | ||||||
| +	      f->sym->ts.cl->backend_decl = length;
 |  | ||||||
|  	    } |  | ||||||
|   |  | ||||||
|  	  hidden_typelist = TREE_CHAIN (hidden_typelist); |  | ||||||
| --- gcc/testsuite/gfortran.dg/assumed_charlen_sharing.f90.jj	2007-08-21 08:29:57.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gfortran.dg/assumed_charlen_sharing.f90	2007-08-21 08:29:57.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,29 @@
 |  | ||||||
| +! This testcase was miscompiled, because ts.cl
 |  | ||||||
| +! in function bar was initially shared between both
 |  | ||||||
| +! dummy arguments.  Although it was later unshared,
 |  | ||||||
| +! all expressions which copied ts.cl from bar2
 |  | ||||||
| +! before that used incorrectly bar1's length
 |  | ||||||
| +! instead of bar2.
 |  | ||||||
| +! { dg-do run }
 |  | ||||||
| +
 |  | ||||||
| +subroutine foo (foo1, foo2)
 |  | ||||||
| +  implicit none
 |  | ||||||
| +  integer, intent(in) :: foo2
 |  | ||||||
| +  character(*), intent(in) :: foo1(foo2)
 |  | ||||||
| +end subroutine foo
 |  | ||||||
| +
 |  | ||||||
| +subroutine bar (bar1, bar2)
 |  | ||||||
| +  implicit none
 |  | ||||||
| +  character(*), intent(in) :: bar1, bar2
 |  | ||||||
| +
 |  | ||||||
| +  call foo ((/ bar2 /), 1)
 |  | ||||||
| +end subroutine bar
 |  | ||||||
| +
 |  | ||||||
| +program test
 |  | ||||||
| +  character(80) :: str1
 |  | ||||||
| +  character(5) :: str2
 |  | ||||||
| +
 |  | ||||||
| +  str1 = 'String'
 |  | ||||||
| +  str2 = 'Strng'
 |  | ||||||
| +  call bar (str2, str1)
 |  | ||||||
| +end program test
 |  | ||||||
| @ -1,433 +0,0 @@ | |||||||
| 2007-09-17  Jakub Jelinek  <jakub@redhat.com> |  | ||||||
| 
 |  | ||||||
| 	* c-format.h (format_kind_info): Add alloc_char field. |  | ||||||
| 	* c-format.c (scanf_flag_specs): Add 'm'. |  | ||||||
| 	(scanf_flag_pairs): Add 'a', 'm' pair. |  | ||||||
| 	(scan_char_table): Allow 'm' modifier for c, s, [, C and S. |  | ||||||
| 	(format_types_orig): Add alloc_char fields. |  | ||||||
| 	(check_format_info_main): Rename aflag to alloc_flag. |  | ||||||
| 	Handle fki->alloc_char. modifier after width and before length |  | ||||||
| 	modifiers.  Move FMT_FLAG_SCANF_A_KLUDGE handling before |  | ||||||
| 	length modifiers as well. |  | ||||||
| 	* config/sol2-c.c (solaris_format_types): Add alloc_char field. |  | ||||||
| 
 |  | ||||||
| 	* gcc.dg/format/c90-scanf-5.c: New test. |  | ||||||
| 	* gcc.dg/format/c99-scanf-4.c: New test. |  | ||||||
| 	* gcc.dg/format/ext-7.c: New test. |  | ||||||
| 	* gcc.dg/format/ext-8.c: New test. |  | ||||||
| 
 |  | ||||||
| --- gcc/c-format.h.jj	2007-02-20 22:39:12.000000000 +0100
 |  | ||||||
| +++ gcc/c-format.h	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| @@ -234,6 +234,8 @@ typedef struct
 |  | ||||||
|       specifiers, but is used to check for bad combinations such as length |  | ||||||
|       modifier with assignment suppression in scanf.  */ |  | ||||||
|    int length_code_char; |  | ||||||
| +  /* Assignment-allocation flag character ('m' in scanf), otherwise 0.  */
 |  | ||||||
| +  int alloc_char;
 |  | ||||||
|    /* Pointer to type of argument expected if '*' is used for a width, |  | ||||||
|       or NULL if '*' not used for widths.  */ |  | ||||||
|    tree *width_type; |  | ||||||
| --- gcc/c-format.c.jj	2007-02-20 22:39:12.000000000 +0100
 |  | ||||||
| +++ gcc/c-format.c	2007-09-17 22:51:08.000000000 +0200
 |  | ||||||
| @@ -423,6 +423,7 @@ static const format_flag_spec scanf_flag
 |  | ||||||
|  { |  | ||||||
|    { '*',  0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 }, |  | ||||||
|    { 'a',  0, 0, N_("'a' flag"),               N_("the 'a' scanf flag"),                       STD_EXT }, |  | ||||||
| +  { 'm',  0, 0, N_("'m' flag"),               N_("the 'm' scanf flag"),                       STD_EXT },
 |  | ||||||
|    { 'w',  0, 0, N_("field width"),            N_("field width in scanf format"),              STD_C89 }, |  | ||||||
|    { 'L',  0, 0, N_("length modifier"),        N_("length modifier in scanf format"),          STD_C89 }, |  | ||||||
|    { '\'', 0, 0, N_("''' flag"),               N_("the ''' scanf flag"),                       STD_EXT }, |  | ||||||
| @@ -434,6 +435,7 @@ static const format_flag_spec scanf_flag
 |  | ||||||
|  static const format_flag_pair scanf_flag_pairs[] = |  | ||||||
|  { |  | ||||||
|    { '*', 'L', 0, 0 }, |  | ||||||
| +  { 'a', 'm', 0, 0 },
 |  | ||||||
|    { 0, 0, 0, 0 } |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -648,16 +650,16 @@ static const format_char_info scan_char_
 |  | ||||||
|    { "u",     1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w'I", "W",   NULL }, |  | ||||||
|    { "oxX",   1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w",   "W",   NULL }, |  | ||||||
|    { "efgEG", 1, STD_C89, { T89_F,   BADLEN,  BADLEN,  T89_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W",   NULL }, |  | ||||||
| -  { "c",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "cW",  NULL },
 |  | ||||||
| -  { "s",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW",  NULL },
 |  | ||||||
| -  { "[",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW[", NULL },
 |  | ||||||
| +  { "c",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*mw",  "cW",  NULL },
 |  | ||||||
| +  { "s",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*amw", "cW",  NULL },
 |  | ||||||
| +  { "[",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*amw", "cW[", NULL },
 |  | ||||||
|    { "p",     2, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W",   NULL }, |  | ||||||
|    { "n",     1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",     "W",   NULL }, |  | ||||||
|    /* C99 conversion specifiers.  */ |  | ||||||
|    { "FaA",   1, STD_C99, { T99_F,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W",   NULL }, |  | ||||||
|    /* X/Open conversion specifiers.  */ |  | ||||||
| -  { "C",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W",   NULL },
 |  | ||||||
| -  { "S",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "W",   NULL },
 |  | ||||||
| +  { "C",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*mw",  "W",   NULL },
 |  | ||||||
| +  { "S",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*amw", "W",   NULL },
 |  | ||||||
|    { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -700,59 +702,59 @@ static const format_kind_info format_typ
 |  | ||||||
|    { "printf",   printf_length_specs,  print_char_table, " +#0-'I", NULL,  |  | ||||||
|      printf_flag_specs, printf_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK, |  | ||||||
| -    'w', 0, 'p', 0, 'L',
 |  | ||||||
| +    'w', 0, 'p', 0, 'L', 0,
 |  | ||||||
|      &integer_type_node, &integer_type_node |  | ||||||
|    }, |  | ||||||
|    { "asm_fprintf",   asm_fprintf_length_specs,  asm_fprintf_char_table, " +#0-", NULL,  |  | ||||||
|      asm_fprintf_flag_specs, asm_fprintf_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, |  | ||||||
| -    'w', 0, 'p', 0, 'L',
 |  | ||||||
| +    'w', 0, 'p', 0, 'L', 0,
 |  | ||||||
|      NULL, NULL |  | ||||||
|    }, |  | ||||||
|    { "gcc_diag",   gcc_diag_length_specs,  gcc_diag_char_table, "q+", NULL,  |  | ||||||
|      gcc_diag_flag_specs, gcc_diag_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT, |  | ||||||
| -    0, 0, 'p', 0, 'L',
 |  | ||||||
| +    0, 0, 'p', 0, 'L', 0,
 |  | ||||||
|      NULL, &integer_type_node |  | ||||||
|    }, |  | ||||||
|    { "gcc_tdiag",   gcc_tdiag_length_specs,  gcc_tdiag_char_table, "q+", NULL,  |  | ||||||
|      gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT, |  | ||||||
| -    0, 0, 'p', 0, 'L',
 |  | ||||||
| +    0, 0, 'p', 0, 'L', 0,
 |  | ||||||
|      NULL, &integer_type_node |  | ||||||
|    }, |  | ||||||
|    { "gcc_cdiag",   gcc_cdiag_length_specs,  gcc_cdiag_char_table, "q+", NULL,  |  | ||||||
|      gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT, |  | ||||||
| -    0, 0, 'p', 0, 'L',
 |  | ||||||
| +    0, 0, 'p', 0, 'L', 0,
 |  | ||||||
|      NULL, &integer_type_node |  | ||||||
|    }, |  | ||||||
|    { "gcc_cxxdiag",   gcc_cxxdiag_length_specs,  gcc_cxxdiag_char_table, "q+#", NULL,  |  | ||||||
|      gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT, |  | ||||||
| -    0, 0, 'p', 0, 'L',
 |  | ||||||
| +    0, 0, 'p', 0, 'L', 0,
 |  | ||||||
|      NULL, &integer_type_node |  | ||||||
|    }, |  | ||||||
|    { "gcc_gfc", NULL, gcc_gfc_char_table, "", NULL,  |  | ||||||
|      NULL, gcc_gfc_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT, |  | ||||||
| -    0, 0, 0, 0, 0,
 |  | ||||||
| +    0, 0, 0, 0, 0, 0,
 |  | ||||||
|      NULL, NULL |  | ||||||
|    }, |  | ||||||
|    { "scanf",    scanf_length_specs,   scan_char_table,  "*'I", NULL,  |  | ||||||
|      scanf_flag_specs, scanf_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, |  | ||||||
| -    'w', 0, 0, '*', 'L',
 |  | ||||||
| +    'w', 0, 0, '*', 'L', 'm',
 |  | ||||||
|      NULL, NULL |  | ||||||
|    }, |  | ||||||
|    { "strftime", NULL,                 time_char_table,  "_-0^#", "EO", |  | ||||||
|      strftime_flag_specs, strftime_flag_pairs, |  | ||||||
| -    FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0,
 |  | ||||||
| +    FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0,
 |  | ||||||
|      NULL, NULL |  | ||||||
|    }, |  | ||||||
|    { "strfmon",  strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,  |  | ||||||
|      strfmon_flag_specs, strfmon_flag_pairs, |  | ||||||
| -    FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L',
 |  | ||||||
| +    FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0,
 |  | ||||||
|      NULL, NULL |  | ||||||
|    } |  | ||||||
|  }; |  | ||||||
| @@ -1462,7 +1464,7 @@ check_format_info_main (format_check_res
 |  | ||||||
|        const format_length_info *fli = NULL; |  | ||||||
|        const format_char_info *fci = NULL; |  | ||||||
|        char flag_chars[256]; |  | ||||||
| -      int aflag = 0;
 |  | ||||||
| +      int alloc_flag = 0;
 |  | ||||||
|        const char *format_start = format_chars; |  | ||||||
|        if (*format_chars == 0) |  | ||||||
|  	{ |  | ||||||
| @@ -1721,6 +1723,31 @@ check_format_info_main (format_check_res
 |  | ||||||
|  	    } |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +      if (fki->alloc_char && fki->alloc_char == *format_chars)
 |  | ||||||
| +	{
 |  | ||||||
| +	  i = strlen (flag_chars);
 |  | ||||||
| +	  flag_chars[i++] = fki->alloc_char;
 |  | ||||||
| +	  flag_chars[i] = 0;
 |  | ||||||
| +	  format_chars++;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +      /* Handle the scanf allocation kludge.  */
 |  | ||||||
| +      if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
 |  | ||||||
| +	{
 |  | ||||||
| +	  if (*format_chars == 'a' && !flag_isoc99)
 |  | ||||||
| +	    {
 |  | ||||||
| +	      if (format_chars[1] == 's' || format_chars[1] == 'S'
 |  | ||||||
| +		  || format_chars[1] == '[')
 |  | ||||||
| +		{
 |  | ||||||
| +		  /* 'a' is used as a flag.  */
 |  | ||||||
| +		  i = strlen (flag_chars);
 |  | ||||||
| +		  flag_chars[i++] = 'a';
 |  | ||||||
| +		  flag_chars[i] = 0;
 |  | ||||||
| +		  format_chars++;
 |  | ||||||
| +		}
 |  | ||||||
| +	    }
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
|        /* Read any length modifier, if this kind of format has them.  */ |  | ||||||
|        fli = fki->length_char_specs; |  | ||||||
|        length_chars = NULL; |  | ||||||
| @@ -1783,23 +1810,6 @@ check_format_info_main (format_check_res
 |  | ||||||
|  	    } |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -      /* Handle the scanf allocation kludge.  */
 |  | ||||||
| -      if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
 |  | ||||||
| -	{
 |  | ||||||
| -	  if (*format_chars == 'a' && !flag_isoc99)
 |  | ||||||
| -	    {
 |  | ||||||
| -	      if (format_chars[1] == 's' || format_chars[1] == 'S'
 |  | ||||||
| -		  || format_chars[1] == '[')
 |  | ||||||
| -		{
 |  | ||||||
| -		  /* 'a' is used as a flag.  */
 |  | ||||||
| -		  i = strlen (flag_chars);
 |  | ||||||
| -		  flag_chars[i++] = 'a';
 |  | ||||||
| -		  flag_chars[i] = 0;
 |  | ||||||
| -		  format_chars++;
 |  | ||||||
| -		}
 |  | ||||||
| -	    }
 |  | ||||||
| -	}
 |  | ||||||
| -
 |  | ||||||
|        format_char = *format_chars; |  | ||||||
|        if (format_char == 0 |  | ||||||
|  	  || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK) |  | ||||||
| @@ -1872,7 +1882,9 @@ check_format_info_main (format_check_res
 |  | ||||||
|   |  | ||||||
|        if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) |  | ||||||
|  	  && strchr (flag_chars, 'a') != 0) |  | ||||||
| -	aflag = 1;
 |  | ||||||
| +	alloc_flag = 1;
 |  | ||||||
| +      if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0)
 |  | ||||||
| +	alloc_flag = 1;
 |  | ||||||
|   |  | ||||||
|        if (fki->suppression_char |  | ||||||
|  	  && strchr (flag_chars, fki->suppression_char) != 0) |  | ||||||
| @@ -2044,13 +2056,13 @@ check_format_info_main (format_check_res
 |  | ||||||
|   |  | ||||||
|  	      wanted_type_ptr->wanted_type = wanted_type; |  | ||||||
|  	      wanted_type_ptr->wanted_type_name = wanted_type_name; |  | ||||||
| -	      wanted_type_ptr->pointer_count = fci->pointer_count + aflag;
 |  | ||||||
| +	      wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
 |  | ||||||
|  	      wanted_type_ptr->char_lenient_flag = 0; |  | ||||||
|  	      if (strchr (fci->flags2, 'c') != 0) |  | ||||||
|  		wanted_type_ptr->char_lenient_flag = 1; |  | ||||||
|  	      wanted_type_ptr->writing_in_flag = 0; |  | ||||||
|  	      wanted_type_ptr->reading_from_flag = 0; |  | ||||||
| -	      if (aflag)
 |  | ||||||
| +	      if (alloc_flag)
 |  | ||||||
|  		wanted_type_ptr->writing_in_flag = 1; |  | ||||||
|  	      else |  | ||||||
|  		{ |  | ||||||
| --- gcc/config/sol2-c.c.jj	2007-02-20 22:39:11.000000000 +0100
 |  | ||||||
| +++ gcc/config/sol2-c.c	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| @@ -74,7 +74,7 @@ const format_kind_info solaris_format_ty
 |  | ||||||
|    { "cmn_err",  cmn_err_length_specs,  cmn_err_char_table, "", NULL, |  | ||||||
|      cmn_err_flag_specs, cmn_err_flag_pairs, |  | ||||||
|      FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, |  | ||||||
| -    'w', 0, 0, 0, 'L',
 |  | ||||||
| +    'w', 0, 0, 0, 'L', 0,
 |  | ||||||
|      &integer_type_node, &integer_type_node |  | ||||||
|    } |  | ||||||
|  }; |  | ||||||
| --- gcc/testsuite/gcc.dg/format/c90-scanf-5.c.jj	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/format/c90-scanf-5.c	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,19 @@
 |  | ||||||
| +/* Test for scanf formats.  Formats using extensions to the standard
 |  | ||||||
| +   should be rejected in strict pedantic mode.
 |  | ||||||
| +*/
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-std=iso9899:1990 -pedantic -Wformat" } */
 |  | ||||||
| +
 |  | ||||||
| +#include "format.h"
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +foo (char **sp, wchar_t **lsp)
 |  | ||||||
| +{
 |  | ||||||
| +  /* m assignment-allocation modifier, recognized in both C90
 |  | ||||||
| +     and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension.  */
 |  | ||||||
| +  scanf ("%ms", sp); /* { dg-warning "C" "%ms" } */
 |  | ||||||
| +  scanf ("%mS", lsp); /* { dg-warning "C" "%mS" } */
 |  | ||||||
| +  scanf ("%mls", lsp); /* { dg-warning "C" "%mls" } */
 |  | ||||||
| +  scanf ("%m[bcd]", sp); /* { dg-warning "C" "%m[]" } */
 |  | ||||||
| +  scanf ("%ml[bcd]", lsp); /* { dg-warning "C" "%ml[]" } */
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/gcc.dg/format/c99-scanf-4.c.jj	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/format/c99-scanf-4.c	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,19 @@
 |  | ||||||
| +/* Test for scanf formats.  Formats using extensions to the standard
 |  | ||||||
| +   should be rejected in strict pedantic mode.
 |  | ||||||
| +*/
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-std=iso9899:1999 -pedantic -Wformat" } */
 |  | ||||||
| +
 |  | ||||||
| +#include "format.h"
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +foo (char **sp, wchar_t **lsp)
 |  | ||||||
| +{
 |  | ||||||
| +  /* m assignment-allocation modifier, recognized in both C90
 |  | ||||||
| +     and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension.  */
 |  | ||||||
| +  scanf ("%ms", sp); /* { dg-warning "C" "%ms" } */
 |  | ||||||
| +  scanf ("%mS", lsp); /* { dg-warning "C" "%mS" } */
 |  | ||||||
| +  scanf ("%mls", lsp); /* { dg-warning "C" "%mls" } */
 |  | ||||||
| +  scanf ("%m[bcd]", sp); /* { dg-warning "C" "%m[]" } */
 |  | ||||||
| +  scanf ("%ml[bcd]", lsp); /* { dg-warning "C" "%ml[]" } */
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/gcc.dg/format/ext-7.c.jj	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/format/ext-7.c	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,85 @@
 |  | ||||||
| +/* Test for scanf formats.  %a and %m extensions.  */
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-std=gnu89 -Wformat" } */
 |  | ||||||
| +
 |  | ||||||
| +#include "format.h"
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +foo (char **sp, wchar_t **lsp, int *ip, float *fp, void **pp, double *dp)
 |  | ||||||
| +{
 |  | ||||||
| +  /* %a formats for allocation, only recognized in C90 mode, are a
 |  | ||||||
| +     GNU extension.  Followed by other characters, %a is not treated
 |  | ||||||
| +     specially.
 |  | ||||||
| +  */
 |  | ||||||
| +  scanf ("%as", sp);
 |  | ||||||
| +  scanf ("%aS", lsp);
 |  | ||||||
| +  scanf ("%las", dp);
 |  | ||||||
| +  scanf ("%la", lsp);	/* { dg-warning "but argument 2 has type" } */
 |  | ||||||
| +  scanf ("%las", lsp);	/* { dg-warning "but argument 2 has type" } */
 |  | ||||||
| +  scanf ("%a[bcd]", sp);
 |  | ||||||
| +  scanf ("%la[bcd]", dp);
 |  | ||||||
| +  scanf ("%*as");
 |  | ||||||
| +  scanf ("%*aS");
 |  | ||||||
| +  scanf ("%*las");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*a[bcd]");
 |  | ||||||
| +  scanf ("%*la[bcd]");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%10as", sp);
 |  | ||||||
| +  scanf ("%5aS", lsp);
 |  | ||||||
| +  scanf ("%9las", dp);
 |  | ||||||
| +  scanf ("%25a[bcd]", sp);
 |  | ||||||
| +  scanf ("%48la[bcd]", dp);
 |  | ||||||
| +  scanf ("%*10as");
 |  | ||||||
| +  scanf ("%*5aS");
 |  | ||||||
| +  scanf ("%*9las");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*25a[bcd]");
 |  | ||||||
| +  scanf ("%*48la[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +
 |  | ||||||
| +  /* m assignment-allocation modifier, recognized in both C90
 |  | ||||||
| +     and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension.  */
 |  | ||||||
| +  scanf ("%ms", sp);
 |  | ||||||
| +  scanf ("%mS", lsp);
 |  | ||||||
| +  scanf ("%mls", lsp);
 |  | ||||||
| +  scanf ("%m[bcd]", sp);
 |  | ||||||
| +  scanf ("%ml[bcd]", lsp);
 |  | ||||||
| +  scanf ("%mc", sp);
 |  | ||||||
| +  scanf ("%mlc", lsp);
 |  | ||||||
| +  scanf ("%mC", lsp);
 |  | ||||||
| +  scanf ("%*ms");
 |  | ||||||
| +  scanf ("%*mS");
 |  | ||||||
| +  scanf ("%*mls");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*m[bcd]");
 |  | ||||||
| +  scanf ("%*ml[bcd]");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*mc");
 |  | ||||||
| +  scanf ("%*mlc");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*mC");
 |  | ||||||
| +  scanf ("%10ms", sp);
 |  | ||||||
| +  scanf ("%5mS", lsp);
 |  | ||||||
| +  scanf ("%9mls", lsp);
 |  | ||||||
| +  scanf ("%25m[bcd]", sp);
 |  | ||||||
| +  scanf ("%41ml[bcd]", lsp);
 |  | ||||||
| +  scanf ("%131mc", sp);
 |  | ||||||
| +  scanf ("%27mlc", lsp);
 |  | ||||||
| +  scanf ("%2mC", lsp);
 |  | ||||||
| +  scanf ("%*10ms");
 |  | ||||||
| +  scanf ("%*5mS");
 |  | ||||||
| +  scanf ("%*9mls");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*25m[bcd]");
 |  | ||||||
| +  scanf ("%*41ml[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*131mc");
 |  | ||||||
| +  scanf ("%*27mlc");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*2mC");
 |  | ||||||
| +
 |  | ||||||
| +  scanf ("%md", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mi", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mo", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mu", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mx", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%me", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mf", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mg", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mp", pp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +
 |  | ||||||
| +  scanf ("%mas", sp);	/* { dg-warning "flag together" } */
 |  | ||||||
| +  scanf ("%maS", lsp);	/* { dg-warning "flag together" } */
 |  | ||||||
| +  scanf ("%ma[bcd]", sp);	/* { dg-warning "flag together" } */
 |  | ||||||
| +}
 |  | ||||||
| --- gcc/testsuite/gcc.dg/format/ext-8.c.jj	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| +++ gcc/testsuite/gcc.dg/format/ext-8.c	2007-09-17 22:44:17.000000000 +0200
 |  | ||||||
| @@ -0,0 +1,56 @@
 |  | ||||||
| +/* Test for scanf formats.  %m extensions.  */
 |  | ||||||
| +/* { dg-do compile } */
 |  | ||||||
| +/* { dg-options "-std=gnu99 -Wformat" } */
 |  | ||||||
| +
 |  | ||||||
| +#include "format.h"
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +foo (char **sp, wchar_t **lsp, int *ip, float *fp, void **pp)
 |  | ||||||
| +{
 |  | ||||||
| +  /* m assignment-allocation modifier, recognized in both C90
 |  | ||||||
| +     and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension.  */
 |  | ||||||
| +  scanf ("%ms", sp);
 |  | ||||||
| +  scanf ("%mS", lsp);
 |  | ||||||
| +  scanf ("%mls", lsp);
 |  | ||||||
| +  scanf ("%m[bcd]", sp);
 |  | ||||||
| +  scanf ("%ml[bcd]", lsp);
 |  | ||||||
| +  scanf ("%mc", sp);
 |  | ||||||
| +  scanf ("%mlc", lsp);
 |  | ||||||
| +  scanf ("%mC", lsp);
 |  | ||||||
| +  scanf ("%*ms");
 |  | ||||||
| +  scanf ("%*mS");
 |  | ||||||
| +  scanf ("%*mls");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*m[bcd]");
 |  | ||||||
| +  scanf ("%*ml[bcd]");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*mc");
 |  | ||||||
| +  scanf ("%*mlc");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*mC");
 |  | ||||||
| +  scanf ("%10ms", sp);
 |  | ||||||
| +  scanf ("%5mS", lsp);
 |  | ||||||
| +  scanf ("%9mls", lsp);
 |  | ||||||
| +  scanf ("%25m[bcd]", sp);
 |  | ||||||
| +  scanf ("%41ml[bcd]", lsp);
 |  | ||||||
| +  scanf ("%131mc", sp);
 |  | ||||||
| +  scanf ("%27mlc", lsp);
 |  | ||||||
| +  scanf ("%2mC", lsp);
 |  | ||||||
| +  scanf ("%*10ms");
 |  | ||||||
| +  scanf ("%*5mS");
 |  | ||||||
| +  scanf ("%*9mls");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*25m[bcd]");
 |  | ||||||
| +  scanf ("%*41ml[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*131mc");
 |  | ||||||
| +  scanf ("%*27mlc");	/* { dg-warning "assignment suppression and length modifier" } */
 |  | ||||||
| +  scanf ("%*2mC");
 |  | ||||||
| +
 |  | ||||||
| +  scanf ("%md", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mi", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mo", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mu", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mx", ip);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%ma", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mA", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%me", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mf", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mg", fp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +  scanf ("%mp", pp);	/* { dg-warning "flag used with" } */
 |  | ||||||
| +}
 |  | ||||||
| @ -1,519 +0,0 @@ | |||||||
| 2006-03-02  David S. Miller  <davem@sunset.davemloft.net> |  | ||||||
| 
 |  | ||||||
| 	Sun Niagara specific optimizations. |  | ||||||
| 	* config.gcc: Recognize niagara as target. |  | ||||||
| 	* config/sparc/sparc.h (SPARC_RELAXED_ORDERING): Mention Niagara. |  | ||||||
| 	(TARGET_CPU_niagara): Define. |  | ||||||
| 	(CPP_CPU64_DEFAULT_SPEC): Define __sparc_v9__ for Niagara. |  | ||||||
| 	(ASM_CPU64_DEFAULT_SPEC): Pass -Av9b for Niagara. |  | ||||||
| 	(CPP_CPU_SPEC): Handle -mcpu=niagara. |  | ||||||
| 	(ASM_CPU_SPEC): Likewise. |  | ||||||
| 	(PROCESSOR_NIAGARA): New enum entry. |  | ||||||
| 	(REGISTER_MOVE_COST): Handle Niagara. |  | ||||||
| 	(BRANCH_COST, PREFETCH_BLOCK, SIMULTANEOUS_PREFETCHES): Likewise. |  | ||||||
| 	* config/sparc/sparc.c (niagara_costs): New processor_costs entry. |  | ||||||
| 	(sparc_override_options): Recognize "niagara", set appropriate |  | ||||||
| 	default MASK_* values for it, and align functions to 32-bytes |  | ||||||
| 	by default just like ULTRASPARC/ULTRASPARC3. |  | ||||||
| 	(sparc_initialize_trampoline): Handle niagara like ultrasparc. |  | ||||||
| 	(sparc64_initialize_trampoline): Likewise. |  | ||||||
| 	(sparc_use_sched_lookahead): Use zero for niagara. |  | ||||||
| 	(sparc_issue_rate): Use one for niagara. |  | ||||||
| 	* config/sparc/niagara.md: New file. |  | ||||||
| 	* config/sparc/sparc.md: Include it. |  | ||||||
| 	* config/sparc/sol2-bi.h (CPP_CPU64_DEFAULT_SPEC, |  | ||||||
| 	ASM_CPU32_DEFAULT_SPEC, ASM_CPU64_DEFAULT_SPEC): Set appropriately |  | ||||||
| 	when default cpu is niagara. |  | ||||||
| 	(CPP_CPU_SPEC): Handle -mcpu=niagara. |  | ||||||
| 	(ASM_CPU_SPEC): Likewise. |  | ||||||
| 	* config/sparc/sol2.h (ASM_CPU_DEFAULT_SPEC): Set appropriately |  | ||||||
| 	when default cpu is niagara. |  | ||||||
| 	(ASM_CPU_SPEC): Handle -mcpu=niagara. |  | ||||||
| 	* config/sparc/linux64.h: Handle a default of TARGET_CPU_niagara |  | ||||||
| 	just like v9/ultrasparc/ultrasparc3. |  | ||||||
| 	* doc/invoke.texi: Add documentation for "niagara" and improve |  | ||||||
| 	existing documentation for ultrasparc variants. |  | ||||||
| 
 |  | ||||||
| --- gcc/doc/invoke.texi	(revision 111647)
 |  | ||||||
| +++ gcc/doc/invoke.texi	(revision 111648)
 |  | ||||||
| @@ -12268,8 +12268,8 @@ Set the instruction set, register set, a
 |  | ||||||
|  for machine type @var{cpu_type}.  Supported values for @var{cpu_type} are |  | ||||||
|  @samp{v7}, @samp{cypress}, @samp{v8}, @samp{supersparc}, @samp{sparclite}, |  | ||||||
|  @samp{f930}, @samp{f934}, @samp{hypersparc}, @samp{sparclite86x}, |  | ||||||
| -@samp{sparclet}, @samp{tsc701}, @samp{v9}, @samp{ultrasparc}, and
 |  | ||||||
| -@samp{ultrasparc3}.
 |  | ||||||
| +@samp{sparclet}, @samp{tsc701}, @samp{v9}, @samp{ultrasparc},
 |  | ||||||
| +@samp{ultrasparc3}, and @samp{niagara}.
 |  | ||||||
|   |  | ||||||
|  Default instruction scheduling parameters are used for values that select |  | ||||||
|  an architecture and not an implementation.  These are @samp{v7}, @samp{v8}, |  | ||||||
| @@ -12283,7 +12283,7 @@ implementations.
 |  | ||||||
|      v8:             supersparc, hypersparc |  | ||||||
|      sparclite:      f930, f934, sparclite86x |  | ||||||
|      sparclet:       tsc701 |  | ||||||
| -    v9:             ultrasparc, ultrasparc3
 |  | ||||||
| +    v9:             ultrasparc, ultrasparc3, niagara
 |  | ||||||
|  @end smallexample |  | ||||||
|   |  | ||||||
|  By default (unless configured otherwise), GCC generates code for the V7 |  | ||||||
| @@ -12317,9 +12317,11 @@ With @option{-mcpu=v9}, GCC generates co
 |  | ||||||
|  architecture.  This adds 64-bit integer and floating-point move instructions, |  | ||||||
|  3 additional floating-point condition code registers and conditional move |  | ||||||
|  instructions.  With @option{-mcpu=ultrasparc}, the compiler additionally |  | ||||||
| -optimizes it for the Sun UltraSPARC I/II chips.  With
 |  | ||||||
| +optimizes it for the Sun UltraSPARC I/II/IIi chips.  With
 |  | ||||||
|  @option{-mcpu=ultrasparc3}, the compiler additionally optimizes it for the |  | ||||||
| -Sun UltraSPARC III chip.
 |  | ||||||
| +Sun UltraSPARC III/III+/IIIi/IIIi+/IV/IV+ chips.  With
 |  | ||||||
| +@option{-mcpu=niagara}, the compiler additionally optimizes it for
 |  | ||||||
| +Sun UltraSPARC T1 chips.
 |  | ||||||
|   |  | ||||||
|  @item -mtune=@var{cpu_type} |  | ||||||
|  @opindex mtune |  | ||||||
| @@ -12331,8 +12333,8 @@ The same values for @option{-mcpu=@var{c
 |  | ||||||
|  @option{-mtune=@var{cpu_type}}, but the only useful values are those |  | ||||||
|  that select a particular cpu implementation.  Those are @samp{cypress}, |  | ||||||
|  @samp{supersparc}, @samp{hypersparc}, @samp{f930}, @samp{f934}, |  | ||||||
| -@samp{sparclite86x}, @samp{tsc701}, @samp{ultrasparc}, and
 |  | ||||||
| -@samp{ultrasparc3}.
 |  | ||||||
| +@samp{sparclite86x}, @samp{tsc701}, @samp{ultrasparc},
 |  | ||||||
| +@samp{ultrasparc3}, and @samp{niagara}.
 |  | ||||||
|   |  | ||||||
|  @item -mv8plus |  | ||||||
|  @itemx -mno-v8plus |  | ||||||
| --- gcc/config.gcc	(revision 111647)
 |  | ||||||
| +++ gcc/config.gcc	(revision 111648)
 |  | ||||||
| @@ -2830,7 +2830,7 @@ case "${target}" in
 |  | ||||||
|  			"" | sparc | sparcv9 | sparc64 | sparc86x \ |  | ||||||
|  			| v7 | cypress | v8 | supersparc | sparclite | f930 \ |  | ||||||
|  			| f934 | hypersparc | sparclite86x | sparclet | tsc701 \ |  | ||||||
| -			| v9 | ultrasparc | ultrasparc3)
 |  | ||||||
| +			| v9 | ultrasparc | ultrasparc3 | niagara)
 |  | ||||||
|  				# OK |  | ||||||
|  				;; |  | ||||||
|  			*) |  | ||||||
| --- gcc/config/sparc/niagara.md	(revision 0)
 |  | ||||||
| +++ gcc/config/sparc/niagara.md	(revision 111648)
 |  | ||||||
| @@ -0,0 +1,119 @@
 |  | ||||||
| +;; Scheduling description for Niagara.
 |  | ||||||
| +;;   Copyright (C) 2006 Free Software Foundation, Inc.
 |  | ||||||
| +;;
 |  | ||||||
| +;; This file is part of GCC.
 |  | ||||||
| +;;
 |  | ||||||
| +;; GCC is free software; you can redistribute it and/or modify
 |  | ||||||
| +;; it under the terms of the GNU General Public License as published by
 |  | ||||||
| +;; the Free Software Foundation; either version 2, or (at your option)
 |  | ||||||
| +;; any later version.
 |  | ||||||
| +;;
 |  | ||||||
| +;; GCC is distributed in the hope that it will be useful,
 |  | ||||||
| +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 |  | ||||||
| +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 |  | ||||||
| +;; GNU General Public License for more details.
 |  | ||||||
| +;;
 |  | ||||||
| +;; You should have received a copy of the GNU General Public License
 |  | ||||||
| +;; along with GCC; see the file COPYING.  If not, write to
 |  | ||||||
| +;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 |  | ||||||
| +;; Boston, MA 02110-1301, USA.
 |  | ||||||
| +
 |  | ||||||
| +;; Niagara is a single-issue processor.
 |  | ||||||
| +
 |  | ||||||
| +(define_automaton "niagara_0")
 |  | ||||||
| +
 |  | ||||||
| +(define_cpu_unit "niag_pipe" "niagara_0")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_5cycle" 5
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "multi,flushw,iflush,trap"))
 |  | ||||||
| +  "niag_pipe*5")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_4cycle" 4
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "savew"))
 |  | ||||||
| +  "niag_pipe*4")
 |  | ||||||
| +
 |  | ||||||
| +/* Most basic operations are single-cycle. */
 |  | ||||||
| +(define_insn_reservation "niag_ialu" 1
 |  | ||||||
| + (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +   (eq_attr "type" "ialu,shift,compare,cmove"))
 |  | ||||||
| + "niag_pipe")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_imul" 11
 |  | ||||||
| + (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +   (eq_attr "type" "imul"))
 |  | ||||||
| + "niag_pipe*11")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_idiv" 72
 |  | ||||||
| + (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +   (eq_attr "type" "idiv"))
 |  | ||||||
| + "niag_pipe*72")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_branch" 3
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch,branch"))
 |  | ||||||
| +  "niag_pipe*3")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_3cycle_load" 3
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "load"))
 |  | ||||||
| +  "niag_pipe*3")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_9cycle_load" 9
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpload"))
 |  | ||||||
| +  "niag_pipe*9")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_1cycle_store" 1
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "store"))
 |  | ||||||
| +  "niag_pipe")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_8cycle_store" 8
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpstore"))
 |  | ||||||
| +  "niag_pipe*8")
 |  | ||||||
| +
 |  | ||||||
| +/* Things incorrectly modelled here:
 |  | ||||||
| + *  FPADD{s,d}: 26 cycles
 |  | ||||||
| + *  FPSUB{s,d}: 26 cycles
 |  | ||||||
| + *  FABSD: 26 cycles
 |  | ||||||
| + *  F{s,d}TO{s,d}: 26 cycles
 |  | ||||||
| + *  F{s,d}TO{i,x}: 26 cycles
 |  | ||||||
| + *  FSMULD: 29 cycles
 |  | ||||||
| + */
 |  | ||||||
| +(define_insn_reservation "niag_fmov" 8
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpmove,fpcmove,fpcrmove"))
 |  | ||||||
| +  "niag_pipe*8")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_fpcmp" 26
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpcmp"))
 |  | ||||||
| +  "niag_pipe*26")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_fmult" 29
 |  | ||||||
| + (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpmul"))
 |  | ||||||
| +  "niag_pipe*29")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_fdivs" 54
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpdivs"))
 |  | ||||||
| +  "niag_pipe*54")
 |  | ||||||
| +
 |  | ||||||
| +(define_insn_reservation "niag_fdivd" 83
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fpdivd"))
 |  | ||||||
| +  "niag_pipe*83")
 |  | ||||||
| +
 |  | ||||||
| +/* Things incorrectly modelled here:
 |  | ||||||
| + *  FPADD{16,32}: 10 cycles
 |  | ||||||
| + *  FPSUB{16,32}: 10 cycles
 |  | ||||||
| + *  FALIGNDATA: 10 cycles
 |  | ||||||
| + */
 |  | ||||||
| +(define_insn_reservation "niag_vis" 8
 |  | ||||||
| +  (and (eq_attr "cpu" "niagara")
 |  | ||||||
| +    (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist"))
 |  | ||||||
| +  "niag_pipe*8")
 |  | ||||||
| --- gcc/config/sparc/sparc.md	(revision 111647)
 |  | ||||||
| +++ gcc/config/sparc/sparc.md	(revision 111648)
 |  | ||||||
| @@ -94,7 +94,8 @@ (define_attr "cpu"
 |  | ||||||
|     sparclet,tsc701, |  | ||||||
|     v9, |  | ||||||
|     ultrasparc, |  | ||||||
| -   ultrasparc3"
 |  | ||||||
| +   ultrasparc3,
 |  | ||||||
| +   niagara"
 |  | ||||||
|    (const (symbol_ref "sparc_cpu_attr"))) |  | ||||||
|   |  | ||||||
|  ;; Attribute for the instruction set. |  | ||||||
| @@ -315,6 +316,7 @@ (define_delay (eq_attr "type" "return")
 |  | ||||||
|  (include "sparclet.md") |  | ||||||
|  (include "ultra1_2.md") |  | ||||||
|  (include "ultra3.md") |  | ||||||
| +(include "niagara.md")
 |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  ;; Operand and operator predicates. |  | ||||||
| --- gcc/config/sparc/sparc.c	(revision 111647)
 |  | ||||||
| +++ gcc/config/sparc/sparc.c	(revision 111648)
 |  | ||||||
| @@ -197,6 +197,30 @@ struct processor_costs ultrasparc3_costs
 |  | ||||||
|    0, /* shift penalty */ |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +static const
 |  | ||||||
| +struct processor_costs niagara_costs = {
 |  | ||||||
| +  COSTS_N_INSNS (3), /* int load */
 |  | ||||||
| +  COSTS_N_INSNS (3), /* int signed load */
 |  | ||||||
| +  COSTS_N_INSNS (3), /* int zeroed load */
 |  | ||||||
| +  COSTS_N_INSNS (9), /* float load */
 |  | ||||||
| +  COSTS_N_INSNS (8), /* fmov, fneg, fabs */
 |  | ||||||
| +  COSTS_N_INSNS (8), /* fadd, fsub */
 |  | ||||||
| +  COSTS_N_INSNS (26), /* fcmp */
 |  | ||||||
| +  COSTS_N_INSNS (8), /* fmov, fmovr */
 |  | ||||||
| +  COSTS_N_INSNS (29), /* fmul */
 |  | ||||||
| +  COSTS_N_INSNS (54), /* fdivs */
 |  | ||||||
| +  COSTS_N_INSNS (83), /* fdivd */
 |  | ||||||
| +  COSTS_N_INSNS (100), /* fsqrts - not implemented in hardware */
 |  | ||||||
| +  COSTS_N_INSNS (100), /* fsqrtd - not implemented in hardware */
 |  | ||||||
| +  COSTS_N_INSNS (11), /* imul */
 |  | ||||||
| +  COSTS_N_INSNS (11), /* imulX */
 |  | ||||||
| +  0, /* imul bit factor */
 |  | ||||||
| +  COSTS_N_INSNS (72), /* idiv */
 |  | ||||||
| +  COSTS_N_INSNS (72), /* idivX */
 |  | ||||||
| +  COSTS_N_INSNS (1), /* movcc/movr */
 |  | ||||||
| +  0, /* shift penalty */
 |  | ||||||
| +};
 |  | ||||||
| +
 |  | ||||||
|  const struct processor_costs *sparc_costs = &cypress_costs; |  | ||||||
|   |  | ||||||
|  #ifdef HAVE_AS_RELAX_OPTION |  | ||||||
| @@ -597,6 +621,7 @@ sparc_override_options (void)
 |  | ||||||
|      { TARGET_CPU_v9, "v9" }, |  | ||||||
|      { TARGET_CPU_ultrasparc, "ultrasparc" }, |  | ||||||
|      { TARGET_CPU_ultrasparc3, "ultrasparc3" }, |  | ||||||
| +    { TARGET_CPU_niagara, "niagara" },
 |  | ||||||
|      { 0, 0 } |  | ||||||
|    }; |  | ||||||
|    const struct cpu_default *def; |  | ||||||
| @@ -632,6 +657,8 @@ sparc_override_options (void)
 |  | ||||||
|      /* TI ultrasparc III */ |  | ||||||
|      /* ??? Check if %y issue still holds true in ultra3.  */ |  | ||||||
|      { "ultrasparc3", PROCESSOR_ULTRASPARC3, MASK_ISA, MASK_V9|MASK_DEPRECATED_V8_INSNS}, |  | ||||||
| +    /* UltraSPARC T1 */
 |  | ||||||
| +    { "niagara", PROCESSOR_NIAGARA, MASK_ISA, MASK_V9|MASK_DEPRECATED_V8_INSNS},
 |  | ||||||
|      { 0, 0, 0, 0 } |  | ||||||
|    }; |  | ||||||
|    const struct cpu_table *cpu; |  | ||||||
| @@ -741,7 +768,8 @@ sparc_override_options (void)
 |  | ||||||
|    /* Supply a default value for align_functions.  */ |  | ||||||
|    if (align_functions == 0 |  | ||||||
|        && (sparc_cpu == PROCESSOR_ULTRASPARC |  | ||||||
| -	  || sparc_cpu == PROCESSOR_ULTRASPARC3))
 |  | ||||||
| +	  || sparc_cpu == PROCESSOR_ULTRASPARC3
 |  | ||||||
| +	  || sparc_cpu == PROCESSOR_NIAGARA))
 |  | ||||||
|      align_functions = 32; |  | ||||||
|   |  | ||||||
|    /* Validate PCC_STRUCT_RETURN.  */ |  | ||||||
| @@ -790,6 +818,9 @@ sparc_override_options (void)
 |  | ||||||
|      case PROCESSOR_ULTRASPARC3: |  | ||||||
|        sparc_costs = &ultrasparc3_costs; |  | ||||||
|        break; |  | ||||||
| +    case PROCESSOR_NIAGARA:
 |  | ||||||
| +      sparc_costs = &niagara_costs;
 |  | ||||||
| +      break;
 |  | ||||||
|      }; |  | ||||||
|   |  | ||||||
|  #ifdef TARGET_DEFAULT_LONG_DOUBLE_128 |  | ||||||
| @@ -7099,7 +7130,8 @@ sparc_initialize_trampoline (rtx tramp, 
 |  | ||||||
|       aligned on a 16 byte boundary so one flush clears it all.  */ |  | ||||||
|    emit_insn (gen_flush (validize_mem (gen_rtx_MEM (SImode, tramp)))); |  | ||||||
|    if (sparc_cpu != PROCESSOR_ULTRASPARC |  | ||||||
| -      && sparc_cpu != PROCESSOR_ULTRASPARC3)
 |  | ||||||
| +      && sparc_cpu != PROCESSOR_ULTRASPARC3
 |  | ||||||
| +      && sparc_cpu != PROCESSOR_NIAGARA)
 |  | ||||||
|      emit_insn (gen_flush (validize_mem (gen_rtx_MEM (SImode, |  | ||||||
|  						     plus_constant (tramp, 8))))); |  | ||||||
|   |  | ||||||
| @@ -7141,7 +7173,8 @@ sparc64_initialize_trampoline (rtx tramp
 |  | ||||||
|    emit_insn (gen_flushdi (validize_mem (gen_rtx_MEM (DImode, tramp)))); |  | ||||||
|   |  | ||||||
|    if (sparc_cpu != PROCESSOR_ULTRASPARC |  | ||||||
| -      && sparc_cpu != PROCESSOR_ULTRASPARC3)
 |  | ||||||
| +      && sparc_cpu != PROCESSOR_ULTRASPARC3
 |  | ||||||
| +      && sparc_cpu != PROCESSOR_NIAGARA)
 |  | ||||||
|      emit_insn (gen_flushdi (validize_mem (gen_rtx_MEM (DImode, plus_constant (tramp, 8))))); |  | ||||||
|   |  | ||||||
|    /* Call __enable_execute_stack after writing onto the stack to make sure |  | ||||||
| @@ -7321,6 +7354,8 @@ sparc_sched_init (FILE *dump ATTRIBUTE_U
 |  | ||||||
|  static int |  | ||||||
|  sparc_use_sched_lookahead (void) |  | ||||||
|  { |  | ||||||
| +  if (sparc_cpu == PROCESSOR_NIAGARA)
 |  | ||||||
| +    return 0;
 |  | ||||||
|    if (sparc_cpu == PROCESSOR_ULTRASPARC |  | ||||||
|        || sparc_cpu == PROCESSOR_ULTRASPARC3) |  | ||||||
|      return 4; |  | ||||||
| @@ -7336,6 +7371,7 @@ sparc_issue_rate (void)
 |  | ||||||
|  { |  | ||||||
|    switch (sparc_cpu) |  | ||||||
|      { |  | ||||||
| +    case PROCESSOR_NIAGARA:
 |  | ||||||
|      default: |  | ||||||
|        return 1; |  | ||||||
|      case PROCESSOR_V9: |  | ||||||
| --- gcc/config/sparc/sol2-bi.h	(revision 111647)
 |  | ||||||
| +++ gcc/config/sparc/sol2-bi.h	(revision 111648)
 |  | ||||||
| @@ -39,6 +39,15 @@
 |  | ||||||
|  #define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "b" |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#if TARGET_CPU_DEFAULT == TARGET_CPU_niagara
 |  | ||||||
| +#undef CPP_CPU64_DEFAULT_SPEC
 |  | ||||||
| +#define CPP_CPU64_DEFAULT_SPEC ""
 |  | ||||||
| +#undef ASM_CPU32_DEFAULT_SPEC
 |  | ||||||
| +#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plusb"
 |  | ||||||
| +#undef ASM_CPU64_DEFAULT_SPEC
 |  | ||||||
| +#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "b"
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
|  #if DEFAULT_ARCH32_P |  | ||||||
|  #define DEF_ARCH32_SPEC(__str) "%{!m64:" __str "}" |  | ||||||
|  #define DEF_ARCH64_SPEC(__str) "%{m64:" __str "}" |  | ||||||
| @@ -57,7 +66,7 @@
 |  | ||||||
|  %{mcpu=sparclite|mcpu-f930|mcpu=f934:-D__sparclite__} \ |  | ||||||
|  %{mcpu=v8:" DEF_ARCH32_SPEC("-D__sparcv8") "} \ |  | ||||||
|  %{mcpu=supersparc:-D__supersparc__ " DEF_ARCH32_SPEC("-D__sparcv8") "} \ |  | ||||||
| -%{mcpu=v9|mcpu=ultrasparc|mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
 |  | ||||||
| +%{mcpu=v9|mcpu=ultrasparc|mcpu=ultrasparc3|mcpu=niagara:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
 |  | ||||||
|  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \ |  | ||||||
|  " |  | ||||||
|   |  | ||||||
| @@ -66,7 +75,8 @@
 |  | ||||||
|  %{mcpu=v9:" DEF_ARCH32_SPEC("-xarch=v8plus") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "} \ |  | ||||||
|  %{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \ |  | ||||||
|  %{mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \ |  | ||||||
| -%{!mcpu=ultrasparc3:%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}}} \
 |  | ||||||
| +%{mcpu=niagara:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
 |  | ||||||
| +%{!mcpu=niagara:%{!mcpu=ultrasparc3:%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}}}} \
 |  | ||||||
|  %{!mcpu*:%(asm_cpu_default)} \ |  | ||||||
|  " |  | ||||||
|   |  | ||||||
| --- gcc/config/sparc/sparc.h	(revision 111647)
 |  | ||||||
| +++ gcc/config/sparc/sparc.h	(revision 111648)
 |  | ||||||
| @@ -206,7 +206,7 @@ extern enum cmodel sparc_cmodel;
 |  | ||||||
|     which requires the following macro to be true if enabled.  Prior to V9, |  | ||||||
|     there are no instructions to even talk about memory synchronization. |  | ||||||
|     Note that the UltraSPARC III processors don't implement RMO, unlike the |  | ||||||
| -   UltraSPARC II processors.
 |  | ||||||
| +   UltraSPARC II processors.  Niagara does not implement RMO either.
 |  | ||||||
|   |  | ||||||
|     Default to false; for example, Solaris never enables RMO, only ever uses |  | ||||||
|     total memory ordering (TMO).  */ |  | ||||||
| @@ -238,10 +238,12 @@ extern enum cmodel sparc_cmodel;
 |  | ||||||
|  #define TARGET_CPU_sparc64	7	/* alias */ |  | ||||||
|  #define TARGET_CPU_ultrasparc	8 |  | ||||||
|  #define TARGET_CPU_ultrasparc3	9 |  | ||||||
| +#define TARGET_CPU_niagara	10
 |  | ||||||
|   |  | ||||||
|  #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \ |  | ||||||
|   || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \ |  | ||||||
| - || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
 |  | ||||||
| + || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3 \
 |  | ||||||
| + || TARGET_CPU_DEFAULT == TARGET_CPU_niagara
 |  | ||||||
|   |  | ||||||
|  #define CPP_CPU32_DEFAULT_SPEC "" |  | ||||||
|  #define ASM_CPU32_DEFAULT_SPEC "" |  | ||||||
| @@ -262,6 +264,10 @@ extern enum cmodel sparc_cmodel;
 |  | ||||||
|  #define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__" |  | ||||||
|  #define ASM_CPU64_DEFAULT_SPEC "-Av9b" |  | ||||||
|  #endif |  | ||||||
| +#if TARGET_CPU_DEFAULT == TARGET_CPU_niagara
 |  | ||||||
| +#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
 |  | ||||||
| +#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
 |  | ||||||
| +#endif
 |  | ||||||
|   |  | ||||||
|  #else |  | ||||||
|   |  | ||||||
| @@ -352,6 +358,7 @@ extern enum cmodel sparc_cmodel;
 |  | ||||||
|  %{mcpu=v9:-D__sparc_v9__} \ |  | ||||||
|  %{mcpu=ultrasparc:-D__sparc_v9__} \ |  | ||||||
|  %{mcpu=ultrasparc3:-D__sparc_v9__} \ |  | ||||||
| +%{mcpu=niagara:-D__sparc_v9__} \
 |  | ||||||
|  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \ |  | ||||||
|  " |  | ||||||
|  #define CPP_ARCH32_SPEC "" |  | ||||||
| @@ -401,6 +408,7 @@ extern enum cmodel sparc_cmodel;
 |  | ||||||
|  %{mcpu=v9:-Av9} \ |  | ||||||
|  %{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \ |  | ||||||
|  %{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \ |  | ||||||
| +%{mcpu=niagara:%{!mv8plus:-Av9b}} \
 |  | ||||||
|  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \ |  | ||||||
|  " |  | ||||||
|   |  | ||||||
| @@ -524,7 +532,8 @@ enum processor_type {
 |  | ||||||
|    PROCESSOR_TSC701, |  | ||||||
|    PROCESSOR_V9, |  | ||||||
|    PROCESSOR_ULTRASPARC, |  | ||||||
| -  PROCESSOR_ULTRASPARC3
 |  | ||||||
| +  PROCESSOR_ULTRASPARC3,
 |  | ||||||
| +  PROCESSOR_NIAGARA
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  /* This is set from -m{cpu,tune}=xxx.  */ |  | ||||||
| @@ -2137,7 +2146,8 @@ do {                                    
 |  | ||||||
|      || (GENERAL_OR_I64 (CLASS1) && FP_REG_CLASS_P (CLASS2)) \ |  | ||||||
|      || (CLASS1) == FPCC_REGS || (CLASS2) == FPCC_REGS)		\ |  | ||||||
|     ? ((sparc_cpu == PROCESSOR_ULTRASPARC \ |  | ||||||
| -       || sparc_cpu == PROCESSOR_ULTRASPARC3) ? 12 : 6) : 2)
 |  | ||||||
| +       || sparc_cpu == PROCESSOR_ULTRASPARC3 \
 |  | ||||||
| +       || sparc_cpu == PROCESSOR_NIAGARA) ? 12 : 6) : 2)
 |  | ||||||
|   |  | ||||||
|  /* Provide the cost of a branch.  For pre-v9 processors we use |  | ||||||
|     a value of 3 to take into account the potential annulling of |  | ||||||
| @@ -2147,22 +2157,30 @@ do {                                    
 |  | ||||||
|   |  | ||||||
|     On v9 and later, which have branch prediction facilities, we set |  | ||||||
|     it to the depth of the pipeline as that is the cost of a |  | ||||||
| -   mispredicted branch.  */
 |  | ||||||
| +   mispredicted branch.
 |  | ||||||
| +
 |  | ||||||
| +   On Niagara, normal branches insert 3 bubbles into the pipe
 |  | ||||||
| +   and annulled branches insert 4 bubbles.  */
 |  | ||||||
|   |  | ||||||
|  #define BRANCH_COST \ |  | ||||||
|  	((sparc_cpu == PROCESSOR_V9 \ |  | ||||||
|  	  || sparc_cpu == PROCESSOR_ULTRASPARC) \ |  | ||||||
|  	 ? 7 \ |  | ||||||
|           : (sparc_cpu == PROCESSOR_ULTRASPARC3 \ |  | ||||||
| -            ? 9 : 3))
 |  | ||||||
| +            ? 9 \
 |  | ||||||
| +	 : (sparc_cpu == PROCESSOR_NIAGARA \
 |  | ||||||
| +	    ? 4 \
 |  | ||||||
| +	 : 3)))
 |  | ||||||
|   |  | ||||||
|  #define PREFETCH_BLOCK \ |  | ||||||
|  	((sparc_cpu == PROCESSOR_ULTRASPARC \ |  | ||||||
| -          || sparc_cpu == PROCESSOR_ULTRASPARC3) \
 |  | ||||||
| +          || sparc_cpu == PROCESSOR_ULTRASPARC3 \
 |  | ||||||
| +	  || sparc_cpu == PROCESSOR_NIAGARA) \
 |  | ||||||
|           ? 64 : 32) |  | ||||||
|   |  | ||||||
|  #define SIMULTANEOUS_PREFETCHES \ |  | ||||||
| -	((sparc_cpu == PROCESSOR_ULTRASPARC) \
 |  | ||||||
| +	((sparc_cpu == PROCESSOR_ULTRASPARC \
 |  | ||||||
| +	  || sparc_cpu == PROCESSOR_NIAGARA) \
 |  | ||||||
|           ? 2 \ |  | ||||||
|           : (sparc_cpu == PROCESSOR_ULTRASPARC3 \ |  | ||||||
|              ? 8 : 3)) |  | ||||||
| --- gcc/config/sparc/linux64.h	(revision 111647)
 |  | ||||||
| +++ gcc/config/sparc/linux64.h	(revision 111648)
 |  | ||||||
| @@ -43,7 +43,8 @@ Boston, MA 02110-1301, USA.  */
 |  | ||||||
|   |  | ||||||
|  #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \ |  | ||||||
|      || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \ |  | ||||||
| -    || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
 |  | ||||||
| +    || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3 \
 |  | ||||||
| +    || TARGET_CPU_DEFAULT == TARGET_CPU_niagara
 |  | ||||||
|  /* A 64 bit v9 compiler with stack-bias, |  | ||||||
|     in a Medium/Low code model environment.  */ |  | ||||||
|   |  | ||||||
| --- gcc/config/sparc/sol2.h	(revision 111647)
 |  | ||||||
| +++ gcc/config/sparc/sol2.h	(revision 111648)
 |  | ||||||
| @@ -41,11 +41,17 @@ Boston, MA 02110-1301, USA.  */
 |  | ||||||
|  #define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusb" |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#if TARGET_CPU_DEFAULT == TARGET_CPU_niagara
 |  | ||||||
| +#undef ASM_CPU_DEFAULT_SPEC
 |  | ||||||
| +#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusb"
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
|  #undef ASM_CPU_SPEC |  | ||||||
|  #define ASM_CPU_SPEC "\ |  | ||||||
|  %{mcpu=v9:-xarch=v8plus} \ |  | ||||||
|  %{mcpu=ultrasparc:-xarch=v8plusa} \ |  | ||||||
|  %{mcpu=ultrasparc3:-xarch=v8plusb} \ |  | ||||||
| +%{mcpu=niagara:-xarch=v8plusb} \
 |  | ||||||
|  %{!mcpu*:%(asm_cpu_default)} \ |  | ||||||
|  " |  | ||||||
|   |  | ||||||
							
								
								
									
										65
									
								
								gcc41.spec
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								gcc41.spec
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| %define DATE 20070821 | %define DATE 20070925 | ||||||
| %define gcc_version 4.1.2 | %define gcc_version 4.1.2 | ||||||
| %define gcc_release 26 | %define gcc_release 28 | ||||||
| %define _unpackaged_files_terminate_build 0 | %define _unpackaged_files_terminate_build 0 | ||||||
| %define multilib_64_archs sparc64 ppc64 s390x x86_64 | %define multilib_64_archs sparc64 ppc64 s390x x86_64 | ||||||
| %define include_gappletviewer 1 | %define include_gappletviewer 1 | ||||||
| @ -138,24 +138,13 @@ Patch21: gcc41-rh235008.patch | |||||||
| Patch22: gcc41-build-id.patch | Patch22: gcc41-build-id.patch | ||||||
| Patch23: gcc41-pr28690.patch | Patch23: gcc41-pr28690.patch | ||||||
| Patch24: gcc41-rh247256.patch | Patch24: gcc41-rh247256.patch | ||||||
| Patch25: gcc41-pr22244.patch | Patch25: gcc41-ppc64-ia64-GNU-stack.patch | ||||||
| Patch26: gcc41-pr32678.patch | Patch26: gcc41-pr33506.patch | ||||||
| Patch27: gcc41-pr32912.patch | Patch27: gcc41-artificial-attrib.patch | ||||||
| Patch28: gcc41-sparc-niagara.patch | Patch28: gcc41-error-attrib.patch | ||||||
| Patch29: gcc41-ppc-tramp.patch | Patch29: gcc41-jdwp.patch | ||||||
| Patch30: gcc41-rh253102.patch | Patch30: gcc41-pr20880.patch | ||||||
| Patch31: gcc41-c++-gnu_inline.patch | Patch31: gcc41-pr32694.patch | ||||||
| Patch32: gcc41-ppc-sync-qihi.patch |  | ||||||
| Patch33: gcc41-ppc64-ia64-GNU-stack.patch |  | ||||||
| Patch34: gcc41-builtin-chk-anticipated.patch |  | ||||||
| Patch35: gcc41-builtin-throw.patch |  | ||||||
| Patch36: gcc41-builtin-va-arg-pack.patch |  | ||||||
| Patch37: gcc41-builtin-va-arg-pack-len.patch |  | ||||||
| Patch38: gcc41-pr27954.patch |  | ||||||
| Patch39: gcc41-pr33423.patch |  | ||||||
| Patch40: gcc41-scanf-fmt-check.patch |  | ||||||
| Patch41: gcc41-pr33506.patch |  | ||||||
| Patch42: gcc41-makeinfo-ver.patch |  | ||||||
| 
 | 
 | ||||||
| # On ARM EABI systems, we do want -gnueabi to be part of the | # On ARM EABI systems, we do want -gnueabi to be part of the | ||||||
| # target triple. | # target triple. | ||||||
| @ -463,24 +452,13 @@ which are required to run programs compiled with the GNAT. | |||||||
| %patch22 -p0 -b .build-id~ | %patch22 -p0 -b .build-id~ | ||||||
| %patch23 -p0 -b .pr28690~ | %patch23 -p0 -b .pr28690~ | ||||||
| %patch24 -p0 -b .rh247256~ | %patch24 -p0 -b .rh247256~ | ||||||
| %patch25 -p0 -b .pr22244~ | %patch25 -p0 -b .ppc64-ia64-GNU-stack~ | ||||||
| %patch26 -p0 -b .pr32678~ | %patch26 -p0 -b .pr33506~ | ||||||
| %patch27 -p0 -b .pr32912~ | %patch27 -p0 -b .artificial-attrib~ | ||||||
| %patch28 -p0 -b .sparc-niagara~ | %patch28 -p0 -b .error-attrib~ | ||||||
| %patch29 -p0 -b .ppc-tramp~ | %patch29 -p0 -b .jdwp~ | ||||||
| %patch30 -p0 -b .rh253102~ | %patch30 -p0 -b .pr20880~ | ||||||
| %patch31 -p0 -b .c++-gnu_inline~ | %patch31 -p0 -b .pr32694~ | ||||||
| %patch32 -p0 -b .ppc-sync-qihi~ |  | ||||||
| %patch33 -p0 -b .ppc64-ia64-GNU-stack~ |  | ||||||
| %patch34 -p0 -b .builtin-chk-anticipated~ |  | ||||||
| %patch35 -p0 -b .builtin-throw~ |  | ||||||
| %patch36 -p0 -b .builtin-va-arg-pack~ |  | ||||||
| %patch37 -p0 -b .builtin-va-arg-pack-len~ |  | ||||||
| %patch38 -p0 -b .pr27954~ |  | ||||||
| %patch39 -p0 -b .pr33423~ |  | ||||||
| %patch40 -p0 -b .scanf-fmt-check~ |  | ||||||
| %patch41 -p0 -b .pr33506~ |  | ||||||
| %patch42 -p0 -b .makeinfo-ver~ |  | ||||||
| 
 | 
 | ||||||
| sed -i -e 's/4\.1\.3/4.1.2/' gcc/BASE-VER gcc/version.c | sed -i -e 's/4\.1\.3/4.1.2/' gcc/BASE-VER gcc/version.c | ||||||
| sed -i -e 's/" (Red Hat[^)]*)"/" (Red Hat %{version}-%{gcc_release})"/' gcc/version.c | sed -i -e 's/" (Red Hat[^)]*)"/" (Red Hat %{version}-%{gcc_release})"/' gcc/version.c | ||||||
| @ -1635,6 +1613,17 @@ fi | |||||||
| %doc rpm.doc/changelogs/libmudflap/ChangeLog* | %doc rpm.doc/changelogs/libmudflap/ChangeLog* | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Tue Sep 25 2007 Jakub Jelinek <jakub@redhat.com> 4.1.2-28 | ||||||
|  | - update from gcc-4_1-branch (-r127672:128736) | ||||||
|  |   - PRs bootstrap/33418, c++/31941, c++/32113, java/31842, target/33256, | ||||||
|  | 	tree-optimization/33142 | ||||||
|  | - add support for artificial, error and warning attributes | ||||||
|  | - restore Java CNI ABI compatibility broken by JDWP changes (Keith Seitz) | ||||||
|  | - fix ICE with set_rhs allowing non-gimple (Roger Sayle, #247407, | ||||||
|  |   PR tree-optimization/32694) | ||||||
|  | - fix ICE on Fortran interface-body declaring current subroutine name | ||||||
|  |   (Paul Thomas, #300851, PR fortran/20880) | ||||||
|  | 
 | ||||||
| * Sat Sep 22 2007 Jakub Jelinek <jakub@redhat.com> 4.1.2-26 | * Sat Sep 22 2007 Jakub Jelinek <jakub@redhat.com> 4.1.2-26 | ||||||
| - don't ignore throw specification of function types in type hashing | - don't ignore throw specification of function types in type hashing | ||||||
|   (PR c++/33506) |   (PR c++/33506) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user