@@ -65,78 +65,9 @@ bool RemoveItypes;
65
65
bool ForceItypes;
66
66
#endif
67
67
68
- static ClangTool *GlobalCTool = nullptr ;
69
-
70
68
static CompilationDatabase *CurrCompDB = nullptr ;
71
69
static tooling::CommandLineArguments SourceFiles;
72
70
73
- template <typename T, typename V>
74
- class GenericAction : public ASTFrontendAction {
75
- public:
76
- GenericAction (V &I) : Info(I) {}
77
-
78
- virtual std::unique_ptr<ASTConsumer>
79
- CreateASTConsumer (CompilerInstance &Compiler, StringRef InFile) {
80
- return std::unique_ptr<ASTConsumer>(new T (Info, &Compiler.getASTContext ()));
81
- }
82
-
83
- private:
84
- V &Info;
85
- };
86
-
87
- template <typename T, typename V>
88
- class RewriteAction : public ASTFrontendAction {
89
- public:
90
- RewriteAction (V &I) : Info(I) {}
91
-
92
- virtual std::unique_ptr<ASTConsumer>
93
- CreateASTConsumer (CompilerInstance &Compiler, StringRef InFile) {
94
- return std::unique_ptr<ASTConsumer>(new T (Info));
95
- }
96
-
97
- private:
98
- V &Info;
99
- };
100
-
101
- template <typename T>
102
- std::unique_ptr<FrontendActionFactory>
103
- newFrontendActionFactoryA (ProgramInfo &I, bool VerifyTheseDiagnostics = false ) {
104
- class ArgFrontendActionFactory : public FrontendActionFactory {
105
- public:
106
- explicit ArgFrontendActionFactory (ProgramInfo &I,
107
- bool VerifyTheseDiagnostics)
108
- : Info(I), VerifyTheseDiagnostics(VerifyTheseDiagnostics) {}
109
-
110
- std::unique_ptr<FrontendAction> create () override {
111
- return std::unique_ptr<FrontendAction>(new T (Info));
112
- }
113
-
114
- bool runInvocation (std::shared_ptr<CompilerInvocation> Invocation,
115
- FileManager *Files,
116
- std::shared_ptr<PCHContainerOperations> PCHContainerOps,
117
- DiagnosticConsumer *DiagConsumer) override {
118
- if (VerifyTheseDiagnostics) {
119
- // Mirroring the logic of clang::ParseDiagnosticArgs in
120
- // clang/lib/Frontend/CompilerInvocation.cpp. In particular, note that
121
- // VerifyPrefixes is assumed to be sorted, in case we add more in the
122
- // future.
123
- DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts ();
124
- DiagOpts.VerifyDiagnostics = true ;
125
- DiagOpts.VerifyPrefixes .push_back (" expected" );
126
- }
127
- return FrontendActionFactory::runInvocation (
128
- Invocation, Files, PCHContainerOps, DiagConsumer);
129
- }
130
-
131
- private:
132
- ProgramInfo &Info;
133
- bool VerifyTheseDiagnostics;
134
- };
135
-
136
- return std::unique_ptr<FrontendActionFactory>(
137
- new ArgFrontendActionFactory (I, VerifyTheseDiagnostics));
138
- }
139
-
140
71
ArgumentsAdjuster getIgnoreCheckedPointerAdjuster () {
141
72
return [](const CommandLineArguments &Args, StringRef /* unused*/ ) {
142
73
CommandLineArguments AdjustedArgs;
@@ -154,13 +85,16 @@ ArgumentsAdjuster getIgnoreCheckedPointerAdjuster() {
154
85
return AdjustedArgs;
155
86
};
156
87
}
157
-
158
- static ClangTool &getGlobalClangTool () {
159
- if (GlobalCTool == nullptr ) {
160
- GlobalCTool = new ClangTool (*CurrCompDB, SourceFiles);
161
- GlobalCTool->appendArgumentsAdjuster (getIgnoreCheckedPointerAdjuster ());
162
- }
163
- return *GlobalCTool;
88
+ ArgumentsAdjuster addVerifyAdjuster () {
89
+ return [](const CommandLineArguments &Args, StringRef /* unused*/ ) {
90
+ CommandLineArguments AdjustedArgs (Args);
91
+ if (std::find (AdjustedArgs.begin (),AdjustedArgs.end ()," -verify" )
92
+ == AdjustedArgs.end ()) {
93
+ AdjustedArgs.push_back (" -Xclang" );
94
+ AdjustedArgs.push_back (" -verify" );
95
+ }
96
+ return AdjustedArgs;
97
+ };
164
98
}
165
99
166
100
void dumpConstraintOutputJson (const std::string &PostfixStr,
@@ -347,42 +281,53 @@ _3CInterface::_3CInterface(const struct _3COptions &CCopt,
347
281
GlobalProgramInfo.getPerfStats ().startTotalTime ();
348
282
}
349
283
350
- bool _3CInterface::addVariables () {
284
+ bool _3CInterface::parseASTs () {
351
285
352
286
std::lock_guard<std::mutex> Lock (InterfaceMutex);
353
287
354
- ClangTool &Tool = getGlobalClangTool ();
288
+ auto *Tool = new ClangTool (*CurrCompDB, SourceFiles);
289
+ Tool->appendArgumentsAdjuster (getIgnoreCheckedPointerAdjuster ());
290
+ // TODO: This currently only enables compiler diagnostic verification.
291
+ // see https://github.com/correctcomputation/checkedc-clang/issues/425
292
+ // for status.
293
+ if (VerifyDiagnosticOutput)
294
+ Tool->appendArgumentsAdjuster (addVerifyAdjuster ());
355
295
356
- // 1a. Add Variables.
357
- std::unique_ptr<ToolAction> AdderTool = newFrontendActionFactoryA<
358
- GenericAction<VariableAdderConsumer, ProgramInfo>>(GlobalProgramInfo);
296
+ // load the ASTs
297
+ return !Tool-> buildASTs (ASTs);
298
+ }
359
299
360
- if (AdderTool) {
361
- int ToolExitCode = Tool.run (AdderTool.get ());
362
- if (ToolExitCode != 0 )
363
- return false ;
364
- } else
365
- llvm_unreachable (" No action" );
300
+ bool _3CInterface::addVariables () {
366
301
367
- return true ;
302
+ std::lock_guard<std::mutex> Lock (InterfaceMutex);
303
+
304
+ // 1. Add Variables.
305
+ VariableAdderConsumer VA = VariableAdderConsumer (GlobalProgramInfo, nullptr );
306
+ unsigned int Errs = 0 ;
307
+ for (auto &TU : ASTs) {
308
+ TU->enableSourceFileDiagnostics ();
309
+ VA.HandleTranslationUnit (TU->getASTContext ());
310
+ TU->getDiagnostics ().getClient ()->EndSourceFile ();
311
+ Errs += TU->getDiagnostics ().getClient ()->getNumErrors ();
312
+ }
313
+
314
+ return Errs == 0 ;
368
315
}
369
316
370
317
bool _3CInterface::buildInitialConstraints () {
371
318
372
319
std::lock_guard<std::mutex> Lock (InterfaceMutex);
373
320
374
- ClangTool &Tool = getGlobalClangTool ();
375
-
376
- // 1b. Gather constraints.
377
- std::unique_ptr<ToolAction> ConstraintTool = newFrontendActionFactoryA<
378
- GenericAction<ConstraintBuilderConsumer, ProgramInfo>>(GlobalProgramInfo);
379
-
380
- if (ConstraintTool) {
381
- int ToolExitCode = Tool.run (ConstraintTool.get ());
382
- if (ToolExitCode != 0 )
383
- return false ;
384
- } else
385
- llvm_unreachable (" No action" );
321
+ // 2. Gather constraints.
322
+ ConstraintBuilderConsumer CB = ConstraintBuilderConsumer (GlobalProgramInfo, nullptr );
323
+ unsigned int Errs = 0 ;
324
+ for (auto &TU : ASTs) {
325
+ TU->enableSourceFileDiagnostics ();
326
+ CB.HandleTranslationUnit (TU->getASTContext ());
327
+ TU->getDiagnostics ().getClient ()->EndSourceFile ();
328
+ Errs += TU->getDiagnostics ().getClient ()->getNumErrors ();
329
+ }
330
+ if (Errs > 0 ) return false ;
386
331
387
332
if (!GlobalProgramInfo.link ()) {
388
333
errs () << " Linking failed!\n " ;
@@ -398,7 +343,7 @@ bool _3CInterface::solveConstraints() {
398
343
std::lock_guard<std::mutex> Lock (InterfaceMutex);
399
344
assert (ConstraintsBuilt && " Constraints not yet built. We need to call "
400
345
" build constraint before trying to solve them." );
401
- // 2 . Solve constraints.
346
+ // 3 . Solve constraints.
402
347
if (Verbose)
403
348
errs () << " Solving constraints\n " ;
404
349
@@ -420,7 +365,6 @@ bool _3CInterface::solveConstraints() {
420
365
if (DumpIntermediate)
421
366
dumpConstraintOutputJson (FINAL_OUTPUT_SUFFIX, GlobalProgramInfo);
422
367
423
- ClangTool &Tool = getGlobalClangTool ();
424
368
if (AllTypes) {
425
369
if (DebugArrSolver)
426
370
GlobalProgramInfo.getABoundsInfo ().dumpAVarGraph (
@@ -430,31 +374,32 @@ bool _3CInterface::solveConstraints() {
430
374
// bounds declarations.
431
375
GlobalProgramInfo.getABoundsInfo ().performFlowAnalysis (&GlobalProgramInfo);
432
376
433
- // 3 . Infer the bounds based on calls to malloc and calloc
434
- std::unique_ptr<ToolAction> ABInfTool = newFrontendActionFactoryA<
435
- GenericAction<AllocBasedBoundsInference, ProgramInfo>>(
436
- GlobalProgramInfo);
437
- if (ABInfTool) {
438
- int ToolExitCode = Tool. run (ABInfTool. get ());
439
- if (ToolExitCode != 0 )
440
- return false ;
441
- } else
442
- llvm_unreachable ( " No Action " ) ;
377
+ // 4 . Infer the bounds based on calls to malloc and calloc
378
+ AllocBasedBoundsInference ABBI = AllocBasedBoundsInference (GlobalProgramInfo, nullptr );
379
+ unsigned int Errs = 0 ;
380
+ for ( auto &TU : ASTs) {
381
+ TU-> enableSourceFileDiagnostics ();
382
+ ABBI. HandleTranslationUnit (TU-> getASTContext ());
383
+ TU-> getDiagnostics (). getClient ()-> EndSourceFile ();
384
+ Errs += TU-> getDiagnostics (). getClient ()-> getNumErrors () ;
385
+ }
386
+ if (Errs > 0 ) return false ;
443
387
444
388
// Propagate the information from allocator bounds.
445
389
GlobalProgramInfo.getABoundsInfo ().performFlowAnalysis (&GlobalProgramInfo);
446
390
}
447
391
448
- // 4 . Run intermediate tool hook to run visitors that need to be executed
392
+ // 5 . Run intermediate tool hook to run visitors that need to be executed
449
393
// after constraint solving but before rewriting.
450
- std::unique_ptr<ToolAction> IMTool = newFrontendActionFactoryA<
451
- GenericAction<IntermediateToolHook, ProgramInfo>>(GlobalProgramInfo);
452
- if (IMTool) {
453
- int ToolExitCode = Tool.run (IMTool.get ());
454
- if (ToolExitCode != 0 )
455
- return false ;
456
- } else
457
- llvm_unreachable (" No Action" );
394
+ IntermediateToolHook ITH = IntermediateToolHook (GlobalProgramInfo, nullptr );
395
+ unsigned int Errs = 0 ;
396
+ for (auto &TU : ASTs) {
397
+ TU->enableSourceFileDiagnostics ();
398
+ ITH.HandleTranslationUnit (TU->getASTContext ());
399
+ TU->getDiagnostics ().getClient ()->EndSourceFile ();
400
+ Errs += TU->getDiagnostics ().getClient ()->getNumErrors ();
401
+ }
402
+ if (Errs > 0 ) return false ;
458
403
459
404
if (AllTypes) {
460
405
// Propagate data-flow information for Array pointers.
@@ -497,48 +442,19 @@ bool _3CInterface::solveConstraints() {
497
442
return true ;
498
443
}
499
444
500
- bool _3CInterface::writeConvertedFileToDisk (const std::string &FilePath) {
501
- std::lock_guard<std::mutex> Lock (InterfaceMutex);
502
- bool RetVal = false ;
503
- if (std::find (SourceFiles.begin (), SourceFiles.end (), FilePath) !=
504
- SourceFiles.end ()) {
505
- RetVal = true ;
506
- std::vector<std::string> SourceFiles;
507
- SourceFiles.clear ();
508
- SourceFiles.push_back (FilePath);
509
- // Don't use global tool. Create a new tool for give single file.
510
- ClangTool Tool (*CurrCompDB, SourceFiles);
511
- Tool.appendArgumentsAdjuster (getIgnoreCheckedPointerAdjuster ());
512
- std::unique_ptr<ToolAction> RewriteTool =
513
- newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
514
- GlobalProgramInfo, VerifyDiagnosticOutput);
515
-
516
- if (RewriteTool) {
517
- int ToolExitCode = Tool.run (RewriteTool.get ());
518
- if (ToolExitCode != 0 )
519
- RetVal = false ;
520
- }
521
- }
522
- GlobalProgramInfo.getPerfStats ().endTotalTime ();
523
- GlobalProgramInfo.getPerfStats ().startTotalTime ();
524
- return RetVal;
525
- }
526
-
527
445
bool _3CInterface::writeAllConvertedFilesToDisk () {
528
446
std::lock_guard<std::mutex> Lock (InterfaceMutex);
529
447
530
- ClangTool &Tool = getGlobalClangTool ();
531
-
532
- // Rewrite the input files.
533
- std::unique_ptr<ToolAction> RewriteTool =
534
- newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
535
- GlobalProgramInfo, VerifyDiagnosticOutput);
536
- if (RewriteTool) {
537
- int ToolExitCode = Tool.run (RewriteTool.get ());
538
- if (ToolExitCode != 0 )
539
- return false ;
540
- } else
541
- llvm_unreachable (" No action" );
448
+ // 6. Rewrite the input files.
449
+ RewriteConsumer RC = RewriteConsumer (GlobalProgramInfo);
450
+ unsigned int Errs = 0 ;
451
+ for (auto &TU : ASTs) {
452
+ TU->enableSourceFileDiagnostics ();
453
+ RC.HandleTranslationUnit (TU->getASTContext ());
454
+ TU->getDiagnostics ().getClient ()->EndSourceFile ();
455
+ Errs += TU->getDiagnostics ().getClient ()->getNumErrors ();
456
+ }
457
+ if (Errs > 0 ) return false ;
542
458
543
459
GlobalProgramInfo.getPerfStats ().endTotalTime ();
544
460
GlobalProgramInfo.getPerfStats ().startTotalTime ();
0 commit comments