@@ -54,6 +54,7 @@ bool DisableCCTypeChecker;
5454bool WarnRootCause;
5555bool WarnAllRootCause;
5656std::set<std::string> FilePaths;
57+ bool VerifyDiagnosticOutput;
5758
5859#ifdef FIVE_C
5960bool RemoveItypes;
@@ -95,19 +96,39 @@ class RewriteAction : public ASTFrontendAction {
9596
9697template <typename T>
9798std::unique_ptr<FrontendActionFactory>
98- newFrontendActionFactoryA (ProgramInfo &I) {
99+ newFrontendActionFactoryA (ProgramInfo &I, bool VerifyTheseDiagnostics = false ) {
99100 class ArgFrontendActionFactory : public FrontendActionFactory {
100101 public:
101- explicit ArgFrontendActionFactory (ProgramInfo &I) : Info(I) {}
102+ explicit ArgFrontendActionFactory (ProgramInfo &I,
103+ bool VerifyTheseDiagnostics)
104+ : Info(I), VerifyTheseDiagnostics(VerifyTheseDiagnostics) {}
102105
103106 FrontendAction *create () override { return new T (Info); }
104107
108+ bool runInvocation (std::shared_ptr<CompilerInvocation> Invocation,
109+ FileManager *Files,
110+ std::shared_ptr<PCHContainerOperations> PCHContainerOps,
111+ DiagnosticConsumer *DiagConsumer) override {
112+ if (VerifyTheseDiagnostics) {
113+ // Mirroring the logic of clang::ParseDiagnosticArgs in
114+ // clang/lib/Frontend/CompilerInvocation.cpp. In particular, note that
115+ // VerifyPrefixes is assumed to be sorted, in case we add more in the
116+ // future.
117+ DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts ();
118+ DiagOpts.VerifyDiagnostics = true ;
119+ DiagOpts.VerifyPrefixes .push_back (" expected" );
120+ }
121+ return FrontendActionFactory::runInvocation (
122+ Invocation, Files, PCHContainerOps, DiagConsumer);
123+ }
124+
105125 private:
106126 ProgramInfo &Info;
127+ bool VerifyTheseDiagnostics;
107128 };
108129
109130 return std::unique_ptr<FrontendActionFactory>(
110- new ArgFrontendActionFactory (I));
131+ new ArgFrontendActionFactory (I, VerifyTheseDiagnostics ));
111132}
112133
113134ArgumentsAdjuster getIgnoreCheckedPointerAdjuster () {
@@ -192,6 +213,7 @@ _3CInterface::_3CInterface(const struct _3COptions &CCopt,
192213 AllocatorFunctions = CCopt.AllocatorFunctions ;
193214 WarnRootCause = CCopt.WarnRootCause || CCopt.WarnAllRootCause ;
194215 WarnAllRootCause = CCopt.WarnAllRootCause ;
216+ VerifyDiagnosticOutput = CCopt.VerifyDiagnosticOutput ;
195217
196218#ifdef FIVE_C
197219 RemoveItypes = CCopt.RemoveItypes ;
@@ -246,9 +268,11 @@ bool _3CInterface::buildInitialConstraints() {
246268 std::unique_ptr<ToolAction> ConstraintTool = newFrontendActionFactoryA<
247269 GenericAction<ConstraintBuilderConsumer, ProgramInfo>>(GlobalProgramInfo);
248270
249- if (ConstraintTool)
250- Tool.run (ConstraintTool.get ());
251- else
271+ if (ConstraintTool) {
272+ int ToolExitCode = Tool.run (ConstraintTool.get ());
273+ if (ToolExitCode != 0 )
274+ return false ;
275+ } else
252276 llvm_unreachable (" No action" );
253277
254278 if (!GlobalProgramInfo.link ()) {
@@ -297,9 +321,11 @@ bool _3CInterface::solveConstraints(bool ComputeInterimState) {
297321 std::unique_ptr<ToolAction> ABInfTool = newFrontendActionFactoryA<
298322 GenericAction<AllocBasedBoundsInference, ProgramInfo>>(
299323 GlobalProgramInfo);
300- if (ABInfTool)
301- Tool.run (ABInfTool.get ());
302- else
324+ if (ABInfTool) {
325+ int ToolExitCode = Tool.run (ABInfTool.get ());
326+ if (ToolExitCode != 0 )
327+ return false ;
328+ } else
303329 llvm_unreachable (" No Action" );
304330
305331 // Propagate the information from allocator bounds.
@@ -310,9 +336,11 @@ bool _3CInterface::solveConstraints(bool ComputeInterimState) {
310336 // after constraint solving but before rewriting.
311337 std::unique_ptr<ToolAction> IMTool = newFrontendActionFactoryA<
312338 GenericAction<IntermediateToolHook, ProgramInfo>>(GlobalProgramInfo);
313- if (IMTool)
314- Tool.run (IMTool.get ());
315- else
339+ if (IMTool) {
340+ int ToolExitCode = Tool.run (IMTool.get ());
341+ if (ToolExitCode != 0 )
342+ return false ;
343+ } else
316344 llvm_unreachable (" No Action" );
317345
318346 if (AllTypes) {
@@ -362,10 +390,13 @@ bool _3CInterface::writeConvertedFileToDisk(const std::string &FilePath) {
362390 Tool.appendArgumentsAdjuster (getIgnoreCheckedPointerAdjuster ());
363391 std::unique_ptr<ToolAction> RewriteTool =
364392 newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
365- GlobalProgramInfo);
393+ GlobalProgramInfo, VerifyDiagnosticOutput );
366394
367- if (RewriteTool)
368- Tool.run (RewriteTool.get ());
395+ if (RewriteTool) {
396+ int ToolExitCode = Tool.run (RewriteTool.get ());
397+ if (ToolExitCode != 0 )
398+ return false ;
399+ }
369400 return true ;
370401 }
371402 return false ;
@@ -379,10 +410,12 @@ bool _3CInterface::writeAllConvertedFilesToDisk() {
379410 // Rewrite the input files
380411 std::unique_ptr<ToolAction> RewriteTool =
381412 newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
382- GlobalProgramInfo);
383- if (RewriteTool)
384- Tool.run (RewriteTool.get ());
385- else
413+ GlobalProgramInfo, VerifyDiagnosticOutput);
414+ if (RewriteTool) {
415+ int ToolExitCode = Tool.run (RewriteTool.get ());
416+ if (ToolExitCode != 0 )
417+ return false ;
418+ } else
386419 llvm_unreachable (" No action" );
387420
388421 return true ;
0 commit comments