OSDN Git Service

PR middle-end/14311
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Apr 2005 02:07:33 +0000 (02:07 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Apr 2005 02:07:33 +0000 (02:07 +0000)
        * 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
gcc/cp/semantics.c
gcc/testsuite/g++.dg/ext/sync-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/sync-2.C [new file with mode: 0644]

index 296f280..8f42b1f 100644 (file)
@@ -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
index e8240e8..ac678d5 100644 (file)
@@ -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 (file)
index 0000000..e4d6dff
--- /dev/null
@@ -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 (file)
index 0000000..5695684
--- /dev/null
@@ -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)