summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/arm/arm.c112
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/g++.dg/abi/arm_va_list.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C1
-rw-r--r--gcc/testsuite/g++.dg/other/stdarg1.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-1.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-3.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-4.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-5.C1
-rw-r--r--gcc/testsuite/g++.dg/warn/miss-format-6.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/vaarg2.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/vaarg3.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/vaarg4.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/builtin.C1
-rw-r--r--gcc/testsuite/gcc.target/arm/va_list.c25
-rw-r--r--gcc/testsuite/lib/target-supports.exp13
17 files changed, 204 insertions, 3 deletions
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 <mark@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * 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 <jakub@redhat.com>
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 <stdarg.h>. */
+ /* 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 %<va_list%> 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 <mark@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * 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 <howarth@bromo.med.uc.edu>
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 <stdarg.h>
+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 <stdarg.h>
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 <stdarg.h>
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 <jsm28@cam.ac.uk> */
/* { 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 <ghazi@caip.rutgers.edu> */
/* { dg-do compile } */
/* { dg-options "-Wmissing-format-attribute" } */
+/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */
#include <stdarg.h>
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 <ghazi@caip.rutgers.edu> */
/* { dg-do compile } */
/* { dg-options "-Wmissing-format-attribute" } */
+/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */
#include <stdarg.h>
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 <ghazi@caip.rutgers.edu> */
/* { dg-do compile } */
/* { dg-options "-Wmissing-format-attribute" } */
+/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */
#include <stdarg.h>
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 <ghazi@caip.rutgers.edu> */
/* { dg-do compile } */
/* { dg-options "-Wmissing-format-attribute" } */
+/* { dg-options "-Wmissing-format-attribute -Wno-abi" { target arm_eabi } } */
#include <stdarg.h>
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 <nathan@acm.org>
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 <nathan@acm.org>
@@ -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 <stdarg.h>
+#include <stddef.h>
+
+/* 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 { } {