1import lit.formats 2import lit.TestRunner 3 4# Custom format class for static analyzer tests 5class AnalyzerTest(lit.formats.ShTest): 6 def __init__(self, execute_external, use_z3_solver=False): 7 super(AnalyzerTest, self).__init__(execute_external) 8 self.use_z3_solver = use_z3_solver 9 10 def execute(self, test, litConfig): 11 results = [] 12 13 # Parse any test requirements ('REQUIRES: ') 14 saved_test = test 15 lit.TestRunner.parseIntegratedTestScript(test) 16 17 if "z3" not in test.requires: 18 results.append( 19 self.executeWithAnalyzeSubstitution( 20 saved_test, litConfig, "-analyzer-constraints=range" 21 ) 22 ) 23 24 if results[-1].code == lit.Test.FAIL: 25 return results[-1] 26 27 # If z3 backend available, add an additional run line for it 28 if self.use_z3_solver == "1": 29 assert test.config.clang_staticanalyzer_z3 == "1" 30 results.append( 31 self.executeWithAnalyzeSubstitution( 32 saved_test, litConfig, "-analyzer-constraints=z3 -DANALYZER_CM_Z3" 33 ) 34 ) 35 36 # Combine all result outputs into the last element 37 for x in results: 38 if x != results[-1]: 39 results[-1].output = x.output + results[-1].output 40 41 if results: 42 return results[-1] 43 return lit.Test.Result( 44 lit.Test.UNSUPPORTED, "Test requires the following unavailable features: z3" 45 ) 46 47 def executeWithAnalyzeSubstitution(self, test, litConfig, substitution): 48 saved_substitutions = list(test.config.substitutions) 49 test.config.substitutions.append(("%analyze", substitution)) 50 result = lit.TestRunner.executeShTest(test, litConfig, self.execute_external) 51 test.config.substitutions = saved_substitutions 52 53 return result 54