r224040 - AST: Incomplete types might be zero sized

Richard Smith richard at metafoo.co.uk
Thu Dec 11 12:49:02 PST 2014


On Thu, Dec 11, 2014 at 11:36 AM, David Majnemer <david.majnemer at gmail.com>
wrote:

> Author: majnemer
> Date: Thu Dec 11 13:36:24 2014
> New Revision: 224040
>
> URL: http://llvm.org/viewvc/llvm-project?rev=224040&view=rev
> Log:
> AST: Incomplete types might be zero sized
>
> Comparing the address of an object with an incomplete type might return
> true with a 'distinct' object if the former has a size of zero.
> However, such an object should compare unequal with null.
>
> 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=224040&r1=224039&r2=224040&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Dec 11 13:36:24 2014
> @@ -1424,8 +1424,11 @@ static bool IsWeakLValue(const LValue &V
>
>  static bool isZeroSized(const LValue &Value) {
>    const ValueDecl *Decl = GetLValueBaseDecl(Value);
> -  return Decl && isa<VarDecl>(Decl) &&
> -         Decl->getASTContext().getTypeSize(Decl->getType()) == 0;
> +  if (Decl && isa<VarDecl>(Decl)) {
> +    QualType Ty = Decl->getType();
> +    return Ty->isIncompleteType() ||
> Decl->getASTContext().getTypeSize(Ty) == 0;
> +  }
> +  return false;
>  }
>
>  static bool EvalPointerValueAsBool(const APValue &Value, bool &Result) {
> @@ -6987,7 +6990,8 @@ bool IntExprEvaluator::VisitBinaryOperat
>            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))
> +        if ((RHSValue.Base && isZeroSized(LHSValue)) ||
> +            (LHSValue.Base && isZeroSized(RHSValue)))
>            return Error(E);
>          // Pointers with different bases cannot represent the same object.
>          // (Note that clang defaults to -fmerge-all-constants, which can
>
> 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=224040&r1=224039&r2=224040&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Thu Dec 11
> 13:36:24 2014
> @@ -1960,4 +1960,12 @@ namespace PR21786 {
>    extern void (*start[])();
>    extern void (*end[])();
>    static_assert(&start != &end, ""); // expected-error {{constant
> expression}}
> +
> +  struct Foo;
> +  struct Bar {
> +    static const Foo x;
> +    static const Foo y;
> +  };
> +  static_assert(&Bar::x != nullptr, "");
> +  static_assert(&Bar::x != &Bar::y, ""); // expected-error {{constant
> expression}}
>

This is a rejects-valid. Per the C++11 rules, the above is a constant
expression that is required to evaluate to 'true'.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141211/10652e19/attachment.html>


More information about the cfe-commits mailing list