Skip to content

Commit

Permalink
[SemaExpr] Fix hyperobject-lookup lvalue conversion involving qualifi…
Browse files Browse the repository at this point in the history
…ers and xvalues.
  • Loading branch information
neboat committed Nov 30, 2024
1 parent 5aa7883 commit 0722f03
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
// converted to a prvalue.
if (!E->isGLValue()) return E;

QualType T = E->getType().stripHyperobject();
QualType T = E->getType().stripHyperobject().withFastQualifiers(
E->getType().getLocalFastQualifiers());
assert(!T.isNull() && "r-value conversion on typeless expression?");

// lvalue-to-rvalue conversion cannot be applied to function or array types.
Expand Down Expand Up @@ -2279,7 +2280,7 @@ NonOdrUseReason Sema::getNonOdrUseReasonInCurrentContext(ValueDecl *D) {
}

Expr *Sema::BuildHyperobjectLookup(Expr *E, bool Pointer) {
if (!Pointer && !E->isLValue())
if (!Pointer && !E->isGLValue())
return E;

if (getLangOpts().getCilk() != LangOptions::Cilk_opencilk)
Expand Down
57 changes: 57 additions & 0 deletions clang/test/Cilk/hyper-lookup-lvalue-conversion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Check unusual lvalue conversions involving hyperobject lookups, qualifiers, and xvalues.
//
// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -S -emit-llvm -disable-llvm-passes -o - | FileCheck %s
// expected-no-diagnostics

// Simplified version of std::move for standalone test.
namespace std {
template <typename T>
T &&move(T &obj) {
return static_cast<T &&>(obj);
}
}

// Reducer definition.
template <typename T> void sum_init(void *v) { *reinterpret_cast<T *>(v) = T{}; }

template <typename T> void sum_reduce(void *v, void *v2) {
T *a = reinterpret_cast<T *>(v), *b = reinterpret_cast<T *>(v2);
*a += *b;
}

template <typename T> using SumReducer = T _Hyperobject(sum_init<T>, sum_reduce<T>);

using Real = double;

void h(Real arg);

template <typename T>
void g(const T &arg) { h(arg); }

template <typename T>
void f(T&& arg) { h(std::move(arg)); }

void run() {
SumReducer<Real> sumAParRelError = 0;
// Check handling of hyperobject lookup when result requires extra const qualifier.
g(sumAParRelError);
// Check handling of hyperobject lookup when result treated as xvalue.
f(sumAParRelError);
}

// CHECK-LABEL: define void @_Z3runv()
// CHECK: %[[SUMAPARRELERROR:.+]] = alloca double
// CHECK: call void @llvm.reducer.register.i64(ptr %[[SUMAPARRELERROR]]
// CHECK-NEXT: call void @_Z1gIHdEvRKT_(ptr {{.*}}%[[SUMAPARRELERROR]])
// CHECK-NEXT: call void @_Z1fIRHdEvOT_(ptr {{.*}}%[[SUMAPARRELERROR]])
// CHECK-NEXT: call void @llvm.reducer.unregister(ptr %sumAParRelError)

// CHECK-LABEL: define {{.*}}void @_Z1gIHdEvRKT_(ptr
// CHECK: %[[LOOKUP:.+]] = call ptr @llvm.hyper.lookup.i64(ptr
// CHECK-NEXT: %[[VIEW:.+]] = load double, ptr %[[LOOKUP]]
// CHECK-NEXT: call void @_Z1hd(double {{.*}}%[[VIEW]])

// CHECK-LABEL: define {{.*}}void @_Z1fIRHdEvOT_(ptr
// CHECK: %[[LOOKUP:.+]] = call ptr @llvm.hyper.lookup.i64(ptr
// CHECK-NEXT: %[[VIEW:.+]] = load double, ptr %[[LOOKUP]]
// CHECK-NEXT: call void @_Z1hd(double {{.*}}%[[VIEW]])

0 comments on commit 0722f03

Please sign in to comment.