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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits