diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -231,6 +231,9 @@ ENUM_CODEGENOPT(SanitizeAddressDtor, llvm::AsanDtorKind, 2, llvm::AsanDtorKind::Global) ///< Set how ASan global ///< destructors are emitted. +CODEGENOPT(SanitizeMemoryParamRetval, 1, 0) ///< Enable detection of uninitialized + ///< parameters and return values + ///< in MemorySanitizer CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection ///< in MemorySanitizer CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1669,6 +1669,13 @@ NormalizedValuesScope<"llvm::AsanDtorKind">, NormalizedValues<["None", "Global"]>, MarshallingInfoEnum, "Global">; +defm sanitize_memory_param_retval + : BoolOption<"f", "sanitize-memory-param-retval", + CodeGenOpts<"SanitizeMemoryParamRetval">, + DefaultFalse, + PosFlag, NegFlag, + BothFlags<[], " detection of uninitialized parameters and return values">>, + Group; // Note: This flag was introduced when it was necessary to distinguish between // ABI for correct codegen. This is no longer needed, but the flag is // not removed since targeting either ABI will behave the same. diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2243,7 +2243,7 @@ getLangOpts().Sanitize.has(SanitizerKind::Return); // Determine if the return type could be partially undef - if (CodeGenOpts.EnableNoundefAttrs && HasStrictReturn) { + if (NoundefAnalysisEnabled && HasStrictReturn) { if (!RetTy->isVoidType() && RetAI.getKind() != ABIArgInfo::Indirect && DetermineNoUndef(RetTy, getTypes(), DL, RetAI)) RetAttrs.addAttribute(llvm::Attribute::NoUndef); @@ -2378,7 +2378,7 @@ // Decide whether the argument we're handling could be partially undef bool ArgNoUndef = DetermineNoUndef(ParamType, getTypes(), DL, AI); - if (CodeGenOpts.EnableNoundefAttrs && ArgNoUndef) + if (NoundefAnalysisEnabled && ArgNoUndef) Attrs.addAttribute(llvm::Attribute::NoUndef); // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1620,6 +1620,8 @@ llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map, StringRef Suffix); + + bool NoundefAnalysisEnabled = false; }; } // end namespace CodeGen diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -209,6 +209,9 @@ ModuleNameHash = (Twine(".__uniq.") + Twine(toString(IntHash, /* Radix = */ 10, /* Signed = */false))).str(); } + + NoundefAnalysisEnabled = + CodeGenOpts.EnableNoundefAttrs || CodeGenOpts.SanitizeMemoryParamRetval; } CodeGenModule::~CodeGenModule() {} diff --git a/clang/test/CodeGen/attr-noundef.cpp b/clang/test/CodeGen/attr-noundef.cpp --- a/clang/test/CodeGen/attr-noundef.cpp +++ b/clang/test/CodeGen/attr-noundef.cpp @@ -1,5 +1,7 @@ // RUN: %clang -cc1 -triple x86_64-gnu-linux -x c++ -S -emit-llvm -enable-noundef-analysis %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-INTEL // RUN: %clang -cc1 -triple aarch64-gnu-linux -x c++ -S -emit-llvm -enable-noundef-analysis %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH +// RUN: %clang -cc1 -triple x86_64-gnu-linux -x c++ -S -emit-llvm -fsanitize-memory-param-retval %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-INTEL +// RUN: %clang -cc1 -triple aarch64-gnu-linux -x c++ -S -emit-llvm -fsanitize-memory-param-retval %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH //************ Passing structs by value // TODO: No structs may currently be marked noundef diff --git a/clang/test/CodeGen/indirect-noundef.cpp b/clang/test/CodeGen/indirect-noundef.cpp --- a/clang/test/CodeGen/indirect-noundef.cpp +++ b/clang/test/CodeGen/indirect-noundef.cpp @@ -1,4 +1,5 @@ // RUN: %clang -cc1 -x c++ -triple x86_64-unknown-unknown -O0 -emit-llvm -enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang -cc1 -x c++ -triple x86_64-unknown-unknown -O0 -emit-llvm -fsanitize-memory-param-retval -o - %s | FileCheck %s union u1 { int val;