Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -613,6 +613,7 @@ 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_param : Error< Index: include/clang/Lex/LiteralSupport.h =================================================================== --- include/clang/Lex/LiteralSupport.h +++ include/clang/Lex/LiteralSupport.h @@ -61,6 +61,7 @@ bool isUnsigned : 1; bool isLong : 1; // This is *not* set for long long. bool isLongLong : 1; + bool isHalf : 1; // 1.0h bool isFloat : 1; // 1.0f bool isImaginary : 1; // 1.0i uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. Index: lib/Lex/LiteralSupport.cpp =================================================================== --- lib/Lex/LiteralSupport.cpp +++ lib/Lex/LiteralSupport.cpp @@ -522,6 +522,7 @@ isLong = false; isUnsigned = false; isLongLong = false; + isHalf = false; isFloat = false; isImaginary = false; MicrosoftInteger = 0; @@ -555,10 +556,17 @@ // we break out of the loop. for (; s != ThisTokEnd; ++s) { switch (*s) { + case 'h': // FP Suffix for "half" + case 'H': + if (!PP.getLangOpts().Half) break; + if (!isFPConstant) break; // Error for integer constant. + if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid. + isHalf = true; + continue; // Success. case 'f': // FP Suffix for "float" case 'F': if (!isFPConstant) break; // Error for integer constant. - if (isFloat || isLong) break; // FF, LF invalid. + if (isHalf || isFloat || isLong) break; // HF, FF, LF invalid. isFloat = true; continue; // Success. case 'u': @@ -570,7 +578,7 @@ case 'l': case 'L': if (isLong || isLongLong) break; // Cannot be repeated. - if (isFloat) break; // LF invalid. + if (isHalf || isFloat) break; // LH, LF invalid. // Check for long long. The L's need to be adjacent and the same case. if (s[1] == s[0]) { @@ -647,6 +655,7 @@ isUnsigned = false; isLongLong = false; isFloat = false; + isHalf = false; isImaginary = false; MicrosoftInteger = 0; Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2394,6 +2394,12 @@ SrcExpr = ExprError(); return; } + if (SrcType->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. Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -3294,7 +3294,9 @@ if (Literal.isFloatingLiteral()) { QualType Ty; - if (Literal.isFloat) + if (Literal.isHalf) + Ty = Context.HalfTy; + else if (Literal.isFloat) Ty = Context.FloatTy; else if (!Literal.isLong) Ty = Context.DoubleTy; Index: test/Lexer/opencl-half-literal.cl =================================================================== --- /dev/null +++ test/Lexer/opencl-half-literal.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +constant half a = 1.0h; +constant half aa = 1.0H; +constant half b = 1.0hh; // expected-error{{invalid suffix 'hh' on floating constant}} +constant half c = 1.0fh; // expected-error{{invalid suffix 'fh' on floating constant}} +constant half d = 1.0lh; // expected-error{{invalid suffix 'lh' on floating constant}} +constant half e = 1.0hf; // expected-error{{invalid suffix 'hf' on floating constant}} Index: test/SemaOpenCL/half.cl =================================================================== --- test/SemaOpenCL/half.cl +++ test/SemaOpenCL/half.cl @@ -12,6 +12,7 @@ float c = 1.0f; b = (half) c; // expected-error{{casting to type 'half' is not allowed}} + c = (float) 1.0h; // expected-error{{casting from type 'half' is not allowed}} half *allowed = &p[1]; half *allowed2 = &*p; @@ -31,6 +32,7 @@ float c = 1.0f; b = (half) c; + b = 1.0h; half *allowed = &p[1]; half *allowed2 = &*p;