https://github.com/piotrrak created 
https://github.com/llvm/llvm-project/pull/153508

The default OpenCL address-space was added for function types, which was
breaking transform type builtins for function types, in particular:

- __remove_reference_t
- __remove_cvref
- __remove_pointer

This change fixes SemaCXX/type-traits.cpp pass for clc++ dialect.
(In feature set of clc++ and extension - ie. no VLA, _Atomic etc...)

There is still unaddressed issue with address space of member-fn-ptr
in __is_same trait builtin as address-space specified by user is
ignored on such types.

This is separate unrelated issue and won't be addressed in this change.


>From c15f2c958f51ed3f0de5f33f9f58b3ec1f978632 Mon Sep 17 00:00:00 2001
From: Piotr Rak <piotr....@gmail.com>
Date: Wed, 30 Jul 2025 03:05:35 +0200
Subject: [PATCH 1/3] [OpenCLCpp] Remove address-space from friend declaration

OpenCL prohibits address-space on function, however it
default address-space is implicitly to all member decls.

This causes the lookup to fail find correct free function or free function
template as it is considered different declaration.

This change also makes sure that hidden friend definition doesn't have
associated address-space.

Without this change friend declaration would cause incorrect diagnostic:

'test/SemaCXX/friend.cpp Line 16: conflicting types for 'f'`

in case of prior definition of function f friend declaration was refering to

While bit unsatisfactory it was much easier to fix/remove address-space of
friend declaration since it is still required for friend of member function
decls.

This change also enables compilation of some of failing test exposing this 
defect.

It was originally exhibited by 'test/SemaCXX/type-traits.cpp', however this test
has currently other issues also related to the __cl_clang_function_pointers
extension and address-space inferrence preventing from enabling it by the 
defaut.
---
 clang/include/clang/AST/Type.h                 |  6 ++++++
 clang/include/clang/Sema/SemaOpenCL.h          |  3 +++
 clang/lib/Sema/SemaDecl.cpp                    |  6 ++++++
 clang/lib/Sema/SemaOpenCL.cpp                  | 12 ++++++++++++
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp |  6 ++++++
 clang/test/SemaCXX/friend-template-redecl.cpp  |  1 +
 clang/test/SemaCXX/friend.cpp                  |  1 +
 clang/test/SemaCXX/friend2.cpp                 | 11 ++++++-----
 8 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index c4c23c835ebc2..c3c3902a00731 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -5349,6 +5349,12 @@ class FunctionProtoType final
       return Result;
     }
 
+    ExtProtoInfo withoutAddressSpace() {
+      ExtProtoInfo Result(*this);
+      Result.TypeQuals = TypeQuals.withoutAddressSpace();
+      return Result;
+    }
+
     bool requiresFunctionProtoTypeExtraBitfields() const {
       return ExceptionSpec.Type == EST_Dynamic ||
              requiresFunctionProtoTypeArmAttributes() ||
diff --git a/clang/include/clang/Sema/SemaOpenCL.h 
b/clang/include/clang/Sema/SemaOpenCL.h
index 04b2b617fb12f..715b5845f2151 100644
--- a/clang/include/clang/Sema/SemaOpenCL.h
+++ b/clang/include/clang/Sema/SemaOpenCL.h
@@ -100,6 +100,9 @@ class SemaOpenCL : public SemaBase {
   bool checkBuiltinKernelWorkGroupSize(CallExpr *TheCall);
 
   bool checkBuiltinNDRangeAndBlock(CallExpr *TheCall);
+
+  void removeFriendFunctionAddressSpace(FunctionDecl *FD,
+                                        TypeSourceInfo *TInfo);
 };
 
 } // namespace clang
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cb59782b83304..ff641ee033928 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -51,6 +51,7 @@
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
 #include "clang/Sema/SemaOpenACC.h"
+#include "clang/Sema/SemaOpenCL.h"
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/SemaPPC.h"
 #include "clang/Sema/SemaRISCV.h"
@@ -10300,6 +10301,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, 
DeclContext *DC,
       }
       NewFD->setObjectOfFriendDecl();
       NewFD->setAccess(AS_public);
+      // For OpenCLCPlusPlus dialect remove address space from free friend
+      // function prototype, since it is non-member and none should be present.
+      if (!isa<CXXMethodDecl>(NewFD) && getLangOpts().OpenCLCPlusPlus) {
+        OpenCL().removeFriendFunctionAddressSpace(NewFD, TInfo);
+      }
     }
 
     // If a function is defined as defaulted or deleted, mark it as such now.
diff --git a/clang/lib/Sema/SemaOpenCL.cpp b/clang/lib/Sema/SemaOpenCL.cpp
index f11a40e3964ff..c7b6d9d505b26 100644
--- a/clang/lib/Sema/SemaOpenCL.cpp
+++ b/clang/lib/Sema/SemaOpenCL.cpp
@@ -576,4 +576,16 @@ bool SemaOpenCL::checkBuiltinToAddr(unsigned BuiltinID, 
CallExpr *Call) {
   return false;
 }
 
+void SemaOpenCL::removeFriendFunctionAddressSpace(FunctionDecl *FD,
+                                                  TypeSourceInfo *TInfo) {
+  assert(!isa<CXXMethodDecl>(FD) && "Only free function should be adjusted");
+
+  // For generic address space remove __generic, otherwise remove __private
+  QualType R = TInfo->getType();
+  const FunctionProtoType *FPT = R->getAs<FunctionProtoType>();
+  FD->setType(SemaRef.Context.getFunctionType(
+      FPT->getReturnType(), FPT->getParamTypes(),
+      FPT->getExtProtoInfo().withoutAddressSpace()));
+}
+
 } // namespace clang
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index f02a295220efb..a925e12786806 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -29,6 +29,7 @@
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaObjC.h"
+#include "clang/Sema/SemaOpenCL.h"
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/SemaSwift.h"
 #include "clang/Sema/Template.h"
@@ -2823,6 +2824,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
 
   if (isFriend) {
     Function->setObjectOfFriendDecl();
+    // For OpenCLCPlusPlus dialect remove address space (__generic/__private)
+    // of dependend or template free friend function instantiation.
+    if (SemaRef.getLangOpts().OpenCLCPlusPlus) {
+      SemaRef.OpenCL().removeFriendFunctionAddressSpace(Function, TInfo);
+    }
     if (FunctionTemplateDecl *FT = Function->getDescribedFunctionTemplate())
       FT->setObjectOfFriendDecl();
   }
diff --git a/clang/test/SemaCXX/friend-template-redecl.cpp 
b/clang/test/SemaCXX/friend-template-redecl.cpp
index 4ee03c6f6387f..384291a87b198 100644
--- a/clang/test/SemaCXX/friend-template-redecl.cpp
+++ b/clang/test/SemaCXX/friend-template-redecl.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++17 -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -cl-std=clc++2021 -verify -emit-llvm-only %s
 
 template <class T> void bar(const T &t) { foo(t); }
 
diff --git a/clang/test/SemaCXX/friend.cpp b/clang/test/SemaCXX/friend.cpp
index 53e6bbfcf42a8..3622b71ee3106 100644
--- a/clang/test/SemaCXX/friend.cpp
+++ b/clang/test/SemaCXX/friend.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -cl-std=clc++2021
 
 friend class A; // expected-error {{'friend' used outside of class}}
 void f() { friend class A; } // expected-error {{'friend' used outside of 
class}}
diff --git a/clang/test/SemaCXX/friend2.cpp b/clang/test/SemaCXX/friend2.cpp
index 6d3b545904e48..6c8fe20b7c914 100644
--- a/clang/test/SemaCXX/friend2.cpp
+++ b/clang/test/SemaCXX/friend2.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-noncl %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cl %s 
-cl-std=clc++2021
 
 // If a friend function is defined in several non-template classes,
 // it is an error.
@@ -62,16 +63,16 @@ template<typename T> struct C6b {
   friend void func6(int) {}  // expected-error{{redefinition of 'func6'}}
 };
 C6a<long> c6a;
-C6b<int*> c6b;  // expected-note{{in instantiation of template class 'C6b<int 
*>' requested here}}
-
+C6b<int*> c6b;  // expected-noncl-note{{in instantiation of template class 
'C6b<int *>' requested here}}
+                // expected-cl-note@-1{{in instantiation of template class 
'C6b<__generic int *>' requested here}}
 void func7(int);
 template<typename T> struct C7 {
   friend void func7(int) {}  // expected-error{{redefinition of 'func7'}}
                              // expected-note@-1{{previous definition is here}}
 };
 C7<long> c7a;
-C7<int*> c7b;  // expected-note{{in instantiation of template class 'C7<int 
*>' requested here}}
-
+C7<int*> c7b;  // expected-noncl-note{{in instantiation of template class 
'C7<int *>' requested here}}
+               // expected-cl-note@-1{{in instantiation of template class 
'C7<__generic int *>' requested here}}
 
 // Even if clases are not instantiated and hence friend functions defined in 
them are not
 // available, their declarations can be checked.

>From 33ed1c3f1a17d96e67025ace0bec8f9c7c89f9b8 Mon Sep 17 00:00:00 2001
From: Piotr Rak <piotr....@gmail.com>
Date: Wed, 13 Aug 2025 22:00:22 +0200
Subject: [PATCH 2/3] [OpenCLCpp] Avoid inferred adding address-space to
 function types

The default OpenCL address-space was added for function types, which was
breaking transform type builtins for function types, in particular:

- __remove_reference_t
- __remove_cvref
- __remove_pointer

This change fixes SemaCXX/type-traits.cpp pass for clc++ dialect.
(In feature set of clc++ and extension - ie. no VLA, _Atomic etc...)

There is still unaddressed issue with address space of member-fn-ptr
in __is_same trait builtin as address-space specified by user is
ignored on such types.

This is seperate unrelated issue and won't be addressed in this change.
---
 clang/lib/Sema/SemaType.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 0985b5b565dab..7f1094d5e4503 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1793,9 +1793,10 @@ bool Sema::CheckQualifiedFunctionForTypeId(QualType T, 
SourceLocation Loc) {
 }
 
 // Helper to deduce addr space of a pointee type in OpenCL mode.
-static QualType deduceOpenCLPointeeAddrSpace(Sema &S, QualType PointeeType) {
+static QualType deduceOpenCLPointeeAddrSpace(Sema &S, QualType PointeeType, 
bool IsBlock) {
   if (!PointeeType->isUndeducedAutoType() && !PointeeType->isDependentType() &&
       !PointeeType->isSamplerT() &&
+      (!PointeeType->isFunctionType() || IsBlock) &&
       !PointeeType.hasAddressSpace())
     PointeeType = S.getASTContext().getAddrSpaceQualType(
         PointeeType, S.getASTContext().getDefaultOpenCLPointeeAddrSpace());
@@ -1834,7 +1835,7 @@ QualType Sema::BuildPointerType(QualType T,
     T = inferARCLifetimeForPointee(*this, T, Loc, /*reference*/ false);
 
   if (getLangOpts().OpenCL)
-    T = deduceOpenCLPointeeAddrSpace(*this, T);
+    T = deduceOpenCLPointeeAddrSpace(*this, T, /*IsBlock*/ false);
 
   // In WebAssembly, pointers to reference types and pointers to tables are
   // illegal.
@@ -1911,7 +1912,7 @@ QualType Sema::BuildReferenceType(QualType T, bool 
SpelledAsLValue,
     T = inferARCLifetimeForPointee(*this, T, Loc, /*reference*/ true);
 
   if (getLangOpts().OpenCL)
-    T = deduceOpenCLPointeeAddrSpace(*this, T);
+    T = deduceOpenCLPointeeAddrSpace(*this, T, /*IsBlock*/ false);
 
   // In WebAssembly, references to reference types and tables are illegal.
   if (getASTContext().getTargetInfo().getTriple().isWasm() &&
@@ -2766,7 +2767,7 @@ QualType Sema::BuildBlockPointerType(QualType T,
     return QualType();
 
   if (getLangOpts().OpenCL)
-    T = deduceOpenCLPointeeAddrSpace(*this, T);
+    T = deduceOpenCLPointeeAddrSpace(*this, T, /*IsBlock*/ true);
 
   return Context.getBlockPointerType(T);
 }

>From 202c673561327dc6ba93738bf13820d1fa4a414c Mon Sep 17 00:00:00 2001
From: Piotr Rak <piotr....@gmail.com>
Date: Fri, 1 Aug 2025 12:23:54 +0200
Subject: [PATCH 3/3] [OpenCLCpp] Enable type-traits tests for clc++

---
 clang/test/SemaCXX/type-traits.cpp            | 491 ++++++++++++++++--
 .../SemaOpenCLCXX/address-space-traits.clcpp  |  29 ++
 2 files changed, 491 insertions(+), 29 deletions(-)
 create mode 100644 clang/test/SemaOpenCLCXX/address-space-traits.clcpp

diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index 3f0124755c674..96298f9156f90 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1,8 +1,19 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify 
-std=gnu++11 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted 
-Wno-c++17-extensions  %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify 
-std=gnu++14 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted 
-Wno-c++17-extensions  %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify 
-std=gnu++17 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted  
%s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify 
-std=gnu++20 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted  
%s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only 
-verify=expected,expected-noncl -std=gnu++11 -fblocks -Wno-deprecated-builtins 
-Wno-defaulted-function-deleted -Wno-c++17-extensions  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only 
-verify=expected,expected-noncl -std=gnu++14 -fblocks -Wno-deprecated-builtins 
-Wno-defaulted-function-deleted -Wno-c++17-extensions  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only 
-verify=expected,expected-noncl -std=gnu++17 -fblocks -Wno-deprecated-builtins 
-Wno-defaulted-function-deleted  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only 
-verify=expected,expected-noncl -std=gnu++20 -fblocks -Wno-deprecated-builtins 
-Wno-defaulted-function-deleted  %s
+// RUN: %clang_cc1 -triple spirv64-none-none -fsyntax-only -fno-rtti 
-verify=expected,expected-cl -cl-std=clc++2021 -Wno-deprecated-builtins 
-Wno-defaulted-function-deleted 
-cl-ext=+__cl_clang_variadic_functions,+__cl_clang_function_pointers,+__cl_clang_bitfields
 -DVANILLAOPENCLCPLUSPLUS %s
+// RUN: %clang_cc1 -triple spirv64-none-none -fsyntax-only -fno-rtti 
-verify=expected,expected-cl -cl-std=clc++2021 -Wno-deprecated-builtins 
-Wno-defaulted-function-deleted 
-cl-ext=+__cl_clang_variadic_functions,+__cl_clang_function_pointers,+__cl_clang_bitfields
 -DEXTOPENCLCPLUSPLUS %s
+
+#if defined(EXTOPENCLCPLUSPLUS)
+#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
+#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
+#pragma OPENCL EXTENSION __cl_clang_bitfields : enable
+#endif
 
+#if defined(EXTOPENCLCPLUSPLUS) || defined(VANILLAOPENCLCPLUSPLUS)
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#endif
 
 struct NonPOD { NonPOD(int); };
 typedef NonPOD NonPODAr[10];
@@ -111,9 +122,16 @@ class  HasProt { protected: int prot; };
 struct HasRef { int i; int& ref; HasRef() : i(0), ref(i) {} };
 struct HasRefAggregate { int i; int& ref; };
 struct HasNonPOD { NonPOD np; };
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+struct HasVirt { virtual void Virt() {}; };
+#else
 struct HasVirt { virtual void Virt() {}; };
+//expected-error@-1 {{virtual functions are not supported in C++ for OpenCL}}
+#endif
 typedef NonPOD NonPODAr[10];
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 typedef HasVirt VirtAr[10];
+#endif
 typedef NonPOD NonPODArNB[];
 union NonPODUnion { int i; Derives n; };
 struct DerivesHasCons : HasCons {};
@@ -123,7 +141,9 @@ struct DerivesHasDest : HasDest {};
 struct DerivesHasPriv : HasPriv {};
 struct DerivesHasProt : HasProt {};
 struct DerivesHasRef : HasRef {};
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct DerivesHasVirt : HasVirt {};
+#endif
 struct DerivesHasMoveCtor : HasMoveCtor {};
 
 struct HasNoThrowCopyAssign {
@@ -161,9 +181,14 @@ struct HasMultipleNoThrowCopy {
   HasMultipleNoThrowCopy(volatile HasMultipleNoThrowCopy&) throw();
 };
 
+#if defined(VANILLAOPENCLCPLUSPLUS)
+struct HasVirtDest { virtual ~HasVirtDest(); };
+//expected-error@-1 {{virtual functions are not supported in C++ for OpenCL}}
+#else
 struct HasVirtDest { virtual ~HasVirtDest(); };
 struct DerivedVirtDest : HasVirtDest {};
 typedef HasVirtDest VirtDestAr[1];
+#endif
 
 class AllPrivate {
   AllPrivate() throw();
@@ -244,13 +269,17 @@ void is_pod()
   static_assert(!__is_pod(HasMoveAssign));
   static_assert(!__is_pod(HasDest));
   static_assert(!__is_pod(HasRef));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_pod(HasVirt));
+#endif
   static_assert(!__is_pod(DerivesHasCons));
   static_assert(!__is_pod(DerivesHasCopyAssign));
   static_assert(!__is_pod(DerivesHasMoveAssign));
   static_assert(!__is_pod(DerivesHasDest));
   static_assert(!__is_pod(DerivesHasRef));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_pod(DerivesHasVirt));
+#endif
   static_assert(!__is_pod(NonPOD));
   static_assert(!__is_pod(HasNonPOD));
   static_assert(!__is_pod(NonPODAr));
@@ -266,11 +295,13 @@ void is_pod()
 }
 
 typedef Empty EmptyAr[10];
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct Bit0 { int : 0; };
 struct Bit0Cons { int : 0; Bit0Cons(); };
 struct AnonBitOnly { int : 3; };
 struct BitOnly { int x : 3; };
 struct DerivesVirt : virtual POD {};
+#endif
 
 void is_empty()
 {
@@ -284,8 +315,10 @@ void is_empty()
   static_assert(__is_empty(HasOp));
   static_assert(__is_empty(HasConv));
   static_assert(__is_empty(HasAssign));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_empty(Bit0));
   static_assert(__is_empty(Bit0Cons));
+#endif
 
   static_assert(!__is_empty(Int));
   static_assert(!__is_empty(POD));
@@ -293,9 +326,11 @@ void is_empty()
   static_assert(!__is_empty(IncompleteUnion));
   static_assert(!__is_empty(EmptyAr));
   static_assert(!__is_empty(HasRef));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_empty(HasVirt));
   static_assert(!__is_empty(AnonBitOnly));
   static_assert(!__is_empty(BitOnly));
+#endif
   static_assert(!__is_empty(void));
   static_assert(!__is_empty(IntArNB));
   static_assert(!__is_empty(HasAnonymousUnion));
@@ -442,13 +477,17 @@ void is_final()
 }
 
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 typedef HasVirt Polymorph;
 struct InheritPolymorph : Polymorph {};
+#endif
 
 void is_polymorphic()
 {
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_polymorphic(Polymorph));
   static_assert(__is_polymorphic(InheritPolymorph));
+#endif
 
   static_assert(!__is_polymorphic(int));
   static_assert(!__is_polymorphic(Union));
@@ -590,8 +629,10 @@ void is_aggregate()
   static_assert(!__is_aggregate(HasProt));
   static_assert(__is_aggregate(HasRefAggregate));
   static_assert(__is_aggregate(HasNonPOD));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_aggregate(HasVirt));
   static_assert(__is_aggregate(VirtAr));
+#endif
   static_assert(__is_aggregate(HasInClassInit) == TrueAfterCpp11);
   static_assert(!__is_aggregate(HasPrivateBase));
   static_assert(!__is_aggregate(HasProtectedBase));
@@ -747,8 +788,10 @@ void is_bounded_array(int n) {
   static_assert(!__is_bounded_array(void *));
   static_assert(!__is_bounded_array(cvoid *));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   int t32[n];
   (void)__is_bounded_array(decltype(t32)); // expected-error{{variable length 
arrays are not supported in '__is_bounded_array'}}
+#endif
 }
 
 void is_unbounded_array(int n) {
@@ -780,8 +823,10 @@ void is_unbounded_array(int n) {
   static_assert(!__is_unbounded_array(void *));
   static_assert(!__is_unbounded_array(cvoid *));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   int t32[n];
   (void)__is_unbounded_array(decltype(t32)); // expected-error{{variable 
length arrays are not supported in '__is_unbounded_array'}}
+#endif
 }
 
 template <typename T> void tmpl_func(T&) {}
@@ -794,10 +839,15 @@ template <typename T> struct type_wrapper {
 
 void is_function()
 {
+#if !defined(VANILLAOPENCLCPLUSPLUS)&& !defined(EXTOPENCLCPLUSPLUS)
+  // Requires RTTI
   static_assert(__is_function(type_wrapper<void(void)>::type));
   static_assert(__is_function(typeof(tmpl_func<int>)));
+#endif
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   typedef void (*ptr_to_func_type)(void);
+#endif
 
   static_assert(!__is_function(void));
   static_assert(!__is_function(cvoid));
@@ -821,10 +871,12 @@ void is_function()
   static_assert(!__is_function(Enum));
   static_assert(!__is_function(void*));
   static_assert(!__is_function(cvoid*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_function(void(*)()));
   static_assert(!__is_function(ptr_to_func_type));
   static_assert(!__is_function(type_wrapper<void(void)>::ptrtype));
   static_assert(!__is_function(type_wrapper<void(void)>::reftype));
+#endif
 }
 
 void is_reference()
@@ -908,7 +960,9 @@ void is_object()
   static_assert(__is_object(ClassType));
   static_assert(__is_object(Enum));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_object(type_wrapper<void(void)>::type));
+#endif
   static_assert(!__is_object(int&));
   static_assert(!__is_object(void));
 }
@@ -951,9 +1005,11 @@ void is_compound()
 {
   static_assert(__is_compound(void*));
   static_assert(__is_compound(cvoid*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_compound(void (*)()));
   static_assert(__is_compound(int StructWithMembers::*));
   static_assert(__is_compound(void (StructWithMembers::*)()));
+#endif
   static_assert(__is_compound(int&));
   static_assert(__is_compound(Union));
   static_assert(__is_compound(UnionAr));
@@ -997,7 +1053,10 @@ void is_pointer()
   static_assert(__is_pointer(Union*));
   static_assert(__is_pointer(UnionAr*));
   static_assert(__is_pointer(StructWithMembers*));
+
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_pointer(void (*)()));
+#endif
 
   static_assert(!__is_pointer(void));
   static_assert(!__is_pointer(cvoid));
@@ -1013,7 +1072,9 @@ void is_pointer()
   static_assert(!__is_pointer(UnionAr));
   static_assert(!__is_pointer(StructWithMembers));
   static_assert(!__is_pointer(int StructWithMembers::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_pointer(void (StructWithMembers::*) ()));
+#endif
 }
 
 void is_member_object_pointer()
@@ -1022,7 +1083,9 @@ void is_member_object_pointer()
 
   static_assert(__is_member_object_pointer(int StructWithMembers::*));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_member_object_pointer(void (StructWithMembers::*) ()));
+#endif
   static_assert(!__is_member_object_pointer(void*));
   static_assert(!__is_member_object_pointer(cvoid*));
   static_assert(!__is_member_object_pointer(cvoid*));
@@ -1049,14 +1112,18 @@ void is_member_object_pointer()
   static_assert(!__is_member_object_pointer(Union));
   static_assert(!__is_member_object_pointer(UnionAr));
   static_assert(!__is_member_object_pointer(StructWithMembers));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_member_object_pointer(void (*)()));
+#endif
 }
 
 void is_member_function_pointer()
 {
   StructWithMembers x;
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_member_function_pointer(void (StructWithMembers::*) ()));
+#endif
 
   static_assert(!__is_member_function_pointer(int StructWithMembers::*));
   static_assert(!__is_member_function_pointer(void*));
@@ -1085,7 +1152,9 @@ void is_member_function_pointer()
   static_assert(!__is_member_function_pointer(Union));
   static_assert(!__is_member_function_pointer(UnionAr));
   static_assert(!__is_member_function_pointer(StructWithMembers));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_member_function_pointer(void (*)()));
+#endif
 }
 
 void is_member_pointer()
@@ -1093,7 +1162,9 @@ void is_member_pointer()
   StructWithMembers x;
 
   static_assert(__is_member_pointer(int StructWithMembers::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_member_pointer(void (StructWithMembers::*) ()));
+#endif
 
   static_assert(!__is_member_pointer(void*));
   static_assert(!__is_member_pointer(cvoid*));
@@ -1121,7 +1192,9 @@ void is_member_pointer()
   static_assert(!__is_member_pointer(Union));
   static_assert(!__is_member_pointer(UnionAr));
   static_assert(!__is_member_pointer(StructWithMembers));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_member_pointer(void (*)()));
+#endif
 }
 
 void is_const()
@@ -1392,12 +1465,14 @@ struct CppStructNonStandardByBase : CStruct {
   int three;
   int four;
 };
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct CppStructNonStandardByVirt : CStruct {
   virtual void method() {}
 };
 struct CppStructNonStandardByMemb : CStruct {
   CppStructNonStandardByVirt member;
 };
+#endif
 struct CppStructNonStandardByProt : CStruct {
   int five;
 protected:
@@ -1429,8 +1504,10 @@ void is_standard_layout()
 
   typedef CppStructNonStandardByBase CppStructNonStandardByBaseAr[4];
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_standard_layout(CppStructNonStandardByVirt));
   static_assert(!__is_standard_layout(CppStructNonStandardByMemb));
+#endif
   static_assert(!__is_standard_layout(CppStructNonStandardByProt));
   static_assert(!__is_standard_layout(CppStructNonStandardByVirtBase));
   static_assert(!__is_standard_layout(CppStructNonStandardByBase));
@@ -1445,6 +1522,7 @@ void is_standard_layout()
   static_assert(!__is_standard_layout(void));
   static_assert(!__is_standard_layout(const volatile void));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   struct HasAnonEmptyBitfield { int : 0; };
   struct HasAnonBitfield { int : 4; };
   struct DerivesFromBitfield : HasAnonBitfield {};
@@ -1456,6 +1534,7 @@ void is_standard_layout()
   static_assert(__is_standard_layout(DerivesFromBitfield));
   static_assert(!__is_standard_layout(DerivesFromBitfieldWithBitfield));
   static_assert(!__is_standard_layout(DerivesFromBitfieldTwice));
+#endif
 
   struct Empty {};
   struct HasEmptyBase : Empty {};
@@ -1467,7 +1546,9 @@ void is_standard_layout()
   struct HasEmptyBaseAsSubobjectOfMember3 : Empty { HoldsEmptyBase e[2]; };
   struct HasEmptyIndirectBaseAsMember : HasEmptyBase { Empty e; };
   struct HasEmptyIndirectBaseAsSecondMember : HasEmptyBase { int n; Empty e; };
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   struct HasEmptyIndirectBaseAfterBitfield : HasEmptyBase { int : 4; Empty e; 
};
+#endif
 
   static_assert(__is_standard_layout(Empty));
   static_assert(__is_standard_layout(HasEmptyBase));
@@ -1478,7 +1559,9 @@ void is_standard_layout()
   static_assert(!__is_standard_layout(HasEmptyBaseAsSubobjectOfMember3));
   static_assert(!__is_standard_layout(HasEmptyIndirectBaseAsMember));
   static_assert(__is_standard_layout(HasEmptyIndirectBaseAsSecondMember));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_standard_layout(HasEmptyIndirectBaseAfterBitfield)); // 
FIXME: standard bug?
+#endif
 
   struct StructWithEmptyFields {
     int n;
@@ -1515,12 +1598,14 @@ struct CppStructNonStandardByBase2 : CStruct2 {
   int three;
   int four;
 };
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct CppStructNonStandardByVirt2 : CStruct2 {
   virtual void method() {}
 };
 struct CppStructNonStandardByMemb2 : CStruct2 {
   CppStructNonStandardByVirt member;
 };
+#endif
 struct CppStructNonStandardByProt2 : CStruct2 {
   int five;
 protected:
@@ -1579,6 +1664,7 @@ struct CStructNested2 {
   int b2;
 };
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct CStructWithBitfelds {
   int a : 5;
   int : 0;
@@ -1598,6 +1684,7 @@ struct CStructWithBitfelds4 {
   EnumLayout a : 5;
   int : 0;
 };
+#endif
 
 union UnionLayout {
   int a;
@@ -1694,22 +1781,29 @@ void is_layout_compatible(int n)
   static_assert(__is_layout_compatible(int, volatile int));
   static_assert(__is_layout_compatible(const int, volatile int));
   static_assert(__is_layout_compatible(int *, int * __restrict));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   // Note: atomic qualification matters for layout compatibility.
+  // Note: OpenCL no _Atomic
   static_assert(!__is_layout_compatible(int, _Atomic int));
   static_assert(__is_layout_compatible(_Atomic(int), _Atomic int));
+#endif
   static_assert(!__is_layout_compatible(int, unsigned int));
   static_assert(!__is_layout_compatible(char, unsigned char));
   static_assert(!__is_layout_compatible(char, signed char));
   static_assert(!__is_layout_compatible(unsigned char, signed char));
   static_assert(__is_layout_compatible(int[], int[]));
   static_assert(__is_layout_compatible(int[2], int[2]));
+  // OpenCLCPP: No VLA
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(!__is_layout_compatible(int[n], int[2]));
   // expected-error@-1 {{variable length arrays are not supported in 
'__is_layout_compatible'}}
   static_assert(!__is_layout_compatible(int[n], int[n]));
   // expected-error@-1 {{variable length arrays are not supported in 
'__is_layout_compatible'}}
   // expected-error@-2 {{variable length arrays are not supported in 
'__is_layout_compatible'}}
+#endif
   static_assert(__is_layout_compatible(int&, int&));
   static_assert(!__is_layout_compatible(int&, char&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_layout_compatible(void(int), void(int)));
   static_assert(!__is_layout_compatible(void(int), void(char)));
   static_assert(__is_layout_compatible(void(&)(int), void(&)(int)));
@@ -1725,7 +1819,9 @@ void is_layout_compatible(int n)
   // expected-warning@-1 {{'const' qualifier on function type 'function_type' 
(aka 'void ()') has no effect}}
   static_assert(!__is_layout_compatible(const function_type, const 
function_type2));
   // expected-warning@-1 {{'const' qualifier on function type 'function_type' 
(aka 'void ()') has no effect}}
-  // expected-warning@-2 {{'const' qualifier on function type 'function_type2' 
(aka 'void (char)') has no effect}}
+  // expected-noncl-warning@-2 {{'const' qualifier on function type 
'function_type2' (aka 'void (char)') has no effect}}
+  // expected-cl-warning@-3 {{'const' qualifier on function type 
'function_type2' (aka 'void (__private char)') has no effect}}
+#endif
   static_assert(__is_layout_compatible(CStruct, CStruct2));
   static_assert(__is_layout_compatible(CStruct, const CStruct2));
   static_assert(__is_layout_compatible(CStruct, volatile CStruct2));
@@ -1734,26 +1830,34 @@ void is_layout_compatible(int n)
   static_assert(__is_layout_compatible(CppEmptyStruct, CppEmptyStruct2));
   static_assert(__is_layout_compatible(CppStructStandard, CppStructStandard2));
   static_assert(!__is_layout_compatible(CppStructNonStandardByBase, 
CppStructNonStandardByBase2));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_layout_compatible(CppStructNonStandardByVirt, 
CppStructNonStandardByVirt2));
   static_assert(!__is_layout_compatible(CppStructNonStandardByMemb, 
CppStructNonStandardByMemb2));
+#endif
   static_assert(!__is_layout_compatible(CppStructNonStandardByProt, 
CppStructNonStandardByProt2));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_layout_compatible(CppStructNonStandardByVirtBase, 
CppStructNonStandardByVirtBase2));
   static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, 
CppStructNonStandardBySameBase2));
   static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, 
CppStructNonStandardBy2ndVirtBase2));
+#endif
   static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers));
   static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) != 
bool(__has_cpp_attribute(no_unique_address)));
   static_assert(__is_layout_compatible(CStructNoUniqueAddress, 
CStructNoUniqueAddress2) != bool(__has_cpp_attribute(no_unique_address)));
   static_assert(__is_layout_compatible(CStruct, CStructAlignment));
   static_assert(!__is_layout_compatible(CStruct, CStructAlignedMembers));
   static_assert(__is_layout_compatible(UnionNoOveralignedMembers, 
UnionWithOveralignedMembers));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_layout_compatible(CStructWithBitfelds, 
CStructWithBitfelds));
   static_assert(__is_layout_compatible(CStructWithBitfelds, 
CStructWithBitfelds2));
   static_assert(!__is_layout_compatible(CStructWithBitfelds, 
CStructWithBitfelds3));
   static_assert(!__is_layout_compatible(CStructWithBitfelds, 
CStructWithBitfelds4));
+#endif
   static_assert(__is_layout_compatible(int CStruct2::*, int CStruct2::*));
   static_assert(!__is_layout_compatible(int CStruct2::*, char CStruct2::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_layout_compatible(void(CStruct2::*)(int), 
void(CStruct2::*)(int)));
   static_assert(!__is_layout_compatible(void(CStruct2::*)(int), 
void(CStruct2::*)(char)));
+#endif
   static_assert(__is_layout_compatible(CStructNested, CStructNested2));
   static_assert(__is_layout_compatible(UnionLayout, UnionLayout));
   static_assert(!__is_layout_compatible(UnionLayout, UnionLayout2));
@@ -1844,12 +1948,15 @@ void is_pointer_interconvertible_base_of(int n)
   static_assert(!__is_pointer_interconvertible_base_of(int, volatile int));
   static_assert(!__is_pointer_interconvertible_base_of(const int, volatile 
int));
   static_assert(!__is_pointer_interconvertible_base_of(int *, int * 
__restrict));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(!__is_pointer_interconvertible_base_of(int, _Atomic int));
   static_assert(!__is_pointer_interconvertible_base_of(_Atomic(int), _Atomic 
int));
+#endif
   static_assert(!__is_pointer_interconvertible_base_of(int, unsigned int));
   static_assert(!__is_pointer_interconvertible_base_of(char, unsigned char));
   static_assert(!__is_pointer_interconvertible_base_of(char, signed char));
   static_assert(!__is_pointer_interconvertible_base_of(unsigned char, signed 
char));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   using function_type = void();
   using function_type2 = void(char);
   static_assert(!__is_pointer_interconvertible_base_of(const function_type, 
const function_type));
@@ -1859,27 +1966,36 @@ void is_pointer_interconvertible_base_of(int n)
   // expected-warning@-1 {{'const' qualifier on function type 'function_type' 
(aka 'void ()') has no effect}}
   static_assert(!__is_pointer_interconvertible_base_of(const function_type, 
const function_type2));
   // expected-warning@-1 {{'const' qualifier on function type 'function_type' 
(aka 'void ()') has no effect}}
-  // expected-warning@-2 {{'const' qualifier on function type 'function_type2' 
(aka 'void (char)') has no effect}}
+  // expected-noncl-warning@-2 {{'const' qualifier on function type 
'function_type2' (aka 'void (char)') has no effect}}
+  // expected-cl-warning@-3 {{'const' qualifier on function type 
'function_type2' (aka 'void (__private char)') has no effect}}
+#endif
   static_assert(!__is_pointer_interconvertible_base_of(int CStruct2::*, int 
CStruct2::*));
   static_assert(!__is_pointer_interconvertible_base_of(int CStruct2::*, char 
CStruct2::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_pointer_interconvertible_base_of(void(CStruct2::*)(int), 
void(CStruct2::*)(int)));
   static_assert(!__is_pointer_interconvertible_base_of(void(CStruct2::*)(int), 
void(CStruct2::*)(char)));
+#endif
   static_assert(!__is_pointer_interconvertible_base_of(int[], int[]));
   static_assert(!__is_pointer_interconvertible_base_of(int[], double[]));
   static_assert(!__is_pointer_interconvertible_base_of(int[2], int[2]));
+  // OpenCLCPP: No VLA
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(!__is_pointer_interconvertible_base_of(int[n], int[2]));
   // expected-error@-1 {{variable length arrays are not supported in 
'__is_pointer_interconvertible_base_of'}}
   static_assert(!__is_pointer_interconvertible_base_of(int[n], int[n]));
   // expected-error@-1 {{variable length arrays are not supported in 
'__is_pointer_interconvertible_base_of'}}
   // expected-error@-2 {{variable length arrays are not supported in 
'__is_pointer_interconvertible_base_of'}}
+#endif
   static_assert(!__is_pointer_interconvertible_base_of(int&, int&));
   static_assert(!__is_pointer_interconvertible_base_of(int&, char&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_pointer_interconvertible_base_of(void(int), void(int)));
   static_assert(!__is_pointer_interconvertible_base_of(void(int), void(char)));
   static_assert(!__is_pointer_interconvertible_base_of(void(&)(int), 
void(&)(int)));
   static_assert(!__is_pointer_interconvertible_base_of(void(&)(int), 
void(&)(char)));
   static_assert(!__is_pointer_interconvertible_base_of(void(*)(int), 
void(*)(int)));
   static_assert(!__is_pointer_interconvertible_base_of(void(*)(int), 
void(*)(char)));
+#endif
 }
 }
 
@@ -1925,13 +2041,17 @@ struct UserDeletedDestructorInAggregate {
   ~UserDeletedDestructorInAggregate() = delete;
 };
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct UserDeletedDestructorInNonAggregate {
   virtual void NonAggregate();
   ~UserDeletedDestructorInNonAggregate() = delete;
 };
+#endif
 
 struct DeletedDestructorViaBaseInAggregate : UserDeletedDestructorInAggregate 
{};
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct DeletedDestructorViaBaseInNonAggregate : 
UserDeletedDestructorInNonAggregate {};
+#endif
 
 #if __cplusplus >= 202002L
 template<bool B>
@@ -1975,10 +2095,13 @@ void is_implicit_lifetime(int n) {
   static_assert(__builtin_is_implicit_lifetime(int*));
   static_assert(__builtin_is_implicit_lifetime(int[]));
   static_assert(__builtin_is_implicit_lifetime(int[5]));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(__builtin_is_implicit_lifetime(int[n]));
   // expected-error@-1 {{variable length arrays are not supported in 
'__builtin_is_implicit_lifetime'}}
+#endif
   static_assert(__builtin_is_implicit_lifetime(Enum));
   static_assert(__builtin_is_implicit_lifetime(EnumClass));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__builtin_is_implicit_lifetime(void()));
   static_assert(!__builtin_is_implicit_lifetime(void() &));
   static_assert(!__builtin_is_implicit_lifetime(void() const));
@@ -1990,6 +2113,7 @@ void is_implicit_lifetime(int n) {
   static_assert(__builtin_is_implicit_lifetime(int 
(UserDeclaredDestructor::*)() const));
   static_assert(__builtin_is_implicit_lifetime(int 
(UserDeclaredDestructor::*)() &));
   static_assert(__builtin_is_implicit_lifetime(int 
(UserDeclaredDestructor::*)() &&));
+#endif
   static_assert(!__builtin_is_implicit_lifetime(IncompleteStruct));
   // expected-error@-1 {{incomplete type 'IncompleteStruct' used in type trait 
expression}}
   static_assert(__builtin_is_implicit_lifetime(IncompleteStruct[]));
@@ -2005,9 +2129,13 @@ void is_implicit_lifetime(int n) {
   
static_assert(__builtin_is_implicit_lifetime(InheritedOnlyDefaultConstructorIsTrivial));
   
static_assert(__builtin_is_implicit_lifetime(InheritedAllContstructorsAreTrivial));
   
static_assert(__builtin_is_implicit_lifetime(UserDeletedDestructorInAggregate));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   
static_assert(!__builtin_is_implicit_lifetime(UserDeletedDestructorInNonAggregate));
+#endif
   
static_assert(__builtin_is_implicit_lifetime(DeletedDestructorViaBaseInAggregate)
 == __cplusplus >= 201703L);
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   
static_assert(!__builtin_is_implicit_lifetime(DeletedDestructorViaBaseInNonAggregate));
+#endif
 #if __cplusplus >= 202002L
   
static_assert(__builtin_is_implicit_lifetime(ConstrainedUserDeclaredDefaultConstructor<true>));
   
static_assert(!__builtin_is_implicit_lifetime(ConstrainedUserDeclaredDefaultConstructor<false>));
@@ -2015,14 +2143,18 @@ void is_implicit_lifetime(int n) {
   
static_assert(__builtin_is_implicit_lifetime(ConstrainedUserProvidedDestructor<false>));
 #endif
 
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(__builtin_is_implicit_lifetime(__int128));
+#endif
   static_assert(__builtin_is_implicit_lifetime(_BitInt(8)));
   static_assert(__builtin_is_implicit_lifetime(_BitInt(128)));
   static_assert(__builtin_is_implicit_lifetime(int[0]));
   static_assert(__builtin_is_implicit_lifetime(StructWithFAM));
   static_assert(__builtin_is_implicit_lifetime(StructWithZeroSizedArray));
   static_assert(__builtin_is_implicit_lifetime(__fp16));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(__builtin_is_implicit_lifetime(__bf16));
+#endif
   static_assert(__builtin_is_implicit_lifetime(_Complex double));
   static_assert(__builtin_is_implicit_lifetime(float4));
   static_assert(__builtin_is_implicit_lifetime(align_value_int));
@@ -2033,8 +2165,10 @@ void is_implicit_lifetime(int n) {
   static_assert(__builtin_is_implicit_lifetime(int * _Nonnull));
   static_assert(__builtin_is_implicit_lifetime(int * _Null_unspecified));
   static_assert(__builtin_is_implicit_lifetime(int * _Nullable));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(!__builtin_is_implicit_lifetime(_Atomic int));
   // expected-error@-1 {{atomic types are not supported in 
'__builtin_is_implicit_lifetime'}}
+#endif
   static_assert(__builtin_is_implicit_lifetime(int * __restrict));
 }
 
@@ -2110,12 +2244,14 @@ struct HasMove {
   HasMove(HasMove&& cp);
 };
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct HasTemplateCons {
   HasVirt Annoying;
 
   template <typename T>
   HasTemplateCons(const T&);
 };
+#endif
 
 void has_trivial_default_constructor() {
   static_assert(__has_trivial_constructor(Int));
@@ -2141,10 +2277,14 @@ void has_trivial_default_constructor() {
   static_assert(!__has_trivial_constructor(HasRef));
   static_assert(!__has_trivial_constructor(HasCopy));
   static_assert(!__has_trivial_constructor(IntRef));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_trivial_constructor(VirtAr));
+#endif
   static_assert(!__has_trivial_constructor(void));
   static_assert(!__has_trivial_constructor(cvoid));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_trivial_constructor(HasTemplateCons));
+#endif
   static_assert(!__has_trivial_constructor(AllPrivate));
   static_assert(!__has_trivial_constructor(ExtDefaulted));
 }
@@ -2170,8 +2310,10 @@ void has_trivial_move_constructor() {
   static_assert(__has_trivial_move_constructor(ACompleteType[]));
 
   static_assert(!__has_trivial_move_constructor(AnIncompleteType[])); // 
expected-error {{incomplete type}}
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_trivial_move_constructor(HasVirt));
   static_assert(!__has_trivial_move_constructor(DerivesVirt));
+#endif
   static_assert(!__has_trivial_move_constructor(HasMoveCtor));
   static_assert(!__has_trivial_move_constructor(DerivesHasMoveCtor));
   static_assert(!__has_trivial_move_constructor(HasMemberMoveCtor));
@@ -2203,8 +2345,10 @@ void has_trivial_copy_constructor() {
 
   static_assert(!__has_trivial_copy(AnIncompleteType[])); // expected-error 
{{incomplete type}}
   static_assert(!__has_trivial_copy(HasCopy));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_trivial_copy(HasTemplateCons));
   static_assert(!__has_trivial_copy(VirtAr));
+#endif
   static_assert(!__has_trivial_copy(void));
   static_assert(!__has_trivial_copy(cvoid));
   static_assert(!__has_trivial_copy(AllPrivate));
@@ -2237,7 +2381,9 @@ void has_trivial_copy_assignment() {
   static_assert(!__has_trivial_assign(const Int));
   static_assert(!__has_trivial_assign(ConstIntAr));
   static_assert(!__has_trivial_assign(ConstIntArAr));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_trivial_assign(VirtAr));
+#endif
   static_assert(!__has_trivial_assign(void));
   static_assert(!__has_trivial_assign(cvoid));
   static_assert(!__has_trivial_assign(AllPrivate));
@@ -2263,7 +2409,9 @@ void has_trivial_destructor() {
   static_assert(__has_trivial_destructor(HasMoveAssign));
   static_assert(__has_trivial_destructor(const Int));
   static_assert(__has_trivial_destructor(DerivesAr));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__has_trivial_destructor(VirtAr));
+#endif
   static_assert(__has_trivial_destructor(AllDefaulted));
   static_assert(__has_trivial_destructor(AllDeleted));
   static_assert(__has_trivial_destructor(DerivesHasRef));
@@ -2331,7 +2479,9 @@ void has_nothrow_assign() {
   static_assert(!__has_nothrow_assign(const Int));
   static_assert(!__has_nothrow_assign(ConstIntAr));
   static_assert(!__has_nothrow_assign(ConstIntArAr));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_nothrow_assign(VirtAr));
+#endif
   static_assert(!__has_nothrow_assign(void));
   static_assert(!__has_nothrow_assign(cvoid));
   static_assert(!__has_nothrow_assign(PR11110));
@@ -2386,8 +2536,10 @@ void has_trivial_move_assign() {
   static_assert(__has_trivial_move_assign(ACompleteType[]));
 
   static_assert(!__has_trivial_move_assign(AnIncompleteType[])); // 
expected-error {{incomplete type}}
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_trivial_move_assign(HasVirt));
   static_assert(!__has_trivial_move_assign(DerivesVirt));
+#endif
   static_assert(!__has_trivial_move_assign(HasMoveAssign));
   static_assert(!__has_trivial_move_assign(DerivesHasMoveAssign));
   static_assert(!__has_trivial_move_assign(HasMemberMoveAssign));
@@ -2415,8 +2567,10 @@ void has_nothrow_copy() {
   static_assert(__has_nothrow_copy(HasMoveAssign));
   static_assert(__has_nothrow_copy(HasNoThrowCopy));
   static_assert(__has_nothrow_copy(HasMultipleNoThrowCopy));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__has_nothrow_copy(HasVirtDest));
   static_assert(__has_nothrow_copy(HasTemplateCons));
+#endif
   static_assert(__has_nothrow_copy(AllPrivate));
   static_assert(__has_nothrow_copy(DerivesAr));
   static_assert(__has_nothrow_copy(ACompleteType[]));
@@ -2424,7 +2578,9 @@ void has_nothrow_copy() {
   static_assert(!__has_nothrow_copy(AnIncompleteType[])); // expected-error 
{{incomplete type}}
   static_assert(!__has_nothrow_copy(HasCopy));
   static_assert(!__has_nothrow_copy(HasMultipleCopy));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_nothrow_copy(VirtAr));
+#endif
   static_assert(!__has_nothrow_copy(void));
   static_assert(!__has_nothrow_copy(cvoid));
 }
@@ -2458,7 +2614,9 @@ void has_nothrow_constructor() {
   static_assert(!__has_nothrow_constructor(IntRef));
   static_assert(!__has_nothrow_constructor(void));
   static_assert(!__has_nothrow_constructor(cvoid));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_nothrow_constructor(HasTemplateCons));
+#endif
 
   static_assert(!__has_nothrow_constructor(HasMultipleDefaultConstructor1));
   static_assert(!__has_nothrow_constructor(HasMultipleDefaultConstructor2));
@@ -2484,13 +2642,17 @@ void has_virtual_destructor() {
   static_assert(!__has_virtual_destructor(HasCopyAssign));
   static_assert(!__has_virtual_destructor(HasMoveAssign));
   static_assert(!__has_virtual_destructor(IntRef));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__has_virtual_destructor(VirtAr));
+#endif
   static_assert(!__has_virtual_destructor(ACompleteType[]));
 
   static_assert(!__has_virtual_destructor(AnIncompleteType[])); // 
expected-error {{incomplete type}}
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__has_virtual_destructor(HasVirtDest));
   static_assert(__has_virtual_destructor(DerivedVirtDest));
   static_assert(!__has_virtual_destructor(VirtDestAr));
+#endif
   static_assert(!__has_virtual_destructor(void));
   static_assert(!__has_virtual_destructor(cvoid));
   static_assert(!__has_virtual_destructor(AllPrivate));
@@ -2594,7 +2756,9 @@ void is_virtual_base_of(int n) {
   static_assert(!__builtin_is_virtual_base_of(class_forward, Empty));
   static_assert(!__builtin_is_virtual_base_of(Base&, Derived&));
   static_assert(!__builtin_is_virtual_base_of(Base[10], Derived[10]));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(!__builtin_is_virtual_base_of(Base[n], Derived[n])); // 
expected-error 2 {{variable length arrays are not supported in 
'__builtin_is_virtual_base_of'}}
+#endif
   static_assert(!__builtin_is_virtual_base_of(int, int));
   static_assert(!__builtin_is_virtual_base_of(int[], int[]));
   static_assert(!__builtin_is_virtual_base_of(long, int));
@@ -2629,7 +2793,9 @@ void is_virtual_base_of(int n) {
   static_assert(!__builtin_is_virtual_base_of(Union, Empty));
   static_assert(!__builtin_is_virtual_base_of(int, Empty));
   static_assert(!__builtin_is_virtual_base_of(Union, int));
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   static_assert(!__builtin_is_virtual_base_of(IncompleteStruct, 
IncompleteStruct[n])); // expected-error {{variable length arrays are not 
supported in '__builtin_is_virtual_base_of'}}
+#endif
 }
 
 template<class T, class U>
@@ -2752,7 +2918,9 @@ struct X0 {
   template<typename U> X0(const X0<U>&);
 };
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct Abstract { virtual void f() = 0; };
+#endif
 
 void is_convertible_to() {
   static_assert(__is_convertible_to(Int, Int));
@@ -2778,7 +2946,9 @@ void is_convertible_to() {
   static_assert(!__is_convertible_to(Function, Function));
   static_assert(!__is_convertible_to(PrivateCopy, PrivateCopy));
   static_assert(__is_convertible_to(X0<int>, X0<float>));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_convertible_to(Abstract, Abstract));
+#endif
 }
 
 namespace is_convertible_to_instantiate {
@@ -2821,13 +2991,17 @@ void is_trivial()
   static_assert(!__is_trivial(HasDest));
   static_assert(!__is_trivial(HasRef));
   static_assert(!__is_trivial(HasNonPOD));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_trivial(HasVirt));
+#endif
   static_assert(!__is_trivial(DerivesHasCons));
   static_assert(!__is_trivial(DerivesHasCopyAssign));
   static_assert(!__is_trivial(DerivesHasMoveAssign));
   static_assert(!__is_trivial(DerivesHasDest));
   static_assert(!__is_trivial(DerivesHasRef));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_trivial(DerivesHasVirt));
+#endif
   static_assert(!__is_trivial(void));
   static_assert(!__is_trivial(cvoid));
 }
@@ -2876,11 +3050,15 @@ void trivial_checks()
   static_assert(!__is_trivially_copyable(HasCopyAssign));
   static_assert(!__is_trivially_copyable(HasMoveAssign));
   static_assert(!__is_trivially_copyable(HasDest));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_trivially_copyable(HasVirt));
+#endif
   static_assert(!__is_trivially_copyable(DerivesHasCopyAssign));
   static_assert(!__is_trivially_copyable(DerivesHasMoveAssign));
   static_assert(!__is_trivially_copyable(DerivesHasDest));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__is_trivially_copyable(DerivesHasVirt));
+#endif
   static_assert(!__is_trivially_copyable(void));
   static_assert(!__is_trivially_copyable(cvoid));
 
@@ -3035,9 +3213,11 @@ void constructible_checks() {
   static_assert(__is_constructible(NonPOD, int));
   static_assert(!__is_nothrow_constructible(NonPOD, int));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   // PR19178
   static_assert(!__is_constructible(Abstract));
   static_assert(!__is_nothrow_constructible(Abstract));
+#endif
 
   // PR20228
   static_assert(__is_constructible(VariadicCtor,
@@ -3086,7 +3266,9 @@ void is_trivially_constructible_test() {
   static_assert(!(is_trivially_constructible<int, int*>::value));
   static_assert(!(is_trivially_constructible<NonTrivialDefault>::value));
   static_assert(!(is_trivially_constructible<ThreeArgCtor, int*, char*, 
int&>::value));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!(is_trivially_constructible<Abstract>::value)); // PR19178
+#endif
 
   static_assert(__is_trivially_constructible(ACompleteType));
   static_assert(!__is_trivially_constructible(AnIncompleteType)); // 
expected-error {{incomplete type}}
@@ -3145,8 +3327,10 @@ void reference_binds_to_temporary_checks() {
   static_assert((__reference_binds_to_temporary(const int &, long)));
 
   // Test that function references are never considered bound to temporaries.
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__reference_binds_to_temporary(void(&)(), void()));
   static_assert(!__reference_binds_to_temporary(void(&&)(), void()));
+#endif
 }
 
 
@@ -3206,8 +3390,10 @@ void reference_constructs_from_temporary_checks() {
   static_assert(__reference_constructs_from_temporary(const int &, long));
 
   // Test that function references are never considered bound to temporaries.
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(!__reference_constructs_from_temporary(void(&&)(), void()));
   static_assert(!__reference_constructs_from_temporary(void(&)(), void()));
+#endif
 
   // LWG3819: reference_meows_from_temporary should not use is_meowible
   
static_assert(__reference_constructs_from_temporary(ConvertsFromNonMovable&&, 
NonMovable) == __cplusplus >= 201703L);
@@ -3272,9 +3458,11 @@ void reference_converts_from_temporary_checks() {
 
   static_assert(__reference_converts_from_temporary(const int &, long));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   // Test that function references are never considered bound to temporaries.
   static_assert(!__reference_converts_from_temporary(void(&)(), void()));
   static_assert(!__reference_converts_from_temporary(void(&&)(), void()));
+#endif
 
   // LWG3819: reference_meows_from_temporary should not use is_meowible
   static_assert(__reference_converts_from_temporary(ConvertsFromNonMovable&&, 
NonMovable) == __cplusplus >= 201703L);
@@ -3399,19 +3587,25 @@ 
static_assert(__has_unique_object_representations(volatile int *), "as are point
 static_assert(__has_unique_object_representations(const volatile int *), "as 
are pointers");
 
 class C {};
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 using FP = int (*)(int);
 using PMF = int (C::*)(int);
+#endif
 using PMD = int C::*;
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 static_assert(__has_unique_object_representations(FP), "even function 
pointers");
 static_assert(__has_unique_object_representations(const FP), "even function 
pointers");
 static_assert(__has_unique_object_representations(volatile FP), "even function 
pointers");
 static_assert(__has_unique_object_representations(const volatile FP), "even 
function pointers");
+#endif
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 static_assert(__has_unique_object_representations(PMF), "and pointer to 
members");
 static_assert(__has_unique_object_representations(const PMF), "and pointer to 
members");
 static_assert(__has_unique_object_representations(volatile PMF), "and pointer 
to members");
 static_assert(__has_unique_object_representations(const volatile PMF), "and 
pointer to members");
+#endif
 
 static_assert(__has_unique_object_representations(PMD), "and pointer to 
members");
 static_assert(__has_unique_object_representations(const PMD), "and pointer to 
members");
@@ -3428,8 +3622,10 @@ static_assert(__has_unique_object_representations(int), 
"yes, all integral types
 static_assert(__has_unique_object_representations(unsigned int), "yes, all 
integral types");
 static_assert(__has_unique_object_representations(long), "yes, all integral 
types");
 static_assert(__has_unique_object_representations(unsigned long), "yes, all 
integral types");
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 static_assert(__has_unique_object_representations(long long), "yes, all 
integral types");
 static_assert(__has_unique_object_representations(unsigned long long), "yes, 
all integral types");
+#endif
 static_assert(__has_unique_object_representations(wchar_t), "yes, all integral 
types");
 static_assert(__has_unique_object_representations(char16_t), "yes, all 
integral types");
 static_assert(__has_unique_object_representations(char32_t), "yes, all 
integral types");
@@ -3565,6 +3761,7 @@ class EmptyInheritor : Compressed {};
 
 static_assert(__has_unique_object_representations(EmptyInheritor), "As long as 
the base has items, empty is ok");
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 class Dynamic {
   virtual void A();
   int i;
@@ -3577,6 +3774,7 @@ class InheritsDynamic : Dynamic {
 };
 
 static_assert(!__has_unique_object_representations(InheritsDynamic), "Dynamic 
types are not valid");
+#endif
 
 static_assert(__has_unique_object_representations(int[42]), "Arrays are fine, 
as long as their value type is");
 static_assert(__has_unique_object_representations(int[]), "Arrays are fine, as 
long as their value type is");
@@ -3619,6 +3817,7 @@ 
static_assert(!__has_unique_object_representations(int(int) const &&), "Function
 static_assert(!__has_unique_object_representations(int(int) volatile &&), 
"Functions are not unique");
 static_assert(!__has_unique_object_representations(int(int) const volatile 
&&), "Functions are not unique");
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 static_assert(!__has_unique_object_representations(int(int, ...)), "Functions 
are not unique");
 static_assert(!__has_unique_object_representations(int(int, ...) const), 
"Functions are not unique");
 static_assert(!__has_unique_object_representations(int(int, ...) volatile), 
"Functions are not unique");
@@ -3631,6 +3830,7 @@ 
static_assert(!__has_unique_object_representations(int(int, ...) &&), "Functions
 static_assert(!__has_unique_object_representations(int(int, ...) const &&), 
"Functions are not unique");
 static_assert(!__has_unique_object_representations(int(int, ...) volatile &&), 
"Functions are not unique");
 static_assert(!__has_unique_object_representations(int(int, ...) const 
volatile &&), "Functions are not unique");
+#endif
 
 void foo(){
   static auto lambda = []() {};
@@ -3640,6 +3840,7 @@ void foo(){
   static_assert(__has_unique_object_representations(decltype(lambda2)), 
"Lambdas follow struct rules");
 }
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct PaddedBitfield {
   char c : 6;
   char d : 1;
@@ -3705,6 +3906,7 @@ struct GreaterSizeBitfield {
 
 static_assert(sizeof(GreaterSizeBitfield) == 128, "Bitfield Size");
 static_assert(!__has_unique_object_representations(GreaterSizeBitfield), 
"Bitfield padding");
+#endif
 
 struct StructWithRef {
   int &I;
@@ -4051,6 +4253,7 @@ struct 
NotTriviallyEqualityComparableTriviallyEqualityComparableBases
 };
 
static_assert(!__is_trivially_equality_comparable(NotTriviallyEqualityComparableTriviallyEqualityComparableBases));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct NotTriviallyEqualityComparableBitfield {
   int i : 1;
 
@@ -4065,6 +4268,7 @@ struct NotTriviallyEqualityComparableBitfieldFilled {
   bool operator==(const NotTriviallyEqualityComparableBitfieldFilled&) const = 
default;
 };
 
static_assert(!__is_trivially_equality_comparable(NotTriviallyEqualityComparableBitfield));
+#endif
 
 union U {
   int i;
@@ -4304,6 +4508,7 @@ struct 
NotTriviallyEqualityComparableTriviallyEqualityComparableBases
 };
 
static_assert(!__is_trivially_equality_comparable(NotTriviallyEqualityComparableTriviallyEqualityComparableBases));
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 struct NotTriviallyEqualityComparableBitfield {
   int i : 1;
 
@@ -4318,6 +4523,7 @@ struct NotTriviallyEqualityComparableBitfieldFilled {
   friend bool operator==(const NotTriviallyEqualityComparableBitfieldFilled&, 
const NotTriviallyEqualityComparableBitfieldFilled&) = default;
 };
 
static_assert(!__is_trivially_equality_comparable(NotTriviallyEqualityComparableBitfield));
+#endif
 
 union U {
   int i;
@@ -4433,9 +4639,11 @@ void check_remove_const() {
   static_assert(__is_same(remove_const_t<int const &>, int const &));
   static_assert(__is_same(remove_const_t<int &&>, int &&));
   static_assert(__is_same(remove_const_t<int const &&>, int const &&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_const_t<int()>, int()));
   static_assert(__is_same(remove_const_t<int (*const)()>, int (*)()));
   static_assert(__is_same(remove_const_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(remove_const_t<S>, S));
   static_assert(__is_same(remove_const_t<const S>, S));
@@ -4444,7 +4652,9 @@ void check_remove_const() {
   static_assert(__is_same(remove_const_t<const volatile S>, volatile S));
   static_assert(__is_same(remove_const_t<S *const volatile __restrict>, S 
*volatile __restrict));
   static_assert(__is_same(remove_const_t<int S::*const>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_const_t<int (S::*const)()>, int(S::*)()));
+#endif
 }
 
 template <class T> using remove_restrict_t = __remove_restrict(T);
@@ -4462,9 +4672,11 @@ void check_remove_restrict() {
   static_assert(__is_same(remove_restrict_t<int &__restrict>, int &));
   static_assert(__is_same(remove_restrict_t<int &&>, int &&));
   static_assert(__is_same(remove_restrict_t<int &&__restrict>, int &&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_restrict_t<int()>, int()));
   static_assert(__is_same(remove_restrict_t<int (*const volatile)()>, int 
(*const volatile)()));
   static_assert(__is_same(remove_restrict_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(remove_restrict_t<S>, S));
   static_assert(__is_same(remove_restrict_t<const S>, const S));
@@ -4472,7 +4684,9 @@ void check_remove_restrict() {
   static_assert(__is_same(remove_restrict_t<S *__restrict>, S *));
   static_assert(__is_same(remove_restrict_t<S *const volatile __restrict>, S 
*const volatile));
   static_assert(__is_same(remove_restrict_t<int S::*__restrict>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_restrict_t<int (S::*const volatile)()>, 
int(S::*const volatile)()));
+#endif
 }
 
 template <class T> using remove_volatile_t = __remove_volatile(T);
@@ -4493,16 +4707,20 @@ void check_remove_volatile() {
   static_assert(__is_same(remove_volatile_t<int volatile &>, int volatile &));
   static_assert(__is_same(remove_volatile_t<int &&>, int &&));
   static_assert(__is_same(remove_volatile_t<int volatile &&>, int volatile 
&&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_volatile_t<int()>, int()));
   static_assert(__is_same(remove_volatile_t<int (*volatile)()>, int (*)()));
   static_assert(__is_same(remove_volatile_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(remove_volatile_t<S>, S));
   static_assert(__is_same(remove_volatile_t<const S>, const S));
   static_assert(__is_same(remove_volatile_t<volatile S>, S));
   static_assert(__is_same(remove_volatile_t<const volatile S>, const S));
   static_assert(__is_same(remove_volatile_t<int S::*volatile>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_volatile_t<int (S::*volatile)()>, 
int(S::*)()));
+#endif
 }
 
 template <class T> using remove_cv_t = __remove_cv(T);
@@ -4523,16 +4741,20 @@ void check_remove_cv() {
   static_assert(__is_same(remove_cv_t<int const volatile &>, int const 
volatile &));
   static_assert(__is_same(remove_cv_t<int &&>, int &&));
   static_assert(__is_same(remove_cv_t<int const volatile &&>, int const 
volatile &&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_cv_t<int()>, int()));
   static_assert(__is_same(remove_cv_t<int (*const volatile)()>, int (*)()));
   static_assert(__is_same(remove_cv_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(remove_cv_t<S>, S));
   static_assert(__is_same(remove_cv_t<const S>, S));
   static_assert(__is_same(remove_cv_t<volatile S>, S));
   static_assert(__is_same(remove_cv_t<const volatile S>, S));
   static_assert(__is_same(remove_cv_t<int S::*const volatile>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_cv_t<int (S::*const volatile)()>, 
int(S::*)()));
+#endif
 }
 
 template <class T> using add_pointer_t = __add_pointer(T);
@@ -4549,16 +4771,20 @@ void add_pointer() {
   static_assert(__is_same(add_pointer_t<int *>, int **));
   static_assert(__is_same(add_pointer_t<int &>, int *));
   static_assert(__is_same(add_pointer_t<int &&>, int *));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(add_pointer_t<int()>, int (*)()));
   static_assert(__is_same(add_pointer_t<int (*)()>, int (**)()));
   static_assert(__is_same(add_pointer_t<int (&)()>, int (*)()));
+#endif
 
   static_assert(__is_same(add_pointer_t<S>, S *));
   static_assert(__is_same(add_pointer_t<const S>, const S *));
   static_assert(__is_same(add_pointer_t<volatile S>, volatile S *));
   static_assert(__is_same(add_pointer_t<const volatile S>, const volatile S 
*));
   static_assert(__is_same(add_pointer_t<int S::*>, int S::**));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(add_pointer_t<int (S::*)()>, int(S::**)()));
+#endif
 
   static_assert(__is_same(add_pointer_t<int 
__attribute__((address_space(1)))>, int __attribute__((address_space(1))) *));
   static_assert(__is_same(add_pointer_t<S __attribute__((address_space(2)))>, 
S __attribute__((address_space(2))) *));
@@ -4566,7 +4792,7 @@ void add_pointer() {
 
 template <class T> using remove_pointer_t = __remove_pointer(T);
 
-void remove_pointer() {
+void remove_pointer_common() {
   static_assert(__is_same(remove_pointer_t<void>, void));
   static_assert(__is_same(remove_pointer_t<const void>, const void));
   static_assert(__is_same(remove_pointer_t<volatile void>, volatile void));
@@ -4575,6 +4801,21 @@ void remove_pointer() {
   static_assert(__is_same(remove_pointer_t<const int>, const int));
   static_assert(__is_same(remove_pointer_t<volatile int>, volatile int));
   static_assert(__is_same(remove_pointer_t<const volatile int>, const volatile 
int));
+
+  static_assert(__is_same(remove_pointer_t<S>, S));
+  static_assert(__is_same(remove_pointer_t<const S>, const S));
+  static_assert(__is_same(remove_pointer_t<volatile S>, volatile S));
+  static_assert(__is_same(remove_pointer_t<const volatile S>, const volatile 
S));
+  static_assert(__is_same(remove_pointer_t<int S::*>, int S::*));
+
+  static_assert(__is_same(remove_pointer_t<int 
__attribute__((address_space(1))) *>, int __attribute__((address_space(1)))));
+  static_assert(__is_same(remove_pointer_t<S __attribute__((address_space(2))) 
*>, S  __attribute__((address_space(2)))));
+
+}
+
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
+
+void remove_pointer_cpp() {
   static_assert(__is_same(remove_pointer_t<int *>, int));
   static_assert(__is_same(remove_pointer_t<const int *>, const int));
   static_assert(__is_same(remove_pointer_t<volatile int *>, volatile int));
@@ -4584,22 +4825,36 @@ void remove_pointer() {
   static_assert(__is_same(remove_pointer_t<int *const volatile>, int));
   static_assert(__is_same(remove_pointer_t<int &>, int &));
   static_assert(__is_same(remove_pointer_t<int &&>, int &&));
+}
+
+#else
+
+void remove_pointer_clcpp() {
+  static_assert(__is_same(remove_pointer_t<int *>, __generic int));
+  static_assert(__is_same(remove_pointer_t<const int *>, __generic const int));
+  static_assert(__is_same(remove_pointer_t<volatile int *>, __generic volatile 
int));
+  static_assert(__is_same(remove_pointer_t<const volatile int *>, __generic 
const volatile int));
+  static_assert(__is_same(remove_pointer_t<int *const>, __generic int));
+  static_assert(__is_same(remove_pointer_t<int *volatile>, __generic int));
+  static_assert(__is_same(remove_pointer_t<int *const volatile>, __generic 
int));
+  static_assert(__is_same(remove_pointer_t<int &>, __generic int &));
+  static_assert(__is_same(remove_pointer_t<int &&>, __generic int &&));
+
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_pointer_t<int()>, int()));
-  static_assert(__is_same(remove_pointer_t<int (*)()>, int()));
+  // It is impossible to specify such type
+  static_assert(__is_same(remove_pointer_t<int (*)()>, int ()));
   static_assert(__is_same(remove_pointer_t<int (&)()>, int (&)()));
-
-  static_assert(__is_same(remove_pointer_t<S>, S));
-  static_assert(__is_same(remove_pointer_t<const S>, const S));
-  static_assert(__is_same(remove_pointer_t<volatile S>, volatile S));
-  static_assert(__is_same(remove_pointer_t<const volatile S>, const volatile 
S));
-  static_assert(__is_same(remove_pointer_t<int S::*>, int S::*));
+#endif
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_pointer_t<int (S::*)()>, int(S::*)()));
+#endif
 
-  static_assert(__is_same(remove_pointer_t<int 
__attribute__((address_space(1))) *>, int __attribute__((address_space(1)))));
-  static_assert(__is_same(remove_pointer_t<S __attribute__((address_space(2))) 
*>, S  __attribute__((address_space(2)))));
-
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_pointer_t<int (^)(char)>, int (^)(char)));
+#endif
 }
+#endif
 
 template <class T> using add_lvalue_reference_t = __add_lvalue_reference(T);
 
@@ -4615,16 +4870,20 @@ void add_lvalue_reference() {
   static_assert(__is_same(add_lvalue_reference_t<int *>, int *&));
   static_assert(__is_same(add_lvalue_reference_t<int &>, int &));
   static_assert(__is_same(add_lvalue_reference_t<int &&>, int &)); // 
reference collapsing
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(add_lvalue_reference_t<int()>, int (&)()));
   static_assert(__is_same(add_lvalue_reference_t<int (*)()>, int (*&)()));
   static_assert(__is_same(add_lvalue_reference_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(add_lvalue_reference_t<S>, S &));
   static_assert(__is_same(add_lvalue_reference_t<const S>, const S &));
   static_assert(__is_same(add_lvalue_reference_t<volatile S>, volatile S &));
   static_assert(__is_same(add_lvalue_reference_t<const volatile S>, const 
volatile S &));
   static_assert(__is_same(add_lvalue_reference_t<int S::*>, int S::*&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(add_lvalue_reference_t<int (S::*)()>, int(S::*&)()));
+#endif
 }
 
 template <class T> using add_rvalue_reference_t = __add_rvalue_reference(T);
@@ -4641,27 +4900,35 @@ void add_rvalue_reference() {
   static_assert(__is_same(add_rvalue_reference_t<int *>, int *&&));
   static_assert(__is_same(add_rvalue_reference_t<int &>, int &)); // reference 
collapsing
   static_assert(__is_same(add_rvalue_reference_t<int &&>, int &&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(add_rvalue_reference_t<int()>, int(&&)()));
   static_assert(__is_same(add_rvalue_reference_t<int (*)()>, int (*&&)()));
   static_assert(__is_same(add_rvalue_reference_t<int (&)()>, int (&)())); // 
reference collapsing
+#endif
 
   static_assert(__is_same(add_rvalue_reference_t<S>, S &&));
   static_assert(__is_same(add_rvalue_reference_t<const S>, const S &&));
   static_assert(__is_same(add_rvalue_reference_t<volatile S>, volatile S &&));
   static_assert(__is_same(add_rvalue_reference_t<const volatile S>, const 
volatile S &&));
   static_assert(__is_same(add_rvalue_reference_t<int S::*>, int S::*&&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(add_rvalue_reference_t<int (S::*)()>, int(S::* 
&&)()));
+#endif
 }
 
 template <class T> using remove_reference_t = __remove_reference_t(T);
 
-void check_remove_reference() {
+void check_remove_reference_common() {
   static_assert(__is_same(remove_reference_t<void>, void));
   static_assert(__is_same(remove_reference_t<const volatile void>, const 
volatile void));
   static_assert(__is_same(remove_reference_t<int>, int));
   static_assert(__is_same(remove_reference_t<const int>, const int));
   static_assert(__is_same(remove_reference_t<volatile int>, volatile int));
-  static_assert(__is_same(remove_reference_t<const volatile int>, const 
volatile int));
+}
+
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
+
+void check_remove_reference_cpp() {
   static_assert(__is_same(remove_reference_t<int *>, int *));
   static_assert(__is_same(remove_reference_t<int *const volatile>, int *const 
volatile));
   static_assert(__is_same(remove_reference_t<int const *const volatile>, int 
const *const volatile));
@@ -4690,15 +4957,57 @@ void check_remove_reference() {
   static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() &>, 
int(S::*const volatile)() &));
 }
 
+#else
+
+void check_remove_reference_clcpp() {
+  static_assert(__is_same(remove_reference_t<int *>, __generic int *));
+  static_assert(__is_same(remove_reference_t<int *const volatile>, __generic 
int *const volatile));
+  static_assert(__is_same(remove_reference_t<int const *const volatile>, 
__generic int const *const volatile));
+  static_assert(__is_same(remove_reference_t<int &>, __generic int));
+  static_assert(__is_same(remove_reference_t<int const volatile &>, __generic 
int const volatile));
+  static_assert(__is_same(remove_reference_t<int &&>, __generic int));
+  static_assert(__is_same(remove_reference_t<int const volatile &&>, __generic 
int const volatile));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  static_assert(__is_same(remove_reference_t<int()>, int()));
+  static_assert(__is_same(remove_reference_t<int (*const volatile)()>, int 
(*const volatile)()));
+  static_assert(__is_same(remove_reference_t<int (&)()>, int ()));
+#endif
+
+  static_assert(__is_same(remove_reference_t<S>, S));
+  static_assert(__is_same(remove_reference_t<S &>, __generic S));
+  static_assert(__is_same(remove_reference_t<S &&>, __generic S));
+  static_assert(__is_same(remove_reference_t<const S>, const S));
+  static_assert(__is_same(remove_reference_t<const S &>, __generic const S));
+  static_assert(__is_same(remove_reference_t<const S &&>, __generic const S));
+  static_assert(__is_same(remove_reference_t<volatile S>, volatile S));
+  static_assert(__is_same(remove_reference_t<volatile S &>, __generic volatile 
S));
+  static_assert(__is_same(remove_reference_t<volatile S &&>, __generic 
volatile S));
+  static_assert(__is_same(remove_reference_t<const volatile S>, const volatile 
S));
+  static_assert(__is_same(remove_reference_t<const volatile S &>, __generic 
const volatile S));
+  static_assert(__is_same(remove_reference_t<const volatile S &&>, __generic 
const volatile S));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  static_assert(__is_same(remove_reference_t<int S::*const volatile &>, int 
S::*__generic const volatile));
+  static_assert(__is_same(remove_reference_t<int (S::*const volatile &)()>, 
int(S::*__generic const volatile)()));
+  static_assert(__is_same(remove_reference_t<int (S::*const volatile &&)() &>, 
int(S::*__generic const volatile)() &));
+#endif
+}
+
+#endif
+
 template <class T> using remove_cvref_t = __remove_cvref(T);
 
-void check_remove_cvref() {
+void check_remove_cvref_common() {
   static_assert(__is_same(remove_cvref_t<void>, void));
   static_assert(__is_same(remove_cvref_t<const volatile void>, void));
   static_assert(__is_same(remove_cvref_t<int>, int));
   static_assert(__is_same(remove_cvref_t<const int>, int));
   static_assert(__is_same(remove_cvref_t<volatile int>, int));
   static_assert(__is_same(remove_cvref_t<const volatile int>, int));
+}
+
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
+
+void check_remove_cvref_cpp() {
   static_assert(__is_same(remove_cvref_t<int *>, int *));
   static_assert(__is_same(remove_cvref_t<int *const volatile>, int *));
   static_assert(__is_same(remove_cvref_t<int const *const volatile>, int const 
*));
@@ -4729,16 +5038,59 @@ void check_remove_cvref() {
   static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() &>, 
int(S::*)() &));
   static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() &&>, 
int(S::*)() &&));
 }
+#else
+void check_remove_cvref_clcpp() {
+  static_assert(__is_same(remove_cvref_t<int *>, __generic int *));
+  static_assert(__is_same(remove_cvref_t<int *const volatile>, __generic int 
*));
+  static_assert(__is_same(remove_cvref_t<int const *const volatile>, __generic 
int const *));
+  static_assert(__is_same(remove_cvref_t<int const *const volatile 
__restrict>, __generic int const *__restrict));
+  static_assert(__is_same(remove_cvref_t<int const *const volatile _Nonnull>, 
__generic int const *_Nonnull));
+  static_assert(__is_same(remove_cvref_t<int &>, __generic int));
+  static_assert(__is_same(remove_cvref_t<int const volatile &>, __generic 
int));
+  static_assert(__is_same(remove_cvref_t<int &&>, __generic int));
+  static_assert(__is_same(remove_cvref_t<int const volatile &&>, __generic 
int));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  static_assert(__is_same(remove_cvref_t<int()>, int()));
+  static_assert(__is_same(remove_cvref_t<int (*const volatile)()>, int (*)()));
+  static_assert(__is_same(remove_cvref_t<int (&)()>, int ()));
+#endif
+
+  static_assert(__is_same(remove_cvref_t<S>, S));
+  static_assert(__is_same(remove_cvref_t<S &>, __generic S));
+  static_assert(__is_same(remove_cvref_t<S &&>, __generic S));
+  static_assert(__is_same(remove_cvref_t<const S>, S));
+  static_assert(__is_same(remove_cvref_t<const S &>, __generic S));
+  static_assert(__is_same(remove_cvref_t<const S &&>, __generic S));
+  static_assert(__is_same(remove_cvref_t<volatile S>, S));
+  static_assert(__is_same(remove_cvref_t<volatile S &>, __generic S));
+  static_assert(__is_same(remove_cvref_t<volatile S &&>, __generic S));
+  static_assert(__is_same(remove_cvref_t<const volatile S>, S));
+  static_assert(__is_same(remove_cvref_t<const volatile S &>, __generic S));
+  static_assert(__is_same(remove_cvref_t<const volatile S &&>, __generic S));
+  static_assert(__is_same(remove_cvref_t<int S::*const volatile>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  // TODO: Behaviour of those is most likely incorrect
+  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)()>, 
int(S::*)()));
+  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() &>, 
int(S::*)() &));
+  static_assert(__is_same(remove_cvref_t<int (S::*const volatile)() &&>, 
int(S::*)() &&));
+#endif
+}
+#endif
 
 template <class T> using decay_t = __decay(T);
 
-void check_decay() {
+void check_decay_common() {
   static_assert(__is_same(decay_t<void>, void));
   static_assert(__is_same(decay_t<const volatile void>, void));
   static_assert(__is_same(decay_t<int>, int));
   static_assert(__is_same(decay_t<const int>, int));
   static_assert(__is_same(decay_t<volatile int>, int));
   static_assert(__is_same(decay_t<const volatile int>, int));
+}
+
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
+
+void check_decay_cpp() {
   static_assert(__is_same(decay_t<int *>, int *));
   static_assert(__is_same(decay_t<int *const volatile>, int *));
   static_assert(__is_same(decay_t<int *const volatile __restrict>, int *));
@@ -4775,6 +5127,55 @@ void check_decay() {
   static_assert(__is_same(decay_t<int (S::*const volatile &)()>, int(S::*)()));
   static_assert(__is_same(decay_t<int S::*const volatile &&>, int S::*));
 }
+#else
+
+typedef __generic int GenInt;
+typedef GenInt GenIntAr[10];
+typedef GenInt GenIntArNB[];
+
+void check_decay_clcpp() {
+  static_assert(__is_same(decay_t<__generic int *>, int *));
+  static_assert(__is_same(decay_t<int *const volatile>, int *));
+  static_assert(__is_same(decay_t<int *const volatile __restrict>, int *));
+  static_assert(__is_same(decay_t<int const *const volatile>, int const *));
+  static_assert(__is_same(decay_t<int const *const volatile _Nonnull>, int 
const *));
+  static_assert(__is_same(decay_t<int &>, __generic int));
+  static_assert(__is_same(decay_t<int const volatile &>, __generic int));
+  static_assert(__is_same(decay_t<int &&>, __generic int));
+  static_assert(__is_same(decay_t<int const volatile &&>, __generic int));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  static_assert(__is_same(decay_t<int()>, int (*)()));
+  static_assert(__is_same(decay_t<int (*)()>, int (*)()));
+  static_assert(__is_same(decay_t<int (*const)()>, int (*)()));
+  static_assert(__is_same(decay_t<int (*volatile)()>, int (*)()));
+  static_assert(__is_same(decay_t<int (*const volatile)()>, int (*)()));
+  static_assert(__is_same(decay_t<int (&)()>, int (*)()));
+#endif
+  static_assert(__is_same(decay_t<GenIntAr>, int *));
+  static_assert(__is_same(decay_t<GenIntArNB>, int *));
+
+  static_assert(__is_same(decay_t<S &>, __generic S));
+  static_assert(__is_same(decay_t<S &&>, __generic S));
+  static_assert(__is_same(decay_t<const S>, S));
+  static_assert(__is_same(decay_t<const S &>, __generic S));
+  static_assert(__is_same(decay_t<const S &&>, __generic S));
+  static_assert(__is_same(decay_t<volatile S>, S));
+  static_assert(__is_same(decay_t<volatile S &>, __generic S));
+  static_assert(__is_same(decay_t<volatile S &&>, __generic S));
+  static_assert(__is_same(decay_t<const volatile S>, S));
+  static_assert(__is_same(decay_t<const volatile S &>, __generic S));
+  static_assert(__is_same(decay_t<const volatile S &&>, __generic S));
+  static_assert(__is_same(decay_t<int S::*const volatile>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  static_assert(__is_same(decay_t<int (S::*const volatile)()>, int(S::*)()));
+#endif
+  static_assert(__is_same(decay_t<int S::*const volatile &>, int 
S::*__generic));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
+  static_assert(__is_same(decay_t<int (S::*const volatile &)()>, 
int(S::*__generic)()));
+#endif
+  static_assert(__is_same(decay_t<int S::*const volatile &&>, int 
S::*__generic));
+}
+#endif
 
 template <class T> struct CheckAbominableFunction {};
 template <class M>
@@ -4793,6 +5194,7 @@ struct CheckAbominableFunction<M S::*> {
   }
 };
 
+#if !defined(VANILLAOPENCLCPLUSPLUS)
 void check_abominable_function() {
   { CheckAbominableFunction<int (S::*)() &> x; }
   { CheckAbominableFunction<int (S::*)() &&> x; }
@@ -4806,6 +5208,7 @@ void check_abominable_function() {
   { CheckAbominableFunction<int (S::*)() const volatile &> x; }
   { CheckAbominableFunction<int (S::*)() const volatile &&> x; }
 }
+#endif
 
 template <class T> using make_signed_t = __make_signed(T);
 template <class T, class Expected>
@@ -4836,10 +5239,12 @@ enum UnscopedLongLong : long long {};
 enum UnscopedULongLong : unsigned long long {};
 enum class ScopedLongLong : long long {};
 enum class ScopedULongLong : unsigned long long {};
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
 enum class UnscopedInt128 : __int128 {};
 enum class ScopedInt128 : __int128 {};
 enum class UnscopedUInt128 : unsigned __int128 {};
 enum class ScopedUInt128 : unsigned __int128 {};
+#endif
 
 void make_signed() {
   check_make_signed<char, signed char>();
@@ -4853,8 +5258,10 @@ void make_signed() {
   check_make_signed<unsigned long, long>();
   check_make_signed<long long, long long>();
   check_make_signed<unsigned long long, long long>();
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   check_make_signed<__int128, __int128>();
   check_make_signed<__uint128_t, __int128>();
+#endif
   check_make_signed<_BitInt(65), _BitInt(65)>();
   check_make_signed<unsigned _BitInt(65), _BitInt(65)>();
 
@@ -4872,6 +5279,7 @@ void make_signed() {
   check_make_signed<UnscopedUChar, signed char>();
   check_make_signed<ScopedUChar, signed char>();
 
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   check_make_signed<UnscopedLongLong, Int64>();
   check_make_signed<UnscopedULongLong, Int64>();
   check_make_signed<ScopedLongLong, Int64>();
@@ -4881,6 +5289,7 @@ void make_signed() {
   check_make_signed<ScopedInt128, __int128>();
   check_make_signed<UnscopedUInt128, __int128>();
   check_make_signed<ScopedUInt128, __int128>();
+#endif
 
   { using ExpectedError = __make_signed(bool); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'bool'}}
@@ -4897,11 +5306,14 @@ void make_signed() {
   { using ExpectedError = __make_signed(void); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'void'}}
   { using ExpectedError = __make_signed(int *); }
-  // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int *'}}
+  // expected-noncl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int *'}}
+  // expected-cl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given '__generic int *'}}
   { using ExpectedError = __make_signed(int &); }
-  // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int &'}}
+  // expected-noncl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int &'}}
+  // expected-cl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given '__generic int &'}}
   { using ExpectedError = __make_signed(int &&); }
-  // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int &&'}}
+  // expected-noncl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int &&'}}
+  // expected-cl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given '__generic int &&'}}
   { using ExpectedError = __make_signed(float); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'float'}}
   { using ExpectedError = __make_signed(double); }
@@ -4911,11 +5323,14 @@ void make_signed() {
   { using ExpectedError = __make_signed(S); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'S'}}
   { using ExpectedError = __make_signed(S *); }
-  // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'S *'}}
+  // expected-noncl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'S *'}}
+  // expected-cl-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given '__generic S *'}}
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   { using ExpectedError = __make_signed(int S::*); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int S::*'}}
   { using ExpectedError = __make_signed(int(S::*)()); }
   // expected-error@*:*{{'make_signed' is only compatible with non-bool 
integers and enum types, but was given 'int (S::*)()'}}
+#endif
 }
 
 template <class T>
@@ -4941,8 +5356,10 @@ void make_unsigned() {
   check_make_unsigned<unsigned long, unsigned long>();
   check_make_unsigned<long long, unsigned long long>();
   check_make_unsigned<unsigned long long, unsigned long long>();
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   check_make_unsigned<__int128, __uint128_t>();
   check_make_unsigned<__uint128_t, __uint128_t>();
+#endif
   check_make_unsigned<_BitInt(65), unsigned _BitInt(65)>();
   check_make_unsigned<unsigned _BitInt(65), unsigned _BitInt(65)>();
 
@@ -4960,6 +5377,7 @@ void make_unsigned() {
   check_make_unsigned<UnscopedUChar, unsigned char>();
   check_make_unsigned<ScopedUChar, unsigned char>();
 
+#if !defined(VANILLAOPENCLCPLUSPLUS) && !defined(EXTOPENCLCPLUSPLUS)
   check_make_unsigned<UnscopedLongLong, UInt64>();
   check_make_unsigned<UnscopedULongLong, UInt64>();
   check_make_unsigned<ScopedLongLong, UInt64>();
@@ -4969,6 +5387,7 @@ void make_unsigned() {
   check_make_unsigned<ScopedInt128, unsigned __int128>();
   check_make_unsigned<UnscopedUInt128, unsigned __int128>();
   check_make_unsigned<ScopedUInt128, unsigned __int128>();
+#endif
 
   { using ExpectedError = __make_unsigned(bool); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'bool'}}
@@ -4985,11 +5404,14 @@ void make_unsigned() {
   { using ExpectedError = __make_unsigned(void); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'void'}}
   { using ExpectedError = __make_unsigned(int *); }
-  // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'int *'}}
+  // expected-noncl-error@*:*{{'make_unsigned' is only compatible with 
non-bool integers and enum types, but was given 'int *'}}
+  // expected-cl-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given '__generic int *'}}
   { using ExpectedError = __make_unsigned(int &); }
-  // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'int &'}}
+  // expected-noncl-error@*:*{{'make_unsigned' is only compatible with 
non-bool integers and enum types, but was given 'int &'}}
+  // expected-cl-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given '__generic int &'}}
   { using ExpectedError = __make_unsigned(int &&); }
-  // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'int &&'}}
+  // expected-noncl-error@*:*{{'make_unsigned' is only compatible with 
non-bool integers and enum types, but was given 'int &&'}}
+  // expected-cl-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given '__generic int &&'}}
   { using ExpectedError = __make_unsigned(float); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'float'}}
   { using ExpectedError = __make_unsigned(double); }
@@ -4999,11 +5421,14 @@ void make_unsigned() {
   { using ExpectedError = __make_unsigned(S); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'S'}}
   { using ExpectedError = __make_unsigned(S *); }
-  // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'S *'}}
+  // expected-noncl-error@*:*{{'make_unsigned' is only compatible with 
non-bool integers and enum types, but was given 'S *'}}
+  // expected-cl-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given '__generic S *'}}
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   { using ExpectedError = __make_unsigned(int S::*); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'int S::*'}}
   { using ExpectedError = __make_unsigned(int(S::*)()); }
   // expected-error@*:*{{'make_unsigned' is only compatible with non-bool 
integers and enum types, but was given 'int (S::*)()'}}
+#endif
 }
 
 template <class T> using remove_extent_t = __remove_extent(T);
@@ -5030,13 +5455,17 @@ void remove_extent() {
   static_assert(__is_same(remove_extent_t<int *>, int *));
   static_assert(__is_same(remove_extent_t<int &>, int &));
   static_assert(__is_same(remove_extent_t<int &&>, int &&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_extent_t<int()>, int()));
   static_assert(__is_same(remove_extent_t<int (*)()>, int (*)()));
   static_assert(__is_same(remove_extent_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(remove_extent_t<S>, S));
   static_assert(__is_same(remove_extent_t<int S::*>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_extent_t<int (S::*)()>, int(S::*)()));
+#endif
 
   using SomeArray = int[1][2];
   static_assert(__is_same(remove_extent_t<const SomeArray>, const int[2]));
@@ -5069,13 +5498,17 @@ void remove_all_extents() {
   static_assert(__is_same(remove_all_extents_t<int *>, int *));
   static_assert(__is_same(remove_all_extents_t<int &>, int &));
   static_assert(__is_same(remove_all_extents_t<int &&>, int &&));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_all_extents_t<int()>, int()));
   static_assert(__is_same(remove_all_extents_t<int (*)()>, int (*)()));
   static_assert(__is_same(remove_all_extents_t<int (&)()>, int (&)()));
+#endif
 
   static_assert(__is_same(remove_all_extents_t<S>, S));
   static_assert(__is_same(remove_all_extents_t<int S::*>, int S::*));
+#if !defined(VANILLAOPENCLCPLUSPLUS)
   static_assert(__is_same(remove_all_extents_t<int (S::*)()>, int(S::*)()));
+#endif
 
   using SomeArray = int[1][2];
   static_assert(__is_same(remove_all_extents_t<const SomeArray>, const int));
diff --git a/clang/test/SemaOpenCLCXX/address-space-traits.clcpp 
b/clang/test/SemaOpenCLCXX/address-space-traits.clcpp
new file mode 100644
index 0000000000000..adb71c2105ea8
--- /dev/null
+++ b/clang/test/SemaOpenCLCXX/address-space-traits.clcpp
@@ -0,0 +1,29 @@
+//RUN: %clang_cc1 %s -triple spirv64-unknown-unknown -pedantic -fsyntax-only 
-verify -cl-ext=+__cl_clang_function_pointers,+__opencl_c_generic_address_space
+
+#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
+
+template <class T> using remove_pointer_t = __remove_pointer(T);
+static_assert(__is_same(remove_pointer_t<int (*)()>, int()));
+
+static_assert(__is_same(remove_pointer_t<int (*)()>, int()));
+
+static_assert(__is_same(remove_pointer_t<int (&)()>, int (&)()));
+
+template <class T> using remove_reference_t = __remove_reference_t(T);
+
+static_assert(__is_same(remove_reference_t<int (&)()>, int()));
+static_assert(__is_same(remove_reference_t<int (&)()>, void()));
+  // expected-error@-1 {{static assertion failed due to requirement 
'__is_same(int (), void ())'}}
+
+static_assert(!__is_same(remove_reference_t<__add_lvalue_reference(int 
(*)())>, int));
+
+struct S {
+  int foo() __local;
+};
+
+// FIXME: this fails since address-space is not preserved on member-function 
when speciefied (2nd parameter)
+//static_assert(!__is_same(remove_pointer_t<decltype(&S::foo)>, int (S::*)() 
const __local));
+//static_assert(__is_same(remove_pointer_t<decltype(&S::foo)>, int (S::*)() 
__local));
+
+//static_assert(!__is_same(remove_reference_t<decltype(&S::foo)>, int (S::*)() 
const __local));
+//static_assert(__is_same(remove_reference_t<decltype(&S::foo)>, int (S::*)() 
__local));

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to