Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,8 @@ Bug Fixes in This Version
- Fixed a crash with an invalid member function parameter list with a default
argument which contains a pragma. (#GH113722)
- Fixed assertion failures when generating name lookup table in modules. (#GH61065, #GH134739)
- Fix crash due to unknown references and pointer implementation and handling of
base classes. (GH139452)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3314,7 +3314,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
return false;

// Extract most-derived object and corresponding type.
DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
// FIXME: After implementing P2280R4 it became possible to get references
// here. We do MostDerivedType->getAsCXXRecordDecl() in several other
// locations and if we see crashes in those locations in the future
// it may make more sense to move this fix into Lvalue::set.
DerivedDecl = D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
if (!CastToDerivedClass(Info, E, Obj, DerivedDecl, D.MostDerivedPathLength))
return false;

Expand Down
21 changes: 21 additions & 0 deletions clang/test/SemaCXX/constant-expression-p2280r4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,24 @@ namespace extern_reference_used_as_unknown {
int y;
constinit int& g = (x,y); // expected-warning {{left operand of comma operator has no effect}}
}

namespace GH139452 {
struct Dummy {
explicit operator bool() const noexcept { return true; }
};

struct Base { int error; };
struct Derived : virtual Base { };

template <class R>
constexpr R get_value() {
const auto& derived_val = Derived{};
if (derived_val.error != 0)
/* nothing */;
return R{};
}

int f() {
return !get_value<Dummy>(); // contextually convert the function call result to bool
}
}