[clang] 010005f - [Sema][SVE] Reject subscripts on pointers to sizeless types

Richard Sandiford via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 17 04:27:48 PDT 2020


Author: Richard Sandiford
Date: 2020-03-17T11:24:57Z
New Revision: 010005f0774e13475c321f78b89bdc79eb78d5a5

URL: https://github.com/llvm/llvm-project/commit/010005f0774e13475c321f78b89bdc79eb78d5a5
DIFF: https://github.com/llvm/llvm-project/commit/010005f0774e13475c321f78b89bdc79eb78d5a5.diff

LOG: [Sema][SVE] Reject subscripts on pointers to sizeless types

clang currently accepts:

  __SVInt8_t &foo1(__SVInt8_t *x) { return *x; }
  __SVInt8_t &foo2(__SVInt8_t *x) { return x[1]; }

The first function is valid ACLE code and generates correct LLVM IR
(and assembly code).  But the second function is invalid for the
same reason that arrays of sizeless types are.  Trying to code-generate
the function leads to:

  llvm/include/llvm/Support/TypeSize.h:126: uint64_t llvm::TypeSize::getFixedSize() const: Assertion `!IsScalable && "Request for a fixed size on a s
calable object"' failed.

Another problem is that:

  template<typename T>
  constexpr __SIZE_TYPE__ f(T *x) { return &x[1] - x; }
  typedef int arr1[f((int *)0) - 1];
  typedef int arr2[f((__SVInt8_t *)0) - 1];

produces:

  a.cpp:2:48: warning: subtraction of pointers to type '__SVInt8_t' of zero size has undefined behavior [-Wpointer-arith]
  constexpr __SIZE_TYPE__ f(T *x) { return &x[1] - x; }
					   ~~~~~ ^ ~
  a.cpp:4:18: note: in instantiation of function template specialization 'f<__SVInt8_t>' requested here
  typedef int arr2[f((__SVInt8_t *)0) - 1];

This patch reports an appropriate diagnostic instead.

Differential Revision: https://reviews.llvm.org/D76084

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaExpr.cpp
    clang/test/Sema/sizeless-1.c
    clang/test/SemaCXX/sizeless-1.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cc815a4993d5..4c057badbfe2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6126,8 +6126,8 @@ def err_typecheck_subscript_not_integer : Error<
   "array subscript is not an integer">;
 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_incomplete_or_sizeless_type : Error<
+  "subscript of pointer to %select{incomplete|sizeless}0 type %1">;
 def err_dereference_incomplete_type : Error<
   "dereference of pointer to incomplete type %0">;
 def ext_gnu_subscript_void_type : Extension<

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 546f3ac7325b..a3ac74323d59 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4885,8 +4885,9 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
     // See IsCForbiddenLValueType.
     if (!ResultType.hasQualifiers()) VK = VK_RValue;
   } else if (!ResultType->isDependentType() &&
-      RequireCompleteType(LLoc, ResultType,
-                          diag::err_subscript_incomplete_type, BaseExpr))
+             RequireCompleteSizedType(
+                 LLoc, ResultType,
+                 diag::err_subscript_incomplete_or_sizeless_type, BaseExpr))
     return ExprError();
 
   assert(VK == VK_RValue || LangOpts.CPlusPlus ||

diff  --git a/clang/test/Sema/sizeless-1.c b/clang/test/Sema/sizeless-1.c
index 962595b7b1f8..70f9fb777cc5 100644
--- a/clang/test/Sema/sizeless-1.c
+++ b/clang/test/Sema/sizeless-1.c
@@ -142,6 +142,10 @@ void func(int sel) {
   *&volatile_int8 = local_int8;
   *&const_volatile_int8 = local_int8; // expected-error {{read-only variable is not assignable}}
 
+  global_int8_ptr[0] = local_int8;       // expected-error {{subscript of pointer to sizeless type 'svint8_t'}}
+  global_int8_ptr[1] = local_int8;       // expected-error {{subscript of pointer to sizeless type 'svint8_t'}}
+  global_int8_ptr = &global_int8_ptr[2]; // expected-error {{subscript of pointer to sizeless type 'svint8_t'}}
+
   overf(local_int8);
   overf(local_int16);
 

diff  --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp
index 8b6c00f6e044..4c56784f35db 100644
--- a/clang/test/SemaCXX/sizeless-1.cpp
+++ b/clang/test/SemaCXX/sizeless-1.cpp
@@ -163,6 +163,10 @@ void func(int sel) {
   *&volatile_int8 = local_int8;
   *&const_volatile_int8 = local_int8; // expected-error {{read-only variable is not assignable}}
 
+  global_int8_ptr[0] = local_int8;       // expected-error {{subscript of pointer to sizeless type 'svint8_t'}}
+  global_int8_ptr[1] = local_int8;       // expected-error {{subscript of pointer to sizeless type 'svint8_t'}}
+  global_int8_ptr = &global_int8_ptr[2]; // expected-error {{subscript of pointer to sizeless type 'svint8_t'}}
+
   overf(local_int8);
   overf(local_int16);
 


        


More information about the cfe-commits mailing list