diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 3dc851264956..4fb7c4d6514c 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4996,9 +4996,14 @@ static void TryReferenceInitializationCore(Sema &S, // OpenCilk: If the right hand side is a hyperobject, see if the // left hand side wants the hyperobject or a view. if (T2->isHyperobjectType() && !T1->isHyperobjectType()) { - Sequence.AddViewLookup(T1); - T2 = T2.stripHyperobject(); - cv2T2 = cv2T2.stripHyperobject(); + // If the view of T2 is a reference type (already diagnosed) + // then CompareReferenceRelationship will assert fail. + QualType View2 = T2.stripHyperobject(); + if (!View2->isReferenceType()) { + Sequence.AddViewLookup(T1); + T2 = View2; + cv2T2 = cv2T2.stripHyperobject(); + } } // Compute some basic properties of the types and the initializer. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index ad2110207729..c7582e57de9e 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1324,13 +1324,6 @@ static std::optional ContainsHyperobject(QualType Outer) { case Type::Decltype: Inner = cast(T)->getUnderlyingType(); break; - case Type::Elaborated: - Inner = cast(T)->desugar(); - break; - case Type::Adjusted: - case Type::Decayed: - Inner = cast(T)->desugar(); - break; case Type::Auto: case Type::DeducedTemplateSpecialization: Inner = cast(T)->desugar(); @@ -1340,6 +1333,11 @@ static std::optional ContainsHyperobject(QualType Outer) { case Type::DependentTemplateSpecialization: case Type::PackExpansion: case Type::UnaryTransform: + case Type::LValueReference: + case Type::RValueReference: + case Type::BlockPointer: + case Type::FunctionProto: + case Type::FunctionNoProto: return diag::confusing_hyperobject; case Type::Builtin: case Type::TemplateTypeParm: @@ -2495,6 +2493,9 @@ QualType Sema::BuildHyperobjectType(QualType Element, Expr *Identity, Diag(Loc, *Code) << Element; } + if (!Element->isObjectType()) + Diag(Loc, diag::confusing_hyperobject) << Element; + if (Element.isConstQualified() || Element.isVolatileQualified()) { Diag(Loc, diag::qualified_hyperobject) << Element; // Volatile reducers generate confusing diagnostics when used. diff --git a/clang/test/Cilk/hyper-errors.cpp b/clang/test/Cilk/hyper-errors.cpp index e5a45d155d18..4e30625451f5 100644 --- a/clang/test/Cilk/hyper-errors.cpp +++ b/clang/test/Cilk/hyper-errors.cpp @@ -27,6 +27,22 @@ 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 *)'}} +template struct T { + View _Hyperobject field; + // expected-error@-1{{qualified type 'const int' may not be a hyperobject}} + // expected-error@-2{{type 'int _Hyperobject', which contains a hyperobject, may not be a hyperobject}} + // expected-error@-3{{type 'int &' may not be a hyperobject}} + // expected-error@-4{{type 'int &' may not be a hyperobject}} + View &get_view() { return field; } + // expected-error@-1{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'int &_Hyperobject'}} + // The text of the preceding error message is unimportant. + // The compiler used to crash in this situation. + View &&get_view_xvalue() { return (View &&)field; } + const View &get_view_const() const { return field; } + T(); + ~T(); +}; + void function() { int _Hyperobject(typo1, reduce) var1 = 0; // expected-error@-1{{use of undeclared identifier 'typo1'}} @@ -35,4 +51,16 @@ void function() { // expected-error@-2{{use of undeclared identifier 'typo3'}} int _Hyperobject(0, typo4) var3 = 0; // expected-error@-1{{use of undeclared identifier 'typo4'}} + T var4; + // expected-note@-1{{requested here}} + T var5; + // expected-note@-1{{requested here}} + T var6; + T var7; + // expected-note@-1{{requested here}} + int &ref1 = var6.get_view(); + const int &ref2 = var6.get_view_const(); + int &&ref3 = var6.get_view_xvalue(); + var7.get_view(); + // expected-note@-1{{requested here}} }