1. A method comprising: by one or more computing devices, compiling a C++ program having one or more input variables to obtain bytecode of the C++ program; compiling a C++ library to obtain bytecode of the C++ library; symbolically executing the bytecode of the C++ program and the bytecode of the C++ library, comprising: assigning a symbolic input to each input variable of the C++ program; determining one or more execution paths in the C++ program; and for each execution path, constructing a symbolic expression that if satisfied, causes the C++ program to proceed down the execution path; and generating one or more test cases for the C++ program by solving the symbolic expressions.