A static analysis is an algorithm that checks (or calculates) invariants of a program based on its syntactic (static) structure, in contrast to a dynamic analysis which observes properties of actual program executions. Static analysis can tell us properties of all possible executions, while dynamic analysis can only observe executions on particular inputs.
A sound static analysis is one with a proof that any invariants checked by the analysis will actually hold on all executions. A foundationally sound analysis is one where the soundness proof is (ideally) machine-checked, (ideally) with respect to the machine-language instruction-set architecture specification—not the source language—and (ideally) with no axioms other than the foundations of logic and the ISA specification.
Some of the first foundationally sound static analyses were proof-carrying code systems of the early 21st century [5, 45, 35, 3]. It was considered impractical (at that time) to prove the correctness of compilers, so these proof-carrying systems transformed source-language typechecking (or Hoare logic [14]) phase by phase through the compilation, into an assembly-language Hoare logic.
With the existence of foundationally correct compilers such as CompCert, instead of proof-carrying code we can prove the soundness of a static analysis from the source-language semantics, and compose that proof with the compiler-correctness proof. See for example the value analysis using abstract interpretation by Blazy et al. [22]
Some kinds of static analysis may be easier to prove sound with respect to a program logic than directly from the operational semantics.