diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6234,8 +6234,8 @@ "cannot %select{decrement|increment}1 value of type %0">; def err_typecheck_expect_int : Error< "used type %0 where integer is required">; -def err_typecheck_arithmetic_incomplete_type : Error< - "arithmetic on a pointer to an incomplete type %0">; +def err_typecheck_arithmetic_incomplete_or_sizeless_type : Error< + "arithmetic on a pointer to %select{an incomplete|sizeless}0 type %1">; def err_typecheck_pointer_arith_function_type : Error< "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 " "function type%select{|s}2 %1%select{| and %3}2">; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9534,9 +9534,10 @@ assert(ResType->isAnyPointerType() && !ResType->isDependentType()); QualType PointeeTy = ResType->getPointeeType(); - return S.RequireCompleteType(Loc, PointeeTy, - diag::err_typecheck_arithmetic_incomplete_type, - PointeeTy, Operand->getSourceRange()); + return S.RequireCompleteSizedType( + Loc, PointeeTy, + diag::err_typecheck_arithmetic_incomplete_or_sizeless_type, + Operand->getSourceRange()); } /// Check the validity of an arithmetic pointer operand. diff --git a/clang/test/Sema/sizeless-1.c b/clang/test/Sema/sizeless-1.c --- a/clang/test/Sema/sizeless-1.c +++ b/clang/test/Sema/sizeless-1.c @@ -137,6 +137,8 @@ dump(&volatile_int8); dump(&const_volatile_int8); + dump(&local_int8 + 1); // expected-error {{arithmetic on a pointer to sizeless type}} + *&local_int8 = local_int8; *&const_int8 = local_int8; // expected-error {{read-only variable is not assignable}} *&volatile_int8 = local_int8; @@ -158,6 +160,16 @@ noproto(local_int8); varargs(1, local_int8, local_int16); + global_int8_ptr++; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr--; // expected-error {{arithmetic on a pointer to sizeless type}} + ++global_int8_ptr; // expected-error {{arithmetic on a pointer to sizeless type}} + --global_int8_ptr; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr + 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr - 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr += 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr -= 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr - global_int8_ptr; // expected-error {{arithmetic on a pointer to sizeless type}} + +init_int8; // expected-error {{invalid argument type 'svint8_t'}} ++init_int8; // expected-error {{cannot increment value of type 'svint8_t'}} init_int8++; // expected-error {{cannot increment value of type 'svint8_t'}} diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -158,6 +158,8 @@ dump(&volatile_int8); dump(&const_volatile_int8); + dump(&local_int8 + 1); // expected-error {{arithmetic on a pointer to sizeless type}} + *&local_int8 = local_int8; *&const_int8 = local_int8; // expected-error {{read-only variable is not assignable}} *&volatile_int8 = local_int8; @@ -178,6 +180,16 @@ varargs(1, local_int8, local_int16); + global_int8_ptr++; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr--; // expected-error {{arithmetic on a pointer to sizeless type}} + ++global_int8_ptr; // expected-error {{arithmetic on a pointer to sizeless type}} + --global_int8_ptr; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr + 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr - 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr += 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr -= 1; // expected-error {{arithmetic on a pointer to sizeless type}} + global_int8_ptr - global_int8_ptr; // expected-error {{arithmetic on a pointer to sizeless type}} + +init_int8; // expected-error {{invalid argument type 'svint8_t'}} ++init_int8; // expected-error {{cannot increment value of type 'svint8_t'}} init_int8++; // expected-error {{cannot increment value of type 'svint8_t'}}