They fall back onto FAA Location IDs. Now, the FAA Location IDs did copy IATA codes.
Basically, all airports in the US get an FAA LID, which will then become the ICAO code.
My guess is that the decision to make the FAA LIDs the same as the IATAs serve to make things much easier.
Meanwhile, look at Europe, and you have much more confusing codes for the layman. Berlin Tegel has the IATA code TXL, but the ICAO is EDDT. Schönefeld/Berlin-Brandenburg has the IATA of SXF (BER when the new airport opens), but will have the ICAO of EDDB.
Compare that to Canada, and they went nuts with their codes. Toronto Pearson has YYZ for the IATA code, but CYYZ is their ICAO. But with Canada, they gave every airport a code which was Y-- or Z--. Those codes were issued by the TCCA, but they got those codes to double as both IATA and ICAO codes.
Understanding why ICAO codes are the way they are is often confusing, and the inconsistent manner in which they are used just makes things harder overall. You have the US, where the 3 letter FAA LID and IATA are relevant to the location name. ICAO just adds the K. Canada, where evey airport gets a very forgettable 3 letter code, which seems randomly generated. That code serves as an IATA code, and also gets C for their ICAO code. And then you have Europe, where IATA codes are selected as 3 letters to refer to the city or airport, but all the ICAO codes are unrelated, because they're usually sequencial in the way they were issued.