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 | ||||
| 	* expr.c (expand_expr_real_1) <case ARRAY_REF>: Make sure | ||||
| 	the const array field optimization doesn't create an extra constant | ||||
| 	MEM. | ||||
| 	* expr.c (expand_constructor): New function. | ||||
| 	(expand_expr_real_1) <case CONSTRUCTOR>: Call it. | ||||
| 	(expand_expr_real_1) <case ARRAY_REF>: Call it if VALUE is | ||||
| 	CONSTRUCTOR. | ||||
| 
 | ||||
| 	* gcc.dg/pr28755.c: New test. | ||||
| 
 | ||||
| --- gcc/expr.c.jj	2006-08-09 17:54:03.000000000 +0200
 | ||||
| +++ gcc/expr.c	2006-08-17 13:00:33.000000000 +0200
 | ||||
| @@ -7105,13 +7105,25 @@ expand_expr_real_1 (tree exp, rtx target
 | ||||
| --- gcc/expr.c	(revision 128684)
 | ||||
| +++ gcc/expr.c	(revision 128685)
 | ||||
| @@ -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) | ||||
|  		      if (tree_int_cst_equal (field, index)) | ||||
|  			{ | ||||
| -			  if (!TREE_SIDE_EFFECTS (value))
 | ||||
| -			    return expand_expr (fold (value), target, tmode,
 | ||||
| -						modifier);
 | ||||
| -			  break;
 | ||||
| +			  if (TREE_SIDE_EFFECTS (value))
 | ||||
| +			    break;
 | ||||
| +
 | ||||
| +			  if (TREE_CODE (value) != CONSTRUCTOR)
 | ||||
|  			    return expand_expr (fold (value), target, tmode, | ||||
|  						modifier); | ||||
| +			  if (TREE_CODE (value) == CONSTRUCTOR)
 | ||||
| +			    {
 | ||||
| +			      /* 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
 | ||||
| +			     a win - if expand_expr creates a temporary
 | ||||
| +			     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; | ||||
| +			  return expand_expr (fold (value), target, tmode,
 | ||||
| +					      modifier);
 | ||||
|  			} | ||||
|  		  } | ||||
| -		else if(TREE_CODE (init) == STRING_CST)
 | ||||
| +		else if (TREE_CODE (init) == STRING_CST)
 | ||||
|  		  { | ||||
|  		    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
 | ||||
|  		else if(TREE_CODE (init) == STRING_CST) | ||||
| --- gcc/testsuite/gcc.dg/pr28755.c	(revision 0)
 | ||||
| +++ gcc/testsuite/gcc.dg/pr28755.c	(revision 128685)
 | ||||
| @@ -0,0 +1,22 @@
 | ||||
| +/* PR middle-end/28755 */
 | ||||
| +/* { 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_release 26 | ||||
| %define gcc_release 28 | ||||
| %define _unpackaged_files_terminate_build 0 | ||||
| %define multilib_64_archs sparc64 ppc64 s390x x86_64 | ||||
| %define include_gappletviewer 1 | ||||
| @ -138,24 +138,13 @@ Patch21: gcc41-rh235008.patch | ||||
| Patch22: gcc41-build-id.patch | ||||
| Patch23: gcc41-pr28690.patch | ||||
| Patch24: gcc41-rh247256.patch | ||||
| Patch25: gcc41-pr22244.patch | ||||
| Patch26: gcc41-pr32678.patch | ||||
| Patch27: gcc41-pr32912.patch | ||||
| Patch28: gcc41-sparc-niagara.patch | ||||
| Patch29: gcc41-ppc-tramp.patch | ||||
| Patch30: gcc41-rh253102.patch | ||||
| Patch31: gcc41-c++-gnu_inline.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 | ||||
| Patch25: gcc41-ppc64-ia64-GNU-stack.patch | ||||
| Patch26: gcc41-pr33506.patch | ||||
| Patch27: gcc41-artificial-attrib.patch | ||||
| Patch28: gcc41-error-attrib.patch | ||||
| Patch29: gcc41-jdwp.patch | ||||
| Patch30: gcc41-pr20880.patch | ||||
| Patch31: gcc41-pr32694.patch | ||||
| 
 | ||||
| # On ARM EABI systems, we do want -gnueabi to be part of the | ||||
| # target triple. | ||||
| @ -463,24 +452,13 @@ which are required to run programs compiled with the GNAT. | ||||
| %patch22 -p0 -b .build-id~ | ||||
| %patch23 -p0 -b .pr28690~ | ||||
| %patch24 -p0 -b .rh247256~ | ||||
| %patch25 -p0 -b .pr22244~ | ||||
| %patch26 -p0 -b .pr32678~ | ||||
| %patch27 -p0 -b .pr32912~ | ||||
| %patch28 -p0 -b .sparc-niagara~ | ||||
| %patch29 -p0 -b .ppc-tramp~ | ||||
| %patch30 -p0 -b .rh253102~ | ||||
| %patch31 -p0 -b .c++-gnu_inline~ | ||||
| %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~ | ||||
| %patch25 -p0 -b .ppc64-ia64-GNU-stack~ | ||||
| %patch26 -p0 -b .pr33506~ | ||||
| %patch27 -p0 -b .artificial-attrib~ | ||||
| %patch28 -p0 -b .error-attrib~ | ||||
| %patch29 -p0 -b .jdwp~ | ||||
| %patch30 -p0 -b .pr20880~ | ||||
| %patch31 -p0 -b .pr32694~ | ||||
| 
 | ||||
| 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 | ||||
| @ -1635,6 +1613,17 @@ fi | ||||
| %doc rpm.doc/changelogs/libmudflap/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 | ||||
| - don't ignore throw specification of function types in type hashing | ||||
|   (PR c++/33506) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user