[PATCH] Fix to PR5683 - issue diagnostic for pointer subtraction with type of size zero.

Serge Pavlov sepavloff at gmail.com
Mon Aug 19 09:10:20 PDT 2013


Friendly ping.


2013/6/22 Serge Pavlov <sepavloff at gmail.com>

>   Updated patch.
>
> Hi rsmith,
>
> http://llvm-reviews.chandlerc.com/D637
>
> CHANGE SINCE LAST DIFF
>   http://llvm-reviews.chandlerc.com/D637?vs=2518&id=2538#toc
>
> Files:
>   include/clang/Basic/DiagnosticSemaKinds.td
>   lib/AST/ExprConstant.cpp
>   lib/Sema/SemaExpr.cpp
>   test/Sema/empty1.c
>   test/Sema/empty1.cpp
>
> Index: include/clang/Basic/DiagnosticSemaKinds.td
> ===================================================================
> --- include/clang/Basic/DiagnosticSemaKinds.td
> +++ include/clang/Basic/DiagnosticSemaKinds.td
> @@ -4113,6 +4113,9 @@
>  def warn_offsetof_non_standardlayout_type : ExtWarn<
>    "offset of on non-standard-layout type %0">, InGroup<InvalidOffsetof>;
>  def err_offsetof_bitfield : Error<"cannot compute offset of bit-field
> %0">;
> +def warn_sub_ptr_zero_size_types : Warning<
> +  "subtraction of pointers to type %0 of zero size has undefined
> behavior">,
> +  InGroup<PointerArith>;
>
>  def warn_floatingpoint_eq : Warning<
>    "comparing floating point with == or != is unsafe">,
> Index: lib/AST/ExprConstant.cpp
> ===================================================================
> --- lib/AST/ExprConstant.cpp
> +++ lib/AST/ExprConstant.cpp
> @@ -6405,6 +6405,14 @@
>          if (!HandleSizeof(Info, E->getExprLoc(), ElementType,
> ElementSize))
>            return false;
>
> +        // As an extension, a type may have zero size (empty struct or
> union in
> +        // C, array of zero length).  Meaning of pointer difference in
> such
> +        // case is unspecified.
> +        if (ElementSize.isZero()) {
> +          Result = APValue(Info.Ctx.MakeIntValue(0, E->getType()));
> +          return true;
> +        }
> +
>          // FIXME: LLVM and GCC both compute LHSOffset - RHSOffset at
> runtime,
>          // and produce incorrect results when it overflows. Such behavior
>          // appears to be non-conforming, but is common, so perhaps we
> should
> Index: lib/Sema/SemaExpr.cpp
> ===================================================================
> --- lib/Sema/SemaExpr.cpp
> +++ lib/Sema/SemaExpr.cpp
> @@ -6870,6 +6870,18 @@
>                                                 LHS.get(), RHS.get()))
>          return QualType();
>
> +      // The pointee type may have zero size.  As an extension, a
> structure or
> +      // union may have zero size or an array may have zero length.  In
> this
> +      // case subtraction does not make sense.
> +      if (!rpointee->isVoidType() && !rpointee->isFunctionType()) {
> +        CharUnits ElementSize = Context.getTypeSizeInChars(rpointee);
> +        if (ElementSize.isZero()) {
> +          Diag(Loc,diag::warn_sub_ptr_zero_size_types)
> +            << rpointee.getUnqualifiedType()
> +            << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
> +        }
> +      }
> +
>        if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
>        return Context.getPointerDiffType();
>      }
> Index: test/Sema/empty1.c
> ===================================================================
> --- test/Sema/empty1.c
> +++ test/Sema/empty1.c
> @@ -36,3 +36,50 @@
>    struct emp_1 f1;
>    union emp_2 f2;
>  };
> +
> +
> +// Checks for pointer subtraction (PR15683)
> +
> +struct emp_1* func_1p (struct emp_1* x) {
> +  return x - 5;
> +}
> +
> +int func_1 () {
> +  struct emp_1 v[1];
> +  return v - v;  // expected-warning {{subtraction of pointers to type
> 'struct emp_1' of zero size has undefined behavior}}
> +}
> +
> +int func_2 (struct emp_1* x) {
> +  return 1 + x - x;  // expected-warning {{subtraction of pointers to
> type 'struct emp_1' of zero size has undefined behavior}}
> +}
> +
> +int func_3 (struct emp_1* x, struct emp_1* y) {
> +  return x - y;  // expected-warning {{subtraction of pointers to type
> 'struct emp_1' of zero size has undefined behavior}}
> +}
> +
> +int func_4 (struct emp_1* x, const struct emp_1* y) {
> +  return x - y;  // expected-warning {{subtraction of pointers to type
> 'struct emp_1' of zero size has undefined behavior}}
> +}
> +
> +int func_5 (volatile struct emp_1* x, const struct emp_1* y) {
> +  return x - y;  // expected-warning {{subtraction of pointers to type
> 'struct emp_1' of zero size has undefined behavior}}
> +}
> +
> +int func_6 () {
> +  union emp_2 v[1];
> +  return v - v;  // expected-warning {{subtraction of pointers to type
> 'union emp_2' of zero size has undefined behavior}}
> +}
> +
> +struct A;  // expected-note {{forward declaration of 'struct A'}}
> +
> +int func_7 (struct A* x, struct A* y) {
> +  return x - y;  // expected-error {{arithmetic on a pointer to an
> incomplete type 'struct A'}}
> +}
> +
> +int func_8 (struct emp_1 (*x)[10], struct emp_1 (*y)[10]) {
> +  return x - y;  // expected-warning {{subtraction of pointers to type
> 'struct emp_1 [10]' of zero size has undefined behavior}}
> +}
> +
> +int func_9 (struct emp_1 (*x)[], struct emp_1 (*y)[]) {
> +  return x - y;  // expected-error {{arithmetic on a pointer to an
> incomplete type 'struct emp_1 []'}}
> +}
> Index: test/Sema/empty1.cpp
> ===================================================================
> --- /dev/null
> +++ test/Sema/empty1.cpp
> @@ -0,0 +1,17 @@
> +// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify
> +
> +int func_1(int (*p1)[0], int (*p2)[0]) {
> +  return p1 - p2;  // expected-warning {{subtraction of pointers to type
> 'int [0]' of zero size has undefined behavior}}
> +}
> +
> +constexpr int (*p1)[0] = 0, (*p2)[0] = 0;
> +constexpr int k = p2 - p1;  // expected-warning {{subtraction of pointers
> to type 'int [0]' of zero size has undefined behavior}}
> +
> +constexpr int func_2(int (*x1)[0], int (*x2)[0]) {
> +  return x1 - x2;  // expected-warning {{subtraction of pointers to type
> 'int [0]' of zero size has undefined behavior}}
> +}
> +
> +constexpr int func_3(int (*x1)[0], long (*x2)[0]) {
> +  return x1 - x2;  // expected-error {{int (*)[0]' and 'long (*)[0]' are
> not pointers to compatible types}} \
> +                   // expected-warning {{of zero size has undefined
> behavior}}
> +}
>



-- 
Thanks,
--Serge
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130819/dda67f42/attachment.html>


More information about the cfe-commits mailing list