pxli168 created this revision. pxli168 added reviewers: pekka.jaaskelainen, Anastasia, yaxunl. pxli168 added a subscriber: cfe-commits.
Add Sema checks for atomics and implicit declaration This patch is partitioned from http://reviews.llvm.org/D16047 http://reviews.llvm.org/D17438 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaInit.cpp test/Parser/opencl-atomics-cl20.cl test/SemaOpenCL/invalid-decl.cl
Index: test/SemaOpenCL/invalid-decl.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/invalid-decl.cl @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -verify -cl-std=CL2.0 %s +int; // expected-error {{declaration does not declare anything}} + +void test1(){ + myfun(); // expected-error {{implicit declaration of function 'myfun' is invalid in OpenCL}} +} Index: test/Parser/opencl-atomics-cl20.cl =================================================================== --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -56,6 +56,7 @@ #endif #ifdef CL20 +#define ATOMIC_VAR_INIT void foo(atomic_int * ptr) {} void atomic_ops_test() { atomic_int i; @@ -66,4 +67,7 @@ i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} } +void atomic_init_test() { + atomic_int guide = ATOMIC_VAR_INIT(42); // expected-error {{initialization of atomic variables is restricted to variables in global address space in opencl}} +} #endif Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6136,6 +6136,32 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1 - The ATOMIC_VAR_INIT macro expands to a token + // sequence suitable for initializing an atomic object of a type that is + // initialization-compatible with value. An atomic object with automatic + // storage duration that is not explicitly initialized using ATOMIC_VAR_INIT + // is initially in an indeterminate state; however, the default (zero) + // initialization for objects with static storage duration is guaranteed to + // produce a valid state. + // #define ATOMIC_VAR_INIT(C value) + // This macro can only be used to initialize atomic objects that are declared + // in program scope in the global address space. + // Examples: + // global atomic_int guide = ATOMIC_VAR_INIT(42); + if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion >= 200 && + Entity.getType()->isAtomicType()) { + Qualifiers TyQualifiers = Entity.getType().getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + if (!HasGlobalAS && Entity.getKind() == InitializedEntity::EK_Variable && + Args.size() > 0) { + Expr *Init = Args[0]; + S.Diag(Init->getLocStart(), diag::err_opencl_atomic_init_addressspace) + << SourceRange(Entity.getDecl()->getLocStart(), Init->getLocEnd()); + return ExprError(); + } + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -3897,6 +3897,12 @@ // names into the program, or shall redeclare a name introduced by a // previous declaration. if (!DeclaresAnything) { + // OpenCL C doesn't support bit-field, so declaration with no declarator + // has no use. + if (getLangOpts().OpenCL) { + Diag(DS.getLocStart(), diag::err_no_declarators) << DS.getSourceRange(); + return 0; + } // In C, we allow this as a (popular) extension / bug. Don't bother // producing further diagnostics for redundant qualifiers after this. Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange(); @@ -7274,8 +7280,13 @@ QualType PointeeType = PT->getPointeeType(); if (PointeeType->isPointerType()) return PtrPtrKernelParam; - return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam - : PtrKernelParam; + // Now generice address space is added, we need to handle like this + unsigned addrSpace = PointeeType.getAddressSpace(); + return (addrSpace != LangAS::opencl_global && + addrSpace != LangAS::opencl_constant && + addrSpace != LangAS::opencl_local) + ? PrivatePtrKernelParam + : PtrKernelParam; } // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can @@ -7293,6 +7304,9 @@ if (PT->isHalfType()) return InvalidKernelParam; + if (PT->isReserveIDT()) + return InvalidKernelParam; + if (PT->isRecordType()) return RecordKernelParam; @@ -11486,6 +11500,10 @@ unsigned diag_id; if (II.getName().startswith("__builtin_")) diag_id = diag::warn_builtin_unknown; + else if (getLangOpts().OpenCL) + // OpenCL function need to be called with prototype, so we don't allow + // implicit function declarations in OpenCL + diag_id = diag::err_opencl_implicit_function_decl; else if (getLangOpts().C99) diag_id = diag::ext_implicit_function_decl; else Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -602,6 +602,7 @@ /// parser diagnostics def ext_no_declarators : ExtWarn<"declaration does not declare anything">, InGroup<MissingDeclarations>; +def err_no_declarators : Error<"declaration does not declare anything">; def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">, InGroup<MissingDeclarations>; def err_typedef_not_identifier : Error<"typedef name must be an identifier">; @@ -7713,12 +7714,16 @@ " in the declaration statement in the program scope">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; +def err_opencl_implicit_function_decl : Error< + "implicit declaration of function %0 is invalid in OpenCL">; def err_opencl_dereferencing : Error< "dereferencing pointer of type %0 is not allowed in OpenCL">; def err_opencl_pointer_to_image : Error< "pointer to image is invalid in OpenCL">; def err_opencl_type_can_only_be_used_as_function_parameter : Error < "%0 can only be used as a function parameter">; +def err_opencl_atomic_init_addressspace : Error< + "initialization of atomic variables is restricted to variables in global address space in opencl">; def err_opencl_block_proto_variadic : Error< "invalid block prototype, variadic arguments are not allowed in opencl">; def err_opencl_invalid_block_array : Error<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits