diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td index 5a9d9822dbfe3d..eb8034ee630ce8 100644 --- a/clang/lib/Sema/OpenCLBuiltins.td +++ b/clang/lib/Sema/OpenCLBuiltins.td @@ -82,6 +82,9 @@ def FuncExtKhrMipmapImage : FunctionExtension<"cl_khr_mipmap_imag def FuncExtKhrMipmapImageWrites : FunctionExtension<"cl_khr_mipmap_image_writes">; def FuncExtKhrGlMsaaSharing : FunctionExtension<"cl_khr_gl_msaa_sharing">; +// Not a real extension, but a workaround to add C++ for OpenCL specific builtins. +def FuncExtOpenCLCxx : FunctionExtension<"__cplusplus">; + // Multiple extensions def FuncExtKhrMipmapWritesAndWrite3d : FunctionExtension<"cl_khr_mipmap_image_writes cl_khr_3d_image_writes">; @@ -1077,6 +1080,17 @@ foreach AS = [GlobalAS, LocalAS] in { } } } + +let Extension = FuncExtOpenCLCxx in { + foreach Type = [Int, UInt] in { + foreach name = ["atomic_add", "atomic_sub", "atomic_xchg", + "atomic_min", "atomic_max", "atomic_and", + "atomic_or", "atomic_xor"] in { + def : Builtin, GenericAS>, Type]>; + } + } +} + // OpenCL v2.0 s6.13.11 - Atomic Functions. let MinVersion = CL20 in { def : Builtin<"atomic_work_item_fence", [Void, MemFenceFlags, MemoryOrder, MemoryScope]>; diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl index 36bdcffbeca483..32457eb939c033 100644 --- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl @@ -122,6 +122,17 @@ void test_atomic_fetch(volatile __generic atomic_int *a_int, } #endif +// Test old atomic overloaded with generic address space in C++ for OpenCL. +#if __OPENCL_C_VERSION__ >= 200 +void test_legacy_atomics_cpp(__generic volatile unsigned int *a) { + atomic_add(a, 1); +#if !defined(__cplusplus) + // expected-error@-2{{no matching function for call to 'atomic_add'}} + // expected-note@-3 4 {{candidate function not viable}} +#endif +} +#endif + kernel void basic_conversion() { float f; char2 c2;