diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4f99e34d18b5..95b15d1b247f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -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. @@ -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) diff --git a/clang/test/Cilk/hyper-lookup-lvalue-conversion.cpp b/clang/test/Cilk/hyper-lookup-lvalue-conversion.cpp new file mode 100644 index 000000000000..f3b0fe813520 --- /dev/null +++ b/clang/test/Cilk/hyper-lookup-lvalue-conversion.cpp @@ -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 +T &&move(T &obj) { + return static_cast(obj); +} +} + +// Reducer definition. +template void sum_init(void *v) { *reinterpret_cast(v) = T{}; } + +template void sum_reduce(void *v, void *v2) { + T *a = reinterpret_cast(v), *b = reinterpret_cast(v2); + *a += *b; +} + +template using SumReducer = T _Hyperobject(sum_init, sum_reduce); + +using Real = double; + +void h(Real arg); + +template +void g(const T &arg) { h(arg); } + +template +void f(T&& arg) { h(std::move(arg)); } + +void run() { + SumReducer 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]])