diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 13 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 277 | ||||
-rw-r--r-- | test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp | 2 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p7.cpp | 4 | ||||
-rw-r--r-- | test/Sema/incomplete-decl.c | 2 | ||||
-rw-r--r-- | test/Sema/pointer-addition.c | 26 | ||||
-rw-r--r-- | test/Sema/pointer-subtract-compat.c | 2 | ||||
-rw-r--r-- | test/Sema/typecheck-binop.c | 6 | ||||
-rw-r--r-- | test/SemaCXX/null_in_arithmetic_ops.cpp | 2 | ||||
-rw-r--r-- | test/SemaObjC/sizeof-interface.m | 2 |
10 files changed, 182 insertions, 154 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1fc43c9dd0..87812febb0 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2900,11 +2900,12 @@ def err_ivar_reference_type : Error< def err_typecheck_illegal_increment_decrement : Error< "cannot %select{decrement|increment}1 value of type %0">; def err_typecheck_arithmetic_incomplete_type : Error< - "arithmetic on pointer to incomplete type %0">; + "arithmetic on a pointer to an incomplete type %0">; def err_typecheck_pointer_arith_function_type : Error< - "arithmetic on pointer to function type %0">; + "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 " + "function type%select{|s}2 %1%select{| and %3}2">; def err_typecheck_pointer_arith_void_type : Error< - "arithmetic on pointer to void type">; + "arithmetic on%select{ a|}0 pointer%select{|s}0 to void">; def err_typecheck_decl_incomplete_type : Error< "variable has incomplete type %0">; def ext_typecheck_decl_incomplete_type : ExtWarn< @@ -3092,9 +3093,11 @@ def note_forward_class : Note< def err_duplicate_property : Error< "property has a previous declaration">; def ext_gnu_void_ptr : Extension< - "use of GNU void* extension">, InGroup<PointerArith>; + "arithmetic on%select{ a|}0 pointer%select{|s}0 to void is a GNU extension">, + InGroup<PointerArith>; def ext_gnu_ptr_func_arith : Extension< - "arithmetic on pointer to function type %0 is a GNU extension">, + "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function " + "type%select{|s}2 %1%select{| and %3}2 is a GNU extension">, InGroup<PointerArith>; def error_readonly_property_assignment : Error< "assigning to property with 'readonly' attribute not allowed">; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 892b882df5..d644e55989 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3092,8 +3092,9 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, if (ResultType->isVoidType() && !getLangOptions().CPlusPlus) { // GNU extension: subscripting on pointer to void + // FIXME: Use a better warning for this. Diag(LLoc, diag::ext_gnu_void_ptr) - << BaseExpr->getSourceRange(); + << 0 << BaseExpr->getSourceRange(); // C forbids expressions of unqualified void type from being l-values. // See IsCForbiddenLValueType. @@ -5595,6 +5596,145 @@ QualType Sema::CheckRemainderOperands( return compType; } +/// \brief Diagnose invalid arithmetic on two void pointers. +static void diagnoseArithmeticOnTwoVoidPointers(Sema &S, SourceLocation Loc, + Expr *LHS, Expr *RHS) { + S.Diag(Loc, S.getLangOptions().CPlusPlus + ? diag::err_typecheck_pointer_arith_void_type + : diag::ext_gnu_void_ptr) + << 1 /* two pointers */ << LHS->getSourceRange() << RHS->getSourceRange(); +} + +/// \brief Diagnose invalid arithmetic on a void pointer. +static void diagnoseArithmeticOnVoidPointer(Sema &S, SourceLocation Loc, + Expr *Pointer) { + S.Diag(Loc, S.getLangOptions().CPlusPlus + ? diag::err_typecheck_pointer_arith_void_type + : diag::ext_gnu_void_ptr) + << 0 /* one pointer */ << Pointer->getSourceRange(); +} + +/// \brief Diagnose invalid arithmetic on two function pointers. +static void diagnoseArithmeticOnTwoFunctionPointers(Sema &S, SourceLocation Loc, + Expr *LHS, Expr *RHS) { + assert(LHS->getType()->isAnyPointerType()); + assert(RHS->getType()->isAnyPointerType()); + S.Diag(Loc, S.getLangOptions().CPlusPlus + ? diag::err_typecheck_pointer_arith_function_type + : diag::ext_gnu_ptr_func_arith) + << 1 /* two pointers */ << LHS->getType()->getPointeeType() + // We only show the second type if it differs from the first. + << (unsigned)!S.Context.hasSameUnqualifiedType(LHS->getType(), + RHS->getType()) + << RHS->getType()->getPointeeType() + << LHS->getSourceRange() << RHS->getSourceRange(); +} + +/// \brief Diagnose invalid arithmetic on a function pointer. +static void diagnoseArithmeticOnFunctionPointer(Sema &S, SourceLocation Loc, + Expr *Pointer) { + assert(Pointer->getType()->isAnyPointerType()); + S.Diag(Loc, S.getLangOptions().CPlusPlus + ? diag::err_typecheck_pointer_arith_function_type + : diag::ext_gnu_ptr_func_arith) + << 0 /* one pointer */ << Pointer->getType()->getPointeeType() + << 0 /* one pointer, so only one type */ + << Pointer->getSourceRange(); +} + +/// \brief Check the validity of an arithmetic pointer operand. +/// +/// If the operand has pointer type, this code will check for pointer types +/// which are invalid in arithmetic operations. These will be diagnosed +/// appropriately, including whether or not the use is supported as an +/// extension. +/// +/// \returns True when the operand is valid to use (even if as an extension). +static bool checkArithmeticOpPointerOperand(Sema &S, SourceLocation Loc, + Expr *Operand) { + if (!Operand->getType()->isAnyPointerType()) return true; + + QualType PointeeTy = Operand->getType()->getPointeeType(); + if (PointeeTy->isVoidType()) { + diagnoseArithmeticOnVoidPointer(S, Loc, Operand); + return !S.getLangOptions().CPlusPlus; + } + if (PointeeTy->isFunctionType()) { + diagnoseArithmeticOnFunctionPointer(S, Loc, Operand); + return !S.getLangOptions().CPlusPlus; + } + + if ((Operand->getType()->isPointerType() && + !Operand->getType()->isDependentType()) || + Operand->getType()->isObjCObjectPointerType()) { + QualType PointeeTy = Operand->getType()->getPointeeType(); + if (S.RequireCompleteType( + Loc, PointeeTy, + S.PDiag(diag::err_typecheck_arithmetic_incomplete_type) + << PointeeTy << Operand->getSourceRange())) + return false; + } + + return true; +} + +/// \brief Check the validity of a binary arithmetic operation w.r.t. pointer +/// operands. +/// +/// This routine will diagnose any invalid arithmetic on pointer operands much +/// like \see checkArithmeticOpPointerOperand. However, it has special logic +/// for emitting a single diagnostic even for operations where both LHS and RHS +/// are (potentially problematic) pointers. +/// +/// \returns True when the operand is valid to use (even if as an extension). +static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc, + Expr *LHS, Expr *RHS) { + bool isLHSPointer = LHS->getType()->isAnyPointerType(); + bool isRHSPointer = RHS->getType()->isAnyPointerType(); + if (!isLHSPointer && !isRHSPointer) return true; + + QualType LHSPointeeTy, RHSPointeeTy; + if (isLHSPointer) LHSPointeeTy = LHS->getType()->getPointeeType(); + if (isRHSPointer) RHSPointeeTy = RHS->getType()->getPointeeType(); + + // Check for arithmetic on pointers to incomplete types. + bool isLHSVoidPtr = isLHSPointer && LHSPointeeTy->isVoidType(); + bool isRHSVoidPtr = isRHSPointer && RHSPointeeTy->isVoidType(); + if (isLHSVoidPtr || isRHSVoidPtr) { + if (!isRHSVoidPtr) diagnoseArithmeticOnVoidPointer(S, Loc, LHS); + else if (!isLHSVoidPtr) diagnoseArithmeticOnVoidPointer(S, Loc, RHS); + else diagnoseArithmeticOnTwoVoidPointers(S, Loc, LHS, RHS); + + return !S.getLangOptions().CPlusPlus; + } + + bool isLHSFuncPtr = isLHSPointer && LHSPointeeTy->isFunctionType(); + bool isRHSFuncPtr = isRHSPointer && RHSPointeeTy->isFunctionType(); + if (isLHSFuncPtr || isRHSFuncPtr) { + if (!isRHSFuncPtr) diagnoseArithmeticOnFunctionPointer(S, Loc, LHS); + else if (!isLHSFuncPtr) diagnoseArithmeticOnFunctionPointer(S, Loc, RHS); + else diagnoseArithmeticOnTwoFunctionPointers(S, Loc, LHS, RHS); + + return !S.getLangOptions().CPlusPlus; + } + + Expr *Operands[] = { LHS, RHS }; + for (unsigned i = 0; i < 2; ++i) { + Expr *Operand = Operands[i]; + if ((Operand->getType()->isPointerType() && + !Operand->getType()->isDependentType()) || + Operand->getType()->isObjCObjectPointerType()) { + QualType PointeeTy = Operand->getType()->getPointeeType(); + if (S.RequireCompleteType( + Loc, PointeeTy, + S.PDiag(diag::err_typecheck_arithmetic_incomplete_type) + << PointeeTy << Operand->getSourceRange())) + return false; + } + } + return true; +} + QualType Sema::CheckAdditionOperands( // C99 6.5.6 ExprResult &lex, ExprResult &rex, SourceLocation Loc, QualType* CompLHSTy) { if (lex.get()->getType()->isVectorType() || rex.get()->getType()->isVectorType()) { @@ -5620,42 +5760,12 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6 std::swap(PExp, IExp); if (PExp->getType()->isAnyPointerType()) { - if (IExp->getType()->isIntegerType()) { - QualType PointeeTy = PExp->getType()->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.get()->getSourceRange() << rex.get()->getSourceRange(); - return QualType(); - } + if (!checkArithmeticOpPointerOperand(*this, Loc, PExp)) + return QualType(); - // GNU extension: arithmetic on pointer to void - Diag(Loc, diag::ext_gnu_void_ptr) - << lex.get()->getSourceRange() << rex.get()->getSourceRange(); - } else if (PointeeTy->isFunctionType()) { - if (getLangOptions().CPlusPlus) { - Diag(Loc, diag::err_typecheck_pointer_arith_function_type) - << PExp->getType() << PExp->getSourceRange(); - return QualType(); - } + QualType PointeeTy = PExp->getType()->getPointeeType(); - // GNU extension: arithmetic on pointer to function - Diag(Loc, diag::ext_gnu_ptr_func_arith) - << PExp->getType() << PExp->getSourceRange(); - } else { - // Check if we require a complete type. - if (((PExp->getType()->isPointerType() && - !PExp->getType()->isDependentType()) || - PExp->getType()->isObjCObjectPointerType()) && - RequireCompleteType(Loc, PointeeTy, - PDiag(diag::err_typecheck_arithmetic_incomplete_type) - << PExp->getSourceRange() - << PExp->getType())) - return QualType(); - } // Diagnose bad cases where we step over interface counts. if (PointeeTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) { Diag(Loc, diag::err_arithmetic_nonfragile_interface) @@ -5705,35 +5815,6 @@ QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex, if (lex.get()->getType()->isAnyPointerType()) { QualType lpointee = lex.get()->getType()->getPointeeType(); - // The LHS must be an completely-defined object type. - - bool ComplainAboutVoid = false; - Expr *ComplainAboutFunc = 0; - if (lpointee->isVoidType()) { - if (getLangOptions().CPlusPlus) { - Diag(Loc, diag::err_typecheck_pointer_arith_void_type) - << lex.get()->getSourceRange() << rex.get()->getSourceRange(); - return QualType(); - } - - // GNU C extension: arithmetic on pointer to void - ComplainAboutVoid = true; - } else if (lpointee->isFunctionType()) { - if (getLangOptions().CPlusPlus) { - Diag(Loc, diag::err_typecheck_pointer_arith_function_type) - << lex.get()->getType() << lex.get()->getSourceRange(); - return QualType(); - } - - // GNU C extension: arithmetic on pointer to function - ComplainAboutFunc = lex.get(); - } else if (!lpointee->isDependentType() && - RequireCompleteType(Loc, lpointee, - PDiag(diag::err_typecheck_sub_ptr_object) - << lex.get()->getSourceRange() - << lex.get()->getType())) - return QualType(); - // Diagnose bad cases where we step over interface counts. if (lpointee->isObjCObjectType() && LangOpts.ObjCNonFragileABI) { Diag(Loc, diag::err_arithmetic_nonfragile_interface) @@ -5743,13 +5824,8 @@ QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex, // The result type of a pointer-int computation is the pointer type. if (rex.get()->getType()->isIntegerType()) { - if (ComplainAboutVoid) - Diag(Loc, diag::ext_gnu_void_ptr) - << lex.get()->getSourceRange() << rex.get()->getSourceRange(); - if (ComplainAboutFunc) - Diag(Loc, diag::ext_gnu_ptr_func_arith) - << ComplainAboutFunc->getType() - << ComplainAboutFunc->getSourceRange(); + if (!checkArithmeticOpPointerOperand(*this, Loc, lex.get())) + return QualType(); if (CompLHSTy) *CompLHSTy = lex.get()->getType(); return lex.get()->getType(); @@ -5759,33 +5835,6 @@ QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex, if (const PointerType *RHSPTy = rex.get()->getType()->getAs<PointerType>()) { QualType rpointee = RHSPTy->getPointeeType(); - // RHS must be a completely-type object type. - // Handle the GNU void* extension. - if (rpointee->isVoidType()) { - if (getLangOptions().CPlusPlus) { - Diag(Loc, diag::err_typecheck_pointer_arith_void_type) - << lex.get()->getSourceRange() << rex.get()->getSourceRange(); - return QualType(); - } - - ComplainAboutVoid = true; - } else if (rpointee->isFunctionType()) { - if (getLangOptions().CPlusPlus) { - Diag(Loc, diag::err_typecheck_pointer_arith_function_type) - << rex.get()->getType() << rex.get()->getSourceRange(); - return QualType(); - } - - // GNU extension: arithmetic on pointer to function - if (!ComplainAboutFunc) - ComplainAboutFunc = rex.get(); - } else if (!rpointee->isDependentType() && - RequireCompleteType(Loc, rpointee, - PDiag(diag::err_typecheck_sub_ptr_object) - << rex.get()->getSourceRange() - << rex.get()->getType())) - return QualType(); - if (getLangOptions().CPlusPlus) { // Pointee types must be the same: C++ [expr.add] if (!Context.hasSameUnqualifiedType(lpointee, rpointee)) { @@ -5806,13 +5855,9 @@ QualType Sema::CheckSubtractionOperands(ExprResult &lex, ExprResult &rex, } } - if (ComplainAboutVoid) - Diag(Loc, diag::ext_gnu_void_ptr) - << lex.get()->getSourceRange() << rex.get()->getSourceRange(); - if (ComplainAboutFunc) - Diag(Loc, diag::ext_gnu_ptr_func_arith) - << ComplainAboutFunc->getType() - << ComplainAboutFunc->getSourceRange(); + if (!checkArithmeticBinOpPointerOperands(*this, Loc, + lex.get(), rex.get())) + return QualType(); if (CompLHSTy) *CompLHSTy = lex.get()->getType(); return Context.getPointerDiffType(); @@ -6819,29 +6864,9 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, QualType PointeeTy = ResType->getPointeeType(); // C99 6.5.2.4p2, 6.5.6p2 - if (PointeeTy->isVoidType()) { - if (S.getLangOptions().CPlusPlus) { - S.Diag(OpLoc, diag::err_typecheck_pointer_arith_void_type) - << Op->getSourceRange(); - return QualType(); - } - - // Pointer to void is a GNU extension in C. - S.Diag(OpLoc, diag::ext_gnu_void_ptr) << Op->getSourceRange(); - } else if (PointeeTy->isFunctionType()) { - if (S.getLangOptions().CPlusPlus) { - S.Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type) - << Op->getType() << Op->getSourceRange(); - return QualType(); - } - - S.Diag(OpLoc, diag::ext_gnu_ptr_func_arith) - << ResType << Op->getSourceRange(); - } else if (S.RequireCompleteType(OpLoc, PointeeTy, - S.PDiag(diag::err_typecheck_arithmetic_incomplete_type) - << Op->getSourceRange() - << ResType)) + if (!checkArithmeticOpPointerOperand(S, OpLoc, Op)) return QualType(); + // Diagnose bad cases where we step over interface counts. else if (PointeeTy->isObjCObjectType() && S.LangOpts.ObjCNonFragileABI) { S.Diag(OpLoc, diag::err_arithmetic_nonfragile_interface) diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 7bfa6fe582..0c92f62582 100644 --- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -129,7 +129,7 @@ void g() { void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} void *end(); }; - for (auto u : NoIncr()) { // expected-error {{arithmetic on pointer to void type}} + for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void type}} } struct NoNotEq { diff --git a/test/CXX/temp/temp.spec/temp.explicit/p7.cpp b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp index b62e0cb9b1..7398dca7ba 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p7.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp @@ -7,14 +7,14 @@ struct X0 { }; T* f0(T* ptr) { - return ptr + 1; // expected-error{{pointer to function}} + return ptr + 1; // expected-error{{pointer to the function}} } static T* static_member; }; template<typename T> -T* X0<T>::static_member = ((T*)0) + 1; // expected-error{{pointer to function}} +T* X0<T>::static_member = ((T*)0) + 1; // expected-error{{pointer to the function}} template class X0<int>; // okay diff --git a/test/Sema/incomplete-decl.c b/test/Sema/incomplete-decl.c index e5b6d5f0da..0214a0c6ce 100644 --- a/test/Sema/incomplete-decl.c +++ b/test/Sema/incomplete-decl.c @@ -22,7 +22,7 @@ void func() { } int h[]; // expected-warning {{tentative array definition assumed to have one element}} -int (*i)[] = &h+1; // expected-error {{arithmetic on pointer to incomplete type 'int (*)[]'}} +int (*i)[] = &h+1; // expected-error {{arithmetic on a pointer to an incomplete type 'int []'}} struct bar j = {1}; // expected-error {{variable has incomplete type 'struct bar'}} \ expected-note {{forward declaration of 'struct bar'}} diff --git a/test/Sema/pointer-addition.c b/test/Sema/pointer-addition.c index 01047a0684..af8258a0f2 100644 --- a/test/Sema/pointer-addition.c +++ b/test/Sema/pointer-addition.c @@ -3,19 +3,19 @@ typedef struct S S; // expected-note 3 {{forward declaration of 'struct S'}} void a(S* b, void* c) { void (*fp)(int) = 0; - b++; // expected-error {{arithmetic on pointer to incomplete type}} - b += 1; // expected-error {{arithmetic on pointer to incomplete type}} - c++; // expected-warning {{use of GNU void* extension}} - c += 1; // expected-warning {{use of GNU void* extension}} - c--; // expected-warning {{use of GNU void* extension}} - c -= 1; // expected-warning {{use of GNU void* extension}} - (void) c[1]; // expected-warning {{use of GNU void* extension}} - b = 1+b; // expected-error {{arithmetic on pointer to incomplete type}} + b++; // expected-error {{arithmetic on a pointer to an incomplete type}} + b += 1; // expected-error {{arithmetic on a pointer to an incomplete type}} + c++; // expected-warning {{arithmetic on a pointer to void is a GNU extension}} + c += 1; // expected-warning {{arithmetic on a pointer to void is a GNU extension}} + c--; // expected-warning {{arithmetic on a pointer to void is a GNU extension}} + c -= 1; // expected-warning {{arithmetic on a pointer to void is a GNU extension}} + (void) c[1]; // expected-warning {{arithmetic on a pointer to void is a GNU extension}} + b = 1+b; // expected-error {{arithmetic on a pointer to an incomplete type}} /* The next couple tests are only pedantic warnings in gcc */ void (*d)(S*,void*) = a; - d += 1; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} - d++; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} - d--; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} - d -= 1; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} - (void)(1 + d); // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} + d += 1; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} + d++; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} + d--; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} + d -= 1; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} + (void)(1 + d); // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' is a GNU extension}} } diff --git a/test/Sema/pointer-subtract-compat.c b/test/Sema/pointer-subtract-compat.c index 70340c6a4c..b801f81473 100644 --- a/test/Sema/pointer-subtract-compat.c +++ b/test/Sema/pointer-subtract-compat.c @@ -7,5 +7,5 @@ int a(char* a, rchar* b) { // <rdar://problem/6520707> void f0(void (*fp)(void)) { - int x = fp - fp; // expected-warning{{arithmetic on pointer to function type 'void (*)(void)' is a GNU extension}} + int x = fp - fp; // expected-warning{{arithmetic on pointers to the function type 'void (void)' is a GNU extension}} } diff --git a/test/Sema/typecheck-binop.c b/test/Sema/typecheck-binop.c index 712dad279d..be52d0bd84 100644 --- a/test/Sema/typecheck-binop.c +++ b/test/Sema/typecheck-binop.c @@ -7,15 +7,15 @@ int sub1(int *a, double *b) { } void *sub2(struct incomplete *P) { - return P-4; /* expected-error{{subtraction of pointer 'struct incomplete *' requires pointee to be a complete object type}} */ + return P-4; /* expected-error{{arithmetic on a pointer to an incomplete type 'struct incomplete'}} */ } void *sub3(void *P) { - return P-4; /* expected-warning{{GNU void* extension}} */ + return P-4; /* expected-warning{{arithmetic on a pointer to void is a GNU extension}} */ } int sub4(void *P, void *Q) { - return P-Q; /* expected-warning{{GNU void* extension}} */ + return P-Q; /* expected-warning{{arithmetic on pointers to void is a GNU extension}} */ } int sub5(void *P, int *Q) { diff --git a/test/SemaCXX/null_in_arithmetic_ops.cpp b/test/SemaCXX/null_in_arithmetic_ops.cpp index 26af5e6e75..fab6f10ab7 100644 --- a/test/SemaCXX/null_in_arithmetic_ops.cpp +++ b/test/SemaCXX/null_in_arithmetic_ops.cpp @@ -33,7 +33,7 @@ void f() { v = 0 ? NULL + d : d + NULL; // \ expected-error {{invalid operands to binary expression ('long' and 'void (X::*)()')}} \ expected-error {{invalid operands to binary expression ('void (X::*)()' and 'long')}} - v = 0 ? NULL + e : e + NULL; // expected-error 2{{arithmetic on pointer to function type 'void (*)()'}} + v = 0 ? NULL + e : e + NULL; // expected-error 2{{arithmetic on a pointer to the function type 'void ()'}} v = 0 ? NULL + f : f + NULL; // expected-warning 2{{use of NULL in arithmetic operation}} v = 0 ? NULL + "f" : "f" + NULL; // expected-warning 2{{use of NULL in arithmetic operation}} diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m index 3fe39645fd..65c8e49e0b 100644 --- a/test/SemaObjC/sizeof-interface.m +++ b/test/SemaObjC/sizeof-interface.m @@ -7,7 +7,7 @@ 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 *'}} + P = P+5; // expected-error {{arithmetic on a pointer to an incomplete type 'I0'}} return &P[4]; // expected-error{{subscript of pointer to incomplete type 'I0'}} } |