Skip to content

Commit 5befd1f

Browse files
shafiktstellar
authored andcommitted
[Clang][AST] Fix HandleLValueBase to deal with references (#140105)
Since P2280R4 Unknown references and pointers was implemented, HandleLValueBase now has to deal with referneces: D.MostDerivedType->getAsCXXRecordDecl() will return a nullptr if D.MostDerivedType is a ReferenceType. The fix is to use getNonReferenceType() to obtain the Pointee Type if we have a reference. Fixes: #139452 (cherry picked from commit 136f2ba) # Conflicts: # clang/docs/ReleaseNotes.rst
1 parent e3d2c00 commit 5befd1f

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,8 @@ Bug Fixes in This Version
909909
being deleted has a potentially throwing destructor (#GH118660).
910910
- Clang now outputs correct values when #embed data contains bytes with negative
911911
signed char values (#GH102798).
912+
- Fix crash due to unknown references and pointer implementation and handling of
913+
base classes. (GH139452)
912914

913915
Bug Fixes to Compiler Builtins
914916
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3311,7 +3311,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
33113311
return false;
33123312

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

clang/test/SemaCXX/constant-expression-p2280r4.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,24 @@ namespace extern_reference_used_as_unknown {
179179
int y;
180180
constinit int& g = (x,y); // expected-warning {{left operand of comma operator has no effect}}
181181
}
182+
183+
namespace GH139452 {
184+
struct Dummy {
185+
explicit operator bool() const noexcept { return true; }
186+
};
187+
188+
struct Base { int error; };
189+
struct Derived : virtual Base { };
190+
191+
template <class R>
192+
constexpr R get_value() {
193+
const auto& derived_val = Derived{};
194+
if (derived_val.error != 0)
195+
/* nothing */;
196+
return R{};
197+
}
198+
199+
int f() {
200+
return !get_value<Dummy>(); // contextually convert the function call result to bool
201+
}
202+
}

0 commit comments

Comments
 (0)