]> granicus.if.org Git - clang/commitdiff
[CLANG][BPF] permit any argument type for __builtin_preserve_access_index()
authorYonghong Song <yhs@fb.com>
Sun, 22 Sep 2019 17:33:48 +0000 (17:33 +0000)
committerYonghong Song <yhs@fb.com>
Sun, 22 Sep 2019 17:33:48 +0000 (17:33 +0000)
Commit c15aa241f821 ("[CLANG][BPF] change __builtin_preserve_access_index()
signature") changed the builtin function signature to
  PointerT __builtin_preserve_access_index(PointerT ptr)
with a pointer type as the argument/return type, where argument and
return types must be the same.

There is really no reason for this constraint. The builtin just
presented a code region so that IR builtins
  __builtin_{array, struct, union}_preserve_access_index
can be applied.

This patch removed the pointer type restriction to permit any
argument type as long as it is permitted by the compiler.

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372516 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LanguageExtensions.rst
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaChecking.cpp
test/CodeGen/builtin-preserve-access-index-nonptr.c [new file with mode: 0644]
test/Sema/builtin-preserve-access-index.c

index 9826c41c358a1de0163255bc9df6cc2b94422843..23c8778113e05169ad11cc39daafc951b5437819 100644 (file)
@@ -2354,13 +2354,13 @@ array subscript access and structure/union member access are relocatable
 under bpf compile-once run-everywhere framework. Debuginfo (typically
 with ``-g``) is needed, otherwise, the compiler will exit with an error.
 The return type for the intrinsic is the same as the type of the
-argument, and must be a pointer type.
+argument.
 
 **Syntax**:
 
 .. code-block:: c
 
-  PointerT __builtin_preserve_access_index(PointerT ptr)
+  type __builtin_preserve_access_index(type arg)
 
 **Example of Use**:
 
@@ -2375,7 +2375,8 @@ argument, and must be a pointer type.
     } c[4];
   };
   struct t *v = ...;
-  const void *pb =__builtin_preserve_access_index(&v->c[3].b);
+  int *pb =__builtin_preserve_access_index(&v->c[3].b);
+  __builtin_preserve_access_index(v->j);
 
 Multiprecision Arithmetic Builtins
 ----------------------------------
index 324a8da10c4c7cca37fe0f1803951ab9b6a853bc..ccf2a60dad1f7b367348feb19e76823e48f30fbd 100644 (file)
@@ -9916,7 +9916,4 @@ def err_bit_cast_non_trivially_copyable : Error<
   "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">;
 def err_bit_cast_type_size_mismatch : Error<
   "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">;
-
-def err_builtin_preserve_access_index_invalid_arg : Error<
-  "__builtin_preserve_access_index argument must a pointer type instead of %0">;
 } // end of sema component.
index fb66bc7db34b049a5440ccca2cc01505705ffb5a..ddf58aba1eb9f3e9d6a31377194ec564ccba284b 100644 (file)
@@ -191,22 +191,12 @@ static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) {
   return false;
 }
 
-/// Check the number of arguments and arg type, and set the result type to
+/// Check the number of arguments and set the result type to
 /// the argument type.
 static bool SemaBuiltinPreserveAI(Sema &S, CallExpr *TheCall) {
   if (checkArgCount(S, TheCall, 1))
     return true;
 
-  // The argument type must be a pointer
-  ExprResult Arg = TheCall->getArg(0);
-  QualType Ty = Arg.get()->getType();
-  if (!Ty->isPointerType()) {
-    S.Diag(Arg.get()->getBeginLoc(),
-           diag::err_builtin_preserve_access_index_invalid_arg)
-        << Ty << Arg.get()->getSourceRange();
-    return true;
-  }
-
   TheCall->setType(TheCall->getArg(0)->getType());
   return false;
 }
diff --git a/test/CodeGen/builtin-preserve-access-index-nonptr.c b/test/CodeGen/builtin-preserve-access-index-nonptr.c
new file mode 100644 (file)
index 0000000..bb8caf4
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang -target x86_64 -emit-llvm -S -g %s -o - | FileCheck %s
+
+#define _(x) (__builtin_preserve_access_index(x))
+
+struct s1 {
+  char a;
+  int b[4];
+};
+
+int unit1(struct s1 *arg) {
+  return _(arg->b[2]);
+}
+// CHECK: define dso_local i32 @unit1
+// CHECK: call [4 x i32]* @llvm.preserve.struct.access.index.p0a4i32.p0s_struct.s1s(%struct.s1* %{{[0-9a-z]+}}, i32 1, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S1:[0-9]+]]
+// CHECK: call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %{{[0-9a-z]+}}, i32 1, i32 2), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[ARRAY:[0-9]+]]
+//
+// CHECK: ![[ARRAY]] = !DICompositeType(tag: DW_TAG_array_type
+// CHECK: ![[STRUCT_S1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1"
index 71da8457fa4aa0cd49567d5e488415f376985d80..8cd829da200b18d746721339c4127c1f6a785c1a 100644 (file)
@@ -4,8 +4,8 @@ const void *invalid1(const int *arg) {
   return __builtin_preserve_access_index(&arg[1], 1); // expected-error {{too many arguments to function call, expected 1, have 2}}
 }
 
-const void *invalid2(const int *arg) {
-  return __builtin_preserve_access_index(1); // expected-error {{__builtin_preserve_access_index argument must a pointer type instead of 'int'}}
+int valid2(void) {
+  return __builtin_preserve_access_index(1);
 }
 
 void *invalid3(const int *arg) {
@@ -29,3 +29,11 @@ struct s { int a; int b; };
 int valid7(struct s *arg) {
   return *__builtin_preserve_access_index(&arg->b);
 }
+
+int valid8(struct s *arg) {
+  return __builtin_preserve_access_index(arg->a + arg->b);
+}
+
+int valid9(struct s *arg) {
+  return __builtin_preserve_access_index(({arg->a = 2; arg->b = 3; }));
+}