"; did you forget * in %1?">;
def err_parameters_retval_cannot_have_fp16_type : Error<
"%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">;
-def err_opencl_half_dereferencing : Error<
- "dereferencing pointer of type %0 is not allowed">;
-def err_opencl_half_subscript : Error<
- "subscript to array of type %0 is not allowed">;
+def err_opencl_half_load_store : Error<
+ "%select{loading directly from|assigning directly to}0 pointer to type %1 is not allowed">;
def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
-def err_opencl_cast_from_half : Error<"casting from type %0 is not allowed">;
def err_opencl_half_declaration : Error<
"declaring variable of type %0 is not allowed">;
def err_opencl_half_argument : Error<
SrcExpr = ExprError();
return;
}
- if (SrcExpr.get()->getType()->isHalfType()) {
- Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_from_half)
- << SrcType << SrcExpr.get()->getSourceRange();
- SrcExpr = ExprError();
- return;
- }
}
// ARC imposes extra restrictions on casts.
if (T->isVoidType())
return Owned(E);
+ // OpenCL usually rejects direct accesses to values of 'half' type.
+ if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 &&
+ T->isHalfType()) {
+ Diag(E->getExprLoc(), diag::err_opencl_half_load_store)
+ << 0 << T;
+ return ExprError();
+ }
+
CheckForNullPointerDereference(*this, E);
// C++ [conv.lval]p1:
diag::err_subscript_incomplete_type, BaseExpr))
return ExprError();
- if (ResultType->isHalfType() && getLangOpts().OpenCL &&
- !getOpenCLOptions().cl_khr_fp16) {
- Diag(BaseExpr->getLocStart(), diag::err_opencl_half_subscript) << ResultType
- << BaseExpr->getType() << BaseExpr->getSourceRange();
- return ExprError();
- }
-
assert(VK == VK_RValue || LangOpts.CPlusPlus ||
!ResultType.isCForbiddenLValueType());
LHSType = Context.getCanonicalType(LHSType).getUnqualifiedType();
RHSType = Context.getCanonicalType(RHSType).getUnqualifiedType();
-
// Common case: no conversion required.
if (LHSType == RHSType) {
Kind = CK_NoOp;
return QualType();
}
- if (Result->isHalfType() && S.getLangOpts().OpenCL &&
- !S.getOpenCLOptions().cl_khr_fp16) {
- S.Diag(OpLoc, diag::err_opencl_half_dereferencing)
- << OpTy << Op->getSourceRange();
- return QualType();
- }
-
// Dereferences are usually l-values...
VK = VK_LValue;
S.Diag(Param->getLocation(),
diag::err_opencl_half_argument) << ArgTy;
D.setInvalidType();
+ Param->setInvalidDecl();
}
} else {
S.Diag(Param->getLocation(),
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -Wno-unused-value
#pragma OPENCL EXTENSION cl_khr_fp16 : disable
{
half a[2]; // expected-error{{declaring variable of type 'half [2]' is not allowed}}
half b; // expected-error{{declaring variable of type 'half' is not allowed}}
-
- b = *p; // expected-error{{dereferencing pointer of type 'half *' is not allowed}}
- *p = b; // expected-error{{dereferencing pointer of type 'half *' is not allowed}}
-
- b = p[1]; // expected-error {{subscript to array of type 'half' is not allowed}}
- p[1] = b; // expected-error {{subscript to array of type 'half' is not allowed}}
+ *p; // expected-error{{loading directly from pointer to type 'half' is not allowed}}
+ p[1]; // expected-error{{loading directly from pointer to type 'half' is not allowed}}
float c = 1.0f;
b = (half) c; // expected-error{{casting to type 'half' is not allowed}}
- c = (float) h; // expected-error{{casting from type 'half' is not allowed}}
+
+ half *allowed = &p[1];
+ half *allowed2 = &*p;
+ half *allowed3 = p + 1;
return h;
}
{
half a[2];
half b;
-
- b = *p;
- *p = b;
-
- b = p[1];
- p[1] = b;
+ *p;
+ p[1];
float c = 1.0f;
b = (half) c;
- c = (float) h;
+
+ half *allowed = &p[1];
+ half *allowed2 = &*p;
+ half *allowed3 = p + 1;
return h;
}