diff options
author | Richard Henderson <rth@redhat.com> | 2005-04-15 19:07:33 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-04-15 19:07:33 -0700 |
commit | 16c35a1fdc507fed4ae66a12c618c916375dc59a (patch) | |
tree | ce0de1f13cb59f59c4397ecabcabe40de0180f95 /gcc | |
parent | 054632e8ab08921f7da62bdd84ec5270f0da8191 (diff) | |
download | gcc-16c35a1fdc507fed4ae66a12c618c916375dc59a.zip gcc-16c35a1fdc507fed4ae66a12c618c916375dc59a.tar.gz gcc-16c35a1fdc507fed4ae66a12c618c916375dc59a.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/sync-1.C | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/sync-2.C | 58 |
4 files changed, 114 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 296f280..8f42b1f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2005-04-15 Richard Henderson <rth@redhat.com> + + PR middle-end/14311 + * semantics.c (finish_call_expr): Call resolve_overloaded_builtin. + 2005-04-15 Kazu Hirata <kazu@cs.umass.edu> * cp-tree.h (lang_type_class): Remove redefined. Move diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e8240e8..ac678d5 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 0000000..e4d6dff --- /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 0000000..5695684 --- /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<typename T> \ +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<typename T> +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) |