Skip to content

Commit

Permalink
Do not process template arguments when checking for recursive hyperob…
Browse files Browse the repository at this point in the history
…jects
  • Loading branch information
VoxSciurorum authored and neboat committed Dec 15, 2023
1 parent ffd26ee commit 60c7e90
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 29 deletions.
31 changes: 2 additions & 29 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,35 +1294,6 @@ static std::optional<unsigned> ContainsHyperobject(QualType Outer) {
break;
case Type::Record: {
const RecordDecl *Decl = cast<RecordType>(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<ClassTemplateSpecializationDecl>(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<unsigned>();
}
if (const RecordDecl *Def = Decl->getDefinition())
return DeclContainsHyperobject(Def);
return diag::confusing_hyperobject;
Expand Down Expand Up @@ -1362,6 +1333,8 @@ static std::optional<unsigned> ContainsHyperobject(QualType Outer) {
}

static std::optional<unsigned> DeclContainsHyperobject(const RecordDecl *Decl) {
if (Decl->isInvalidDecl())
return std::optional<unsigned>();
for (const FieldDecl *FD : Decl->fields())
if (std::optional<unsigned> O = ContainsHyperobject(FD->getType()))
return O;
Expand Down
22 changes: 22 additions & 0 deletions clang/test/Cilk/223.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %clang_cc1 %s -x c++ -O1 -fopencilk -verify -fsyntax-only
template <class T>
class A { };

class B {
A<B> a;
};

void identity(void* view) {}
void reduce(void* l, void* r) {}

B _Hyperobject(identity, reduce) b;

template <class T>
class C { T _Hyperobject *field; };
// expected-error@-1{{incomplete type 'D' may not be a hyperobject}}

class D { // expected-note{{}}}
C<D> a; // expected-note{{}}}
};

D _Hyperobject(identity, reduce) d;

0 comments on commit 60c7e90

Please sign in to comment.