From 07d8efe38503f0e330c788d8ad5949e55657d915 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 20 Feb 2009 15:19:38 +0000 Subject: [PATCH] arm.c (arm_builtin_va_list): New function. 2009-02-20 Mark Mitchell Joseph Myers * config/arm/arm.c (arm_builtin_va_list): New function. (arm_expand_builtin_va_start): Likewise. (arm_gimplify_va_arg_expr): Likewise. (TARGET_BUILD_BUILTIN_VA_LIST): Define. (TARGET_BUILD_BUILTIN_VA_START): Likewise. (TARGET_BUILD_BUILTIN_VA_ARG_EXPR): Likewise. (va_list_type): New variable. (arm_mangle_type): Mangle va_list_type appropriately. testsuite: * gcc.target/arm/va_list.c: New test. * g++.dg/abi/arm_va_list.C: Likewise. * lib/target-supports.exp (check_effective_target_arm_eabi): New function. * g++.dg/cpp0x/temp-va-arg-bug.C, g++.dg/other/stdarg1.C, g++.dg/warn/miss-format-1.C, g++.dg/warn/miss-format-3.C, g++.dg/warn/miss-format-4.C, g++.dg/warn/miss-format-5.C, g++.dg/warn/miss-format-6.C, g++.old-deja/g++.other/vaarg2.C, g++.old-deja/g++.other/vaarg3.C, g++.old-deja/g++.other/vaarg4.C, g++.old-deja/g++.pt/builtin.C: Use -Wno-abi on ARM EABI targets. Co-Authored-By: Joseph Myers From-SVN: r144323 --- gcc/ChangeLog | 12 ++ gcc/config/arm/arm.c | 112 ++++++++++++++++++ gcc/testsuite/ChangeLog | 14 +++ gcc/testsuite/g++.dg/abi/arm_va_list.C | 14 +++ gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C | 1 + gcc/testsuite/g++.dg/other/stdarg1.C | 1 + gcc/testsuite/g++.dg/warn/miss-format-1.C | 1 + gcc/testsuite/g++.dg/warn/miss-format-3.C | 1 + gcc/testsuite/g++.dg/warn/miss-format-4.C | 1 + gcc/testsuite/g++.dg/warn/miss-format-5.C | 1 + gcc/testsuite/g++.dg/warn/miss-format-6.C | 1 + gcc/testsuite/g++.old-deja/g++.other/vaarg2.C | 1 + gcc/testsuite/g++.old-deja/g++.other/vaarg3.C | 7 +- gcc/testsuite/g++.old-deja/g++.other/vaarg4.C | 1 + gcc/testsuite/g++.old-deja/g++.pt/builtin.C | 1 + gcc/testsuite/gcc.target/arm/va_list.c | 25 ++++ gcc/testsuite/lib/target-supports.exp | 13 ++ 17 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/arm_va_list.C create mode 100644 gcc/testsuite/gcc.target/arm/va_list.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb0ad681a4a..70871ff1281 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-02-20 Mark Mitchell + Joseph Myers + + * config/arm/arm.c (arm_builtin_va_list): New function. + (arm_expand_builtin_va_start): Likewise. + (arm_gimplify_va_arg_expr): Likewise. + (TARGET_BUILD_BUILTIN_VA_LIST): Define. + (TARGET_BUILD_BUILTIN_VA_START): Likewise. + (TARGET_BUILD_BUILTIN_VA_ARG_EXPR): Likewise. + (va_list_type): New variable. + (arm_mangle_type): Mangle va_list_type appropriately. + 2009-02-20 Jakub Jelinek PR middle-end/39157 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index ddcdf5a619b..772f1fc5652 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -186,6 +186,9 @@ static void arm_cxx_determine_class_data_visibility (tree); static bool arm_cxx_class_data_always_comdat (void); static bool arm_cxx_use_aeabi_atexit (void); static void arm_init_libfuncs (void); +static tree arm_build_builtin_va_list (void); +static void arm_expand_builtin_va_start (tree, rtx); +static tree arm_gimplify_va_arg_expr (tree, tree, tree *, tree *); static bool arm_handle_option (size_t, const char *, int); static void arm_target_help (void); static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode); @@ -383,6 +386,13 @@ static bool arm_allocate_stack_slots_for_args (void); #undef TARGET_MANGLE_TYPE #define TARGET_MANGLE_TYPE arm_mangle_type +#undef TARGET_BUILD_BUILTIN_VA_LIST +#define TARGET_BUILD_BUILTIN_VA_LIST arm_build_builtin_va_list +#undef TARGET_EXPAND_BUILTIN_VA_START +#define TARGET_EXPAND_BUILTIN_VA_START arm_expand_builtin_va_start +#undef TARGET_GIMPLIFY_VA_ARG_EXPR +#define TARGET_GIMPLIFY_VA_ARG_EXPR arm_gimplify_va_arg_expr + #ifdef HAVE_AS_TLS #undef TARGET_ASM_OUTPUT_DWARF_DTPREL #define TARGET_ASM_OUTPUT_DWARF_DTPREL arm_output_dwarf_dtprel @@ -914,6 +924,93 @@ arm_init_libfuncs (void) set_optab_libfunc (umod_optab, SImode, NULL); } +/* On AAPCS systems, this is the "struct __va_list". */ +static GTY(()) tree va_list_type; + +/* Return the type to use as __builtin_va_list. */ +static tree +arm_build_builtin_va_list (void) +{ + tree va_list_name; + tree ap_field; + + if (!TARGET_AAPCS_BASED) + return std_build_builtin_va_list (); + + /* AAPCS \S 7.1.4 requires that va_list be a typedef for a type + defined as: + + struct __va_list + { + void *__ap; + }; + + The C Library ABI further reinforces this definition in \S + 4.1. + + We must follow this definition exactly. The structure tag + name is visible in C++ mangled names, and thus forms a part + of the ABI. The field name may be used by people who + #include . */ + /* Create the type. */ + va_list_type = lang_hooks.types.make_type (RECORD_TYPE); + /* Give it the required name. */ + va_list_name = build_decl (TYPE_DECL, + get_identifier ("__va_list"), + va_list_type); + DECL_ARTIFICIAL (va_list_name) = 1; + TYPE_NAME (va_list_type) = va_list_name; + /* Create the __ap field. */ + ap_field = build_decl (FIELD_DECL, + get_identifier ("__ap"), + ptr_type_node); + DECL_ARTIFICIAL (ap_field) = 1; + DECL_FIELD_CONTEXT (ap_field) = va_list_type; + TYPE_FIELDS (va_list_type) = ap_field; + /* Compute its layout. */ + layout_type (va_list_type); + + return va_list_type; +} + +/* Return an expression of type "void *" pointing to the next + available argument in a variable-argument list. VALIST is the + user-level va_list object, of type __builtin_va_list. */ +static tree +arm_extract_valist_ptr (tree valist) +{ + if (TREE_TYPE (valist) == error_mark_node) + return error_mark_node; + + /* On an AAPCS target, the pointer is stored within "struct + va_list". */ + if (TARGET_AAPCS_BASED) + { + tree ap_field = TYPE_FIELDS (TREE_TYPE (valist)); + valist = build3 (COMPONENT_REF, TREE_TYPE (ap_field), + valist, ap_field, NULL_TREE); + } + + return valist; +} + +/* Implement TARGET_EXPAND_BUILTIN_VA_START. */ +static void +arm_expand_builtin_va_start (tree valist, rtx nextarg) +{ + valist = arm_extract_valist_ptr (valist); + std_expand_builtin_va_start (valist, nextarg); +} + +/* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */ +static tree +arm_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, + tree *post_p) +{ + valist = arm_extract_valist_ptr (valist); + return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); +} + /* Implement TARGET_HANDLE_OPTION. */ static bool @@ -19506,6 +19603,21 @@ arm_mangle_type (const_tree type) { arm_mangle_map_entry *pos = arm_mangle_map; + /* The ARM ABI documents (10th October 2008) say that "__va_list" + has to be managled as if it is in the "std" namespace. */ + if (TARGET_AAPCS_BASED + && lang_hooks.types_compatible_p (type, va_list_type)) + { + static bool warned; + if (!warned && warn_psabi) + { + warned = true; + inform (input_location, + "the mangling of % has changed in GCC 4.4"); + } + return "St9__va_list"; + } + if (TREE_CODE (type) != VECTOR_TYPE) return NULL; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9505f9bb84f..866f6ae3c33 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2009-02-20 Mark Mitchell + Joseph Myers + + * gcc.target/arm/va_list.c: New test. + * g++.dg/abi/arm_va_list.C: Likewise. + * lib/target-supports.exp (check_effective_target_arm_eabi): New + function. + * g++.dg/cpp0x/temp-va-arg-bug.C, g++.dg/other/stdarg1.C, + g++.dg/warn/miss-format-1.C, g++.dg/warn/miss-format-3.C, + g++.dg/warn/miss-format-4.C, g++.dg/warn/miss-format-5.C, + g++.dg/warn/miss-format-6.C, g++.old-deja/g++.other/vaarg2.C, + g++.old-deja/g++.other/vaarg3.C, g++.old-deja/g++.other/vaarg4.C, + g++.old-deja/g++.pt/builtin.C: Use -Wno-abi on ARM EABI targets. + 2009-02-20 Jack Howarth PR testsuite/38164 diff --git a/gcc/testsuite/g++.dg/abi/arm_va_list.C b/gcc/testsuite/g++.dg/abi/arm_va_list.C new file mode 100644 index 00000000000..45a426a4f38 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/arm_va_list.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-Wno-abi" } +// { dg-require-effective-target arm_eabi } + +// AAPCS \S 7.1.4 requires that va_list be a typedef for "struct +// __va_list". The mangling is as if it were "std::__va_list". +// #include +typedef __builtin_va_list va_list; + +// { dg-final { scan-assembler "\n_Z1fPSt9__va_list:" } } +void f(va_list*) {} + +// { dg-final { scan-assembler "\n_Z1gSt9__va_listS_:" } } +void g(va_list, va_list) {} diff --git a/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C b/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C index 5314b24d1e0..085915f907e 100644 --- a/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C +++ b/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C @@ -1,4 +1,5 @@ // { dg-options "--std=c++0x" } +// { dg-options "-Wno-abi --std=c++0x" { target arm_eabi } } #include struct S { }; diff --git a/gcc/testsuite/g++.dg/other/stdarg1.C b/gcc/testsuite/g++.dg/other/stdarg1.C index e005199d37a..1ac9e8fb229 100644 --- a/gcc/testsuite/g++.dg/other/stdarg1.C +++ b/gcc/testsuite/g++.dg/other/stdarg1.C @@ -1,5 +1,6 @@ // Test stdarg function with anonymous argument // { dg-do run } +// { dg-options "-Wno-abi" { target arm_eabi } } #include diff --git a/gcc/testsuite/g++.dg/warn/miss-format-1.C b/gcc/testsuite/g++.dg/warn/miss-format-1.C index faa3583670d..9d99cdbfff0 100644 --- a/gcc/testsuite/g++.dg/warn/miss-format-1.C +++ b/gcc/testsuite/g++.dg/warn/miss-format-1.C @@ -2,6 +2,7 @@ /* Origin: Joseph Myers */ /* { dg-do compile } */ /* { dg-options "-Wmissing-format-attribute" } */ +/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */ /* VxWorks does not provide vscanf, either in kernel or RTP mode. */ /* { dg-error "not declared" "" { target *-*-solaris2.[7-8] *-*-vxworks* } 25 } */ diff --git a/gcc/testsuite/g++.dg/warn/miss-format-3.C b/gcc/testsuite/g++.dg/warn/miss-format-3.C index 0f61400b1b7..d131d151175 100644 --- a/gcc/testsuite/g++.dg/warn/miss-format-3.C +++ b/gcc/testsuite/g++.dg/warn/miss-format-3.C @@ -2,6 +2,7 @@ /* Origin: Kaveh Ghazi */ /* { dg-do compile } */ /* { dg-options "-Wmissing-format-attribute" } */ +/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */ #include diff --git a/gcc/testsuite/g++.dg/warn/miss-format-4.C b/gcc/testsuite/g++.dg/warn/miss-format-4.C index 1a89abd5a39..73db0d50baa 100644 --- a/gcc/testsuite/g++.dg/warn/miss-format-4.C +++ b/gcc/testsuite/g++.dg/warn/miss-format-4.C @@ -2,6 +2,7 @@ /* Origin: Kaveh Ghazi */ /* { dg-do compile } */ /* { dg-options "-Wmissing-format-attribute" } */ +/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */ #include diff --git a/gcc/testsuite/g++.dg/warn/miss-format-5.C b/gcc/testsuite/g++.dg/warn/miss-format-5.C index 452e812aeb6..cbc27b5e572 100644 --- a/gcc/testsuite/g++.dg/warn/miss-format-5.C +++ b/gcc/testsuite/g++.dg/warn/miss-format-5.C @@ -2,6 +2,7 @@ /* Origin: Kaveh Ghazi */ /* { dg-do compile } */ /* { dg-options "-Wmissing-format-attribute" } */ +/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */ #include diff --git a/gcc/testsuite/g++.dg/warn/miss-format-6.C b/gcc/testsuite/g++.dg/warn/miss-format-6.C index f38e4ca128e..f78dbdfa1fd 100644 --- a/gcc/testsuite/g++.dg/warn/miss-format-6.C +++ b/gcc/testsuite/g++.dg/warn/miss-format-6.C @@ -2,6 +2,7 @@ /* Origin: Kaveh Ghazi */ /* { dg-do compile } */ /* { dg-options "-Wmissing-format-attribute" } */ +/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */ #include diff --git a/gcc/testsuite/g++.old-deja/g++.other/vaarg2.C b/gcc/testsuite/g++.old-deja/g++.other/vaarg2.C index 2992a25a094..278f5376f43 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/vaarg2.C +++ b/gcc/testsuite/g++.old-deja/g++.other/vaarg2.C @@ -1,4 +1,5 @@ // { dg-do run } +// { dg-options "-Wno-abi" { target arm_eabi } } // Copyright (C) 1999, 2000 Free Software Foundation, Inc. // Contributed by Nathan Sidwell 4 Oct 1999 diff --git a/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C b/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C index 8ed6df78632..f852b08ce5a 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C +++ b/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C @@ -1,4 +1,5 @@ // { dg-do assemble } +// { dg-options "-Wno-abi" { target arm_eabi } } // Copyright (C) 1999 Free Software Foundation, Inc. // Contributed by Nathan Sidwell 4 Oct 1999 @@ -21,10 +22,10 @@ void fn1(va_list args) const Z &z2 = va_arg (args, Z); // { dg-error "incomplete" } va_arg (args, char); // { dg-warning "promote" } - // { dg-message "should pass" "pass" { target *-*-* } 23 } - // { dg-message "abort" "abort" { target *-*-* } 23 } + // { dg-message "should pass" "pass" { target *-*-* } 24 } + // { dg-message "abort" "abort" { target *-*-* } 24 } va_arg (args, int []); // { dg-error "array with unspecified bounds" } promote va_arg (args, int ()); // { dg-warning "non-POD" } promote va_arg (args, bool); // { dg-warning "promote" "promote" } - // { dg-message "abort" "abort" { target *-*-* } 28 } + // { dg-message "abort" "abort" { target *-*-* } 29 } } diff --git a/gcc/testsuite/g++.old-deja/g++.other/vaarg4.C b/gcc/testsuite/g++.old-deja/g++.other/vaarg4.C index 3f08b0a4221..9ea165bda74 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/vaarg4.C +++ b/gcc/testsuite/g++.old-deja/g++.other/vaarg4.C @@ -1,4 +1,5 @@ // { dg-do assemble } +// { dg-options "-Wno-abi" { target arm_eabi } } // Bug 845. We were treating __builtin_va_arg as a unary expr, not a primary, // and hence getting parse errors. diff --git a/gcc/testsuite/g++.old-deja/g++.pt/builtin.C b/gcc/testsuite/g++.old-deja/g++.pt/builtin.C index cd79d8a375f..0a2e241de00 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/builtin.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/builtin.C @@ -1,4 +1,5 @@ // { dg-do assemble } +// { dg-options "-Wno-abi" { target arm_eabi } } // Bug: Checking whether A depends on template parms, we crash because // __builtin_va_list lacks TYPE_LANG_SPECIFIC. diff --git a/gcc/testsuite/gcc.target/arm/va_list.c b/gcc/testsuite/gcc.target/arm/va_list.c new file mode 100644 index 00000000000..b988a0d3365 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/va_list.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-require-effective-target arm_eabi } */ + +#include +#include + +/* AAPCS \S 7.1.4 requires that va_list match the structure shown + here */ +typedef struct my_va_list +{ + void *ap; +} my_va_list; + +int +main () { + if (sizeof (va_list) != sizeof (my_va_list)) + return 1; + /* This check confirms both that "va_list" has a member named "__ap" + and that it is located at the correct position. */ + if (offsetof (va_list, __ap) + != offsetof (my_va_list, ap)) + return 2; + + return 0; +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 12dc6852255..03c1779a600 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1451,6 +1451,19 @@ proc check_effective_target_mips_loongson { } { }] } +# Return 1 if this is an ARM target that adheres to the ABI for the ARM +# Architecture. + +proc check_effective_target_arm_eabi { } { + return [check_no_compiler_messages arm_eabi object { + #ifndef __ARM_EABI__ + #error not EABI + #else + int dummy; + #endif + }] +} + # Return 1 if this is a PowerPC target with floating-point registers. proc check_effective_target_powerpc_fprs { } {