<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Hi Galina,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Thanks for reporting it! I believe the issue is fixed in r297530</span>.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Cheers,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Anastasia<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Galina Kistanova [mailto:gkistanova@gmail.com]
<br>
<b>Sent:</b> 10 March 2017 20:29<br>
<b>To:</b> Anastasia Stulova<br>
<b>Cc:</b> cfe-commits<br>
<b>Subject:</b> Re: r297468 - [OpenCL] Fix type compatibility check and generic AS mangling.<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Hello Anastasia,<br>
<br>
Added test fails on one of our new builders:<br>
<br>
Failing Tests (1):<br>
    Clang :: SemaOpenCL/<a href="http://overload_addrspace_resolution.cl">overload_addrspace_resolution.cl</a><br>
<br>
<a href="http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23/steps/test-check-all/logs/stdio">http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23/steps/test-check-all/logs/stdio</a><br>
<br>
Please have a look at it?<br>
<br>
Thanks<br>
<br>
Galina<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Fri, Mar 10, 2017 at 7:23 AM, Anastasia Stulova via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<o:p></o:p></p>
<p class="MsoNormal">Author: stulova<br>
Date: Fri Mar 10 09:23:07 2017<br>
New Revision: 297468<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=297468&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=297468&view=rev</a><br>
Log:<br>
[OpenCL] Fix type compatibility check and generic AS mangling.<br>
<br>
1. Reimplemented conditional operator so that it checks<br>
compatibility of unqualified pointees of the 2nd and<br>
the 3rd operands (C99, OpenCL v2.0 6.5.15).<br>
<br>
Define QualTypes compatibility for OpenCL as following:<br>
<br>
   - corresponding types are compatible (C99 6.7.3)<br>
   - CVR-qualifiers are equal (C99 6.7.3)<br>
   - address spaces are equal (implementation defined)<br>
<br>
2. Added generic address space to Itanium mangling.<br>
<br>
Review: D30037<br>
<br>
Patch by Dmitry Borisenkov!<br>
<br>
<br>
Added:<br>
    cfe/trunk/test/SemaOpenCL/<a href="http://overload_addrspace_resolution.cl" target="_blank">overload_addrspace_resolution.cl</a><br>
Modified:<br>
    cfe/trunk/lib/AST/ASTContext.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/test/SemaOpenCL/<a href="http://address-spaces-conversions-cl2.0.cl" target="_blank">address-spaces-conversions-cl2.0.cl</a><br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=297468&r1=297467&r2=297468&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=297468&r1=297467&r2=297468&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Mar 10 09:23:07 2017<br>
@@ -8066,15 +8066,6 @@ QualType ASTContext::mergeTypes(QualType<br>
   Qualifiers LQuals = LHSCan.getLocalQualifiers();<br>
   Qualifiers RQuals = RHSCan.getLocalQualifiers();<br>
   if (LQuals != RQuals) {<br>
-    if (getLangOpts().OpenCL) {<br>
-      if (LHSCan.getUnqualifiedType() != RHSCan.getUnqualifiedType() ||<br>
-          LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers())<br>
-        return QualType();<br>
-      if (LQuals.isAddressSpaceSupersetOf(RQuals))<br>
-        return LHS;<br>
-      if (RQuals.isAddressSpaceSupersetOf(LQuals))<br>
-        return RHS;<br>
-    }<br>
     // If any of these qualifiers are different, we have a type<br>
     // mismatch.<br>
     if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||<br>
@@ -8200,6 +8191,20 @@ QualType ASTContext::mergeTypes(QualType<br>
       LHSPointee = LHSPointee.getUnqualifiedType();<br>
       RHSPointee = RHSPointee.getUnqualifiedType();<br>
     }<br>
+    if (getLangOpts().OpenCL) {<br>
+      Qualifiers LHSPteeQual = LHSPointee.getQualifiers();<br>
+      Qualifiers RHSPteeQual = RHSPointee.getQualifiers();<br>
+      // Blocks can't be an expression in a ternary operator (OpenCL v2.0<br>
+      // 6.12.5) thus the following check is asymmetric.<br>
+      if (!LHSPteeQual.isAddressSpaceSupersetOf(RHSPteeQual))<br>
+        return QualType();<br>
+      LHSPteeQual.removeAddressSpace();<br>
+      RHSPteeQual.removeAddressSpace();<br>
+      LHSPointee =<br>
+          QualType(LHSPointee.getTypePtr(), LHSPteeQual.getAsOpaqueValue());<br>
+      RHSPointee =<br>
+          QualType(RHSPointee.getTypePtr(), RHSPteeQual.getAsOpaqueValue());<br>
+    }<br>
     QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,<br>
                                      Unqualified);<br>
     if (ResultType.isNull()) return QualType();<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=297468&r1=297467&r2=297468&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=297468&r1=297467&r2=297468&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Mar 10 09:23:07 2017<br>
@@ -2159,10 +2159,12 @@ void CXXNameMangler::mangleQualifiers(Qu<br>
     } else {<br>
       switch (AS) {<br>
       default: llvm_unreachable("Not a language specific address space");<br>
-      //  <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" ]<br>
+      //  <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant |<br>
+      //                                "generic" ]<br>
       case LangAS::opencl_global:   ASString = "CLglobal";   break;<br>
       case LangAS::opencl_local:    ASString = "CLlocal";    break;<br>
       case LangAS::opencl_constant: ASString = "CLconstant"; break;<br>
+      case LangAS::opencl_generic:  ASString = "CLgeneric";  break;<br>
       //  <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]<br>
       case LangAS::cuda_device:     ASString = "CUdevice";   break;<br>
       case LangAS::cuda_constant:   ASString = "CUconstant"; break;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=297468&r1=297467&r2=297468&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=297468&r1=297467&r2=297468&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Mar 10 09:23:07 2017<br>
@@ -6335,92 +6335,98 @@ static QualType checkConditionalPointerC<br>
   Qualifiers lhQual = lhptee.getQualifiers();<br>
   Qualifiers rhQual = rhptee.getQualifiers();<br>
<br>
+  unsigned ResultAddrSpace = 0;<br>
+  unsigned LAddrSpace = lhQual.getAddressSpace();<br>
+  unsigned RAddrSpace = rhQual.getAddressSpace();<br>
+  if (S.getLangOpts().OpenCL) {<br>
+    // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address<br>
+    // spaces is disallowed.<br>
+    if (lhQual.isAddressSpaceSupersetOf(rhQual))<br>
+      ResultAddrSpace = LAddrSpace;<br>
+    else if (rhQual.isAddressSpaceSupersetOf(lhQual))<br>
+      ResultAddrSpace = RAddrSpace;<br>
+    else {<br>
+      S.Diag(Loc,<br>
+             diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)<br>
+          << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()<br>
+          << RHS.get()->getSourceRange();<br>
+      return QualType();<br>
+    }<br>
+  }<br>
+<br>
   unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();<br>
+  auto LHSCastKind = CK_BitCast, RHSCastKind = CK_BitCast;<br>
   lhQual.removeCVRQualifiers();<br>
   rhQual.removeCVRQualifiers();<br>
<br>
+  // OpenCL v2.0 specification doesn't extend compatibility of type qualifiers<br>
+  // (C99 6.7.3) for address spaces. We assume that the check should behave in<br>
+  // the same manner as it's defined for CVR qualifiers, so for OpenCL two<br>
+  // qual types are compatible iff<br>
+  //  * corresponded types are compatible<br>
+  //  * CVR qualifiers are equal<br>
+  //  * address spaces are equal<br>
+  // Thus for conditional operator we merge CVR and address space unqualified<br>
+  // pointees and if there is a composite type we return a pointer to it with<br>
+  // merged qualifiers.<br>
+  if (S.getLangOpts().OpenCL) {<br>
+    LHSCastKind = LAddrSpace == ResultAddrSpace<br>
+                      ? CK_BitCast<br>
+                      : CK_AddressSpaceConversion;<br>
+    RHSCastKind = RAddrSpace == ResultAddrSpace<br>
+                      ? CK_BitCast<br>
+                      : CK_AddressSpaceConversion;<br>
+    lhQual.removeAddressSpace();<br>
+    rhQual.removeAddressSpace();<br>
+  }<br>
+<br>
   lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual);<br>
   rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual);<br>
<br>
-  // For OpenCL:<br>
-  // 1. If LHS and RHS types match exactly and:<br>
-  //  (a) AS match => use standard C rules, no bitcast or addrspacecast<br>
-  //  (b) AS overlap => generate addrspacecast<br>
-  //  (c) AS don't overlap => give an error<br>
-  // 2. if LHS and RHS types don't match:<br>
-  //  (a) AS match => use standard C rules, generate bitcast<br>
-  //  (b) AS overlap => generate addrspacecast instead of bitcast<br>
-  //  (c) AS don't overlap => give an error<br>
-<br>
-  // For OpenCL, non-null composite type is returned only for cases 1a and 1b.<br>
   QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee);<br>
<br>
-  // OpenCL cases 1c, 2a, 2b, and 2c.<br>
   if (CompositeTy.isNull()) {<br>
     // In this situation, we assume void* type. No especially good<br>
     // reason, but this is what gcc does, and we do have to pick<br>
     // to get a consistent AST.<br>
     QualType incompatTy;<br>
-    if (S.getLangOpts().OpenCL) {<br>
-      // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address<br>
-      // spaces is disallowed.<br>
-      unsigned ResultAddrSpace;<br>
-      if (lhQual.isAddressSpaceSupersetOf(rhQual)) {<br>
-        // Cases 2a and 2b.<br>
-        ResultAddrSpace = lhQual.getAddressSpace();<br>
-      } else if (rhQual.isAddressSpaceSupersetOf(lhQual)) {<br>
-        // Cases 2a and 2b.<br>
-        ResultAddrSpace = rhQual.getAddressSpace();<br>
-      } else {<br>
-        // Cases 1c and 2c.<br>
-        S.Diag(Loc,<br>
-               diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)<br>
-            << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()<br>
-            << RHS.get()->getSourceRange();<br>
-        return QualType();<br>
-      }<br>
-<br>
-      // Continue handling cases 2a and 2b.<br>
-      incompatTy = S.Context.getPointerType(<br>
-          S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace));<br>
-      LHS = S.ImpCastExprToType(LHS.get(), incompatTy,<br>
-                                (lhQual.getAddressSpace() != ResultAddrSpace)<br>
-                                    ? CK_AddressSpaceConversion /* 2b */<br>
-                                    : CK_BitCast /* 2a */);<br>
-      RHS = S.ImpCastExprToType(RHS.get(), incompatTy,<br>
-                                (rhQual.getAddressSpace() != ResultAddrSpace)<br>
-                                    ? CK_AddressSpaceConversion /* 2b */<br>
-                                    : CK_BitCast /* 2a */);<br>
-    } else {<br>
-      S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)<br>
-          << LHSTy << RHSTy << LHS.get()->getSourceRange()<br>
-          << RHS.get()->getSourceRange();<br>
-      incompatTy = S.Context.getPointerType(S.Context.VoidTy);<br>
-      LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);<br>
-      RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);<br>
-    }<br>
+    incompatTy = S.Context.getPointerType(<br>
+        S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace));<br>
+    LHS = S.ImpCastExprToType(LHS.get(), incompatTy, LHSCastKind);<br>
+    RHS = S.ImpCastExprToType(RHS.get(), incompatTy, RHSCastKind);<br>
+    // FIXME: For OpenCL the warning emission and cast to void* leaves a room<br>
+    // for casts between types with incompatible address space qualifiers.<br>
+    // For the following code the compiler produces casts between global and<br>
+    // local address spaces of the corresponded innermost pointees:<br>
+    // local int *global *a;<br>
+    // global int *global *b;<br>
+    // a = (0 ? a : b); // see C99 6.5.16.1.p1.<br>
+    S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)<br>
+        << LHSTy << RHSTy << LHS.get()->getSourceRange()<br>
+        << RHS.get()->getSourceRange();<br>
     return incompatTy;<br>
   }<br>
<br>
   // The pointer types are compatible.<br>
-  QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual);<br>
-  auto LHSCastKind = CK_BitCast, RHSCastKind = CK_BitCast;<br>
+  // In case of OpenCL ResultTy should have the address space qualifier<br>
+  // which is a superset of address spaces of both the 2nd and the 3rd<br>
+  // operands of the conditional operator.<br>
+  QualType ResultTy = [&, ResultAddrSpace]() {<br>
+    if (S.getLangOpts().OpenCL) {<br>
+      Qualifiers CompositeQuals = CompositeTy.getQualifiers();<br>
+      CompositeQuals.setAddressSpace(ResultAddrSpace);<br>
+      return S.Context<br>
+          .getQualifiedType(CompositeTy.getUnqualifiedType(), CompositeQuals)<br>
+          .withCVRQualifiers(MergedCVRQual);<br>
+    } else<br>
+      return CompositeTy.withCVRQualifiers(MergedCVRQual);<br>
+  }();<br>
   if (IsBlockPointer)<br>
     ResultTy = S.Context.getBlockPointerType(ResultTy);<br>
   else {<br>
-    // Cases 1a and 1b for OpenCL.<br>
-    auto ResultAddrSpace = ResultTy.getQualifiers().getAddressSpace();<br>
-    LHSCastKind = lhQual.getAddressSpace() == ResultAddrSpace<br>
-                      ? CK_BitCast /* 1a */<br>
-                      : CK_AddressSpaceConversion /* 1b */;<br>
-    RHSCastKind = rhQual.getAddressSpace() == ResultAddrSpace<br>
-                      ? CK_BitCast /* 1a */<br>
-                      : CK_AddressSpaceConversion /* 1b */;<br>
     ResultTy = S.Context.getPointerType(ResultTy);<br>
   }<br>
<br>
-  // For case 1a of OpenCL, S.ImpCastExprToType will not insert bitcast<br>
-  // if the target type does not change.<br>
   LHS = S.ImpCastExprToType(LHS.get(), ResultTy, LHSCastKind);<br>
   RHS = S.ImpCastExprToType(RHS.get(), ResultTy, RHSCastKind);<br>
   return ResultTy;<br>
@@ -7399,7 +7405,22 @@ checkBlockPointerTypesForAssignment(Sema<br>
   if (LQuals != RQuals)<br>
     ConvTy = Sema::CompatiblePointerDiscardsQualifiers;<br>
<br>
-  if (!S.Context.typesAreBlockPointerCompatible(LHSType, RHSType))<br>
+  // FIXME: OpenCL doesn't define the exact compile time semantics for a block<br>
+  // assignment.<br>
+  // The current behavior is similar to C++ lambdas. A block might be<br>
+  // assigned to a variable iff its return type and parameters are compatible<br>
+  // (C99 6.2.7) with the corresponding return type and parameters of the LHS of<br>
+  // an assignment. Presumably it should behave in way that a function pointer<br>
+  // assignment does in C, so for each parameter and return type:<br>
+  //  * CVR and address space of LHS should be a superset of CVR and address<br>
+  //  space of RHS.<br>
+  //  * unqualified types should be compatible.<br>
+  if (S.getLangOpts().OpenCL) {<br>
+    if (!S.Context.typesAreBlockPointerCompatible(<br>
+            S.Context.getQualifiedType(LHSType.getUnqualifiedType(), LQuals),<br>
+            S.Context.getQualifiedType(RHSType.getUnqualifiedType(), RQuals)))<br>
+      return Sema::IncompatibleBlockPointer;<br>
+  } else if (!S.Context.typesAreBlockPointerCompatible(LHSType, RHSType))<br>
     return Sema::IncompatibleBlockPointer;<br>
<br>
   return ConvTy;<br>
<br>
Modified: cfe/trunk/test/SemaOpenCL/<a href="http://address-spaces-conversions-cl2.0.cl" target="_blank">address-spaces-conversions-cl2.0.cl</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl?rev=297468&r1=297467&r2=297468&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl?rev=297468&r1=297467&r2=297468&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaOpenCL/<a href="http://address-spaces-conversions-cl2.0.cl" target="_blank">address-spaces-conversions-cl2.0.cl</a> (original)<br>
+++ cfe/trunk/test/SemaOpenCL/<a href="http://address-spaces-conversions-cl2.0.cl" target="_blank">address-spaces-conversions-cl2.0.cl</a> Fri Mar 10 09:23:07 2017<br>
@@ -18,14 +18,20 @@<br>
<br>
 #ifdef GENERIC<br>
 #define AS generic<br>
+#define AS_COMP local<br>
+#define AS_INCOMP constant<br>
 #endif<br>
<br>
 #ifdef GLOBAL<br>
 #define AS global<br>
+#define AS_COMP global<br>
+#define AS_INCOMP local<br>
 #endif<br>
<br>
 #ifdef CONSTANT<br>
 #define AS constant<br>
+#define AS_COMP constant<br>
+#define AS_INCOMP global<br>
 #endif<br>
<br>
 void f_glob(global int *arg_glob) {}<br>
@@ -263,12 +269,16 @@ void test_ternary() {<br>
   var_void_gen = 0 ? var_cond : var_glob_ch;<br>
 #ifdef CONSTANT<br>
 // expected-error@-2{{conditional operator with the second and third operands of type  ('__constant int *' and '__global char *') which are pointers to non-overlapping address spaces}}<br>
+#else<br>
+// expected-warning-re@-4{{pointer type mismatch ('__{{global|generic}} int *' and '__global char *')}}<br>
 #endif<br>
<br>
   local char *var_loc_ch;<br>
   var_void_gen = 0 ? var_cond : var_loc_ch;<br>
 #ifndef GENERIC<br>
 // expected-error-re@-2{{conditional operator with the second and third operands of type  ('__{{global|constant}} int *' and '__local char *') which are pointers to non-overlapping address spaces}}<br>
+#else<br>
+// expected-warning@-4{{pointer type mismatch ('__generic int *' and '__local char *')}}<br>
 #endif<br>
<br>
   constant void *var_void_const;<br>
@@ -276,18 +286,45 @@ void test_ternary() {<br>
   var_void_const = 0 ? var_cond : var_const_ch;<br>
 #ifndef CONSTANT<br>
 // expected-error-re@-2{{conditional operator with the second and third operands of type  ('__{{global|generic}} int *' and '__constant char *') which are pointers to non-overlapping address spaces}}<br>
+#else<br>
+// expected-warning@-4{{pointer type mismatch ('__constant int *' and '__constant char *')}}<br>
 #endif<br>
<br>
   private char *var_priv_ch;<br>
   var_void_gen = 0 ? var_cond : var_priv_ch;<br>
 #ifndef GENERIC<br>
 // expected-error-re@-2{{conditional operator with the second and third operands of type  ('__{{global|constant}} int *' and 'char *') which are pointers to non-overlapping address spaces}}<br>
+#else<br>
+// expected-warning@-4{{pointer type mismatch ('__generic int *' and 'char *')}}<br>
 #endif<br>
<br>
   generic char *var_gen_ch;<br>
   var_void_gen = 0 ? var_cond : var_gen_ch;<br>
 #ifdef CONSTANT<br>
 // expected-error@-2{{conditional operator with the second and third operands of type  ('__constant int *' and '__generic char *') which are pointers to non-overlapping address spaces}}<br>
+#else<br>
+// expected-warning-re@-4{{pointer type mismatch ('__{{global|generic}} int *' and '__generic char *')}}<br>
 #endif<br>
 }<br>
<br>
+void test_pointer_chains() {<br>
+  AS int *AS *var_as_as_int;<br>
+  AS int *AS_COMP *var_asc_as_int;<br>
+  AS_INCOMP int *AS_COMP *var_asc_asn_int;<br>
+  AS_COMP int *AS_COMP *var_asc_asc_int;<br>
+<br>
+  // Case 1:<br>
+  //  * address spaces of corresponded most outer pointees overlaps, their canonical types are equal<br>
+  //  * CVR, address spaces and canonical types of the rest of pointees are equivalent.<br>
+  var_as_as_int = 0 ? var_as_as_int : var_asc_as_int;<br>
+<br>
+  // Case 2: Corresponded inner pointees has non-overlapping address spaces.<br>
+  var_as_as_int = 0 ? var_as_as_int : var_asc_asn_int;<br>
+// expected-warning-re@-1{{pointer type mismatch ('__{{(generic|global|constant)}} int *__{{(generic|global|constant)}} *' and '__{{(local|global|constant)}} int *__{{(constant|local|global)}} *')}}<br>
+<br>
+  // Case 3: Corresponded inner pointees has overlapping but not equivalent address spaces.<br>
+#ifdef GENERIC<br>
+  var_as_as_int = 0 ? var_as_as_int : var_asc_asc_int;<br>
+// expected-warning-re@-1{{pointer type mismatch ('__{{(generic|global|constant)}} int *__{{(generic|global|constant)}} *' and '__{{(local|global|constant)}} int *__{{(local|global|constant)}} *')}}<br>
+#endif<br>
+}<br>
<br>
Added: cfe/trunk/test/SemaOpenCL/<a href="http://overload_addrspace_resolution.cl" target="_blank">overload_addrspace_resolution.cl</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/overload_addrspace_resolution.cl?rev=297468&view=auto" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/overload_addrspace_resolution.cl?rev=297468&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaOpenCL/<a href="http://overload_addrspace_resolution.cl" target="_blank">overload_addrspace_resolution.cl</a> (added)<br>
+++ cfe/trunk/test/SemaOpenCL/<a href="http://overload_addrspace_resolution.cl" target="_blank">overload_addrspace_resolution.cl</a> Fri Mar 10 09:23:07 2017<br>
@@ -0,0 +1,29 @@<br>
+// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - %s | FileCheck %s<br>
+<br>
+void __attribute__((overloadable)) foo(global int *a, global int *b);<br>
+void __attribute__((overloadable)) foo(generic int *a, generic int *b);<br>
+void __attribute__((overloadable)) bar(generic int *global *a, generic int *global *b);<br>
+void __attribute__((overloadable)) bar(generic int *generic *a, generic int *generic *b);<br>
+<br>
+void kernel ker() {<br>
+  global int *a;<br>
+  global int *b;<br>
+  generic int *c;<br>
+  local int *d;<br>
+  generic int *generic *gengen;<br>
+  generic int *local *genloc;<br>
+  generic int *global *genglob;<br>
+  // CHECK: call void @_Z3fooPU8CLglobaliS0_(i32* undef, i32* undef)<br>
+  foo(a, b);<br>
+  // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef)<br>
+  foo(b, c);<br>
+  // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef)<br>
+  foo(a, d);<br>
+<br>
+  // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef)<br>
+  bar(gengen, genloc);<br>
+  // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef)<br>
+  bar(gengen, genglob);<br>
+  // CHECK: call void @_Z3barPU8CLglobalPU9CLgenericiS2_(i32** undef, i32** undef)<br>
+  bar(genglob, genglob);<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</body>
</html>