OpenCilk / opencilk-project

Monorepo for the OpenCilk compiler. Forked from llvm/llvm-project and based on Tapir/LLVM.
Other
89 stars 29 forks source link

Recursive template with hyperobject causes crash #222

Closed VoxSciurorum closed 8 months ago

VoxSciurorum commented 9 months ago

This code:

#define DEPTH 3
template<int N> struct R {
  static void identity(void *);
  static void reduce(void *, void *);
  int get(int depth) { return depth <= 0 ? i : field.get(depth - 1); }
public:
  R<N - 1> field;
  int _Hyperobject(identity, reduce) i;
};

template<> struct R<0> { int field; int get(int) { return field; } };

extern R<DEPTH> r;

int f() { return r.get(DEPTH / 2); }

causes a compiler error:

clang/lib/AST/ExprConstant.cpp:15455: bool clang::Expr::isEvaluatable(const clang::ASTContext&, clang::Expr::SideEffectsKind) const: Assertion `!isValueDependent() && "Expression evaluator can't be called on a dependent expression."' failed.
VoxSciurorum commented 8 months ago

BuildHyperobjectLookup is called on

MemberExpr 0x83bce5740 'int _Hyperobject(identity, reduce)' lvalue ->i 0x83bce51c0
`-CXXThisExpr 0x83bce5730 'struct R<3> *' implicit this

on which isValueDependent() returns false. The expansion into a hyperobject lookup has isValueDependent true because of the added references to the identity and reduce members. They may still be the generic versions instead of the R<3> versions.