diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-24 23:50:08 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-24 23:50:08 +0000 |
commit | b5f1562d7b57a3dbe27a39b45995f59862973820 (patch) | |
tree | 8ea7e145c317f21123d49f631527d6f81edf4205 | |
parent | ad38a8595f2458309de3a8e30d0d3d62566b984f (diff) |
reject explicit pointer arithmetic on interface pointers in 64-bit objc ABI
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70004 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 22 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 29 | ||||
-rw-r--r-- | test/SemaObjC/sizeof-interface.m | 6 |
3 files changed, 42 insertions, 15 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a5aa6bdb84..071fcab437 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -917,11 +917,6 @@ def ext_sizeof_function_type : Extension< "invalid application of 'sizeof' to a function type">; def ext_sizeof_void_type : Extension< "invalid application of '%0' to a void type">; -def err_sizeof_nonfragile_interface : Error< - "invalid application of '%select{alignof|sizeof}1' to interface %0 in " - "non-fragile ABI">; -def err_atdef_nonfragile_interface : Error< - "invalid application of @defs in non-fragile ABI">; // FIXME: merge with %select def err_sizeof_incomplete_type : Error< "invalid application of 'sizeof' to an incomplete type %0">; @@ -938,6 +933,20 @@ def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup<DiagGroup<"float-equal">>, DefaultIgnore; +def err_sizeof_nonfragile_interface : Error< + "invalid application of '%select{alignof|sizeof}1' to interface %0 in " + "non-fragile ABI">; +def err_atdef_nonfragile_interface : Error< + "invalid application of @defs in non-fragile ABI">; +def err_subscript_nonfragile_interface : Error< + "subscript requires size of interface %0, which is not constant in " + "non-fragile ABI">; + +def err_arithmetic_nonfragile_interface : Error< + "arithmetic on pointer to interface %0, which is not a constant size in " + "non-fragile ABI">; + + def err_typecheck_subscript_value : Error< "subscripted value is neither array nor pointer">; def err_typecheck_subscript : Error<"array subscript is not an integer">; @@ -945,9 +954,6 @@ def err_subscript_function_type : Error< "subscript of pointer to function type %0">; def err_subscript_incomplete_type : Error< "subscript of pointer to incomplete type %0">; -def err_subscript_nonfragile_interface : Error< - "subscript requires size of interface %0, which is not constant in " - "non-fragile ABI">; def err_typecheck_member_reference_struct_union : Error< "member reference base type %0 is not a structure or union">; def err_typecheck_member_reference_ivar : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 53fe80cb72..781c64c22c 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3275,10 +3275,11 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 if (IExp->getType()->isPointerType()) std::swap(PExp, IExp); - if (const PointerType* PTy = PExp->getType()->getAsPointerType()) { + if (const PointerType *PTy = PExp->getType()->getAsPointerType()) { if (IExp->getType()->isIntegerType()) { - // Check for arithmetic on pointers to incomplete types - if (PTy->getPointeeType()->isVoidType()) { + QualType PointeeTy = PTy->getPointeeType(); + // Check for arithmetic on pointers to incomplete types. + if (PointeeTy->isVoidType()) { if (getLangOptions().CPlusPlus) { Diag(Loc, diag::err_typecheck_pointer_arith_void_type) << lex->getSourceRange() << rex->getSourceRange(); @@ -3288,7 +3289,7 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 // GNU extension: arithmetic on pointer to void Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); - } else if (PTy->getPointeeType()->isFunctionType()) { + } else if (PointeeTy->isFunctionType()) { if (getLangOptions().CPlusPlus) { Diag(Loc, diag::err_typecheck_pointer_arith_function_type) << lex->getType() << lex->getSourceRange(); @@ -3299,12 +3300,19 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 Diag(Loc, diag::ext_gnu_ptr_func_arith) << lex->getType() << lex->getSourceRange(); } else if (!PTy->isDependentType() && - RequireCompleteType(Loc, PTy->getPointeeType(), + RequireCompleteType(Loc, PointeeTy, diag::err_typecheck_arithmetic_incomplete_type, - lex->getSourceRange(), SourceRange(), - lex->getType())) + PExp->getSourceRange(), SourceRange(), + PExp->getType())) return QualType(); + // Diagnose bad cases where we step over interface counts. + if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) { + Diag(Loc, diag::err_arithmetic_nonfragile_interface) + << PointeeTy << PExp->getSourceRange(); + return QualType(); + } + if (CompLHSTy) { QualType LHSTy = lex->getType(); if (LHSTy->isPromotableIntegerType()) @@ -3371,6 +3379,13 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex, lex->getType())) return QualType(); + // Diagnose bad cases where we step over interface counts. + if (lpointee->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) { + Diag(Loc, diag::err_arithmetic_nonfragile_interface) + << lpointee << lex->getSourceRange(); + return QualType(); + } + // The result type of a pointer-int computation is the pointer type. if (rex->getType()->isIntegerType()) { if (ComplainAboutVoid) diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m index a1d722b742..75d7daafbb 100644 --- a/test/SemaObjC/sizeof-interface.m +++ b/test/SemaObjC/sizeof-interface.m @@ -7,6 +7,8 @@ int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an in // rdar://6821047 void *g3(I0 *P) { + P = P+5; // expected-error {{arithmetic on pointer to incomplete type 'I0 *'}} + return &P[4]; // expected-error{{subscript of pointer to incomplete type 'I0'}} } @@ -49,6 +51,10 @@ typedef struct { @defs(I1) } I1_defs; // expected-error {{invalid application of // rdar://6821047 int bar(I0 *P) { + P = P+5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + P = 5+P; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + P = P-5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + return P[4].x[2]; // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}} } |