Skip to content

Commit 592f4da

Browse files
heatdChenyang-L
authored andcommitted
[clang] Add -fcheck-new support
Add -fcheck-new and -fno-check-new, from GCC, which make the compiler not assume pointers returned from operator new are non-null. Fixes #16931. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D125272
1 parent 81c8003 commit 592f4da

File tree

8 files changed

+49
-4
lines changed

8 files changed

+49
-4
lines changed

clang/include/clang/Basic/LangOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ LANGOPT(IncrementalExtensions, 1, 0, " True if we want to process statements"
495495
"avoid tearing the Lexer and etc. down). Controlled by "
496496
"-fincremental-extensions.")
497497

498+
BENIGN_LANGOPT(CheckNew, 1, 0, "Do not assume C++ operator new may not return NULL")
499+
498500
#undef LANGOPT
499501
#undef COMPATIBLE_LANGOPT
500502
#undef BENIGN_LANGOPT

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5288,7 +5288,11 @@ def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group<clang_ignored_gcc_op
52885288
// ignore it for now to avoid breaking builds that use it.
52895289
def fdiagnostics_show_location_EQ : Joined<["-"], "fdiagnostics-show-location=">, Group<clang_ignored_f_Group>;
52905290

5291-
defm fcheck_new : BooleanFFlag<"check-new">, Group<clang_ignored_f_Group>;
5291+
defm check_new : BoolOption<"f", "check-new",
5292+
LangOpts<"CheckNew">, DefaultFalse,
5293+
PosFlag<SetTrue, [], "Do not assume C++ operator new may not return NULL">,
5294+
NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
5295+
52925296
defm caller_saves : BooleanFFlag<"caller-saves">, Group<clang_ignored_gcc_optimization_f_Group>;
52935297
defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>;
52945298
defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>;

clang/lib/AST/ExprCXX.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ CXXNewExpr *CXXNewExpr::CreateEmpty(const ASTContext &Ctx, bool IsArray,
276276
}
277277

278278
bool CXXNewExpr::shouldNullCheckAllocation() const {
279+
if (getOperatorNew()->getLangOpts().CheckNew)
280+
return true;
279281
return !getOperatorNew()->hasAttr<ReturnsNonNullAttr>() &&
280282
getOperatorNew()
281283
->getType()

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6842,6 +6842,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
68426842
Triple.hasDefaultEmulatedTLS()))
68436843
CmdArgs.push_back("-femulated-tls");
68446844

6845+
Args.addOptInFlag(CmdArgs, options::OPT_fcheck_new,
6846+
options::OPT_fno_check_new);
6847+
68456848
if (Arg *A = Args.getLastArg(options::OPT_fzero_call_used_regs_EQ)) {
68466849
// FIXME: There's no reason for this to be restricted to X86. The backend
68476850
// code needs to be changed to include the appropriate function calls

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16247,7 +16247,11 @@ void Sema::AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(
1624716247
// indicates failure by returning a null pointer value. Any other allocation
1624816248
// function never returns a null pointer value and indicates failure only by
1624916249
// throwing an exception [...]
16250-
if (!IsNothrow && !FD->hasAttr<ReturnsNonNullAttr>())
16250+
//
16251+
// However, -fcheck-new invalidates this possible assumption, so don't add
16252+
// NonNull when that is enabled.
16253+
if (!IsNothrow && !FD->hasAttr<ReturnsNonNullAttr>() &&
16254+
!getLangOpts().CheckNew)
1625116255
FD->addAttr(ReturnsNonNullAttr::CreateImplicit(Context, FD->getLocation()));
1625216256

1625316257
// C++2a [basic.stc.dynamic.allocation]p2:

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3166,7 +3166,8 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
31663166
// Global allocation functions should always be visible.
31673167
Alloc->setVisibleDespiteOwningModule();
31683168

3169-
if (HasBadAllocExceptionSpec && getLangOpts().NewInfallible)
3169+
if (HasBadAllocExceptionSpec && getLangOpts().NewInfallible &&
3170+
!getLangOpts().CheckNew)
31703171
Alloc->addAttr(
31713172
ReturnsNonNullAttr::CreateImplicit(Context, Alloc->getLocation()));
31723173

clang/test/CodeGenCXX/fcheck-new.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -fcheck-new -triple x86_64-linux-gnu -disable-O0-optnone \
3+
// RUN: -emit-llvm -o - %s | FileCheck %s
4+
5+
struct A { A(); };
6+
7+
// CHECK-LABEL: @_Z5test0v(
8+
// CHECK-NEXT: entry:
9+
// CHECK-NEXT: [[CALL:%.*]] = call noalias noundef ptr @_Znwm(i64 noundef 1) #[[ATTR3:[0-9]+]]
10+
// CHECK-NEXT: [[NEW_ISNULL:%.*]] = icmp eq ptr [[CALL]], null
11+
// CHECK-NEXT: br i1 [[NEW_ISNULL]], label [[NEW_CONT:%.*]], label [[NEW_NOTNULL:%.*]]
12+
// CHECK: new.notnull:
13+
// CHECK-NEXT: call void @_ZN1AC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[CALL]])
14+
// CHECK-NEXT: br label [[NEW_CONT]]
15+
// CHECK: new.cont:
16+
// CHECK-NEXT: [[TMP0:%.*]] = phi ptr [ [[CALL]], [[NEW_NOTNULL]] ], [ null, [[ENTRY:%.*]] ]
17+
// CHECK-NEXT: ret ptr [[TMP0]]
18+
//
19+
A *test0() {
20+
return new A();
21+
}
22+
23+
// CHECK-LABEL: @_Z5test1v(
24+
// CHECK-NEXT: entry:
25+
// CHECK-NEXT: [[CALL:%.*]] = call noalias noundef ptr @_Znwm(i64 noundef 4) #[[ATTR3]]
26+
// CHECK-NEXT: ret ptr [[CALL]]
27+
//
28+
int *test1() {
29+
return new int;
30+
}

clang/test/Driver/clang_f_opts.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@
302302
// RUN: -fno-reorder-blocks -freorder-blocks \
303303
// RUN: -fno-schedule-insns2 -fschedule-insns2 \
304304
// RUN: -fno-stack-check \
305-
// RUN: -fno-check-new -fcheck-new \
306305
// RUN: -ffriend-injection \
307306
// RUN: -fno-implement-inlines -fimplement-inlines \
308307
// RUN: -fstack-check \

0 commit comments

Comments
 (0)