Of course now I'm wondering why NASA has all these guidelines for how to "safely" use an imperative language in the first place. Why not create a new language whose grammar and syntax makes it at least difficult, ideally impossible, to write problematic code in the first place? Why all the emphasis on after-the-fact checking tools?
1) Don't allow GOTO by not having it in the first place. For recursion, the first thought that occurs to me is that at run time, entry to a function first examines the stack to see if it's already there. Just in case static analysis misses this. A bit more time-consuming, yes, but contemporary processors are very fast.
2) Give loops a default bound. Explicitly change it if necessary. Make this built-in so everyone knows one is always there. Kind of like default array bounds in BASIC. You don't have to rely on them, but they're always there.
3) Don't like the heap? Don't have one. Darn thing fragments anyway.
4) It's easy enough to figure out the maximum number of characters on a page. Have the compiler barf if you try to feed it more than that.
5) Not sure how to automate this, aside from looking to see how they are often used in practice and trying to get the run-time package to check for the most common cases anyway.
6) Make it really hard to access data outside its declaration scope. I kind of like how in Python I can read a variable as long as it's in a higher scope, but I can't write it unless I somehow note that it's not in the current scope. That could be pushed to make both reading and writing an out of scope variable painful, and hence avoided whenever possible.
7) Make checking return value mandatory. Compile time failure if not done.
Don't like the preprocessor? Don't have one. It's mostly a kind of syntactic sugar anyway.
9) Fine, don't allow more than one level of de-reference (you can't even write such a thing). And don't make functions first-class objects that can be indirectly referenced.
10) Have the compiler sulk and refuse to create an object file if it sees the least little thing it doesn't like. That would lead to a lot of programmer frustration, but hey, we're talking safety here!
There could be a "C-NASA" version of the language, if you like. Might even be possible to eliminate some of the ambiguities along the way. No more "undefined behavior" quirks.
I'm just going to note that the software for the Voyageur probes was created decades before these guidelines came into place. There was probably some system of checking in place even at that time. What happened to those? They seem to have worked well. Are the ones in place now easier, simpler or more effective?