On Mon, Aug 19, 2013 at 9:10 AM, Serge Pavlov <[email protected]> wrote:
> 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 >> >> C++-specific tests should go into test/SemaCXX/ Otherwise looks fine, but please let Richard take another look at the ExprConstant.cpp changes first. -Eli
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
