Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1073,6 +1073,12 @@ Flags<[CC1Option]>; def fno_rewrite_imports : Flag<["-"], "fno-rewrite-imports">, Group; +def fdelete_null_pointer_checks : Flag<["-"], + "fdelete-null-pointer-checks">, Group; +def fno_delete_null_pointer_checks : Flag<["-"], + "fno-delete-null-pointer-checks">, Group, Flags<[CC1Option]>, + HelpText<"Assume that null pointer dereferences are not undefined">; + def frewrite_map_file : Separate<["-"], "frewrite-map-file">, Group, Flags<[ DriverOption, CC1Option ]>; @@ -2829,8 +2835,6 @@ defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group; defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group; defm default_inline : BooleanFFlag<"default-inline">, Group; -defm delete_null_pointer_checks : BooleanFFlag<"delete-null-pointer-checks">, - Group; defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group; defm float_store : BooleanFFlag<"float-store">, Group; defm friend_injection : BooleanFFlag<"friend-injection">, Group; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -130,6 +130,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero +CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(Reassociate , 1, 0) ///< Allow reassociation of FP math ops CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled. Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1721,6 +1721,8 @@ FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); + if (CodeGenOpts.NullPointerIsValid) + FuncAttrs.addAttribute("null-pointer-is-valid", "true"); if (!CodeGenOpts.FPDenormalMode.empty()) FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode); Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3382,6 +3382,10 @@ options::OPT_fno_merge_all_constants, false)) CmdArgs.push_back("-fmerge-all-constants"); + if (Args.hasFlag(options::OPT_fno_delete_null_pointer_checks, + options::OPT_fdelete_null_pointer_checks, false)) + CmdArgs.push_back("-fno-delete-null-pointer-checks"); + // LLVM Code Generator Options. if (Args.hasArg(options::OPT_frewrite_map_file) || Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -742,6 +742,7 @@ OPT_fno_unique_section_names, true); Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions); + Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks); Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables); Index: test/CodeGen/delete-null-pointer-checks.c =================================================================== --- /dev/null +++ test/CodeGen/delete-null-pointer-checks.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=NULL-POINTER-INVALID %s +// RUN: %clang_cc1 -emit-llvm -o - %s -fno-delete-null-pointer-checks | FileCheck -check-prefix=NULL-POINTER-VALID %s + +int test1(int a) { + return a; +} + +// NULL-POINTER-INVALID-NOT: attributes #0 = {{.*}} "null-pointer-is-valid"="true" +// NULL-POINTER-VALID: attributes #0 = {{.*}} "null-pointer-is-valid"="true" Index: test/Driver/clang_f_opts.c =================================================================== --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -348,7 +348,6 @@ // RUN: -fwhole-program \ // RUN: -fcaller-saves \ // RUN: -freorder-blocks \ -// RUN: -fdelete-null-pointer-checks \ // RUN: -ffat-lto-objects \ // RUN: -fmerge-constants \ // RUN: -finline-small-functions \ @@ -414,7 +413,6 @@ // CHECK-WARNING-DAG: optimization flag '-fwhole-program' is not supported // CHECK-WARNING-DAG: optimization flag '-fcaller-saves' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported -// CHECK-WARNING-DAG: optimization flag '-fdelete-null-pointer-checks' is not supported // CHECK-WARNING-DAG: optimization flag '-ffat-lto-objects' is not supported // CHECK-WARNING-DAG: optimization flag '-fmerge-constants' is not supported // CHECK-WARNING-DAG: optimization flag '-finline-small-functions' is not supported @@ -526,3 +524,10 @@ // RUN: %clang -### -S -fno-merge-all-constants -fmerge-all-constants %s 2>&1 | FileCheck -check-prefix=CHECK-MERGE-ALL-CONSTANTS %s // CHECK-NO-MERGE-ALL-CONSTANTS-NOT: "-fmerge-all-constants" // CHECK-MERGE-ALL-CONSTANTS: "-fmerge-all-constants" + +// RUN: %clang -### -S -fdelete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NULL-POINTER-CHECKS %s +// RUN: %clang -### -S -fno-delete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NO-NULL-POINTER-CHECKS %s +// RUN: %clang -### -S -fdelete-null-pointer-checks -fno-delete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NO-NULL-POINTER-CHECKS %s +// RUN: %clang -### -S -fno-delete-null-pointer-checks -fdelete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NULL-POINTER-CHECKS %s +// CHECK-NO-NULL-POINTER-CHECKS: "-fno-delete-null-pointer-checks" +// CHECK-NULL-POINTER-CHECKS-NOT: "-fno-delete-null-pointer-checks"