AST: Don't assume two zero sized objects live at different addresses
Zero sized objects may overlap with each other or any other object. This fixes PR21786. llvm-svn: 223852
This commit is contained in:
parent
a97c4d2154
commit
b511603281
|
@ -1422,6 +1422,12 @@ static bool IsWeakLValue(const LValue &Value) {
|
|||
return Decl && Decl->isWeak();
|
||||
}
|
||||
|
||||
static bool isZeroSized(const LValue &Value) {
|
||||
const ValueDecl *Decl = GetLValueBaseDecl(Value);
|
||||
return Decl && isa<VarDecl>(Decl) &&
|
||||
Decl->getASTContext().getTypeSize(Decl->getType()) == 0;
|
||||
}
|
||||
|
||||
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result) {
|
||||
// A null base expression indicates a null pointer. These are always
|
||||
// evaluatable, and they are false unless the offset is zero.
|
||||
|
@ -6979,6 +6985,10 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
|||
(RHSValue.Base && RHSValue.Offset.isZero() &&
|
||||
isOnePastTheEndOfCompleteObject(Info.Ctx, LHSValue)))
|
||||
return Error(E);
|
||||
// We can't tell whether an object is at the same address as another
|
||||
// zero sized object.
|
||||
if (isZeroSized(LHSValue) || isZeroSized(RHSValue))
|
||||
return Error(E);
|
||||
// Pointers with different bases cannot represent the same object.
|
||||
// (Note that clang defaults to -fmerge-all-constants, which can
|
||||
// lead to inconsistent results for comparisons involving the address
|
||||
|
|
|
@ -1955,3 +1955,9 @@ namespace EmptyClass {
|
|||
constexpr E2 e2b(e2); // expected-error {{constant expression}} expected-note{{read of non-const}} expected-note {{in call}}
|
||||
constexpr E3 e3b(e3);
|
||||
}
|
||||
|
||||
namespace PR21786 {
|
||||
extern void (*start[])();
|
||||
extern void (*end[])();
|
||||
static_assert(&start != &end, ""); // expected-error {{constant expression}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue