forked from OSchip/llvm-project
Re-land "[Clang][Driver] Remove -M group options ..." and "[Clang] Avoid crashing when generating crash diagnostics when '#pragma clang __debug ..."
This re-lands commitsf41ec709d9
(https://reviews.llvm.org/D74076) and commit5fedc2b410
(https://reviews.llvm.org/D74070) The previous build break was caused by '#pragma clang __debug llvm_unreachable' used in a non-assert build. Move it to a separate test in crash-report-with-asserts.c.
This commit is contained in:
parent
ea9166b5a8
commit
75f09b5442
|
@ -866,6 +866,8 @@ def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">
|
|||
HelpText<"include a detailed record of preprocessing actions">;
|
||||
def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">,
|
||||
HelpText<"Set up preprocessor for static analyzer (done automatically when static analyzer is run).">;
|
||||
def disable_pragma_debug_crash : Flag<["-"], "disable-pragma-debug-crash">,
|
||||
HelpText<"Disable any #pragma clang __debug that can lead to crashing behavior. This is meant for testing.">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OpenCL Options
|
||||
|
|
|
@ -189,6 +189,9 @@ public:
|
|||
/// Set up preprocessor for RunAnalysis action.
|
||||
bool SetUpStaticAnalyzer = false;
|
||||
|
||||
/// Prevents intended crashes when using #pragma clang __debug. For testing.
|
||||
bool DisablePragmaDebugCrash = false;
|
||||
|
||||
public:
|
||||
PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
|
||||
|
||||
|
|
|
@ -258,14 +258,23 @@ void Compilation::initCompilationForDiagnostics() {
|
|||
|
||||
// Remove any user specified output. Claim any unclaimed arguments, so as
|
||||
// to avoid emitting warnings about unused args.
|
||||
OptSpecifier OutputOpts[] = { options::OPT_o, options::OPT_MD,
|
||||
options::OPT_MMD };
|
||||
OptSpecifier OutputOpts[] = {
|
||||
options::OPT_o, options::OPT_MD, options::OPT_MMD, options::OPT_M,
|
||||
options::OPT_MM, options::OPT_MF, options::OPT_MG, options::OPT_MJ,
|
||||
options::OPT_MQ, options::OPT_MT, options::OPT_MV};
|
||||
for (unsigned i = 0, e = llvm::array_lengthof(OutputOpts); i != e; ++i) {
|
||||
if (TranslatedArgs->hasArg(OutputOpts[i]))
|
||||
TranslatedArgs->eraseArg(OutputOpts[i]);
|
||||
}
|
||||
TranslatedArgs->ClaimAllArgs();
|
||||
|
||||
// Force re-creation of the toolchain Args, otherwise our modifications just
|
||||
// above will have no effect.
|
||||
for (auto Arg : TCArgs)
|
||||
if (Arg.second != TranslatedArgs)
|
||||
delete Arg.second;
|
||||
TCArgs.clear();
|
||||
|
||||
// Redirect stdout/stderr to /dev/null.
|
||||
Redirects = {None, {""}, {""}};
|
||||
|
||||
|
|
|
@ -4750,6 +4750,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
: "-");
|
||||
}
|
||||
|
||||
// Give the gen diagnostics more chances to succeed, by avoiding intentional
|
||||
// crashes.
|
||||
if (D.CCGenDiagnostics)
|
||||
CmdArgs.push_back("-disable-pragma-debug-crash");
|
||||
|
||||
bool UseSeparateSections = isUseSeparateSections(Triple);
|
||||
|
||||
if (Args.hasFlag(options::OPT_ffunction_sections,
|
||||
|
|
|
@ -3471,6 +3471,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
|||
Opts.LexEditorPlaceholders = false;
|
||||
|
||||
Opts.SetUpStaticAnalyzer = Args.hasArg(OPT_setup_static_analyzer);
|
||||
Opts.DisablePragmaDebugCrash = Args.hasArg(OPT_disable_pragma_debug_crash);
|
||||
}
|
||||
|
||||
static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "clang/Lex/PPCallbacks.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Lex/PreprocessorLexer.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "clang/Lex/Token.h"
|
||||
#include "clang/Lex/TokenLexer.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
@ -1034,15 +1035,19 @@ struct PragmaDebugHandler : public PragmaHandler {
|
|||
IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
|
||||
if (II->isStr("assert")) {
|
||||
llvm_unreachable("This is an assertion!");
|
||||
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
|
||||
llvm_unreachable("This is an assertion!");
|
||||
} else if (II->isStr("crash")) {
|
||||
LLVM_BUILTIN_TRAP;
|
||||
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
|
||||
LLVM_BUILTIN_TRAP;
|
||||
} else if (II->isStr("parser_crash")) {
|
||||
Token Crasher;
|
||||
Crasher.startToken();
|
||||
Crasher.setKind(tok::annot_pragma_parser_crash);
|
||||
Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
|
||||
PP.EnterToken(Crasher, /*IsReinject*/false);
|
||||
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) {
|
||||
Token Crasher;
|
||||
Crasher.startToken();
|
||||
Crasher.setKind(tok::annot_pragma_parser_crash);
|
||||
Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
|
||||
PP.EnterToken(Crasher, /*IsReinject*/ false);
|
||||
}
|
||||
} else if (II->isStr("dump")) {
|
||||
Token Identifier;
|
||||
PP.LexUnexpandedToken(Identifier);
|
||||
|
@ -1074,9 +1079,11 @@ struct PragmaDebugHandler : public PragmaHandler {
|
|||
<< II->getName();
|
||||
}
|
||||
} else if (II->isStr("llvm_fatal_error")) {
|
||||
llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
|
||||
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
|
||||
llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
|
||||
} else if (II->isStr("llvm_unreachable")) {
|
||||
llvm_unreachable("#pragma clang __debug llvm_unreachable");
|
||||
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
|
||||
llvm_unreachable("#pragma clang __debug llvm_unreachable");
|
||||
} else if (II->isStr("macro")) {
|
||||
Token MacroName;
|
||||
PP.LexUnexpandedToken(MacroName);
|
||||
|
@ -1103,7 +1110,8 @@ struct PragmaDebugHandler : public PragmaHandler {
|
|||
}
|
||||
M->dump();
|
||||
} else if (II->isStr("overflow_stack")) {
|
||||
DebugOverflowStack();
|
||||
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
|
||||
DebugOverflowStack();
|
||||
} else if (II->isStr("captured")) {
|
||||
HandleCaptured(PP);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: mkdir %t
|
||||
|
||||
// RUN: echo '-fsyntax-only \
|
||||
// RUN: -F/tmp/ -I /tmp/ -idirafter /tmp/ -iquote /tmp/ -isystem /tmp/ \
|
||||
// RUN: -iprefix /the/prefix -iwithprefix /tmp -iwithprefixbefore /tmp/ \
|
||||
// RUN: -Xclang -internal-isystem -Xclang /tmp/ \
|
||||
// RUN: -Xclang -internal-externc-isystem -Xclang /tmp/ \
|
||||
// RUN: -Xclang -main-file-name -Xclang foo.c \
|
||||
// RUN: -DFOO=BAR -DBAR="BAZ QUX"' > %t.rsp
|
||||
|
||||
// RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \
|
||||
// RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \
|
||||
// RUN: not %clang %s @%t.rsp -DASSERT 2>&1 | FileCheck %s
|
||||
// RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s
|
||||
// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s
|
||||
|
||||
// RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \
|
||||
// RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \
|
||||
// RUN: not %clang %s @%t.rsp -DUNREACHABLE 2>&1 | FileCheck %s
|
||||
// RUN: cat %t/crash-report-with-asserts-*.c | FileCheck --check-prefix=CHECKSRC %s
|
||||
// RUN: cat %t/crash-report-with-asserts-*.sh | FileCheck --check-prefix=CHECKSH %s
|
||||
|
||||
// REQUIRES: crash-recovery, asserts
|
||||
|
||||
#ifdef ASSERT
|
||||
#pragma clang __debug assert
|
||||
#elif UNREACHABLE
|
||||
#pragma clang __debug llvm_unreachable
|
||||
#endif
|
||||
|
||||
// CHECK: Preprocessed source(s) and associated run script(s) are located at:
|
||||
// CHECK-NEXT: note: diagnostic msg: {{.*}}crash-report-with-asserts-{{.*}}.c
|
||||
FOO
|
||||
// CHECKSRC: FOO
|
||||
// CHECKSH: # Crash reproducer
|
||||
// CHECKSH-NEXT: # Driver args: {{.*}}"-fsyntax-only"
|
||||
// CHECKSH-SAME: "-D" "FOO=BAR"
|
||||
// CHECKSH-SAME: "-D" "BAR=BAZ QUX"
|
||||
// CHECKSH-NEXT: # Original command: {{.*$}}
|
||||
// CHECKSH-NEXT: "-cc1"
|
||||
// CHECKSH: "-main-file-name" "crash-report-with-asserts.c"
|
||||
// CHECKSH-NOT: "-header-include-file"
|
||||
// CHECKSH-NOT: "-diagnostic-log-file"
|
||||
// CHECKSH: "-D" "FOO=BAR"
|
||||
// CHECKSH: "-D" "BAR=BAZ QUX"
|
||||
// CHECKSH-NOT: "-F/tmp/"
|
||||
// CHECKSH-NOT: "-I" "/tmp/"
|
||||
// CHECKSH-NOT: "-idirafter" "/tmp/"
|
||||
// CHECKSH-NOT: "-iquote" "/tmp/"
|
||||
// CHECKSH-NOT: "-isystem" "/tmp/"
|
||||
// CHECKSH-NOT: "-iprefix" "/the/prefix"
|
||||
// CHECKSH-NOT: "-iwithprefix" "/tmp/"
|
||||
// CHECKSH-NOT: "-iwithprefixbefore" "/tmp/"
|
||||
// CHECKSH-NOT: "-internal-isystem" "/tmp/"
|
||||
// CHECKSH-NOT: "-internal-externc-isystem" "/tmp/"
|
||||
// CHECKSH-NOT: "-dwarf-debug-flags"
|
||||
// CHECKSH: "crash-report-with-asserts-{{[^ ]*}}.c"
|
|
@ -1,25 +1,40 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: mkdir %t
|
||||
// RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \
|
||||
// RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \
|
||||
// RUN: not %clang -fsyntax-only %s \
|
||||
|
||||
// RUN: echo '-fsyntax-only \
|
||||
// RUN: -F/tmp/ -I /tmp/ -idirafter /tmp/ -iquote /tmp/ -isystem /tmp/ \
|
||||
// RUN: -iprefix /the/prefix -iwithprefix /tmp -iwithprefixbefore /tmp/ \
|
||||
// RUN: -Xclang -internal-isystem -Xclang /tmp/ \
|
||||
// RUN: -Xclang -internal-externc-isystem -Xclang /tmp/ \
|
||||
// RUN: -Xclang -main-file-name -Xclang foo.c \
|
||||
// RUN: -DFOO=BAR -DBAR="BAZ QUX" 2>&1 | FileCheck %s
|
||||
// RUN: -DFOO=BAR -DBAR="BAZ QUX"' > %t.rsp
|
||||
|
||||
// RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \
|
||||
// RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \
|
||||
// RUN: not %clang %s @%t.rsp -DPARSER 2>&1 | FileCheck %s
|
||||
// RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s
|
||||
// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s
|
||||
|
||||
// RUN: env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 \
|
||||
// RUN: CC_PRINT_HEADERS=1 CC_LOG_DIAGNOSTICS=1 \
|
||||
// RUN: not %clang %s @%t.rsp -DCRASH 2>&1 | FileCheck %s
|
||||
// RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s
|
||||
// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s
|
||||
|
||||
// REQUIRES: crash-recovery
|
||||
|
||||
#ifdef PARSER
|
||||
#pragma clang __debug parser_crash
|
||||
#elif CRASH
|
||||
#pragma clang __debug crash
|
||||
#endif
|
||||
|
||||
// CHECK: Preprocessed source(s) and associated run script(s) are located at:
|
||||
// CHECK-NEXT: note: diagnostic msg: {{.*}}crash-report-{{.*}}.c
|
||||
FOO
|
||||
// CHECKSRC: FOO
|
||||
// CHECKSH: # Crash reproducer
|
||||
// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
|
||||
// CHECKSH-NEXT: # Driver args: {{.*}}"-fsyntax-only"
|
||||
// CHECKSH-SAME: "-D" "FOO=BAR"
|
||||
// CHECKSH-SAME: "-D" "BAR=BAZ QUX"
|
||||
// CHECKSH-NEXT: # Original command: {{.*$}}
|
||||
|
|
Loading…
Reference in New Issue