From 87daa93b27b9afb92a0a0cf88740ca0c2cf8b2ee Mon Sep 17 00:00:00 2001 From: rth Date: Sat, 16 Apr 2005 02:07:33 +0000 Subject: [PATCH] PR middle-end/14311 * semantics.c (finish_call_expr): Call resolve_overloaded_builtin. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98221 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 296f280..8f42b1f 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 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 \ +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) -- 2.7.4