From 16c35a1fdc507fed4ae66a12c618c916375dc59a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Apr 2005 19:07:33 -0700 Subject: [PATCH] re PR middle-end/14311 (builtins for atomic operations needed) PR middle-end/14311 * semantics.c (finish_call_expr): Call resolve_overloaded_builtin. From-SVN: r98221 --- gcc/cp/ChangeLog | 5 +++ gcc/cp/semantics.c | 13 +++++-- gcc/testsuite/g++.dg/ext/sync-1.C | 40 +++++++++++++++++++++ gcc/testsuite/g++.dg/ext/sync-2.C | 58 +++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/sync-1.C create mode 100644 gcc/testsuite/g++.dg/ext/sync-2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 296f280fd2b..8f42b1f76b6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2005-04-15 Richard Henderson + + PR middle-end/14311 + * semantics.c (finish_call_expr): Call resolve_overloaded_builtin. + 2005-04-15 Kazu Hirata * cp-tree.h (lang_type_class): Remove redefined. Move diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e8240e8b29d..ac678d5cdd5 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1833,8 +1833,16 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p) ? LOOKUP_NONVIRTUAL : 0)); } else if (is_overloaded_fn (fn)) - /* A call to a namespace-scope function. */ - result = build_new_function_call (fn, args); + { + /* If the function is an overloaded builtin, resolve it. */ + if (TREE_CODE (fn) == FUNCTION_DECL + && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL) + result = resolve_overloaded_builtin (fn, args); + + if (!result) + /* A call to a namespace-scope function. */ + result = build_new_function_call (fn, args); + } else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) { if (args) @@ -1851,6 +1859,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p) have an overloaded `operator ()'. */ result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE, /*overloaded_p=*/NULL); + if (!result) /* A call where the function is unknown. */ result = build_function_call (fn, args); diff --git a/gcc/testsuite/g++.dg/ext/sync-1.C b/gcc/testsuite/g++.dg/ext/sync-1.C new file mode 100644 index 00000000000..e4d6dff6145 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/sync-1.C @@ -0,0 +1,40 @@ +// Validate that the __sync builtins are overloaded properly. +// { dg-do compile } +// { dg-options "-Werror" } + +#define TEST1(TYPE, BUILTIN) \ +void t_##TYPE##BUILTIN(TYPE *p) \ +{ \ + __typeof(BUILTIN(p, 1)) *pp; \ + pp = p; \ +} + +#define TEST2(BUILTIN) \ + TEST1(int, BUILTIN) \ + TEST1(long, BUILTIN) + +TEST2(__sync_fetch_and_add) +TEST2(__sync_fetch_and_sub) +TEST2(__sync_fetch_and_or) +TEST2(__sync_fetch_and_and) +TEST2(__sync_fetch_and_xor) +TEST2(__sync_fetch_and_nand) + +TEST2(__sync_add_and_fetch) +TEST2(__sync_sub_and_fetch) +TEST2(__sync_or_and_fetch) +TEST2(__sync_and_and_fetch) +TEST2(__sync_xor_and_fetch) +TEST2(__sync_nand_and_fetch) + +TEST2(__sync_lock_test_and_set) + +#define TEST3(TYPE) \ +void t_##TYPE##__sync_val_compare_and_swap(TYPE *p) \ +{ \ + __typeof(__sync_val_compare_and_swap(p, 1, 2)) *pp; \ + pp = p; \ +} + +TEST3(int) +TEST3(long) diff --git a/gcc/testsuite/g++.dg/ext/sync-2.C b/gcc/testsuite/g++.dg/ext/sync-2.C new file mode 100644 index 00000000000..5695684c3e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/sync-2.C @@ -0,0 +1,58 @@ +// Validate that the __sync builtins are overloaded properly in templates. +// { dg-do compile } +// { dg-options "-Werror" } + + +#define TEST1(BUILTIN) \ +template \ +void f##BUILTIN(T *p) \ +{ \ + __typeof(BUILTIN(p, 1)) *pp; \ + pp = p; \ +} + +TEST1(__sync_fetch_and_add) +TEST1(__sync_fetch_and_sub) +TEST1(__sync_fetch_and_or) +TEST1(__sync_fetch_and_and) +TEST1(__sync_fetch_and_xor) +TEST1(__sync_fetch_and_nand) + +TEST1(__sync_add_and_fetch) +TEST1(__sync_sub_and_fetch) +TEST1(__sync_or_and_fetch) +TEST1(__sync_and_and_fetch) +TEST1(__sync_xor_and_fetch) +TEST1(__sync_nand_and_fetch) + +TEST1(__sync_lock_test_and_set) + +template +void f__sync_val_compare_and_swap(T *p) +{ + __typeof(__sync_val_compare_and_swap(p, 1, 2)) *pp; + pp = p; +} + +#define TEST2(TYPE) \ +void h_##TYPE () \ +{ \ + TYPE x; \ + f__sync_fetch_and_add (&x); \ + f__sync_fetch_and_sub (&x); \ + f__sync_fetch_and_or (&x); \ + f__sync_fetch_and_and (&x); \ + f__sync_fetch_and_xor (&x); \ + f__sync_fetch_and_nand (&x); \ + f__sync_add_and_fetch (&x); \ + f__sync_sub_and_fetch (&x); \ + f__sync_or_and_fetch (&x); \ + f__sync_and_and_fetch (&x); \ + f__sync_xor_and_fetch (&x); \ + f__sync_nand_and_fetch (&x); \ + f__sync_lock_test_and_set (&x); \ + f__sync_val_compare_and_swap (&x); \ +} + +TEST2(int) +TEST2(long)