Skip to content

Commit

Permalink
Call overloaded unary operator on hyperobject
Browse files Browse the repository at this point in the history
  • Loading branch information
VoxSciurorum committed Jun 5, 2023
1 parent 7c706d5 commit f4ef573
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
24 changes: 14 additions & 10 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15293,16 +15293,20 @@ ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
Input = Result.get();
}

if (getLangOpts().CPlusPlus && Input->getType()->isOverloadableType() &&
UnaryOperator::getOverloadedOperator(Opc) != OO_None &&
!(Opc == UO_AddrOf && isQualifiedMemberAccess(Input))) {
// Find all of the overloaded operators visible from this point.
UnresolvedSet<16> Functions;
OverloadedOperatorKind OverOp = UnaryOperator::getOverloadedOperator(Opc);
if (S && OverOp != OO_None)
LookupOverloadedOperatorName(OverOp, S, Functions);

return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input);
if (getLangOpts().CPlusPlus) {
// A hyperobject may need to be converted to a view.
QualType Real = Input->getType().stripHyperobject();
if (Real->isOverloadableType() &&
UnaryOperator::getOverloadedOperator(Opc) != OO_None &&
!(Opc == UO_AddrOf && isQualifiedMemberAccess(Input))) {
// Find all of the overloaded operators visible from this point.
UnresolvedSet<16> Functions;
OverloadedOperatorKind OverOp = UnaryOperator::getOverloadedOperator(Opc);
if (S && OverOp != OO_None)
LookupOverloadedOperatorName(OverOp, S, Functions);

return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input);
}
}

return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13320,6 +13320,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
if (checkPlaceholderForOverload(*this, Input))
return ExprError();

if (Input->getType()->isHyperobjectType())
Input = BuildHyperobjectLookup(Input, false);

Expr *Args[2] = { Input, nullptr };
unsigned NumArgs = 1;

Expand Down
20 changes: 20 additions & 0 deletions clang/test/Cilk/hyper-overload.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 %s -fopencilk -verify -S -emit-llvm -disable-llvm-passes -o - | FileCheck %s
// expected-no-diagnostics
struct S { int operator&(); };
extern int operator+(S &, int);

// Behavior without hyperobjects
// CHECK-LABEL: f1
// CHECK-NOT: @llvm.hyper.lookup
// CHECK: @_ZN1SadEv
int f1(struct S*sp) { return &*sp; }
// Lookup view then call S::operator &().
// CHECK-LABEL: f2
// CHECK: @llvm.hyper.lookup
// CHECK: @_ZN1SadEv
int f2(struct S _Hyperobject*sp) { return &*sp; }
// Lookup view then call operator+(S &, int);
// CHECK-LABEL: f3
// CHECK: @llvm.hyper.lookup
// CHECK: @_ZplR1Si
int f3(struct S _Hyperobject*sp) { return *sp + 1; }

0 comments on commit f4ef573

Please sign in to comment.