jcai19 created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Add -ftrivial-auto-var-init-stop-after= to limit the number of times stack variables are initialized when -ftrivial-auto-var-init= is used to initialize stack variables to zero or a pattern. This flag can be used to bisect uninitialized uses of a stack variable exposed by automatic variable initialization, such as http://crrev.com/c/2020401. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77168 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGDecl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3273,6 +3273,11 @@ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init_stop_after)) { + unsigned Val = (unsigned)std::stoi(A->getValue()); + Opts.TrivialAutoVarInitStopAfter = Val; + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3088,6 +3088,13 @@ CmdArgs.push_back( Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit)); } + + if (Arg *A = Args.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after)) { + A->claim(); + StringRef Val = A->getValue(); + CmdArgs.push_back( + Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val)); + } } static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs) { Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -1809,6 +1809,19 @@ LangOptions::TrivialAutoVarInitKind::Uninitialized) return; + unsigned StopAfter = getContext().getLangOpts().TrivialAutoVarInitStopAfter; + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) + return; + if (Counter++ == StopAfter - 1) { + const DeclContext * CD = D.getParentFunctionOrMethod (); + std::string FunctionName = (cast<FunctionDecl>(CD))->getNameInfo().getAsString(); + StringRef SourceFileName = CGM.getModule().getSourceFileName(); + llvm::errs() << "The last variable initialized is " << D.getName() << " of function " << FunctionName << " in " << SourceFileName << "\n"; + } + } + // Only initialize a __block's storage: we always initialize the header. if (emission.IsEscapingByRef && !locIsByrefHeader) Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1799,6 +1799,8 @@ def enable_trivial_var_init_zero : Flag<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">, Flags<[CC1Option, CoreOption]>, HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">; +def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-stop-after=">, Group<f_Group>, + Flags<[CC1Option, CoreOption]>, HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">; def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CoreOption]>, HelpText<"Emit full debug info for all types used by the program">; def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CoreOption]>, Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -293,6 +293,8 @@ "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, "trivial automatic variable initialization") +VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0, + "stop trivial automatic variable initialization after the specified number of instances") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling")
Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3273,6 +3273,11 @@ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init_stop_after)) { + unsigned Val = (unsigned)std::stoi(A->getValue()); + Opts.TrivialAutoVarInitStopAfter = Val; + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3088,6 +3088,13 @@ CmdArgs.push_back( Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit)); } + + if (Arg *A = Args.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after)) { + A->claim(); + StringRef Val = A->getValue(); + CmdArgs.push_back( + Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val)); + } } static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs) { Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -1809,6 +1809,19 @@ LangOptions::TrivialAutoVarInitKind::Uninitialized) return; + unsigned StopAfter = getContext().getLangOpts().TrivialAutoVarInitStopAfter; + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) + return; + if (Counter++ == StopAfter - 1) { + const DeclContext * CD = D.getParentFunctionOrMethod (); + std::string FunctionName = (cast<FunctionDecl>(CD))->getNameInfo().getAsString(); + StringRef SourceFileName = CGM.getModule().getSourceFileName(); + llvm::errs() << "The last variable initialized is " << D.getName() << " of function " << FunctionName << " in " << SourceFileName << "\n"; + } + } + // Only initialize a __block's storage: we always initialize the header. if (emission.IsEscapingByRef && !locIsByrefHeader) Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1799,6 +1799,8 @@ def enable_trivial_var_init_zero : Flag<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">, Flags<[CC1Option, CoreOption]>, HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">; +def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-stop-after=">, Group<f_Group>, + Flags<[CC1Option, CoreOption]>, HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">; def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CoreOption]>, HelpText<"Emit full debug info for all types used by the program">; def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CoreOption]>, Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -293,6 +293,8 @@ "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, "trivial automatic variable initialization") +VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0, + "stop trivial automatic variable initialization after the specified number of instances") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits