diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 73df2c16f592..470003754a78 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10593,8 +10593,8 @@ def incomplete_hyperobject : Error< def nested_hyperobject : Error< "type %0, which contains a hyperobject, may not be a hyperobject">; -def reducer_callbacks_not_allowed: Warning< - "reducer callbacks not implemented for structure members">, +def reducer_registration_not_implemented: Warning< + "reducer registration not implemented for structure members">, InGroup; def err_invalid_reducer_callback : Error< diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 3cf355714107..1a4e5a790d00 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1071,6 +1071,12 @@ void CXXRecordDecl::addedMember(Decl *D) { data().DefaultedCopyConstructorIsDeleted = true; } + if (T->isHyperobjectType()) { + data().HasIrrelevantDestructor = false; + data().HasTrivialSpecialMembers &= ~SMF_Destructor; + data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor; + } + if (!Field->hasInClassInitializer() && !Field->isMutable()) { if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) { if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit()) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 27366bb87e6d..dffae42a5cea 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18621,11 +18621,12 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, continue; } - if (!FDTy->isDependentType()) { + // In C++ a constructor and destructor will be synthesized + // to register hyperobjects. + if (!CXXRecord && !FDTy->isDependentType()) { if (const HyperobjectType *HT = FDTy->getAs()) { - if (HT->hasCallbacks()) - Diag(FD->getLocation(), diag::reducer_callbacks_not_allowed) - << FD->getDeclName(); + Diag(FD->getLocation(), diag::reducer_registration_not_implemented) + << FD->getDeclName(); } } diff --git a/clang/test/Cilk/222.cpp b/clang/test/Cilk/222.cpp index 8184b3e11f22..e92e8b975ad7 100644 --- a/clang/test/Cilk/222.cpp +++ b/clang/test/Cilk/222.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -x c++ -fopencilk -emit-llvm -verify -mllvm -use-opencilk-runtime-bc=false -mllvm -debug-abi-calls -o /dev/null +// expected-no-diagnostics #define DEPTH 3 template struct R { static void identity(void *); @@ -6,13 +7,7 @@ template struct R { int get(int depth) { return depth <= 0 ? i : field.get(depth - 1); } public: R field; - // expected-note@-1{{in instantiation}} - // expected-note@-2{{in instantiation}} - // expected-note@-3{{in instantiation}} int _Hyperobject(identity, reduce) i; - // expected-warning@-1{{reducer callbacks not implemented for structure members}} - // expected-warning@-2{{reducer callbacks not implemented for structure members}} - // expected-warning@-3{{reducer callbacks not implemented for structure members}} }; template<> struct R<0> { int field; int get(int) { return field; } }; @@ -20,7 +15,3 @@ template<> struct R<0> { int field; int get(int) { return field; } }; extern R r; int f() { return r.get(DEPTH / 2); } -// expected-note@-1{{in instantiation}} -// expected-note@-2{{in instantiation}} -// expected-note@-3{{in instantiation}} - diff --git a/clang/test/Cilk/hyper-errors.c b/clang/test/Cilk/hyper-errors.c index 01e269add34e..5458face1382 100644 --- a/clang/test/Cilk/hyper-errors.c +++ b/clang/test/Cilk/hyper-errors.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -fopencilk -verify -fsyntax-only -Werror=incompatible-function-pointer-types -Werror=int-conversion -// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -fsyntax-only struct C { int _Hyperobject c; }; +// expected-warning@-1{{reducer registration not implemented for structure members}} struct C _Hyperobject c; // expected-error{{type 'struct C', which contains a hyperobject, may not be a hyperobject}} long _Hyperobject d; // expected-note{{previous definition}} void f() { @@ -17,7 +17,7 @@ extern void reduce(void *, void *), identity(void *); struct D { int _Hyperobject(identity, reduce) field; - // expected-warning@-1{{reducer callbacks not implemented for structure members}} + // expected-warning@-1{{reducer registration not implemented for structure members}} }; int _Hyperobject(reduce, identity) h; diff --git a/clang/test/Cilk/hyper-errors.cpp b/clang/test/Cilk/hyper-errors.cpp new file mode 100644 index 000000000000..664df5983143 --- /dev/null +++ b/clang/test/Cilk/hyper-errors.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -fsyntax-only +struct C { int _Hyperobject c; }; +struct C _Hyperobject c; // expected-error{{type 'struct C', which contains a hyperobject, may not be a hyperobject}} +long _Hyperobject d; // expected-note{{previous definition}} +void f() { + extern int _Hyperobject d; + // expected-error@-1{{redeclaration of 'd' with a different type: 'int _Hyperobject' vs 'long _Hyperobject'}} +} +char _Hyperobject e; // expected-note{{previous definition}} +typedef long _Hyperobject long_h; +void g() { + extern long_h e; // expected-error{{redeclaration of 'e'}} +} + +extern void reduce(void *, void *), identity(void *); + +struct D { + int _Hyperobject(identity, reduce) field; +}; + +int _Hyperobject(reduce, identity) h; + // expected-error@-1{{incompatible function pointer types passing 'void (*)(void *, void *)' to parameter of type 'void (*)(void *)'}} + // expected-error@-2{{incompatible function pointer types passing 'void (*)(void *)' to parameter of type 'void (*)(void *, void *)'}} + +int _Hyperobject(x) i; // expected-error{{use of undeclared identifier 'x'}} +int _Hyperobject(0) j; // expected-error{{hyperobject must have 0 or 2 callbacks}} +int _Hyperobject(0,0,0,0) k; // expected-error{{hyperobject must have 0 or 2 callbacks}} +int _Hyperobject(0, 1) x; // expected-error{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void (*)(void *, void *)'}} + +void function() { + int _Hyperobject(typo1, reduce) var1 = 0; + // expected-error@-1{{use of undeclared identifier 'typo1'}} + int _Hyperobject(typo2, typo3) var2 = 0; + // expected-error@-1{{use of undeclared identifier 'typo2'}} + // expected-error@-2{{use of undeclared identifier 'typo3'}} + int _Hyperobject(0, typo4) var3 = 0; + // expected-error@-1{{use of undeclared identifier 'typo4'}} +} diff --git a/clang/test/Cilk/hyper-struct-assign.c b/clang/test/Cilk/hyper-struct-assign.c index 23fbc8ae77ed..91c2871fbbc6 100644 --- a/clang/test/Cilk/hyper-struct-assign.c +++ b/clang/test/Cilk/hyper-struct-assign.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 %s -fopencilk -verify -fsyntax-only struct S { long _Hyperobject field; }; +// expected-warning@-1{{reducer registration not implemented for structure members}} extern struct S x, y; struct S simple_assign(long val) diff --git a/clang/test/Cilk/hyper-template2.cpp b/clang/test/Cilk/hyper-template2.cpp index 01b90a8cda76..883ad62e7961 100644 --- a/clang/test/Cilk/hyper-template2.cpp +++ b/clang/test/Cilk/hyper-template2.cpp @@ -1,20 +1,18 @@ -// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -S -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: %clang_cc1 %s -x c++ -fopencilk -S -emit-llvm -disable-llvm-passes -o - | FileCheck %s template struct reducer { static void identity(void *); static void reduce(void *, void *); char pad; - // Registration of structure members is not implemented. VIEW _Hyperobject(identity, reduce) value; - // expected-warning@-1{{reducer callbacks not implemented}} reducer(); ~reducer(); }; // CHECK: call {{.+}} @_ZN7reducerIsEC1Ev // CHECK: @_ZN7reducerIsED1Ev -reducer r; // expected-note{{in instantiation}} +reducer r; // CHECK-LABEL: _Z1fv // CHECK: call ptr @llvm.hyper.lookup