From 60c7e905cc289504828ea3f50062481c55345080 Mon Sep 17 00:00:00 2001 From: "John F. Carr" Date: Fri, 8 Dec 2023 14:15:42 -0500 Subject: [PATCH] Do not process template arguments when checking for recursive hyperobjects --- clang/lib/Sema/SemaType.cpp | 31 ++----------------------------- clang/test/Cilk/223.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 29 deletions(-) create mode 100644 clang/test/Cilk/223.cpp diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index e85b0711de68..0cff893f0c0d 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1294,35 +1294,6 @@ static std::optional ContainsHyperobject(QualType Outer) { break; case Type::Record: { const RecordDecl *Decl = cast(T)->getDecl(); - // TODO: There must be a better way to do this. - // A hyperobject might sneak in without being explicitly - // declared in the template. - if (auto Spec = dyn_cast(Decl)) { - if (ClassTemplateDecl *Inner = Spec->getSpecializedTemplate()) - if (auto O = DeclContainsHyperobject(Inner->getTemplatedDecl())) - return O; - const TemplateArgumentList &Args = Spec->getTemplateArgs(); - for (unsigned I = 0; I < Args.size(); ++I) { - const TemplateArgument &Arg = Args.get(I); - switch (Arg.getKind()) { - case TemplateArgument::Declaration: - if (auto O = ContainsHyperobject(Arg.getAsDecl()->getType())) - return O; - break; - case TemplateArgument::Type: - if (auto O = ContainsHyperobject(Arg.getAsType())) - return O; - break; - case TemplateArgument::Integral: - case TemplateArgument::NullPtr: - case TemplateArgument::Null: - break; - default: - return diag::confusing_hyperobject; - } - } - return std::optional(); - } if (const RecordDecl *Def = Decl->getDefinition()) return DeclContainsHyperobject(Def); return diag::confusing_hyperobject; @@ -1362,6 +1333,8 @@ static std::optional ContainsHyperobject(QualType Outer) { } static std::optional DeclContainsHyperobject(const RecordDecl *Decl) { + if (Decl->isInvalidDecl()) + return std::optional(); for (const FieldDecl *FD : Decl->fields()) if (std::optional O = ContainsHyperobject(FD->getType())) return O; diff --git a/clang/test/Cilk/223.cpp b/clang/test/Cilk/223.cpp new file mode 100644 index 000000000000..7e7805c801f8 --- /dev/null +++ b/clang/test/Cilk/223.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -x c++ -O1 -fopencilk -verify -fsyntax-only +template +class A { }; + +class B { + A a; +}; + +void identity(void* view) {} +void reduce(void* l, void* r) {} + +B _Hyperobject(identity, reduce) b; + +template +class C { T _Hyperobject *field; }; +// expected-error@-1{{incomplete type 'D' may not be a hyperobject}} + +class D { // expected-note{{}}} + C a; // expected-note{{}}} +}; + +D _Hyperobject(identity, reduce) d;