Skip to content

Commit b03dc7d

Browse files
authored
[Clang] Properly set the value category of dependent unary operators (#88740)
This fixes an assertion in Expr::Classify when a trying to deduce a dependent dereference operator. Fixes #88329
1 parent 43b4e5b commit b03dc7d

File tree

4 files changed

+23
-5
lines changed

4 files changed

+23
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ Bug Fixes to C++ Support
537537
- Clang now correctly tracks type dependence of by-value captures in lambdas with an explicit
538538
object parameter.
539539
Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), (#GH86398), and (#GH86399).
540+
- Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
540541

541542
Bug Fixes to AST Handling
542543
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaOverload.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14395,9 +14395,16 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
1439514395
ArrayRef<Expr *> ArgsArray(Args, NumArgs);
1439614396

1439714397
if (Input->isTypeDependent()) {
14398+
ExprValueKind VK = ExprValueKind::VK_PRValue;
14399+
// [C++26][expr.unary.op][expr.pre.incr]
14400+
// The * operator yields an lvalue of type
14401+
// The pre/post increment operators yied an lvalue.
14402+
if (Opc == UO_PreDec || Opc == UO_PreInc || Opc == UO_Deref)
14403+
VK = VK_LValue;
14404+
1439814405
if (Fns.empty())
14399-
return UnaryOperator::Create(Context, Input, Opc, Context.DependentTy,
14400-
VK_PRValue, OK_Ordinary, OpLoc, false,
14406+
return UnaryOperator::Create(Context, Input, Opc, Context.DependentTy, VK,
14407+
OK_Ordinary, OpLoc, false,
1440114408
CurFPFeatureOverrides());
1440214409

1440314410
CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
@@ -14406,7 +14413,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
1440614413
if (Fn.isInvalid())
1440714414
return ExprError();
1440814415
return CXXOperatorCallExpr::Create(Context, Op, Fn.get(), ArgsArray,
14409-
Context.DependentTy, VK_PRValue, OpLoc,
14416+
Context.DependentTy, VK, OpLoc,
1441014417
CurFPFeatureOverrides());
1441114418
}
1441214419

clang/test/CXX/over/over.built/ast.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ struct A{};
44

55
template <typename T, typename U>
66
auto Test(T* pt, U* pu) {
7-
// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '*'
7+
// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '*'
88
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
99
(void)*pt;
1010

11-
// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '++'
11+
// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '++'
1212
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
1313
(void)(++pt);
1414

clang/test/SemaCXX/overloaded-operator.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,3 +682,13 @@ namespace nw{
682682
}
683683
}
684684
#endif
685+
686+
#if __cplusplus >= 201703L
687+
namespace GH88329 {
688+
689+
template <auto T> struct A {};
690+
template <auto T> A<*T> operator *() { return {}; }
691+
// expected-error@-1 {{overloaded 'operator*' must have at least one parameter of class or enumeration type}}
692+
}
693+
694+
#endif

0 commit comments

Comments
 (0)