Friendly ping.
2013/6/22 Serge Pavlov <[email protected]> > 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
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
