Skip to content

Commit dc90bf0

Browse files
efriedma-quictru
authored andcommitted
[clang] Fix const eval of constexpr-unknown relational comparisons. (llvm#150088)
Like in other places, ignore the reference type of the base. (It might make sense to refactor this at some point.) Fixes llvm#150015. (cherry picked from commit bba8467)
1 parent 81a3436 commit dc90bf0

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14566,7 +14566,9 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
1456614566
if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
1456714567
bool WasArrayIndex;
1456814568
unsigned Mismatch = FindDesignatorMismatch(
14569-
getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
14569+
LHSValue.Base.isNull() ? QualType()
14570+
: getType(LHSValue.Base).getNonReferenceType(),
14571+
LHSDesignator, RHSDesignator, WasArrayIndex);
1457014572
// At the point where the designators diverge, the comparison has a
1457114573
// specified value if:
1457214574
// - we are comparing array indices
@@ -14610,7 +14612,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
1461014612
// compare pointers within the object in question; otherwise, the result
1461114613
// depends on where the object is located in memory.
1461214614
if (!LHSValue.Base.isNull() && IsRelational) {
14613-
QualType BaseTy = getType(LHSValue.Base);
14615+
QualType BaseTy = getType(LHSValue.Base).getNonReferenceType();
1461414616
if (BaseTy->isIncompleteType())
1461514617
return Error(E);
1461614618
CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,17 @@ namespace enable_if_2 {
383383
}
384384
}
385385
}
386+
387+
namespace GH150015 {
388+
extern int (& c)[8]; // interpreter-note {{declared here}}
389+
constexpr int x = c <= c+8; // interpreter-error {{constexpr variable 'x' must be initialized by a constant expression}} \
390+
// interpreter-note {{initializer of 'c' is unknown}}
391+
392+
struct X {};
393+
struct Y {};
394+
struct Z : X, Y {};
395+
extern Z &z; // interpreter-note{{declared here}}
396+
constexpr int bases = (void*)(X*)&z <= (Y*)&z; // expected-error {{constexpr variable 'bases' must be initialized by a constant expression}} \
397+
// nointerpreter-note {{comparison of addresses of subobjects of different base classes has unspecified value}} \
398+
// interpreter-note {{initializer of 'z' is unknown}}
399+
}

0 commit comments

Comments
 (0)