On Thu, Dec 11, 2014 at 11:47 AM, David Majnemer <[email protected]> wrote:
> On Thu, Dec 11, 2014 at 11:28 AM, Richard Smith <[email protected]> > wrote: > >> On Tue, Dec 9, 2014 at 3:32 PM, David Majnemer <[email protected]> >> wrote: >> >>> Author: majnemer >>> Date: Tue Dec 9 17:32:34 2014 >>> New Revision: 223852 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=223852&view=rev >>> Log: >>> 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. >>> >>> Modified: >>> cfe/trunk/lib/AST/ExprConstant.cpp >>> cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp >>> >>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=223852&r1=223851&r2=223852&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Dec 9 17:32:34 2014 >>> @@ -1422,6 +1422,12 @@ static bool IsWeakLValue(const LValue &V >>> 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::VisitBinaryOperat >>> (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); >>> >> >> We can do better here: one of the pointers must be to a zero-sized >> object, and the other must be a past-the-end pointer (where a pointer to a >> zero-sized object is considered to be a past-the-end pointer). >> > > Ah, clever. > > >> >> // 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 >>> >>> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=223852&r1=223851&r2=223852&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original) >>> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Dec 9 >>> 17:32:34 2014 >>> @@ -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}} >>> +} >>> >> >> This testcase looks like valid C++ code to me; the comparison is a >> constant expression under the C++ rules and evaluates to true. I don't >> think we can apply this check in this case, only when we have a complete >> type that is zero-sized. That means we'll constant-fold equality >> comparisons to 'false' even if they turn out to be true, but that seems to >> be unavoidable. >> > > I don't quite understand why we should fold that comparison to false, GCC > and ICC both consider that expression to be non-constant. > That doesn't make them right. =) C++ does not have zero-sized types, nor the possibility of the above objects being at the same address. Per its constant evaluation rules, the above expression *is* a constant expression, and we are required to treat it as such. In this regard, zero-sized types are not a conforming extension.
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
