Ejemplo n.º 1
0
    def check_syntax(self, c_file_name):
        """
        Check the "syntax" of the file -- this is an abuse of terminology, since
        `fsyntax-only' performs symbol lookup, i.e., if a declaration is missing,
        an error is thrown.
        """

        cmd = [self.cc, '-fsyntax-only', c_file_name]

        common_opts = [
            '-Werror=incompatible-pointer-types',
            '-Werror=implicit-function-declaration'
        ]
        cmd += common_opts

        by_cc_opts = {
            CCompilerFacade.GCC: '-Werror=builtin-declaration-mismatch',
            CCompilerFacade.Clang: '-Werror=incompatible-library-redeclaration'
        }
        cmd.append(by_cc_opts[self.cc_family])

        cmd += self.original_options()

        return execute(CCompilerFacade.ID(),
                       cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
Ejemplo n.º 2
0
    def generate_constraints(self, unit: Unit, cc_cmd_summary):
        """
        Generate constraints for a unit.
        """

        cmd = [
            PsycheCFacade._GENERATOR, unit.c_file, '-o', unit.cstr_file,
            '--cc', self.cc, '--cc-std', cc_cmd_summary.c_version
        ]

        cmd += CCompilerFacade.defined_macros('--cc-D')
        cmd += CCompilerFacade.undefined_macros('--cc-U')

        cmd += cc_cmd_summary.defined_macros('-cc-D ')
        cmd += cc_cmd_summary.undefined_macros('--cc-U ')
        cmd += cc_cmd_summary.include_paths('--cc-I ')

        maybe_append('--no-typedef', self.no_typedef, cmd)
        maybe_append('--no-heuristic', self.no_heuristic, cmd)

        if not self.no_stdlib:
            cmd.append('-p')
            dir_path = pathlib.Path(__file__).parent.parent.absolute()
            cmd.append(os.path.join(dir_path, 'libpsychecstd'))

        code = execute(PsycheCFacade.ID(), cmd)
        if code != 0:
            sys.exit(
                DiagnosticReporter.fatal(CONSTRAINT_GENERATION_FOR_FILE_FAILED,
                                         unit.c_file,
                                         error=code))
Ejemplo n.º 3
0
    def generate_constraints(self,
                             unit: Unit,
                             cc_opts):
        """
        Generate constraints for a unit.
        """

        cmd = [self.generator,
               unit.c_file_path,
               '-o', unit.cstr_file_path,
               '--cc', self.host_cc,
               '--cc-std', cc_opts.c_version]
        cmd += CCompilerFacade.predefined_macros('--cc-D')
        cmd += CCompilerFacade.undefined_macros('--cc-U')

        maybe_append('--no-typedef', self.no_typedef, cmd)
        maybe_append('--no-heuristic', self.no_heuristic, cmd)

        if not self.no_stdlib:
            cmd.append('-p')
            cmd.append('libpsychecstd')

        ok = execute(PsycheFacade._id, cmd)
        if ok != 0:
            sys.exit(
                DiagnosticReporter.fatal(CONSTRAINT_GENERATION_FOR_FILE_FAILED,
                                         unit.c_file_path))
Ejemplo n.º 4
0
    def execute(self):
        """
        Entry point.
        """

        trace_op(Driver._id, flatten(self.cnip_opt['host_cc_cmd']))

        if not self.cc.is_supported():
            sys.exit(DiagnosticReporter.fatal(HOST_C_COMPILER_NOT_FOUND))

        cc_cmd = self.cc.parse_command()

        if not cc_cmd.out_file_name:
            gen_dir = ''
        else:
            (gen_dir, _) = os.path.split(cc_cmd.out_file_name)
            if gen_dir:
                gen_dir += '/'
            else:
                gen_dir = ''

        # The adjusted command that is forwarded to the host C compiler is the
        # one provided by the user, with input file replaced.
        new_cmd = self.cnip_opt['host_cc_cmd']

        for c_file_path in cc_cmd.sources:
            if not os.path.isfile(c_file_path):
                sys.exit(
                    DiagnosticReporter.fatal(FILE_DOES_NOT_EXIST, c_file_path))

            if self.cc.check_syntax(c_file_path) == 0:
                # If there are missing declarations in the source, this check
                # would've failed. Since it didn't, there's nothing to infer.
                continue

            unit = make_unit(c_file_path, gen_dir)
            self._compile_unit(unit, cc_cmd)

            trace_op(
                Driver._id,
                f'replace {unit.c_file_path} for {unit.cnip_file_path} in command'
            )
            new_cmd = [
                w.replace(unit.c_file_path, unit.cnip_file_path)
                for w in new_cmd
            ]

        cmd = [self.cnip_opt['host_cc'], '-x', 'c'] + new_cmd

        ok = execute(Driver._id, cmd)
        if ok != 0:
            sys.exit(
                DiagnosticReporter.fatal(HOST_C_COMPILER_FORWARDING_FAILED))

        return 0
Ejemplo n.º 5
0
    def preprocess(self, c_file_name, pp_file_name):
        """
        Preprocess the file.
        """

        cmd = [self.host_cc, '-E', '-x', 'c', c_file_name, '-o', pp_file_name]

        cmd += CCompilerFacade.predefined_macros('-D')
        cmd += CCompilerFacade.undefined_macros('-U')

        ok = execute(CCompilerFacade._id, cmd)
        if ok != 0:
            sys.exit(
                DiagnosticReporter.fatal(PREPROCESSING_FILE_FAILED,
                                         c_file_name))
Ejemplo n.º 6
0
    def execute(self):
        """
        Entry point.
        """

        debug(Driver.ID(), flatten(self.cnip_opts['cc_cmd_line']))

        if not self.cc.is_supported():
            sys.exit(DiagnosticReporter.fatal(HOST_C_COMPILER_NOT_FOUND))

        cc_cmd = self.cc.parse_command()

        if not cc_cmd.out_file_name:
            gen_dir = ''
        else:
            (gen_dir, _) = os.path.split(cc_cmd.out_file_name)
            if gen_dir:
                gen_dir += '/'
            else:
                gen_dir = ''

        # The new command that is forwarded to the host C compiler is the
        # original one provided by the user, with the input file replaced.
        new_cmd = self.cnip_opts['cc_cmd_line']

        for c_file in cc_cmd.c_files:
            if not os.path.isfile(c_file):
                sys.exit(DiagnosticReporter.fatal(FILE_DOES_NOT_EXIST, c_file))

            if self.cc.check_syntax(c_file) == 0:
                # If there are missing declarations in the source, this check
                # would've failed. Since it didn't, there's nothing to infer.
                continue

            unit = make_unit(c_file, gen_dir)
            self._compile_unit(unit, cc_cmd)

            debug(Driver.ID(),
                  f'replace {unit.c_file} for {unit.cnip_file} in command')
            new_cmd = [w.replace(unit.c_file, unit.cnip_file) for w in new_cmd]

        cmd = [self.cnip_opts['cc']] + new_cmd
        code = execute(Driver.ID(), cmd)
        if code != 0:
            sys.exit(
                DiagnosticReporter.fatal(HOST_C_COMPILER_FORWARDING_FAILED))

        return 0
Ejemplo n.º 7
0
    def solve_constraints(self, unit: Unit):
        """
        Solve the constraint.
        """

        cmd = [
            PsycheCFacade._SOLVER, '--', '-i', unit.cstr_file, '-o',
            unit.cnip_file
        ]

        if not self.no_stdlib:
            cmd.append('--match-stdlib=approx')

        ok = execute(PsycheCFacade.ID(), cmd)
        if ok != 0:
            sys.exit(
                DiagnosticReporter.fatal(CONSTRAINT_SOLVING_FOR_FILE_FAILED,
                                         unit.c_file))
Ejemplo n.º 8
0
    def preprocess(self, c_file_name, pp_file_name):
        """
        Preprocess the file.
        """

        cmd = [self.cc,
               '-E',
               '-x',
               'c',
               c_file_name,
               '-o',
               pp_file_name]

        cmd += CCompilerFacade.defined_macros('-D')
        cmd += CCompilerFacade.undefined_macros('-U')

        cmd += self.original_options()

        code = execute(CCompilerFacade.ID(), cmd)
        if code != 0:
            sys.exit(
                DiagnosticReporter.fatal(PREPROCESSING_FILE_FAILED,
                                         c_file_name))