Hi rsmith, The OpenCL specification and conformance tests have code similar to;
void func(event_t e); ... func((event_t)0); Clang (in OpenCL language mode) currently supports the above, but without the explicit cast, like; func(0); But doesn't allow the explicit cast. This patch fixes this, and also adds in a more descriptive error for when a user does; (event_t)5; and also adds in some more expected results to the OpenCL event_t tests. Any comments or suggestions would be greatly appreciated! http://llvm-reviews.chandlerc.com/D2860 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaCast.cpp test/SemaOpenCL/event_t.cl Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -6785,6 +6785,8 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; +def error_opencl_cast_non_zero_to_event_t : Error< + "cannot cast non-zero value '%0' to 'event_t'">; } // end of sema category let CategoryName = "OpenMP Issue" in { Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2238,6 +2238,21 @@ return; } + // for OpenCL, allow casts from '0' to event_t type + if ((Self.getLangOpts().OpenCL) && DestType->isEventT()) { + llvm::APSInt intValue; + if(SrcExpr.get()->EvaluateAsInt(intValue, Self.getASTContext())) { + if(0 == intValue) { + return; + } else { + Self.Diag(OpRange.getBegin(), diag::error_opencl_cast_non_zero_to_event_t) + << intValue.toString(10) << SrcExpr.get()->getSourceRange(); + SrcExpr = ExprError(); + return; + } + } + } + // Reject any other conversions to non-scalar types. Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar) << DestType << SrcExpr.get()->getSourceRange(); Index: test/SemaOpenCL/event_t.cl =================================================================== --- test/SemaOpenCL/event_t.cl +++ test/SemaOpenCL/event_t.cl @@ -6,13 +6,18 @@ event_t evt; // expected-error {{the event_t type cannot be used to declare a structure or union field}} } evt_str = {0}; -void foo(event_t evt); // expected-note {{passing argument to parameter 'evt' here}} +void foo(event_t evt); // expected-note 2 {{passing argument to parameter 'evt' here}} void kernel ker(event_t argevt) { // expected-error {{'event_t' cannot be used as the type of a kernel parameter}} event_t e; + int i; constant event_t const_evt; // expected-error {{the event_t type can only be used with __private address space qualifier}} foo(e); foo(0); + foo((event_t)0); + foo(i); // expected-error {{passing 'int' to parameter of incompatible type 'event_t'}} + foo((event_t)i); // expected-error {{used type 'event_t' where arithmetic or pointer type is required}} foo(5); // expected-error {{passing 'int' to parameter of incompatible type 'event_t'}} + foo((event_t)5); // expected-error {{cannot cast non-zero value '5' to 'event_t'}} }
Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -6785,6 +6785,8 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; +def error_opencl_cast_non_zero_to_event_t : Error< + "cannot cast non-zero value '%0' to 'event_t'">; } // end of sema category let CategoryName = "OpenMP Issue" in { Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2238,6 +2238,21 @@ return; } + // for OpenCL, allow casts from '0' to event_t type + if ((Self.getLangOpts().OpenCL) && DestType->isEventT()) { + llvm::APSInt intValue; + if(SrcExpr.get()->EvaluateAsInt(intValue, Self.getASTContext())) { + if(0 == intValue) { + return; + } else { + Self.Diag(OpRange.getBegin(), diag::error_opencl_cast_non_zero_to_event_t) + << intValue.toString(10) << SrcExpr.get()->getSourceRange(); + SrcExpr = ExprError(); + return; + } + } + } + // Reject any other conversions to non-scalar types. Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar) << DestType << SrcExpr.get()->getSourceRange(); Index: test/SemaOpenCL/event_t.cl =================================================================== --- test/SemaOpenCL/event_t.cl +++ test/SemaOpenCL/event_t.cl @@ -6,13 +6,18 @@ event_t evt; // expected-error {{the event_t type cannot be used to declare a structure or union field}} } evt_str = {0}; -void foo(event_t evt); // expected-note {{passing argument to parameter 'evt' here}} +void foo(event_t evt); // expected-note 2 {{passing argument to parameter 'evt' here}} void kernel ker(event_t argevt) { // expected-error {{'event_t' cannot be used as the type of a kernel parameter}} event_t e; + int i; constant event_t const_evt; // expected-error {{the event_t type can only be used with __private address space qualifier}} foo(e); foo(0); + foo((event_t)0); + foo(i); // expected-error {{passing 'int' to parameter of incompatible type 'event_t'}} + foo((event_t)i); // expected-error {{used type 'event_t' where arithmetic or pointer type is required}} foo(5); // expected-error {{passing 'int' to parameter of incompatible type 'event_t'}} + foo((event_t)5); // expected-error {{cannot cast non-zero value '5' to 'event_t'}} }
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits