diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -2358,7 +2358,7 @@ .. code-block:: c - const void * __builtin_preserve_access_index(const void * ptr) + void * __builtin_preserve_access_index(const volatile void * ptr) **Example of Use**: diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1470,7 +1470,7 @@ BUILTIN(__builtin_operator_delete, "vv*", "tn") BUILTIN(__builtin_char_memchr, "c*cC*iz", "n") BUILTIN(__builtin_dump_struct, "ivC*v*", "tn") -BUILTIN(__builtin_preserve_access_index, "vC*vC*", "nU") +BUILTIN(__builtin_preserve_access_index, "v*vCD*", "nU") // Safestack builtins BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1879,6 +1879,8 @@ IsInPreservedAIRegion = true; Value *Res = EmitScalarExpr(E->getArg(0)); + unsigned AddrSpace = Res->getType()->getPointerAddressSpace(); + Res = Builder.CreateBitCast(Res, Int8Ty->getPointerTo(AddrSpace)); IsInPreservedAIRegion = false; return RValue::get(Res); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -197,7 +197,6 @@ if (checkArgCount(S, TheCall, 1)) return true; - TheCall->setType(TheCall->getArg(0)->getType()); return false; } diff --git a/clang/test/Sema/builtin-preserve-access-index.c b/clang/test/Sema/builtin-preserve-access-index.c --- a/clang/test/Sema/builtin-preserve-access-index.c +++ b/clang/test/Sema/builtin-preserve-access-index.c @@ -4,10 +4,10 @@ return __builtin_preserve_access_index(&arg[1], 1); // expected-error {{too many arguments to function call, expected 1, have 2}} } -void *invalid2(const int *arg) { - return __builtin_preserve_access_index(&arg[1]); // expected-warning {{returning 'const void *' from a function with result type 'void *' discards qualifiers}} +void *valid2(const int *arg) { + return __builtin_preserve_access_index(&arg[1]); } const void *invalid3(const int *arg) { - return __builtin_preserve_access_index(1); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const void *'}} + return __builtin_preserve_access_index(1); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const volatile void *'}} }