llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Nikita Popov (nikic) <details> <summary>Changes</summary> If `-fassume-sane-operator-new` (the default), assume that `operator new` does not read or write accessible memory. Currently, this assumption already exists (I think even if `-fno-assume-sane-operator-new` is used) due to special treatment in BasicAA. I'd like to remove this special treatment (see https://github.com/llvm/llvm-project/pull/197180), and instead rely only on the `memory` attribute. It's worth noting that this is consistent with GCC's interpretation of the flag (where it is also enabled by default): > [...] With -fassume-sane-operators-new-delete option GCC may assume that calls to the replaceable global operators from new or delete expressions or from __builtin_operator_new or __builtin_operator_delete calls don’t read or modify any global variables or variables whose address could escape to the operators (global state; except for errno for the new and new[] operators). [...] --- Full diff: https://github.com/llvm/llvm-project/pull/197199.diff 3 Files Affected: - (modified) clang/lib/CodeGen/CGCall.cpp (+5-2) - (modified) clang/test/CodeGenCXX/new_hot_cold.cpp (+4-4) - (modified) clang/test/CodeGenCXX/operator-new.cpp (+4-2) ``````````diff diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a2b9c945788ee..26ab2ba1224f9 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2615,11 +2615,14 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, AddAttributesFromFunctionProtoType( getContext(), FuncAttrs, Fn->getType()->getAs<FunctionProtoType>()); if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) { - // A sane operator new returns a non-aliasing pointer. + // A sane operator new returns a non-aliasing pointer and does not + // read or write accessible memory. auto Kind = Fn->getDeclName().getCXXOverloadedOperator(); if (getCodeGenOpts().AssumeSaneOperatorNew && - (Kind == OO_New || Kind == OO_Array_New)) + (Kind == OO_New || Kind == OO_Array_New)) { RetAttrs.addAttribute(llvm::Attribute::NoAlias); + FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleMemOnly()); + } } const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn); const bool IsVirtualCall = MD && MD->isVirtual(); diff --git a/clang/test/CodeGenCXX/new_hot_cold.cpp b/clang/test/CodeGenCXX/new_hot_cold.cpp index 014e815201485..385f6cc07f689 100644 --- a/clang/test/CodeGenCXX/new_hot_cold.cpp +++ b/clang/test/CodeGenCXX/new_hot_cold.cpp @@ -124,7 +124,7 @@ void hot_cold_new_align_nothrow_array() { // CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = { nobuiltin allocsize(0) {{.*}} } // CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOTHROW]] = { nobuiltin nounwind allocsize(0) {{.*}} } -// CHECK-DAG: attributes [[ATTR_NO_BUILTIN_CALL]] = { allocsize(0) } -// CHECK-DAG: attributes [[ATTR_BUILTIN_CALL]] = { builtin allocsize(0) } -// CHECK-DAG: attributes [[ATTR_NO_BUILTIN_NOTHROW_CALL]] = { nounwind allocsize(0) } -// CHECK-DAG: attributes [[ATTR_BUILTIN_NOTHROW_CALL]] = { builtin nounwind allocsize(0) } +// CHECK-DAG: attributes [[ATTR_NO_BUILTIN_CALL]] = { allocsize(0) memory(inaccessiblemem: readwrite) } +// CHECK-DAG: attributes [[ATTR_BUILTIN_CALL]] = { builtin allocsize(0) memory(inaccessiblemem: readwrite) } +// CHECK-DAG: attributes [[ATTR_NO_BUILTIN_NOTHROW_CALL]] = { nounwind allocsize(0) memory(inaccessiblemem: readwrite) } +// CHECK-DAG: attributes [[ATTR_BUILTIN_NOTHROW_CALL]] = { builtin nounwind allocsize(0) memory(inaccessiblemem: readwrite) } diff --git a/clang/test/CodeGenCXX/operator-new.cpp b/clang/test/CodeGenCXX/operator-new.cpp index 1d7887146705e..8a71bd96e9b97 100644 --- a/clang/test/CodeGenCXX/operator-new.cpp +++ b/clang/test/CodeGenCXX/operator-new.cpp @@ -22,8 +22,10 @@ void *f2(long N) { // ALL-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1 // ALL-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0 // ALL-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]] - // SANE-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[RESULT]]) - // SANENOT-NEXT: call noundef nonnull ptr @_Znaj(i32 noundef [[RESULT]]) + // SANE-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[RESULT]]) [[ATTR:#[0-9]+]] + // SANENOT-NEXT: call noundef nonnull ptr @_Znaj(i32 noundef [[RESULT]]) [[ATTR:#[0-9]+]] } // ALL: declare noundef nonnull ptr @_Znaj( +// SANE: attributes [[ATTR]] = { builtin allocsize(0) memory(inaccessiblemem: readwrite) } +// SANENOT: attributes [[ATTR]] = { builtin allocsize(0) } `````````` </details> https://github.com/llvm/llvm-project/pull/197199 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
